diff --git a/bun.lockb b/bun.lockb index 541186b4a229c7a1084630a8380ec367adcb78ba..eb973bacbb595524c04f0abd0000e6b6fc16a0d4 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/src/db/migrations/0003_tired_stone_men.sql b/src/db/migrations/0000_flawless_scarecrow.sql similarity index 96% rename from src/db/migrations/0003_tired_stone_men.sql rename to src/db/migrations/0000_flawless_scarecrow.sql index a5140ea269ed7f2a723c263772f0162cd469269a..b967690873d903b71f6d4846f9cddd8ce2de86ff 100644 --- a/src/db/migrations/0003_tired_stone_men.sql +++ b/src/db/migrations/0000_flawless_scarecrow.sql @@ -66,6 +66,17 @@ CREATE TABLE IF NOT EXISTS "collections" ( CONSTRAINT "collections_id_unique" UNIQUE("id") ); --> statement-breakpoint +CREATE TABLE IF NOT EXISTS "commentReply" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "comment_id" integer NOT NULL, + "text" text NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "deleted_at" timestamp, + "update_at" timestamp DEFAULT now() NOT NULL, + CONSTRAINT "commentReply_id_unique" UNIQUE("id") +); +--> statement-breakpoint CREATE TABLE IF NOT EXISTS "comments" ( "id" serial PRIMARY KEY NOT NULL, "user_id" integer NOT NULL, @@ -206,6 +217,7 @@ CREATE TABLE IF NOT EXISTS "resource_stats" ( "shares" integer DEFAULT 0 NOT NULL, "score" numeric DEFAULT '0.0' NOT NULL, "follows" integer DEFAULT 0 NOT NULL, + "comments" integer DEFAULT 0 NOT NULL, CONSTRAINT "resource_stats_id_unique" UNIQUE("id") ); --> statement-breakpoint @@ -376,6 +388,18 @@ EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "commentReply" ADD CONSTRAINT "commentReply_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "commentReply" ADD CONSTRAINT "commentReply_comment_id_comments_id_fk" FOREIGN KEY ("comment_id") REFERENCES "public"."comments"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint DO $$ BEGIN ALTER TABLE "comments" ADD CONSTRAINT "comments_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION diff --git a/src/db/migrations/0000_secret_sharon_ventura.sql b/src/db/migrations/0000_secret_sharon_ventura.sql deleted file mode 100644 index b18047a75834101b6c1688049597c4b6887881a2..0000000000000000000000000000000000000000 --- a/src/db/migrations/0000_secret_sharon_ventura.sql +++ /dev/null @@ -1,588 +0,0 @@ -DO $$ BEGIN - CREATE TYPE "public"."state" AS ENUM('active', 'inactive', 'under_review'); -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "achievements" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "description" text, - "reward_experience" numeric, - "reward_points" numeric, - "state" "state" DEFAULT 'inactive' NOT NULL, - "repeatable" integer NOT NULL, - "is_resettable" boolean NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "achievements_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "actions" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "actions_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "collection_likes" ( - "id" serial PRIMARY KEY NOT NULL, - "user_id" integer NOT NULL, - "collection" integer NOT NULL, - CONSTRAINT "collection_likes_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "collection_resources" ( - "id" serial PRIMARY KEY NOT NULL, - "collection_id" integer NOT NULL, - "resource_id" integer NOT NULL, - CONSTRAINT "collection_resources_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "collection_stats" ( - "id" serial PRIMARY KEY NOT NULL, - "views" integer DEFAULT 0 NOT NULL, - "downloads" integer DEFAULT 0 NOT NULL, - "likes" integer DEFAULT 0 NOT NULL, - "shares" integer DEFAULT 0 NOT NULL, - "score" numeric DEFAULT '0.0' NOT NULL, - "follows" integer DEFAULT 0 NOT NULL, - CONSTRAINT "collection_stats_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "collections" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255), - "description" text, - "is_private" boolean DEFAULT false, - "is_active" boolean DEFAULT true, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - "deleted_at" timestamp, - "thumbnail" varchar(255), - "user_id" integer NOT NULL, - "collection_stats_id" integer NOT NULL, - CONSTRAINT "collections_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "complaints" ( - "id" serial PRIMARY KEY NOT NULL, - "state" "state" DEFAULT 'under_review' NOT NULL, - "description" text NOT NULL, - "denouncer_id" integer NOT NULL, - "resource_id" integer NOT NULL, - "collection_id" integer, - "user_id" integer, - "evaluated_at" timestamp, - "created_at" timestamp DEFAULT now() NOT NULL, - "q1" boolean, - "q2" boolean, - "q3" boolean, - "q4" boolean, - CONSTRAINT "complaints_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "educational_stages" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - CONSTRAINT "educational_stages_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "followers" ( - "id" serial PRIMARY KEY NOT NULL, - "user_id" integer NOT NULL, - "follower_id" integer NOT NULL, - CONSTRAINT "followers_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "institutions" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "uf" varchar(2), - "city" varchar(255), - "cep" varchar(10), - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "institutions_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "items" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "price" numeric, - "discount" numeric, - "description" text, - "is_active" boolean DEFAULT false, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - "achievement_id" integer, - CONSTRAINT "items_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "languages" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "code" varchar(10) NOT NULL, - CONSTRAINT "languages_id_unique" UNIQUE("id"), - CONSTRAINT "languages_code_unique" UNIQUE("code") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "licenses" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "description" text NOT NULL, - "url" varchar(255) NOT NULL, - CONSTRAINT "licenses_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "notifications" ( - "id" serial PRIMARY KEY NOT NULL, - "action_id" integer NOT NULL, - "actor_user_id" integer NOT NULL, - "target_user_id" integer NOT NULL, - "target_resource_id" integer, - "target_collection_id" integer, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "notifications_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "object_types" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - CONSTRAINT "object_types_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "reset_tickets" ( - "id" serial PRIMARY KEY NOT NULL, - "user_id" integer NOT NULL, - "token_hash" varchar(255) NOT NULL, - "expiration_date" timestamp NOT NULL, - "token_used" boolean DEFAULT false NOT NULL, - "valid_token" boolean DEFAULT true NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "reset_tickets_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "resource_educational_stages" ( - "id" serial PRIMARY KEY NOT NULL, - "resource_id" integer NOT NULL, - "educational_stage_id" integer NOT NULL, - CONSTRAINT "resource_educational_stages_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "resource_languages" ( - "id" serial PRIMARY KEY NOT NULL, - "resource_id" integer NOT NULL, - "language_id" integer NOT NULL, - CONSTRAINT "resource_languages_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "resource_likes" ( - "id" serial PRIMARY KEY NOT NULL, - "user_id" integer NOT NULL, - "resource_id" integer NOT NULL, - CONSTRAINT "resource_likes_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "resource_stats" ( - "id" serial PRIMARY KEY NOT NULL, - "views" integer DEFAULT 0 NOT NULL, - "downloads" integer DEFAULT 0 NOT NULL, - "likes" integer DEFAULT 0 NOT NULL, - "shares" integer DEFAULT 0 NOT NULL, - "score" numeric DEFAULT '0.0' NOT NULL, - "follows" integer DEFAULT 0 NOT NULL, - CONSTRAINT "resource_stats_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "resource_subjects" ( - "id" serial PRIMARY KEY NOT NULL, - "resource_id" integer NOT NULL, - "subject_id" integer NOT NULL, - CONSTRAINT "resource_subjects_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "resources" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "author" varchar(255) NOT NULL, - "bucket_key" varchar(255), - "link" varchar(255), - "thumbnail" varchar(255) NOT NULL, - "description" text, - "active" boolean DEFAULT false NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - "published_at" timestamp, - "submitted_at" timestamp, - "deleted_at" timestamp, - "user_id" integer NOT NULL, - "resource_stats_id" integer NOT NULL, - "object_type_id" integer NOT NULL, - "license_id" integer NOT NULL, - CONSTRAINT "resources_id_unique" UNIQUE("id"), - CONSTRAINT "resources_bucket_key_unique" UNIQUE("bucket_key"), - CONSTRAINT "resources_resource_stats_id_unique" UNIQUE("resource_stats_id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "roles" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "description" text, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "roles_id_unique" UNIQUE("id"), - CONSTRAINT "roles_name_unique" UNIQUE("name") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "subjects" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - CONSTRAINT "subjects_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "submissions" ( - "id" serial PRIMARY KEY NOT NULL, - "is_accepted" boolean DEFAULT false NOT NULL, - "justification" text, - "resource_id" integer NOT NULL, - "submitter_id" integer NOT NULL, - "curator_id" integer, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - "answered_at" timestamp, - "q1" boolean, - "q2" boolean, - "q3" boolean, - "q4" boolean, - CONSTRAINT "submissions_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "user_achievements" ( - "id" serial PRIMARY KEY NOT NULL, - "user_id" integer NOT NULL, - "achievement_id" integer NOT NULL, - CONSTRAINT "user_achievements_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "user_institutions" ( - "id" serial PRIMARY KEY NOT NULL, - "user_id" integer NOT NULL, - "institution_id" integer NOT NULL, - CONSTRAINT "user_institutions_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "user_items" ( - "id" serial PRIMARY KEY NOT NULL, - "user_id" integer NOT NULL, - "item_id" integer NOT NULL, - CONSTRAINT "user_items_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "user_roles" ( - "id" serial PRIMARY KEY NOT NULL, - "user_id" integer NOT NULL, - "role_id" integer NOT NULL, - CONSTRAINT "user_roles_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "user_stats" ( - "id" serial PRIMARY KEY NOT NULL, - "score" numeric DEFAULT '0.0' NOT NULL, - "likes" integer DEFAULT 0 NOT NULL, - "likes_received" integer DEFAULT 0 NOT NULL, - "follows" integer DEFAULT 0 NOT NULL, - "followers" integer DEFAULT 0 NOT NULL, - "collections" integer DEFAULT 0 NOT NULL, - "submitted_resources" integer DEFAULT 0 NOT NULL, - "approved_resources" integer DEFAULT 0 NOT NULL, - "reviewed_resources" integer DEFAULT 0 NOT NULL, - "comments" integer DEFAULT 0 NOT NULL, - CONSTRAINT "user_stats_id_unique" UNIQUE("id") -); ---> statement-breakpoint -CREATE TABLE IF NOT EXISTS "users" ( - "id" serial PRIMARY KEY NOT NULL, - "name" varchar(255) NOT NULL, - "username" varchar(255) NOT NULL, - "password" varchar(255) NOT NULL, - "email" varchar(255) NOT NULL, - "description" text DEFAULT 'sem descrição', - "institution" text DEFAULT 'sem instituição', - "birthday" timestamp NOT NULL, - "cpf" varchar(11) NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - "confirmed_at" timestamp, - "confirmation_sent_at" timestamp, - "deleted_at" timestamp, - "reactivated_at" timestamp, - "active" boolean DEFAULT true, - "user_stats_id" integer NOT NULL, - CONSTRAINT "users_id_unique" UNIQUE("id"), - CONSTRAINT "users_username_unique" UNIQUE("username"), - CONSTRAINT "users_email_unique" UNIQUE("email"), - CONSTRAINT "users_cpf_unique" UNIQUE("cpf"), - CONSTRAINT "users_user_stats_id_unique" UNIQUE("user_stats_id") -); ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "collection_likes" ADD CONSTRAINT "collection_likes_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "collection_likes" ADD CONSTRAINT "collection_likes_collection_collections_id_fk" FOREIGN KEY ("collection") REFERENCES "public"."collections"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "collection_resources" ADD CONSTRAINT "collection_resources_collection_id_collections_id_fk" FOREIGN KEY ("collection_id") REFERENCES "public"."collections"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "collection_resources" ADD CONSTRAINT "collection_resources_resource_id_resources_id_fk" FOREIGN KEY ("resource_id") REFERENCES "public"."resources"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "collections" ADD CONSTRAINT "collections_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "collections" ADD CONSTRAINT "collections_collection_stats_id_collection_stats_id_fk" FOREIGN KEY ("collection_stats_id") REFERENCES "public"."collection_stats"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "complaints" ADD CONSTRAINT "complaints_denouncer_id_users_id_fk" FOREIGN KEY ("denouncer_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "complaints" ADD CONSTRAINT "complaints_resource_id_resources_id_fk" FOREIGN KEY ("resource_id") REFERENCES "public"."resources"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "complaints" ADD CONSTRAINT "complaints_collection_id_collections_id_fk" FOREIGN KEY ("collection_id") REFERENCES "public"."collections"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "complaints" ADD CONSTRAINT "complaints_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "followers" ADD CONSTRAINT "followers_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "followers" ADD CONSTRAINT "followers_follower_id_users_id_fk" FOREIGN KEY ("follower_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "items" ADD CONSTRAINT "items_achievement_id_achievements_id_fk" FOREIGN KEY ("achievement_id") REFERENCES "public"."achievements"("id") ON DELETE no action ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "notifications" ADD CONSTRAINT "notifications_action_id_actions_id_fk" FOREIGN KEY ("action_id") REFERENCES "public"."actions"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "notifications" ADD CONSTRAINT "notifications_actor_user_id_users_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "notifications" ADD CONSTRAINT "notifications_target_user_id_users_id_fk" FOREIGN KEY ("target_user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "notifications" ADD CONSTRAINT "notifications_target_resource_id_resources_id_fk" FOREIGN KEY ("target_resource_id") REFERENCES "public"."resources"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "notifications" ADD CONSTRAINT "notifications_target_collection_id_collections_id_fk" FOREIGN KEY ("target_collection_id") REFERENCES "public"."collections"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "reset_tickets" ADD CONSTRAINT "reset_tickets_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resource_educational_stages" ADD CONSTRAINT "resource_educational_stages_resource_id_resources_id_fk" FOREIGN KEY ("resource_id") REFERENCES "public"."resources"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resource_educational_stages" ADD CONSTRAINT "resource_educational_stages_educational_stage_id_educational_stages_id_fk" FOREIGN KEY ("educational_stage_id") REFERENCES "public"."educational_stages"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resource_languages" ADD CONSTRAINT "resource_languages_resource_id_resources_id_fk" FOREIGN KEY ("resource_id") REFERENCES "public"."resources"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resource_languages" ADD CONSTRAINT "resource_languages_language_id_languages_id_fk" FOREIGN KEY ("language_id") REFERENCES "public"."languages"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resource_likes" ADD CONSTRAINT "resource_likes_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resource_likes" ADD CONSTRAINT "resource_likes_resource_id_resources_id_fk" FOREIGN KEY ("resource_id") REFERENCES "public"."resources"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resource_subjects" ADD CONSTRAINT "resource_subjects_resource_id_resources_id_fk" FOREIGN KEY ("resource_id") REFERENCES "public"."resources"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resource_subjects" ADD CONSTRAINT "resource_subjects_subject_id_subjects_id_fk" FOREIGN KEY ("subject_id") REFERENCES "public"."subjects"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resources" ADD CONSTRAINT "resources_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resources" ADD CONSTRAINT "resources_resource_stats_id_resource_stats_id_fk" FOREIGN KEY ("resource_stats_id") REFERENCES "public"."resource_stats"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resources" ADD CONSTRAINT "resources_object_type_id_object_types_id_fk" FOREIGN KEY ("object_type_id") REFERENCES "public"."object_types"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "resources" ADD CONSTRAINT "resources_license_id_licenses_id_fk" FOREIGN KEY ("license_id") REFERENCES "public"."licenses"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "submissions" ADD CONSTRAINT "submissions_resource_id_resources_id_fk" FOREIGN KEY ("resource_id") REFERENCES "public"."resources"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "submissions" ADD CONSTRAINT "submissions_submitter_id_users_id_fk" FOREIGN KEY ("submitter_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "submissions" ADD CONSTRAINT "submissions_curator_id_users_id_fk" FOREIGN KEY ("curator_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "user_achievements" ADD CONSTRAINT "user_achievements_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "user_achievements" ADD CONSTRAINT "user_achievements_achievement_id_users_id_fk" FOREIGN KEY ("achievement_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "user_institutions" ADD CONSTRAINT "user_institutions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "user_institutions" ADD CONSTRAINT "user_institutions_institution_id_institutions_id_fk" FOREIGN KEY ("institution_id") REFERENCES "public"."institutions"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "user_items" ADD CONSTRAINT "user_items_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "user_items" ADD CONSTRAINT "user_items_item_id_items_id_fk" FOREIGN KEY ("item_id") REFERENCES "public"."items"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_role_id_roles_id_fk" FOREIGN KEY ("role_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "users" ADD CONSTRAINT "users_user_stats_id_user_stats_id_fk" FOREIGN KEY ("user_stats_id") REFERENCES "public"."user_stats"("id") ON DELETE no action ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; diff --git a/src/db/migrations/0001_odd_valkyrie.sql b/src/db/migrations/0001_odd_valkyrie.sql new file mode 100644 index 0000000000000000000000000000000000000000..884fc4d10fd0e8165d397081e77da696b8e3838c --- /dev/null +++ b/src/db/migrations/0001_odd_valkyrie.sql @@ -0,0 +1,18 @@ +CREATE TABLE IF NOT EXISTS "userCollections" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "collection_id" integer NOT NULL, + CONSTRAINT "userCollections_id_unique" UNIQUE("id") +); +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "userCollections" ADD CONSTRAINT "userCollections_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "userCollections" ADD CONSTRAINT "userCollections_collection_id_collections_id_fk" FOREIGN KEY ("collection_id") REFERENCES "public"."collections"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; diff --git a/src/db/migrations/0001_strange_famine.sql b/src/db/migrations/0001_strange_famine.sql deleted file mode 100644 index f705a5388412582fcfa03035ee57c1802576994d..0000000000000000000000000000000000000000 --- a/src/db/migrations/0001_strange_famine.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "users" DROP CONSTRAINT "users_username_unique"; \ No newline at end of file diff --git a/src/db/migrations/0002_sleepy_vin_gonzales.sql b/src/db/migrations/0002_sleepy_vin_gonzales.sql deleted file mode 100644 index 1292179562bd15de630a369dd759b659370d856a..0000000000000000000000000000000000000000 --- a/src/db/migrations/0002_sleepy_vin_gonzales.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "users" ADD CONSTRAINT "users_username_unique" UNIQUE("username"); \ No newline at end of file diff --git a/src/db/migrations/0004_useful_paper_doll.sql b/src/db/migrations/0004_useful_paper_doll.sql deleted file mode 100644 index 2927b5a1760d3014b975aacd2daca5e2a28ff71c..0000000000000000000000000000000000000000 --- a/src/db/migrations/0004_useful_paper_doll.sql +++ /dev/null @@ -1,22 +0,0 @@ -CREATE TABLE IF NOT EXISTS "commentReply" ( - "id" serial PRIMARY KEY NOT NULL, - "user_id" integer NOT NULL, - "comment_id" integer NOT NULL, - "text" text NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "deleted_at" timestamp, - "update_at" timestamp DEFAULT now() NOT NULL, - CONSTRAINT "commentReply_id_unique" UNIQUE("id") -); ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "commentReply" ADD CONSTRAINT "commentReply_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "commentReply" ADD CONSTRAINT "commentReply_comment_id_comments_id_fk" FOREIGN KEY ("comment_id") REFERENCES "public"."comments"("id") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; diff --git a/src/db/migrations/0005_eager_darkstar.sql b/src/db/migrations/0005_eager_darkstar.sql deleted file mode 100644 index 96894d5b0079d30ce0c34b32902b383f4924d747..0000000000000000000000000000000000000000 --- a/src/db/migrations/0005_eager_darkstar.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "resource_stats" ADD COLUMN "comments" integer DEFAULT 0 NOT NULL; \ No newline at end of file diff --git a/src/db/migrations/meta/0005_snapshot.json b/src/db/migrations/meta/0000_snapshot.json similarity index 99% rename from src/db/migrations/meta/0005_snapshot.json rename to src/db/migrations/meta/0000_snapshot.json index 6ec69bea3589a85c145d72b6440786d53bddf0ba..d7bd906ef97efcbe6802a0e3e0484a3268a558ee 100644 --- a/src/db/migrations/meta/0005_snapshot.json +++ b/src/db/migrations/meta/0000_snapshot.json @@ -1,6 +1,6 @@ { - "id": "5b878977-1a6e-45e4-8290-26e30a5be5b5", - "prevId": "e2262718-fe9a-4922-8886-5b981115dce9", + "id": "e5bfc3f7-888b-4164-9ff2-fe7328153ca6", + "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", "tables": { diff --git a/src/db/migrations/meta/0004_snapshot.json b/src/db/migrations/meta/0001_snapshot.json similarity index 97% rename from src/db/migrations/meta/0004_snapshot.json rename to src/db/migrations/meta/0001_snapshot.json index f52c13c023bb88696174bfd86b06aa82ab817cec..a63aea56bd8017b06fa3435f486c364a1d444d8d 100644 --- a/src/db/migrations/meta/0004_snapshot.json +++ b/src/db/migrations/meta/0001_snapshot.json @@ -1,6 +1,6 @@ { - "id": "e2262718-fe9a-4922-8886-5b981115dce9", - "prevId": "9a77c1e8-63d4-4588-9c9f-bb93ff5fa910", + "id": "8bb70cc6-4e1b-4435-baaa-8d1a6917165f", + "prevId": "e5bfc3f7-888b-4164-9ff2-fe7328153ca6", "version": "7", "dialect": "postgresql", "tables": { @@ -1584,6 +1584,13 @@ "primaryKey": false, "notNull": true, "default": 0 + }, + "comments": { + "name": "comments", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 } }, "indexes": {}, @@ -2141,6 +2148,69 @@ } } }, + "public.userCollections": { + "name": "userCollections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "collection_id": { + "name": "collection_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "userCollections_user_id_users_id_fk": { + "name": "userCollections_user_id_users_id_fk", + "tableFrom": "userCollections", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "userCollections_collection_id_collections_id_fk": { + "name": "userCollections_collection_id_collections_id_fk", + "tableFrom": "userCollections", + "tableTo": "collections", + "columnsFrom": [ + "collection_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "userCollections_id_unique": { + "name": "userCollections_id_unique", + "nullsNotDistinct": false, + "columns": [ + "id" + ] + } + } + }, "public.user_institutions": { "name": "user_institutions", "schema": "", diff --git a/src/db/migrations/meta/0003_snapshot.json b/src/db/migrations/meta/0003_snapshot.json deleted file mode 100644 index a71853c608b61810c0403e7a7c4d9005ce4aa7c7..0000000000000000000000000000000000000000 --- a/src/db/migrations/meta/0003_snapshot.json +++ /dev/null @@ -1,2523 +0,0 @@ -{ - "id": "9a77c1e8-63d4-4588-9c9f-bb93ff5fa910", - "prevId": "00000000-0000-0000-0000-000000000000", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.achievements": { - "name": "achievements", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "reward_experience": { - "name": "reward_experience", - "type": "numeric", - "primaryKey": false, - "notNull": false - }, - "reward_points": { - "name": "reward_points", - "type": "numeric", - "primaryKey": false, - "notNull": false - }, - "state": { - "name": "state", - "type": "state", - "typeSchema": "public", - "primaryKey": false, - "notNull": true, - "default": "'inactive'" - }, - "repeatable": { - "name": "repeatable", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "is_resettable": { - "name": "is_resettable", - "type": "boolean", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "achievements_id_unique": { - "name": "achievements_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.actions": { - "name": "actions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "actions_id_unique": { - "name": "actions_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.collection_likes": { - "name": "collection_likes", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "collection": { - "name": "collection", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "collection_likes_user_id_users_id_fk": { - "name": "collection_likes_user_id_users_id_fk", - "tableFrom": "collection_likes", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "collection_likes_collection_collections_id_fk": { - "name": "collection_likes_collection_collections_id_fk", - "tableFrom": "collection_likes", - "tableTo": "collections", - "columnsFrom": [ - "collection" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "collection_likes_id_unique": { - "name": "collection_likes_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.collection_resources": { - "name": "collection_resources", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "collection_id": { - "name": "collection_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "resource_id": { - "name": "resource_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "collection_resources_collection_id_collections_id_fk": { - "name": "collection_resources_collection_id_collections_id_fk", - "tableFrom": "collection_resources", - "tableTo": "collections", - "columnsFrom": [ - "collection_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "collection_resources_resource_id_resources_id_fk": { - "name": "collection_resources_resource_id_resources_id_fk", - "tableFrom": "collection_resources", - "tableTo": "resources", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "collection_resources_id_unique": { - "name": "collection_resources_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.collection_stats": { - "name": "collection_stats", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "views": { - "name": "views", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "downloads": { - "name": "downloads", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "likes": { - "name": "likes", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "shares": { - "name": "shares", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "score": { - "name": "score", - "type": "numeric", - "primaryKey": false, - "notNull": true, - "default": "'0.0'" - }, - "follows": { - "name": "follows", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "collection_stats_id_unique": { - "name": "collection_stats_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.collections": { - "name": "collections", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "is_private": { - "name": "is_private", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "deleted_at": { - "name": "deleted_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "thumbnail": { - "name": "thumbnail", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "collection_stats_id": { - "name": "collection_stats_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "collections_user_id_users_id_fk": { - "name": "collections_user_id_users_id_fk", - "tableFrom": "collections", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "collections_collection_stats_id_collection_stats_id_fk": { - "name": "collections_collection_stats_id_collection_stats_id_fk", - "tableFrom": "collections", - "tableTo": "collection_stats", - "columnsFrom": [ - "collection_stats_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "collections_id_unique": { - "name": "collections_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.comments": { - "name": "comments", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "resource_id": { - "name": "resource_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "text": { - "name": "text", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "deleted_at": { - "name": "deleted_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "update_at": { - "name": "update_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "comments_user_id_users_id_fk": { - "name": "comments_user_id_users_id_fk", - "tableFrom": "comments", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "comments_resource_id_resources_id_fk": { - "name": "comments_resource_id_resources_id_fk", - "tableFrom": "comments", - "tableTo": "resources", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "comments_id_unique": { - "name": "comments_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.complaints": { - "name": "complaints", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "state": { - "name": "state", - "type": "state", - "typeSchema": "public", - "primaryKey": false, - "notNull": true, - "default": "'under_review'" - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "denouncer_id": { - "name": "denouncer_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "resource_id": { - "name": "resource_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "collection_id": { - "name": "collection_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "evaluated_at": { - "name": "evaluated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "q1": { - "name": "q1", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "q2": { - "name": "q2", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "q3": { - "name": "q3", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "q4": { - "name": "q4", - "type": "boolean", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "complaints_denouncer_id_users_id_fk": { - "name": "complaints_denouncer_id_users_id_fk", - "tableFrom": "complaints", - "tableTo": "users", - "columnsFrom": [ - "denouncer_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "complaints_resource_id_resources_id_fk": { - "name": "complaints_resource_id_resources_id_fk", - "tableFrom": "complaints", - "tableTo": "resources", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "complaints_collection_id_collections_id_fk": { - "name": "complaints_collection_id_collections_id_fk", - "tableFrom": "complaints", - "tableTo": "collections", - "columnsFrom": [ - "collection_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "complaints_user_id_users_id_fk": { - "name": "complaints_user_id_users_id_fk", - "tableFrom": "complaints", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "complaints_id_unique": { - "name": "complaints_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.educational_stages": { - "name": "educational_stages", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "educational_stages_id_unique": { - "name": "educational_stages_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.followers": { - "name": "followers", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "follower_id": { - "name": "follower_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "followers_user_id_users_id_fk": { - "name": "followers_user_id_users_id_fk", - "tableFrom": "followers", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "followers_follower_id_users_id_fk": { - "name": "followers_follower_id_users_id_fk", - "tableFrom": "followers", - "tableTo": "users", - "columnsFrom": [ - "follower_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "followers_id_unique": { - "name": "followers_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.institutions": { - "name": "institutions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "uf": { - "name": "uf", - "type": "varchar(2)", - "primaryKey": false, - "notNull": false - }, - "city": { - "name": "city", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "cep": { - "name": "cep", - "type": "varchar(10)", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "institutions_id_unique": { - "name": "institutions_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.items": { - "name": "items", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "price": { - "name": "price", - "type": "numeric", - "primaryKey": false, - "notNull": false - }, - "discount": { - "name": "discount", - "type": "numeric", - "primaryKey": false, - "notNull": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "is_active": { - "name": "is_active", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "achievement_id": { - "name": "achievement_id", - "type": "integer", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "items_achievement_id_achievements_id_fk": { - "name": "items_achievement_id_achievements_id_fk", - "tableFrom": "items", - "tableTo": "achievements", - "columnsFrom": [ - "achievement_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "items_id_unique": { - "name": "items_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.languages": { - "name": "languages", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "code": { - "name": "code", - "type": "varchar(10)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "languages_id_unique": { - "name": "languages_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - }, - "languages_code_unique": { - "name": "languages_code_unique", - "nullsNotDistinct": false, - "columns": [ - "code" - ] - } - } - }, - "public.licenses": { - "name": "licenses", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "url": { - "name": "url", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "licenses_id_unique": { - "name": "licenses_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.notifications": { - "name": "notifications", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "action_id": { - "name": "action_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "actor_user_id": { - "name": "actor_user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "target_user_id": { - "name": "target_user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "target_resource_id": { - "name": "target_resource_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "target_collection_id": { - "name": "target_collection_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "notifications_action_id_actions_id_fk": { - "name": "notifications_action_id_actions_id_fk", - "tableFrom": "notifications", - "tableTo": "actions", - "columnsFrom": [ - "action_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "notifications_actor_user_id_users_id_fk": { - "name": "notifications_actor_user_id_users_id_fk", - "tableFrom": "notifications", - "tableTo": "users", - "columnsFrom": [ - "actor_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "notifications_target_user_id_users_id_fk": { - "name": "notifications_target_user_id_users_id_fk", - "tableFrom": "notifications", - "tableTo": "users", - "columnsFrom": [ - "target_user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "notifications_target_resource_id_resources_id_fk": { - "name": "notifications_target_resource_id_resources_id_fk", - "tableFrom": "notifications", - "tableTo": "resources", - "columnsFrom": [ - "target_resource_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "notifications_target_collection_id_collections_id_fk": { - "name": "notifications_target_collection_id_collections_id_fk", - "tableFrom": "notifications", - "tableTo": "collections", - "columnsFrom": [ - "target_collection_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "notifications_id_unique": { - "name": "notifications_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.object_types": { - "name": "object_types", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "object_types_id_unique": { - "name": "object_types_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.reset_tickets": { - "name": "reset_tickets", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "token_hash": { - "name": "token_hash", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "expiration_date": { - "name": "expiration_date", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "token_used": { - "name": "token_used", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "valid_token": { - "name": "valid_token", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "reset_tickets_user_id_users_id_fk": { - "name": "reset_tickets_user_id_users_id_fk", - "tableFrom": "reset_tickets", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "reset_tickets_id_unique": { - "name": "reset_tickets_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.resource_educational_stages": { - "name": "resource_educational_stages", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "resource_id": { - "name": "resource_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "educational_stage_id": { - "name": "educational_stage_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "resource_educational_stages_resource_id_resources_id_fk": { - "name": "resource_educational_stages_resource_id_resources_id_fk", - "tableFrom": "resource_educational_stages", - "tableTo": "resources", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "resource_educational_stages_educational_stage_id_educational_stages_id_fk": { - "name": "resource_educational_stages_educational_stage_id_educational_stages_id_fk", - "tableFrom": "resource_educational_stages", - "tableTo": "educational_stages", - "columnsFrom": [ - "educational_stage_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "resource_educational_stages_id_unique": { - "name": "resource_educational_stages_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.resource_languages": { - "name": "resource_languages", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "resource_id": { - "name": "resource_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "language_id": { - "name": "language_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "resource_languages_resource_id_resources_id_fk": { - "name": "resource_languages_resource_id_resources_id_fk", - "tableFrom": "resource_languages", - "tableTo": "resources", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "resource_languages_language_id_languages_id_fk": { - "name": "resource_languages_language_id_languages_id_fk", - "tableFrom": "resource_languages", - "tableTo": "languages", - "columnsFrom": [ - "language_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "resource_languages_id_unique": { - "name": "resource_languages_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.resource_likes": { - "name": "resource_likes", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "resource_id": { - "name": "resource_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "resource_likes_user_id_users_id_fk": { - "name": "resource_likes_user_id_users_id_fk", - "tableFrom": "resource_likes", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "resource_likes_resource_id_resources_id_fk": { - "name": "resource_likes_resource_id_resources_id_fk", - "tableFrom": "resource_likes", - "tableTo": "resources", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "resource_likes_id_unique": { - "name": "resource_likes_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.resource_stats": { - "name": "resource_stats", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "views": { - "name": "views", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "downloads": { - "name": "downloads", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "likes": { - "name": "likes", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "shares": { - "name": "shares", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "score": { - "name": "score", - "type": "numeric", - "primaryKey": false, - "notNull": true, - "default": "'0.0'" - }, - "follows": { - "name": "follows", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "resource_stats_id_unique": { - "name": "resource_stats_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.resource_subjects": { - "name": "resource_subjects", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "resource_id": { - "name": "resource_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "subject_id": { - "name": "subject_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "resource_subjects_resource_id_resources_id_fk": { - "name": "resource_subjects_resource_id_resources_id_fk", - "tableFrom": "resource_subjects", - "tableTo": "resources", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "resource_subjects_subject_id_subjects_id_fk": { - "name": "resource_subjects_subject_id_subjects_id_fk", - "tableFrom": "resource_subjects", - "tableTo": "subjects", - "columnsFrom": [ - "subject_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "resource_subjects_id_unique": { - "name": "resource_subjects_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.resources": { - "name": "resources", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "author": { - "name": "author", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "bucket_key": { - "name": "bucket_key", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "link": { - "name": "link", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "thumbnail": { - "name": "thumbnail", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "active": { - "name": "active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "published_at": { - "name": "published_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "submitted_at": { - "name": "submitted_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "deleted_at": { - "name": "deleted_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "resource_stats_id": { - "name": "resource_stats_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "object_type_id": { - "name": "object_type_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "license_id": { - "name": "license_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "resources_user_id_users_id_fk": { - "name": "resources_user_id_users_id_fk", - "tableFrom": "resources", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "resources_resource_stats_id_resource_stats_id_fk": { - "name": "resources_resource_stats_id_resource_stats_id_fk", - "tableFrom": "resources", - "tableTo": "resource_stats", - "columnsFrom": [ - "resource_stats_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "resources_object_type_id_object_types_id_fk": { - "name": "resources_object_type_id_object_types_id_fk", - "tableFrom": "resources", - "tableTo": "object_types", - "columnsFrom": [ - "object_type_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "resources_license_id_licenses_id_fk": { - "name": "resources_license_id_licenses_id_fk", - "tableFrom": "resources", - "tableTo": "licenses", - "columnsFrom": [ - "license_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "resources_id_unique": { - "name": "resources_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - }, - "resources_bucket_key_unique": { - "name": "resources_bucket_key_unique", - "nullsNotDistinct": false, - "columns": [ - "bucket_key" - ] - }, - "resources_resource_stats_id_unique": { - "name": "resources_resource_stats_id_unique", - "nullsNotDistinct": false, - "columns": [ - "resource_stats_id" - ] - } - } - }, - "public.roles": { - "name": "roles", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "roles_id_unique": { - "name": "roles_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - }, - "roles_name_unique": { - "name": "roles_name_unique", - "nullsNotDistinct": false, - "columns": [ - "name" - ] - } - } - }, - "public.subjects": { - "name": "subjects", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "subjects_id_unique": { - "name": "subjects_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.submissions": { - "name": "submissions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "is_accepted": { - "name": "is_accepted", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "justification": { - "name": "justification", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "resource_id": { - "name": "resource_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "submitter_id": { - "name": "submitter_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "curator_id": { - "name": "curator_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "answered_at": { - "name": "answered_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "q1": { - "name": "q1", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "q2": { - "name": "q2", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "q3": { - "name": "q3", - "type": "boolean", - "primaryKey": false, - "notNull": false - }, - "q4": { - "name": "q4", - "type": "boolean", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "submissions_resource_id_resources_id_fk": { - "name": "submissions_resource_id_resources_id_fk", - "tableFrom": "submissions", - "tableTo": "resources", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "submissions_submitter_id_users_id_fk": { - "name": "submissions_submitter_id_users_id_fk", - "tableFrom": "submissions", - "tableTo": "users", - "columnsFrom": [ - "submitter_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "submissions_curator_id_users_id_fk": { - "name": "submissions_curator_id_users_id_fk", - "tableFrom": "submissions", - "tableTo": "users", - "columnsFrom": [ - "curator_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "submissions_id_unique": { - "name": "submissions_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.user_achievements": { - "name": "user_achievements", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "achievement_id": { - "name": "achievement_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "user_achievements_user_id_users_id_fk": { - "name": "user_achievements_user_id_users_id_fk", - "tableFrom": "user_achievements", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "user_achievements_achievement_id_users_id_fk": { - "name": "user_achievements_achievement_id_users_id_fk", - "tableFrom": "user_achievements", - "tableTo": "users", - "columnsFrom": [ - "achievement_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_achievements_id_unique": { - "name": "user_achievements_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.user_institutions": { - "name": "user_institutions", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "institution_id": { - "name": "institution_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "user_institutions_user_id_users_id_fk": { - "name": "user_institutions_user_id_users_id_fk", - "tableFrom": "user_institutions", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "user_institutions_institution_id_institutions_id_fk": { - "name": "user_institutions_institution_id_institutions_id_fk", - "tableFrom": "user_institutions", - "tableTo": "institutions", - "columnsFrom": [ - "institution_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_institutions_id_unique": { - "name": "user_institutions_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.user_items": { - "name": "user_items", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "item_id": { - "name": "item_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "user_items_user_id_users_id_fk": { - "name": "user_items_user_id_users_id_fk", - "tableFrom": "user_items", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "user_items_item_id_items_id_fk": { - "name": "user_items_item_id_items_id_fk", - "tableFrom": "user_items", - "tableTo": "items", - "columnsFrom": [ - "item_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_items_id_unique": { - "name": "user_items_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.user_roles": { - "name": "user_roles", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "role_id": { - "name": "role_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "user_roles_user_id_users_id_fk": { - "name": "user_roles_user_id_users_id_fk", - "tableFrom": "user_roles", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "user_roles_role_id_roles_id_fk": { - "name": "user_roles_role_id_roles_id_fk", - "tableFrom": "user_roles", - "tableTo": "roles", - "columnsFrom": [ - "role_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_roles_id_unique": { - "name": "user_roles_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.user_stats": { - "name": "user_stats", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "score": { - "name": "score", - "type": "numeric", - "primaryKey": false, - "notNull": true, - "default": "'0.0'" - }, - "likes": { - "name": "likes", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "likes_received": { - "name": "likes_received", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "follows": { - "name": "follows", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "followers": { - "name": "followers", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "collections": { - "name": "collections", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "submitted_resources": { - "name": "submitted_resources", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "approved_resources": { - "name": "approved_resources", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "reviewed_resources": { - "name": "reviewed_resources", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "comments": { - "name": "comments", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_stats_id_unique": { - "name": "user_stats_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - } - } - }, - "public.users": { - "name": "users", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "username": { - "name": "username", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "password": { - "name": "password", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "'sem descrição'" - }, - "institution": { - "name": "institution", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "'sem instituição'" - }, - "birthday": { - "name": "birthday", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "cpf": { - "name": "cpf", - "type": "varchar(11)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "confirmed_at": { - "name": "confirmed_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "confirmation_sent_at": { - "name": "confirmation_sent_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "deleted_at": { - "name": "deleted_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "reactivated_at": { - "name": "reactivated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "active": { - "name": "active", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - }, - "user_stats_id": { - "name": "user_stats_id", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "users_user_stats_id_user_stats_id_fk": { - "name": "users_user_stats_id_user_stats_id_fk", - "tableFrom": "users", - "tableTo": "user_stats", - "columnsFrom": [ - "user_stats_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "users_id_unique": { - "name": "users_id_unique", - "nullsNotDistinct": false, - "columns": [ - "id" - ] - }, - "users_username_unique": { - "name": "users_username_unique", - "nullsNotDistinct": false, - "columns": [ - "username" - ] - }, - "users_email_unique": { - "name": "users_email_unique", - "nullsNotDistinct": false, - "columns": [ - "email" - ] - }, - "users_cpf_unique": { - "name": "users_cpf_unique", - "nullsNotDistinct": false, - "columns": [ - "cpf" - ] - }, - "users_user_stats_id_unique": { - "name": "users_user_stats_id_unique", - "nullsNotDistinct": false, - "columns": [ - "user_stats_id" - ] - } - } - } - }, - "enums": { - "public.state": { - "name": "state", - "schema": "public", - "values": [ - "active", - "inactive", - "under_review" - ] - } - }, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/src/db/migrations/meta/_journal.json b/src/db/migrations/meta/_journal.json index d5e1531d117d696ef983d6a89d491d589f7fd9d8..fd42dad33acaaa86c9cc5a7367883b8a96bd436d 100644 --- a/src/db/migrations/meta/_journal.json +++ b/src/db/migrations/meta/_journal.json @@ -5,43 +5,15 @@ { "idx": 0, "version": "7", - "when": 1732716257048, - "tag": "0000_secret_sharon_ventura", + "when": 1740147860395, + "tag": "0000_flawless_scarecrow", "breakpoints": true }, { "idx": 1, "version": "7", - "when": 1732716382536, - "tag": "0001_strange_famine", - "breakpoints": true - }, - { - "idx": 2, - "version": "7", - "when": 1732716630298, - "tag": "0002_sleepy_vin_gonzales", - "breakpoints": true - }, - { - "idx": 3, - "version": "7", - "when": 1738594390624, - "tag": "0003_tired_stone_men", - "breakpoints": true - }, - { - "idx": 4, - "version": "7", - "when": 1739363633612, - "tag": "0004_useful_paper_doll", - "breakpoints": true - }, - { - "idx": 5, - "version": "7", - "when": 1739370229565, - "tag": "0005_eager_darkstar", + "when": 1740406482014, + "tag": "0001_odd_valkyrie", "breakpoints": true } ] diff --git a/src/db/relations/user-collection.relation.ts b/src/db/relations/user-collection.relation.ts new file mode 100644 index 0000000000000000000000000000000000000000..9e63a6dba5369cb96df8f961f6b1417acb1a68ce --- /dev/null +++ b/src/db/relations/user-collection.relation.ts @@ -0,0 +1,47 @@ +import { integer, pgTable, serial } from "drizzle-orm/pg-core"; +import { collectionTable, userTable } from "../schema"; +import { relations } from "drizzle-orm"; +import { createInsertSchema, createSelectSchema } from "drizzle-zod"; +import type { z } from "zod"; + +const userCollectionTable = pgTable('userCollections', { + id: serial('id').primaryKey() + .unique() + .notNull(), + user_id: integer("user_id") + .notNull() + .references(() => userTable.id, { onDelete: 'cascade' }), + collection_id: integer("collection_id") + .notNull() + .references(() => collectionTable.id, {onDelete: 'cascade'}) +}) + +export const userCollectionsRelations = relations(userCollectionTable, ({one}) => ({ + user: one(userTable, { + fields: [userCollectionTable.user_id], + references: [userTable.id] + }), + collection: one(collectionTable, { + fields: [userCollectionTable.collection_id], + references: [collectionTable.id] + }) +})) + +const userCollectionsModelSchema = createSelectSchema(userCollectionTable) +const userCollectionsDtoSchema = userCollectionsModelSchema +const userCollectionsInputSchema = createInsertSchema(userCollectionTable) +const userCollectionsUpdateSchema = userCollectionsInputSchema.partial().required({ user_id: true, collection_id: true}) + +export type userCollectionsModel = z.infer<typeof userCollectionsModelSchema> +export type userCollectionsDto = z.infer<typeof userCollectionsDtoSchema> +export type userCollectionsInput = z.infer<typeof userCollectionsInputSchema> +export type userCollectionsUpdate = z.infer<typeof userCollectionsUpdateSchema> + +export const userCollectionsSchemas = { + userCollectionsModelSchema, + userCollectionsDtoSchema, + userCollectionsInputSchema, + userCollectionsUpdateSchema, +} + +export default userCollectionTable diff --git a/src/db/repo/collections.repo.ts b/src/db/repo/collections.repo.ts index 15b4a8640ef01213aff4b2a195980eeeab8fe682..44d1d674c7b523d3606762309e4c4ad0dbf69db3 100644 --- a/src/db/repo/collections.repo.ts +++ b/src/db/repo/collections.repo.ts @@ -7,6 +7,12 @@ import type { import db from ".."; import collectionTable, { collectionSchemas } from "../schema/collection.schema"; import { and, eq, isNull } from 'drizzle-orm' +import type { ResourceModel } from "../schema/resource.schema"; +import fs from 'fs'; +import path from 'path'; +import archiver from 'archiver'; +import { PassThrough } from "stream"; + @Service() export class CollectionRepo { @@ -114,4 +120,11 @@ export class CollectionRepo { .where(and(eq(collectionTable.user_id, id), eq(collectionTable.is_private, true))) ) } + + // async downloadCollection(collectionId: CollectionModel['id']): Promise <Buffer> { + // try { + + // fazer zip + // } + // } } \ No newline at end of file diff --git a/src/db/repo/user-collection.repo.ts b/src/db/repo/user-collection.repo.ts new file mode 100644 index 0000000000000000000000000000000000000000..bf68f0a88458021f1631092fef37f33a94b334d0 --- /dev/null +++ b/src/db/repo/user-collection.repo.ts @@ -0,0 +1,123 @@ +import { Service } from "typedi"; +import type { UserModel } from "../schema/user.schema"; +import type { CollectionModel } from "../schema/collection.schema"; +import db from ".."; +import userCollectionTable from "../relations/user-collection.relation"; +import { and, eq, inArray } from "drizzle-orm"; +import collectionTable from "../schema/collection.schema"; +import userTable from "../schema/user.schema"; + +@Service() +export class userCollectionsRepo { + async associateUserWithCollection(userId: UserModel['id'], collectionIds: CollectionModel['id'][]): Promise<void> { + try { + const existingAssociations = await db + .select({ + collection_id: userCollectionTable.collection_id, + }) + .from(userCollectionTable) + .where(eq(userCollectionTable.user_id, userId)) + .execute(); + + const existingCollectionIds = existingAssociations.map(row => row.collection_id); + + const newCollectionIds = collectionIds.filter(collectionId => !existingCollectionIds.includes(collectionId)); + + if (newCollectionIds.length > 0) { + const valuesToInsert = newCollectionIds.map(collectionId => ({ + user_id: userId, + collection_id: collectionId, + })); + + await db + .insert(userCollectionTable) + .values(valuesToInsert) + .onConflictDoNothing() + .execute(); + + console.log(`User ${userId} associated with new collections: ${newCollectionIds.join(', ')}`); + } else { + console.log(`No new collections to associate with user ${userId}`); + } + } catch (error) { + console.error("Error associating user with collection", error); + } + } + + async getCollectionsByUser(userId: UserModel['id']): Promise<Partial<CollectionModel>[]> { + try { + const collections = await db + .select({ + id: collectionTable.id, + name: collectionTable.name, + }) + .from(collectionTable) + .innerJoin(userCollectionTable, eq(userCollectionTable.collection_id, collectionTable.id)) + .where(eq(userCollectionTable.user_id, userId)) + .execute(); + + return collections; + } catch (error) { + console.log("Error fetching collections by user", error); + throw error; + } + } + + async removeCollectionsFromUser(userId: UserModel['id'], collectionIds: CollectionModel['id'][]): Promise<void> { + try { + await db + .delete(userCollectionTable) + .where( + and( + eq(userCollectionTable.user_id, userId), + inArray(userCollectionTable.collection_id, collectionIds), + ) + ) + .execute(); + + console.log(`Collections removed from user${userId}: ${collectionIds.join(', ')}`); + } catch (error) { + console.error("error removing collections from users", error); + throw error; + } + } + + async isAssociationExists(userId: UserModel['id'], collectionId: CollectionModel['id']): Promise<boolean> { + try { + const result = await db + .select() + .from(userCollectionTable) + .where( + and( + eq(userCollectionTable.user_id, userId), + eq(userCollectionTable.collection_id, collectionId) + ) + ) + .execute(); + + return result.length > 0; + } catch (error) { + console.error("error checking if association exists", error); + throw error; + } + } + + async getUsersByCollection(collectionId: CollectionModel['id']): Promise<UserModel[]> { + try { + const users = await db + .select({ + id: userTable.id, + name: userTable.name, + }) + .from(userCollectionTable) + .innerJoin(userTable, eq(userCollectionTable.user_id, userTable.id)) + .where(eq(userCollectionTable.collection_id, collectionId)) + .execute(); + + return users; + } catch (error) { + console.error("Error fetching users by collection", error); + throw error; + } + } +} \ No newline at end of file diff --git a/src/db/schema/index.ts b/src/db/schema/index.ts index db2002d21c15b9c20dfff05ff79a26deb98ef5b1..d1e439399f4ed05608ac1ae457de8aacc6e94860 100644 --- a/src/db/schema/index.ts +++ b/src/db/schema/index.ts @@ -34,6 +34,7 @@ import userItemRelationTable from '../relations/user-item.relation' import stateEnum from './stateEnum.schema' import commentsTable from './comments.schema' import commentReplyTable from './comment-reply.schema' +import userCollectionTable from '../relations/user-collection.relation' export { userTable, @@ -70,7 +71,8 @@ export { userItemRelationTable, stateEnum, commentsTable, - commentReplyTable + commentReplyTable, + userCollectionTable, } export const tables = [ @@ -103,6 +105,6 @@ export const tables = [ notificationRelationTable, userItemRelationTable, commentsTable, - commentReplyTable - + commentReplyTable, + userCollectionTable, ] diff --git a/src/db/seed.ts b/src/db/seed.ts index e4ae0e42c74ea79d904a5417f6a58237bb0075f5..a6e38e36a64d49359310d47217e0d74745b1d9e1 100644 --- a/src/db/seed.ts +++ b/src/db/seed.ts @@ -21,12 +21,12 @@ for (const table of schema.tables) { await resetTable(db, table) } +// A ordem do userStatsSeed e userSeed deve ser respeitada (stats primeiro), caso contrário o bun db:seed não funcionará await seeds.userStatsSeed(db) await seeds.userSeed(db) await seeds.objectTypeSeed(db) await seeds.licenseSeed(db) await seeds.resourceStatsSeed(db) - await seeds.resourceSeed(db) await seeds.collectionStatsSeed(db) await seeds.collectionSeed(db) @@ -50,5 +50,6 @@ await seeds.itemsSeed(db) await seeds.userAchievementsSeed(db) await seeds.actionSeed(db) await seeds.commentsSeed(db) +await seeds.userCollectionsSeed(db) await connection.end() diff --git a/src/db/seeds/collection-stats.seed.ts b/src/db/seeds/collection-stats.seed.ts index 6fdf2411ef2338eca8a0e724326ee42f43dc02dd..c611b8cb7e0b002667224e4034521080cc22a392 100644 --- a/src/db/seeds/collection-stats.seed.ts +++ b/src/db/seeds/collection-stats.seed.ts @@ -8,6 +8,7 @@ export default async function seed(db:db) { const collectionStatsData: CollectionStatsInput[] = [ { + collection_id: 1, views: 100, downloads: 50, likes: 20, diff --git a/src/db/seeds/index.ts b/src/db/seeds/index.ts index 3e9c104ebea11a2808c85345e2c7520351a12934..29659ff6326a1e83f757aa1221aad24db97e3341 100644 --- a/src/db/seeds/index.ts +++ b/src/db/seeds/index.ts @@ -1,5 +1,6 @@ -export { default as userSeed } from './user.seed' export { default as userStatsSeed } from './user-stats.seed' +export { default as userSeed } from './user.seed' +export { default as userCollectionsSeed } from './user-collection.seed' export { default as resourceSeed } from './resource.seed' export { default as resourceStatsSeed } from './resourceStats.seed' export { default as collectionSeed } from './collections.seed' @@ -25,4 +26,4 @@ export { default as achievementSeed } from './achievement.seed' export { default as itemsSeed } from './items.seed' export { default as userAchievementsSeed } from './user-achievements.seed' export { default as actionSeed } from './action.seed' -export { default as commentsSeed } from './comments.seed' +export { default as commentsSeed } from './comments.seed' \ No newline at end of file diff --git a/src/db/seeds/resource-language.seed.ts b/src/db/seeds/resource-language.seed.ts index d76927dfc567e3164fcc0d72b64dae5f85a5c4be..115fd5b1b696187ba704227c9008968e6489fc93 100644 --- a/src/db/seeds/resource-language.seed.ts +++ b/src/db/seeds/resource-language.seed.ts @@ -9,11 +9,11 @@ export default async function seed(db: db) { const resourceLanguageData: ResourceLanguagesInput[] = [ { - resource_id: 1, + resource_id: 2, language_id: 1 }, { - resource_id: 1, + resource_id: 2, language_id: 2 }, { diff --git a/src/db/seeds/user-collection.seed.ts b/src/db/seeds/user-collection.seed.ts new file mode 100644 index 0000000000000000000000000000000000000000..6333dcd12dbe1e5b7b9042e7d4b7cbb31722f0c0 --- /dev/null +++ b/src/db/seeds/user-collection.seed.ts @@ -0,0 +1,38 @@ +import type db from '@/db' +import userCollectionTable, { type userCollectionsInput } from '../relations/user-collection.relation' + + +export default async function seed(db: db) { + await db.insert(userCollectionTable).values(userCollectionsData) +} + +const userCollectionsData: userCollectionsInput[] = [ + { + user_id: 1, + collection_id: 1 + }, + { + user_id: 1, + collection_id: 2 + }, + { + user_id: 1, + collection_id: 3 + }, + { + user_id: 2, + collection_id: 1 + }, + { + user_id: 2, + collection_id: 2 + }, + { + user_id: 3, + collection_id: 2 + }, + { + user_id: 3, + collection_id: 3 + } +] diff --git a/src/db/seeds/user-stats.seed.ts b/src/db/seeds/user-stats.seed.ts index 47a6a08b4ed45545cae539d8a22f34347b550305..712a51e5cbb912f512cb9b8972138592216d03b4 100644 --- a/src/db/seeds/user-stats.seed.ts +++ b/src/db/seeds/user-stats.seed.ts @@ -8,7 +8,6 @@ export default async function seed(db: db) { const usersStatsData: UserStatsInput[] = [ { - }, { diff --git a/src/index.ts b/src/index.ts index 9061de7561eb69e575373fdcaab164240bcf712a..509f3dfb1342eab936c54cef250e7ed3bd8b1c7c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -42,6 +42,7 @@ import { swaggerUI } from '@hono/swagger-ui' import { OpenAPIHono } from "@hono/zod-openapi"; import { commentsRouter, publicCommentsRoute } from './routes/comments.route' import { publicCommentsReplyRoute, commentReplyRouter } from './routes/comment-reply.route' +import { publicUserCollectionsRoutes, userCollectionsRoute } from './routes/user-collection.route' @@ -117,6 +118,7 @@ app .route('/userAchievements', publicUserAchievementsRoute) .route('/comments', publicCommentsRoute) .route('/replyComment', publicCommentsReplyRoute) + .route('/userCollections', publicUserCollectionsRoutes) //rotas que precisam de token app .basePath('/api') @@ -152,6 +154,7 @@ app .route('/user-item', userItemRouter) .route('/comments', commentsRouter) .route('/replyComment', commentReplyRouter) + .route('/userCollections', userCollectionsRoute) export default app export type AppType = typeof app diff --git a/src/routes/user-collection.route.ts b/src/routes/user-collection.route.ts new file mode 100644 index 0000000000000000000000000000000000000000..108435e748d5bcd6ac673683e668a3082211d409 --- /dev/null +++ b/src/routes/user-collection.route.ts @@ -0,0 +1,120 @@ +import { UserCollectionsService } from "@/services/user-collection.service"; +import Container from "typedi"; +import { z } from "zod"; +import { honoWithJwt } from ".."; +import { zValidator } from "@hono/zod-validator"; +import { createApexError, HttpStatus } from "@/services/error.service"; +import { Hono } from "hono"; + +const associateSchema = z.object({ + userId: z.number(), + collectionIds: z.array(z.number()), +}) + +const service = Container.get(UserCollectionsService); + +export const userCollectionsRoute = honoWithJwt() + .post('/associate', zValidator('json', associateSchema), + async (c) => { + try { + const {userId, collectionIds } = await c.req.valid('json'); + await service.associateUserWithCollections(userId, collectionIds); + return c.json({ message: 'Collections associates succesfully'}, HttpStatus.OK); + } catch (e) { + return c.json( + createApexError({ + status: 'error', + message: 'Failed to associate collections', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'Ensure the user and collection ids are valid', + }), + HttpStatus.BAD_REQUEST + ) + } + } + ) + .post('/:userId/delete/:collectionId', + async (c) => { + try { + const userid = +c.req.param('userId'); + const collectionId = +c.req.param('collectionId'); + await service.removeCollectionsFromUser(userid, [collectionId]); + return c.json({ message: 'Collections removed succesfully'}, HttpStatus.OK); + } catch (e) { + return c.json ( + createApexError({ + status: 'error', + message: 'Failed to remove collections', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'Ensure the user and collection ids are valid', + }), + HttpStatus.BAD_REQUEST + ) + } + } + ) + +export const publicUserCollectionsRoutes = new Hono() + .get('/:userId/collections', + async (c) => { + try { + const userId = +c.req.param('userId'); + const collections = await service.getCollectionByUser(userId); + return c.json(collections, HttpStatus.OK); + } catch (e) { + return c.json( + createApexError({ + status: 'error', + message: 'Failed to fetch collections', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'Ensure the user id is valid', + }), + HttpStatus.BAD_REQUEST + ) + } + } + ) + .get('/:userId/collections/:collectionId/exists', + async (c) => { + try { + const userId = +c.req.param('userId'); + const collectionId = +c.req.param('collectionId'); + const exists = await service.isAssociationExists(userId, collectionId); + return c.json( {exists}, HttpStatus.OK); + } catch (e) { + return c.json( + createApexError({ + status: 'error', + message: 'Failed to check association', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'Check the input and try again', + }), + HttpStatus.BAD_REQUEST + ); + } + } + ) + .get('/collection/:collectionId/users', + async (c) => { + try { + const collectionId = +c.req.param('collectionId'); + const users = await service.getUsersByCollection(collectionId); + return c.json({ users }, HttpStatus.OK); + } catch (e) { + return c.json( + createApexError({ + status: 'error', + message: 'Failed to fetch users', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'Check the input and try again', + }), + HttpStatus.BAD_REQUEST + ); + } + } + ) diff --git a/src/services/user-collection.service.ts b/src/services/user-collection.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..99cad76c504b5c44d53457a8f2a484c60d973796 --- /dev/null +++ b/src/services/user-collection.service.ts @@ -0,0 +1,30 @@ +import { userCollectionsRepo } from "@/db/repo/user-collection.repo"; +import type { CollectionModel } from "@/db/schema/collection.schema"; +import type { UserModel } from "@/db/schema/user.schema"; +import { Inject, Service } from "typedi"; + +@Service() +export class UserCollectionsService { + @Inject() + private readonly repo: userCollectionsRepo; + + async associateUserWithCollections(userId: UserModel['id'], collectionIds: CollectionModel['id'][]): Promise<void> { + await this.repo.associateUserWithCollection(userId, collectionIds); + } + + async getCollectionByUser(userId: UserModel['id']): Promise<Partial<CollectionModel>[]> { + return this.repo.getCollectionsByUser(userId); + } + + async removeCollectionsFromUser(userId: UserModel['id'], collectionIds: CollectionModel['id'][]): Promise<void> { + await this.repo.removeCollectionsFromUser(userId, collectionIds); + } + + async isAssociationExists(userId: UserModel['id'], collectionId: CollectionModel['id']): Promise<boolean> { + return this.repo.isAssociationExists(userId, collectionId); + } + + async getUsersByCollection(collectionId: CollectionModel['id']): Promise<UserModel[]> { + return this.repo.getUsersByCollection(collectionId); + } +} \ No newline at end of file