diff --git a/.vscode/settings.json b/.vscode/settings.json index fd2040b..cfc7fc9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,17 @@ "downvotes", "godotenv", "upvotes" + ], + "sqltools.connections": [ + { + "previewLimit": 50, + "server": "nekiiinkognito.ru", + "port": 5432, + "askForPassword": true, + "driver": "PostgreSQL", + "name": "enshi", + "database": "postgres", + "username": "neki" + } ] } \ No newline at end of file diff --git a/enshi_back/db/create_migration.sh b/enshi_back/db/create_migration.sh new file mode 100755 index 0000000..dd0befb --- /dev/null +++ b/enshi_back/db/create_migration.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +NAME=$1 + +NEXT_INDEX=$(ls migrations/*.up.sql | wc -l) +NEXT_INDEX=$((NEXT_INDEX + 1)) + +UP_FILE="migrations/${NEXT_INDEX}_$NAME.up.sql" +DOWN_FILE="migrations/${NEXT_INDEX}_$NAME.down.sql" + +touch "$UP_FILE" "$DOWN_FILE" + +echo "Created migration files:" +echo " $UP_FILE" +echo " $DOWN_FILE" \ No newline at end of file diff --git a/enshi_back/db/go_queries/models.go b/enshi_back/db/go_queries/models.go index 5ac0f17..e8b0fa7 100644 --- a/enshi_back/db/go_queries/models.go +++ b/enshi_back/db/go_queries/models.go @@ -71,10 +71,11 @@ type PostVote struct { } type Profile struct { - UserID int64 `json:"user_id"` - Bio pgtype.Text `json:"bio"` - AvatarUrl pgtype.Text `json:"avatar_url"` - WebsiteUrl pgtype.Text `json:"website_url"` + UserID int64 `json:"user_id"` + Bio pgtype.Text `json:"bio"` + AvatarUrl pgtype.Text `json:"avatar_url"` + WebsiteUrl pgtype.Text `json:"website_url"` + EmailVerified pgtype.Bool `json:"email_verified"` } type Tag struct { diff --git a/enshi_back/db/go_queries/profiles_queries.sql.go b/enshi_back/db/go_queries/profiles_queries.sql.go index 0170142..70889c2 100644 --- a/enshi_back/db/go_queries/profiles_queries.sql.go +++ b/enshi_back/db/go_queries/profiles_queries.sql.go @@ -15,7 +15,7 @@ const clearProfileByUserId = `-- name: ClearProfileByUserId :one UPDATE public.profiles SET bio='', avatar_url='', website_url='' WHERE user_id=$1 -RETURNING user_id, bio, avatar_url, website_url +RETURNING user_id, bio, avatar_url, website_url, email_verified ` func (q *Queries) ClearProfileByUserId(ctx context.Context, userID int64) (Profile, error) { @@ -26,6 +26,7 @@ func (q *Queries) ClearProfileByUserId(ctx context.Context, userID int64) (Profi &i.Bio, &i.AvatarUrl, &i.WebsiteUrl, + &i.EmailVerified, ) return i, err } @@ -34,7 +35,7 @@ const createProfileForUser = `-- name: CreateProfileForUser :one INSERT INTO public.profiles (user_id, bio, avatar_url, website_url) VALUES($1, '', '', '') -RETURNING user_id, bio, avatar_url, website_url +RETURNING user_id, bio, avatar_url, website_url, email_verified ` func (q *Queries) CreateProfileForUser(ctx context.Context, userID int64) (Profile, error) { @@ -45,6 +46,7 @@ func (q *Queries) CreateProfileForUser(ctx context.Context, userID int64) (Profi &i.Bio, &i.AvatarUrl, &i.WebsiteUrl, + &i.EmailVerified, ) return i, err } @@ -60,7 +62,7 @@ func (q *Queries) DeleteProfileByUserId(ctx context.Context, userID int64) error } const getProfileByUserId = `-- name: GetProfileByUserId :one -SELECT user_id, bio, avatar_url, website_url FROM public.profiles WHERE user_id = $1 +SELECT user_id, bio, avatar_url, website_url, email_verified FROM public.profiles WHERE user_id = $1 ` func (q *Queries) GetProfileByUserId(ctx context.Context, userID int64) (Profile, error) { @@ -71,6 +73,7 @@ func (q *Queries) GetProfileByUserId(ctx context.Context, userID int64) (Profile &i.Bio, &i.AvatarUrl, &i.WebsiteUrl, + &i.EmailVerified, ) return i, err } @@ -79,7 +82,7 @@ const updateProfileByUserId = `-- name: UpdateProfileByUserId :one UPDATE public.profiles SET bio=$2, avatar_url=$3, website_url=$4 WHERE user_id=$1 -RETURNING user_id, bio, avatar_url, website_url +RETURNING user_id, bio, avatar_url, website_url, email_verified ` type UpdateProfileByUserIdParams struct { @@ -102,6 +105,7 @@ func (q *Queries) UpdateProfileByUserId(ctx context.Context, arg UpdateProfileBy &i.Bio, &i.AvatarUrl, &i.WebsiteUrl, + &i.EmailVerified, ) return i, err } diff --git a/enshi_back/db/migrations/0003_badge_table.down.sql b/enshi_back/db/migrations/0003_badge_table.down.sql new file mode 100644 index 0000000..096a689 --- /dev/null +++ b/enshi_back/db/migrations/0003_badge_table.down.sql @@ -0,0 +1 @@ +DROP TABLE badges; \ No newline at end of file diff --git a/enshi_back/db/migrations/0003_badge_table.up.sql b/enshi_back/db/migrations/0003_badge_table.up.sql new file mode 100644 index 0000000..6664e65 --- /dev/null +++ b/enshi_back/db/migrations/0003_badge_table.up.sql @@ -0,0 +1,4 @@ +CREATE TABLE IF NOT EXISTS public.badges( + id uuid PRIMARY KEY, + name VARCHAR(255) NOT NULL +) \ No newline at end of file diff --git a/enshi_back/db/migrations/01_migration.down.sql b/enshi_back/db/migrations/01_migration.down.sql new file mode 100644 index 0000000..27880f6 --- /dev/null +++ b/enshi_back/db/migrations/01_migration.down.sql @@ -0,0 +1,19 @@ +-- Drop the explicit index (if not dropped automatically with the table) +DROP INDEX IF EXISTS "public"."profiles_user_id_idx"; + +-- Drop tables in reverse order to avoid foreign key conflicts +DROP TABLE IF EXISTS "public"."profiles" CASCADE; +DROP TABLE IF EXISTS "public"."post_votes" CASCADE; +DROP TABLE IF EXISTS "public"."post_tags" CASCADE; +DROP TABLE IF EXISTS "public"."tags" CASCADE; +DROP TABLE IF EXISTS "public"."likes" CASCADE; +DROP TABLE IF EXISTS "public"."favorites" CASCADE; +DROP TABLE IF EXISTS "public"."comments" CASCADE; +DROP TABLE IF EXISTS "public"."bookmarks" CASCADE; +DROP TABLE IF EXISTS "public"."posts" CASCADE; +DROP TABLE IF EXISTS "public"."blogs" CASCADE; +DROP TABLE IF EXISTS "public"."users" CASCADE; +DROP TABLE IF EXISTS "public"."categories" CASCADE; + +-- Optionally, if the up migration created the schema (and you want to remove it): +-- DROP SCHEMA IF EXISTS "public" CASCADE; diff --git a/enshi_back/db/migrations/01_migration.up.sql b/enshi_back/db/migrations/01_migration.up.sql new file mode 100644 index 0000000..6ffcddb --- /dev/null +++ b/enshi_back/db/migrations/01_migration.up.sql @@ -0,0 +1,121 @@ +CREATE SCHEMA IF NOT EXISTS "public"; + +-- Create "categories" table +CREATE TABLE IF NOT EXISTS "public"."categories" ( + "category_id" integer NOT NULL, + "category_name" character varying(50) NOT NULL, + PRIMARY KEY ("category_id"), + CONSTRAINT "categories_category_name_key" UNIQUE ("category_name") +); +-- Create "users" table +CREATE TABLE IF NOT EXISTS "public"."users" ( + "user_id" bigint NOT NULL, + "username" character varying(50) NOT NULL, + "email" character varying(100) NOT NULL, + "password" character varying(255) NOT NULL, + "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, + "is_admin" boolean NOT NULL, + "display_name" character varying(32) NULL, + PRIMARY KEY ("user_id"), + CONSTRAINT "users_email_key" UNIQUE ("email"), + CONSTRAINT "users_username_key" UNIQUE ("username") +); +-- Create "blogs" table +CREATE TABLE IF NOT EXISTS "public"."blogs" ( + "blog_id" bigint NOT NULL, + "user_id" bigint NOT NULL, + "title" character varying(255) NULL, + "description" text NULL, + "category_id" integer NULL, + "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY ("blog_id"), + CONSTRAINT "blogs_category_id_fkey" FOREIGN KEY ("category_id") REFERENCES "public"."categories" ("category_id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "blogs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create "posts" table +CREATE TABLE IF NOT EXISTS "public"."posts" ( + "post_id" bigint NOT NULL, + "blog_id" bigint NULL, + "user_id" bigint NOT NULL, + "title" character varying(255) NULL, + "content" text NULL, + "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY ("post_id"), + CONSTRAINT "posts_blog_id_fkey" FOREIGN KEY ("blog_id") REFERENCES "public"."blogs" ("blog_id") ON UPDATE NO ACTION ON DELETE CASCADE, + CONSTRAINT "posts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create "bookmarks" table +CREATE TABLE IF NOT EXISTS "public"."bookmarks" ( + "user_id" bigint NOT NULL, + "post_id" bigint NOT NULL, + "bookmarked_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY ("user_id", "post_id"), + CONSTRAINT "bookmarks_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, + CONSTRAINT "bookmarks_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create "comments" table +CREATE TABLE IF NOT EXISTS "public"."comments" ( + "comment_id" bigint NOT NULL, + "post_id" bigint NULL, + "user_id" bigint NULL, + "content" text NULL, + "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY ("comment_id"), + CONSTRAINT "comments_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, + CONSTRAINT "comments_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create "favorites" table +CREATE TABLE IF NOT EXISTS "public"."favorites" ( + "user_id" bigint NOT NULL, + "blog_id" bigint NOT NULL, + "favorited_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY ("user_id", "blog_id"), + CONSTRAINT "favorites_blog_id_fkey" FOREIGN KEY ("blog_id") REFERENCES "public"."blogs" ("blog_id") ON UPDATE NO ACTION ON DELETE CASCADE, + CONSTRAINT "favorites_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create "likes" table +CREATE TABLE IF NOT EXISTS "public"."likes" ( + "like_id" bigint NOT NULL, + "user_id" bigint NULL, + "comment_id" bigint NULL, + "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY ("like_id"), + CONSTRAINT "likes_comment_id_fkey" FOREIGN KEY ("comment_id") REFERENCES "public"."comments" ("comment_id") ON UPDATE NO ACTION ON DELETE CASCADE, + CONSTRAINT "likes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create "tags" table +CREATE TABLE IF NOT EXISTS "public"."tags" ( + "tag_id" integer NOT NULL, + "tag_name" character varying(50) NOT NULL, + PRIMARY KEY ("tag_id"), + CONSTRAINT "tags_tag_name_key" UNIQUE ("tag_name") +); +-- Create "post_tags" table +CREATE TABLE IF NOT EXISTS "public"."post_tags" ( + "post_id" bigint NOT NULL, + "tag_id" integer NOT NULL, + PRIMARY KEY ("post_id", "tag_id"), + CONSTRAINT "post_tags_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, + CONSTRAINT "post_tags_tag_id_fkey" FOREIGN KEY ("tag_id") REFERENCES "public"."tags" ("tag_id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create "post_votes" table +CREATE TABLE IF NOT EXISTS "public"."post_votes" ( + "post_id" bigint NOT NULL, + "user_id" bigint NOT NULL, + "vote" boolean NOT NULL, + PRIMARY KEY ("post_id", "user_id"), + CONSTRAINT "post_votes_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, + CONSTRAINT "post_votes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "profiles" table +CREATE TABLE IF NOT EXISTS "public"."profiles" ( + "user_id" bigint NOT NULL, + "bio" text NULL, + "avatar_url" character varying(255) NULL, + "website_url" character varying(100) NULL, + PRIMARY KEY ("user_id"), + CONSTRAINT "profiles_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create index "profiles_user_id_idx" to table: "profiles" +CREATE UNIQUE INDEX IF NOT EXISTS "profiles_user_id_idx" ON "public"."profiles" ("user_id"); diff --git a/enshi_back/db/migrations/02_migration.down.sql b/enshi_back/db/migrations/02_migration.down.sql new file mode 100644 index 0000000..74adef8 --- /dev/null +++ b/enshi_back/db/migrations/02_migration.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE profiles + DROP COLUMN email_verified; diff --git a/enshi_back/db/migrations/02_migration.up.sql b/enshi_back/db/migrations/02_migration.up.sql new file mode 100644 index 0000000..d38d75d --- /dev/null +++ b/enshi_back/db/migrations/02_migration.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE profiles +ADD COLUMN email_verified BOOLEAN DEFAULT FALSE; \ No newline at end of file diff --git a/enshi_back/db/migrations/migration1.sql b/enshi_back/db/migrations/migration1.sql deleted file mode 100644 index 30d2fb5..0000000 --- a/enshi_back/db/migrations/migration1.sql +++ /dev/null @@ -1,30 +0,0 @@ --- Add new schema named "public" -CREATE SCHEMA IF NOT EXISTS "public"; --- Set comment to schema: "public" -COMMENT ON SCHEMA "public" IS 'standard public schema'; --- Create "categories" table -CREATE TABLE "public"."categories" ("category_id" integer NOT NULL, "category_name" character varying(50) NOT NULL, PRIMARY KEY ("category_id"), CONSTRAINT "categories_category_name_key" UNIQUE ("category_name")); --- Create "users" table -CREATE TABLE "public"."users" ("user_id" bigint NOT NULL, "username" character varying(50) NOT NULL, "email" character varying(100) NOT NULL, "password" character varying(255) NOT NULL, "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, "is_admin" boolean NOT NULL, "display_name" character varying(32) NULL, PRIMARY KEY ("user_id"), CONSTRAINT "users_email_key" UNIQUE ("email"), CONSTRAINT "users_username_key" UNIQUE ("username")); --- Create "blogs" table -CREATE TABLE "public"."blogs" ("blog_id" bigint NOT NULL, "user_id" bigint NOT NULL, "title" character varying(255) NULL, "description" text NULL, "category_id" integer NULL, "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("blog_id"), CONSTRAINT "blogs_category_id_fkey" FOREIGN KEY ("category_id") REFERENCES "public"."categories" ("category_id") ON UPDATE NO ACTION ON DELETE NO ACTION, CONSTRAINT "blogs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE); --- Create "posts" table -CREATE TABLE "public"."posts" ("post_id" bigint NOT NULL, "blog_id" bigint NULL, "user_id" bigint NOT NULL, "title" character varying(255) NULL, "content" text NULL, "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("post_id"), CONSTRAINT "posts_blog_id_fkey" FOREIGN KEY ("blog_id") REFERENCES "public"."blogs" ("blog_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "posts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE); --- Create "bookmarks" table -CREATE TABLE "public"."bookmarks" ("user_id" bigint NOT NULL, "post_id" bigint NOT NULL, "bookmarked_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("user_id", "post_id"), CONSTRAINT "bookmarks_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "bookmarks_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE); --- Create "comments" table -CREATE TABLE "public"."comments" ("comment_id" bigint NOT NULL, "post_id" bigint NULL, "user_id" bigint NULL, "content" text NULL, "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("comment_id"), CONSTRAINT "comments_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "comments_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE); --- Create "favorites" table -CREATE TABLE "public"."favorites" ("user_id" bigint NOT NULL, "blog_id" bigint NOT NULL, "favorited_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("user_id", "blog_id"), CONSTRAINT "favorites_blog_id_fkey" FOREIGN KEY ("blog_id") REFERENCES "public"."blogs" ("blog_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "favorites_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE); --- Create "likes" table -CREATE TABLE "public"."likes" ("like_id" bigint NOT NULL, "user_id" bigint NULL, "comment_id" bigint NULL, "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("like_id"), CONSTRAINT "likes_comment_id_fkey" FOREIGN KEY ("comment_id") REFERENCES "public"."comments" ("comment_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "likes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE); --- Create "tags" table -CREATE TABLE "public"."tags" ("tag_id" integer NOT NULL, "tag_name" character varying(50) NOT NULL, PRIMARY KEY ("tag_id"), CONSTRAINT "tags_tag_name_key" UNIQUE ("tag_name")); --- Create "post_tags" table -CREATE TABLE "public"."post_tags" ("post_id" bigint NOT NULL, "tag_id" integer NOT NULL, PRIMARY KEY ("post_id", "tag_id"), CONSTRAINT "post_tags_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "post_tags_tag_id_fkey" FOREIGN KEY ("tag_id") REFERENCES "public"."tags" ("tag_id") ON UPDATE NO ACTION ON DELETE CASCADE); --- Create "post_votes" table -CREATE TABLE "public"."post_votes" ("post_id" bigint NOT NULL, "user_id" bigint NOT NULL, "vote" boolean NOT NULL, PRIMARY KEY ("post_id", "user_id"), CONSTRAINT "post_votes_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "post_votes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE NO ACTION); --- Create "profiles" table -CREATE TABLE "public"."profiles" ("user_id" bigint NOT NULL, "bio" text NULL, "avatar_url" character varying(255) NULL, "website_url" character varying(100) NULL, PRIMARY KEY ("user_id"), CONSTRAINT "profiles_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE); --- Create index "profiles_user_id_idx" to table: "profiles" -CREATE UNIQUE INDEX "profiles_user_id_idx" ON "public"."profiles" ("user_id");