From 61e6f8ced3e3dd28108a92352d28691787f2ff12 Mon Sep 17 00:00:00 2001 From: Maria Sauer <mcs22@inf.ufpr.br> Date: Tue, 25 Mar 2025 09:46:52 -0300 Subject: [PATCH] foi amem gracas a deus --- .../migrations/0003_bored_silver_surfer.sql | 1 + src/db/migrations/meta/0003_snapshot.json | 2687 +++++++++++++++++ src/db/migrations/meta/_journal.json | 7 + src/db/relations/user-role.relation.ts | 5 + src/db/repo/auth.repo.ts | 4 +- src/db/repo/homologation.repo.ts | 35 + src/db/repo/resource.repo.ts | 11 + src/db/repo/role.repo.ts | 41 +- src/db/repo/submission.repo.ts | 25 +- src/db/schema/resourceEnum.schema.ts | 2 +- src/db/schema/submission.schema.ts | 2 +- src/db/seeds/resource.seed.ts | 4 +- src/db/seeds/resourceStats.seed.ts | 6 + src/db/seeds/role.seed.ts | 37 +- src/db/seeds/submission.seed.ts | 6 +- src/index.ts | 3 + src/routes/auth.route.ts | 4 +- src/routes/collections.route.ts | 2 +- src/routes/homologation.route.ts | 117 + src/routes/resource.route.ts | 4 +- src/routes/submission.route.ts | 3 +- src/services/auth.service.ts | 6 +- src/services/homologation.service.ts | 19 + src/services/resource.service.ts | 4 + src/services/role.service.ts | 2 + src/services/submission.service.ts | 4 + 26 files changed, 2964 insertions(+), 77 deletions(-) create mode 100644 src/db/migrations/0003_bored_silver_surfer.sql create mode 100644 src/db/migrations/meta/0003_snapshot.json create mode 100644 src/db/repo/homologation.repo.ts create mode 100644 src/routes/homologation.route.ts create mode 100644 src/services/homologation.service.ts diff --git a/src/db/migrations/0003_bored_silver_surfer.sql b/src/db/migrations/0003_bored_silver_surfer.sql new file mode 100644 index 0000000..ea1ccb5 --- /dev/null +++ b/src/db/migrations/0003_bored_silver_surfer.sql @@ -0,0 +1 @@ +ALTER TYPE "resource_state" ADD VALUE 'reported'; \ No newline at end of file diff --git a/src/db/migrations/meta/0003_snapshot.json b/src/db/migrations/meta/0003_snapshot.json new file mode 100644 index 0000000..8b8d598 --- /dev/null +++ b/src/db/migrations/meta/0003_snapshot.json @@ -0,0 +1,2687 @@ +{ + "id": "5be0b9eb-7bd6-4a50-83a5-08fb445c937d", + "prevId": "a2249c37-5786-4d0f-ba5e-1c3b465aa103", + "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.commentReply": { + "name": "commentReply", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "comment_id": { + "name": "comment_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": { + "commentReply_user_id_users_id_fk": { + "name": "commentReply_user_id_users_id_fk", + "tableFrom": "commentReply", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "commentReply_comment_id_comments_id_fk": { + "name": "commentReply_comment_id_comments_id_fk", + "tableFrom": "commentReply", + "tableTo": "comments", + "columnsFrom": [ + "comment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "commentReply_id_unique": { + "name": "commentReply_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 + }, + "comments": { + "name": "comments", + "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 + }, + "resource_state": { + "name": "resource_state", + "type": "resource_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "author": { + "name": "author", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "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_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.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": "", + "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.resource_state": { + "name": "resource_state", + "schema": "public", + "values": [ + "draft", + "submitted", + "accepted", + "reported" + ] + }, + "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 d2fd8ec..5244d53 100644 --- a/src/db/migrations/meta/_journal.json +++ b/src/db/migrations/meta/_journal.json @@ -22,6 +22,13 @@ "when": 1741614026669, "tag": "0002_wakeful_taskmaster", "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1742481466754, + "tag": "0003_bored_silver_surfer", + "breakpoints": true } ] } \ No newline at end of file diff --git a/src/db/relations/user-role.relation.ts b/src/db/relations/user-role.relation.ts index 148bd23..b2b305c 100644 --- a/src/db/relations/user-role.relation.ts +++ b/src/db/relations/user-role.relation.ts @@ -4,6 +4,11 @@ import { relations } from "drizzle-orm" import { createInsertSchema, createSelectSchema } from "drizzle-zod" import type { z } from "zod" + +// id: 1, name: "user", description: "This role represents a normal user in Portal MEC." +// id: 2, name: "admin", description: "This role represents an MEC Admin, that can perform any action." +// id: 3, name: "contributor", description: "This role represents an MEC Contributor, that can approve resources." + const userRoleRelationTable = pgTable('user_roles', { id: serial('id').primaryKey() .unique() diff --git a/src/db/repo/auth.repo.ts b/src/db/repo/auth.repo.ts index 2c37d7e..4e5cb94 100644 --- a/src/db/repo/auth.repo.ts +++ b/src/db/repo/auth.repo.ts @@ -17,13 +17,13 @@ export function verifyPassword( } export const authSchema = userSchemas.userModelSchema.pick({ - username: true, + email: true, password: true, }) export const authPayload = userSchemas.userModelSchema.pick({ id: true, - username: true, + email: true, }) export type AuthPayload = z.infer<typeof authPayload> diff --git a/src/db/repo/homologation.repo.ts b/src/db/repo/homologation.repo.ts new file mode 100644 index 0000000..db953c2 --- /dev/null +++ b/src/db/repo/homologation.repo.ts @@ -0,0 +1,35 @@ +//pegar só os recursos com a tag submitted + +import { Service } from "typedi"; +import db from ".."; +import type { UserRoleRelationModel } from "../relations/user-role.relation"; +import userRoleRelationTable from "../relations/user-role.relation"; +import { and, eq, not } from "drizzle-orm"; +import type { ResourceModel } from "../schema/resource.schema"; +import resourceTable, { resourceSchema } from "../schema/resource.schema"; + +@Service() +export class HomologationRepo { + + async findRolesByUserId(userId: UserRoleRelationModel['user_id']): Promise<number[]> { + const roleIds = await db + .select({ role_id: userRoleRelationTable.role_id }) // Seleciona apenas o role_id + .from(userRoleRelationTable) + .where(eq(userRoleRelationTable.user_id, userId)); // Filtra pelo user_id + + return roleIds.map(role => role.role_id); + } + + async findHomologationResource(userId: ResourceModel['user_id']): Promise<ResourceModel[]> { + const resources = await db + .select() + .from(resourceTable) + .where(and( + eq(resourceTable.resource_state, "submitted"), + not(eq(resourceTable.user_id, userId)) // pega os que nao corresponde ao usuario + )) + + return resourceSchema.model.array().parse(resources) + } + +} diff --git a/src/db/repo/resource.repo.ts b/src/db/repo/resource.repo.ts index 40a9991..e5389ec 100644 --- a/src/db/repo/resource.repo.ts +++ b/src/db/repo/resource.repo.ts @@ -63,6 +63,17 @@ export class ResourceRepo { return resourceSchema.model.parse(ret) } + async setResourceState(id: ResourceModel['id']): Promise<ResourceModel> { + const [ret] = await db + .update(resourceTable) + .set({ + resource_state: 'accepted' + }) + .where(eq(resourceTable.id, id)) + .returning() + + return resourceSchema.model.parse(ret) + } async allResourceByUser(id_user: ResourceModel['user_id']): Promise<ResourceModel[]> { const resources = await db diff --git a/src/db/repo/role.repo.ts b/src/db/repo/role.repo.ts index d153c91..8b8b89d 100644 --- a/src/db/repo/role.repo.ts +++ b/src/db/repo/role.repo.ts @@ -7,50 +7,51 @@ import { z } from "zod"; @Service() export class RoleRepo { - async findMany():Promise<RoleModel[]>{ - + async findMany(): Promise<RoleModel[]> { + return z.array(roleSchemas.model).parse(await db.query.roleTable.findMany()) } - async findById(id: RoleModel['id']): Promise<RoleModel | null>{ + async findById(id: RoleModel['id']): Promise<RoleModel | null> { const role = await db.query.roleTable.findFirst({ where: eq(roleTable.id, id) }) - if(!role) return null + if (!role) return null return roleSchemas.model.parse(role) } - async findByName(name: RoleModel['name']): Promise<RoleModel | null>{ + async findByName(name: RoleModel['name']): Promise<RoleModel | null> { const role = await db.query.roleTable.findFirst({ where: eq(roleTable.name, name) }) - if(!role) return null + if (!role) return null return roleSchemas.model.parse(role) } - async create(role: RoleInput, tx?: db): Promise<RoleModel>{ + async create(role: RoleInput, tx?: db): Promise<RoleModel> { const repo = tx ?? db const [ret] = await repo - .insert(roleTable) - .values(role) - .returning() + .insert(roleTable) + .values(role) + .returning() return roleSchemas.model.parse(ret) } - async update(role: RoleUpdate): Promise<RoleModel>{ + async update(role: RoleUpdate): Promise<RoleModel> { const [ret] = await db - .update(roleTable) - .set(role) - .where(eq(roleTable.id, role.id)) - .returning() + .update(roleTable) + .set(role) + .where(eq(roleTable.id, role.id)) + .returning() return roleSchemas.model.parse(ret) } - async delete(id: RoleModel['id']): Promise<RoleModel>{ + async delete(id: RoleModel['id']): Promise<RoleModel> { const [ret] = await db - .delete(roleTable) - .where(eq(roleTable.id, id)) - .returning() + .delete(roleTable) + .where(eq(roleTable.id, id)) + .returning() return roleSchemas.model.parse(ret) } -} \ No newline at end of file + +} diff --git a/src/db/repo/submission.repo.ts b/src/db/repo/submission.repo.ts index f56920f..6dd83bd 100644 --- a/src/db/repo/submission.repo.ts +++ b/src/db/repo/submission.repo.ts @@ -18,10 +18,10 @@ export class SubmissionRepo { async update(submission: SubmissionUpdate): Promise<SubmissionModel> { submission.updated_at = new Date() - const[ret] = await db + const [ret] = await db .update(submissionTable) .set(submission) - .where(eq(submissionTable.id, submission.id)) + .where(eq(submissionTable.id, submission.resource_id)) .returning() return submissionSchemas.submissionModelSchema.parse(ret) @@ -33,7 +33,7 @@ export class SubmissionRepo { const [ret] = await db .update(submissionTable) .set(submission) - .where(eq(submissionTable.id, submission.id)) + .where(eq(submissionTable.resource_id, submission.resource_id)) .returning() return submissionSchemas.submissionModelSchema.parse(ret) @@ -44,8 +44,19 @@ export class SubmissionRepo { .delete(submissionTable) .where(eq(submissionTable.id, id)) .returning() - - return submissionSchemas.submissionModelSchema.parse(ret) + + return submissionSchemas.submissionModelSchema.parse(ret) + } + + async setIsAccepted(id: SubmissionModel['id']): Promise<SubmissionModel> { + console.log("Tentando atualizar is_accepted para true no ID:", id); + const [ret] = await db + .update(submissionTable) + .set({ is_accepted: true }) + .where(eq(submissionTable.id, id)) + .returning() + + return submissionSchemas.submissionModelSchema.parse(ret) } async find(id: SubmissionModel['id']): Promise<SubmissionModel | undefined> { @@ -58,7 +69,7 @@ export class SubmissionRepo { async findMany(): Promise<SubmissionModel[]> { return submissionSchemas.submissionModelSchema - .array() - .parse(await db.query.submissionTable.findMany()) + .array() + .parse(await db.query.submissionTable.findMany()) } } \ No newline at end of file diff --git a/src/db/schema/resourceEnum.schema.ts b/src/db/schema/resourceEnum.schema.ts index cd49481..6e18592 100644 --- a/src/db/schema/resourceEnum.schema.ts +++ b/src/db/schema/resourceEnum.schema.ts @@ -4,7 +4,7 @@ import { z } from "zod"; const resourceEnum = pgEnum('resource_state', - ['draft', 'submitted', 'accepted'] + ['draft', 'submitted', 'accepted', 'reported'] ) const resourceEnumSchema = z.enum(resourceEnum.enumValues) diff --git a/src/db/schema/submission.schema.ts b/src/db/schema/submission.schema.ts index f739db2..d64bf59 100644 --- a/src/db/schema/submission.schema.ts +++ b/src/db/schema/submission.schema.ts @@ -38,7 +38,7 @@ const submissionTable = pgTable('submissions', { const submissionModelSchema = createSelectSchema(submissionTable) const submissionDtoSchema = submissionModelSchema const submissionInputSchema = createInsertSchema(submissionTable) -const submissionUpdateSchema = submissionInputSchema.partial().required({ id: true, resource_id: true}) +const submissionUpdateSchema = submissionInputSchema.partial().required({resource_id: true}) export type SubmissionModel = z.infer<typeof submissionModelSchema> export type SubmissionDto = z.infer<typeof submissionDtoSchema> diff --git a/src/db/seeds/resource.seed.ts b/src/db/seeds/resource.seed.ts index 98cf82a..0033388 100644 --- a/src/db/seeds/resource.seed.ts +++ b/src/db/seeds/resource.seed.ts @@ -13,7 +13,7 @@ const resourceData: ResourceInput[] = [ author: 'author 1', link: 'link 1', thumbnail: 'thumbnail 1', - user_id: 1, + user_id: 2, resource_stats_id: 1, object_type_id: 1, license_id: 1 @@ -36,7 +36,7 @@ const resourceData: ResourceInput[] = [ link: 'link 2', thumbnail: 'thumbnail 2', user_id: 1, - resource_stats_id: 2, + resource_stats_id: 3, object_type_id: 1, license_id: 1 } diff --git a/src/db/seeds/resourceStats.seed.ts b/src/db/seeds/resourceStats.seed.ts index e592618..db8ed38 100644 --- a/src/db/seeds/resourceStats.seed.ts +++ b/src/db/seeds/resourceStats.seed.ts @@ -14,6 +14,12 @@ const statsResourceData: ResourceStatsInput[] = [ shares: 0, score: '0' }, + { + views: 0, + downloads: 0, + shares: 0, + score: '0' + }, { views: 0, downloads: 0, diff --git a/src/db/seeds/role.seed.ts b/src/db/seeds/role.seed.ts index 1c35215..7db7573 100644 --- a/src/db/seeds/role.seed.ts +++ b/src/db/seeds/role.seed.ts @@ -7,43 +7,16 @@ export default async function seed(db: db) { const rolesData: RoleInput[] = [ { - name: "teacher", - description: "This role represents a Teacher in Portal MEC." - }, - { - name: "student", - description: "This role represents a Student in Portal MEC." + name: "user", + description: "This role represents a normal user in Portal MEC." }, { name: "admin", description: "This role represents an MEC Admin, that can perform any action." }, { - name: "curator", - description: "This role represents a content Curator in Portal MEC." - }, - { - name: "moderator", - description: "This role represents a content Moderator in Portal MEC, with less privileges than admin." - }, - { - name: "supervisor", - description: "This role represents an user Supervisor in Portal MEC." - }, - { - name: "editor", - description: "This role represents a content Supervisor in Portal MEC, with less privileges than admin." - }, - { - name: "partner", - description: "This role represents a partner in Portal MEC." - }, - { - name: "publisher", - description: "This role represents a content publisher without supervision in Portal MEC." - }, - { - name: "submitter", - description: "This role represents a content submitter in Portal MEC." + name: "contributor", + description: "This role represents an MEC Contributor, that can approve resources." + } ] \ No newline at end of file diff --git a/src/db/seeds/submission.seed.ts b/src/db/seeds/submission.seed.ts index f3a8ec3..4e93648 100644 --- a/src/db/seeds/submission.seed.ts +++ b/src/db/seeds/submission.seed.ts @@ -8,7 +8,7 @@ export default async function seed(db: db) { const submissionData: SubmissionInput[] = [ { - is_accepted: true, + is_accepted: false, justification: 'I like it', resource_id: 1, submitter_id: 1, @@ -19,7 +19,7 @@ const submissionData: SubmissionInput[] = [ q4: false, }, { - is_accepted: true, + is_accepted: false, justification: 'I like it', resource_id: 1, submitter_id: 1, @@ -30,7 +30,7 @@ const submissionData: SubmissionInput[] = [ q4: false, }, { - is_accepted: true, + is_accepted: false, justification: 'I like it', resource_id: 1, submitter_id: 1, diff --git a/src/index.ts b/src/index.ts index 97b4c89..099d6b7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -44,6 +44,7 @@ import { commentsRouter, publicCommentsRoute } from './routes/comments.route' import { publicCommentsReplyRoute, commentReplyRouter } from './routes/comment-reply.route' import { publicUserCollectionsRoutes, userCollectionsRoute } from './routes/user-collection.route' import { publicS3, s3Routes } from './routes/s3.route' +import { homologationRouter } from './routes/homologation.route' @@ -158,6 +159,8 @@ app .route('/replyComment', commentReplyRouter) .route('/userCollections', userCollectionsRoute) .route('/s3', s3Routes) + .route('/homologation', homologationRouter) + export default app export type AppType = typeof app diff --git a/src/routes/auth.route.ts b/src/routes/auth.route.ts index ce9b45b..24867b4 100644 --- a/src/routes/auth.route.ts +++ b/src/routes/auth.route.ts @@ -21,7 +21,7 @@ export const authRouter = new Hono().post( zValidator('json', authSchema), async (c) => { try { - const input = await c.req.valid('json') + const input = c.req.valid('json') const token = await authService.login(input) @@ -44,7 +44,7 @@ export const authRouter = new Hono().post( zValidator('json', userSchemas.userInputSchema), async (c) => { try { - const input = await c.req.valid('json') + const input = c.req.valid('json') const userStats = userStatsSchemas.dto.parse(await userStatsService.create()) input.user_stats_id = userStats.id diff --git a/src/routes/collections.route.ts b/src/routes/collections.route.ts index 1aacb15..9ae45c7 100644 --- a/src/routes/collections.route.ts +++ b/src/routes/collections.route.ts @@ -325,7 +325,7 @@ export const getCollections = new Hono() } }); - + (async () => { //busca os arquivos e adiciona ao zip for (const resource of resources) { diff --git a/src/routes/homologation.route.ts b/src/routes/homologation.route.ts new file mode 100644 index 0000000..e19f7bf --- /dev/null +++ b/src/routes/homologation.route.ts @@ -0,0 +1,117 @@ +import { createApexError, HttpStatus } from "@/services/error.service"; +import { honoWithJwt } from ".."; +import Container from "typedi"; +import { zValidator } from "@hono/zod-validator"; +import { submissionSchemas } from "@/db/schema/submission.schema"; +import { z } from "zod"; +import { SubmissionService } from "@/services/submission.service"; +import { HomologationService } from "@/services/homologation.service"; +import { ResourceService } from "@/services/resource.service"; + + + +const serviceHomologation = Container.get(HomologationService) +const service = Container.get(SubmissionService); +const serviceResource = Container.get(ResourceService); + +export const inputSchemaHomologation = z.object({ + resource_id: z.number(), + q1: z.boolean(), + q2: z.boolean(), + q3: z.boolean(), + q4: z.boolean(), + is_accepted: z.boolean().default(false), + curator_id: z.number(), + submitter_id: z.number(), + justification: z.string(), +}); + +export const homologationRouter = honoWithJwt() + + //pegar os que estao abertos para homologaçção + .get('/all', async (c) => { + const user = c.get('jwtPayload').id; + + try { + //verifica se tem a permissao + const userRoles = await serviceHomologation.findRolesByUserId(user); + if (!userRoles || userRoles.length === 0) { + console.warn(`[HomologationService] Usuário ${user} não encontrado.`); + throw new Error("Usuário não encontrado."); + } + + //percorre o vetor de roles verificando se tem permissao + // definido que 1: user, 2: admin, 3: contribuidor + const hasPermission = userRoles.some(role => role === 2 || role === 3); + + if (!hasPermission) { + console.warn(`[HomologationService] Usuário ${user} sem permissão.`); + throw new Error("Acesso negado. Você não deveria estar aqui."); + } + + //rota que pega os com submitted e que nao tem id do usuario atual + const resource = serviceHomologation.findHomologationResource(user); + + return c.json({ resource }) + + } catch (e) { + return c.json( + createApexError({ + status: 'error', + message: 'could not get resource submitted', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'check the code and try again or you can´t be here ', + }), + HttpStatus.BAD_REQUEST) + } + + }) + + .post('/new', zValidator('json', submissionSchemas.submissionUpdateSchema), + async (c) => { + + try { + const input = c.req.valid('json'); + + //verifica se o json esta certo + const validInput = inputSchemaHomologation.parse(input); + + + //verificar as questoes + if (validInput.q1 || validInput.q2 || validInput.q3 || validInput.q4) { + //cria a tabela de submissao + submissionSchemas.submissionDtoSchema.parse( + await service.create(validInput) + ) + // Se um for verdadeiro é suficiente para nao aceitar o recurso + return c.json({ message: "O recurso não foi aceito!" }) + } + + validInput.is_accepted = true; + + //cria a tabela de submissao + const homologation = submissionSchemas.submissionDtoSchema.parse( + await service.create(validInput) + ) + + + //mudando o resource_state + await serviceResource.setResourceState(validInput.resource_id); + + return c.json({ message: "Homologação feita com sucesso!", data: homologation }) + + } catch (e) { + return c.json( + createApexError({ + status: 'error', + message: 'could not answer submission', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'check the input and try again', + + }), + HttpStatus.BAD_REQUEST + ) + } + }) diff --git a/src/routes/resource.route.ts b/src/routes/resource.route.ts index 610e7f5..e890908 100644 --- a/src/routes/resource.route.ts +++ b/src/routes/resource.route.ts @@ -22,7 +22,7 @@ export const resourceRouter = honoWithJwt() async (c) => { try { - const input = await c.req.valid('json') + const input = c.req.valid('json') //cria o stats do recurso correspondente const stats = resourceStatsSchema.dto.parse( @@ -56,7 +56,7 @@ export const resourceRouter = honoWithJwt() zValidator('json', resourceSchema.update), async (c) => { try { - const input = await c.req.valid('json') + const input = c.req.valid('json') const resource = resourceSchema.dto.parse(await service.update(input)) return c.json({ resource }) diff --git a/src/routes/submission.route.ts b/src/routes/submission.route.ts index bb910a6..764a5ed 100644 --- a/src/routes/submission.route.ts +++ b/src/routes/submission.route.ts @@ -67,7 +67,7 @@ export const submissionRouter = honoWithJwt() zValidator('json', submissionSchemas.submissionUpdateSchema), async (c) => { try { - const input = await c.req.valid('json') + const input = c.req.valid('json') const submission = submissionSchemas.submissionDtoSchema.parse( await service.answer(input) @@ -88,6 +88,7 @@ export const submissionRouter = honoWithJwt() } } ) + .post('/delete/:id', async (c) => { try { const id = +c.req.param('id') diff --git a/src/services/auth.service.ts b/src/services/auth.service.ts index bf01c8b..f130f2a 100644 --- a/src/services/auth.service.ts +++ b/src/services/auth.service.ts @@ -15,8 +15,8 @@ export class AuthService { private readonly userService: UserService async login(input: AuthInput): Promise<string> { - const user = await this.userService.findByUsername(input.username) - + const user = await this.userService.findByEmail(input.email) + if (!user) throw new Error('User not found') if (!verifyPassword(input.password, user.password)) @@ -24,7 +24,7 @@ export class AuthService { const payload: AuthPayload = authPayload.parse({ id: user.id, - username: user.username, + email: user.email, }) const token = await sign(payload, env.APP_SECRET) diff --git a/src/services/homologation.service.ts b/src/services/homologation.service.ts new file mode 100644 index 0000000..9de80a8 --- /dev/null +++ b/src/services/homologation.service.ts @@ -0,0 +1,19 @@ +import { HomologationRepo } from "@/db/repo/homologation.repo"; +import type { UserRoleRelationModel } from "@/db/relations/user-role.relation" + +import { Inject, Service } from "typedi"; +import type { ResourceModel } from "@/db/schema/resource.schema"; + +@Service() +export class HomologationService{ + @Inject() + private readonly repo: HomologationRepo + + async findRolesByUserId(id: UserRoleRelationModel['user_id']): Promise<number[]>{ + return this.repo.findRolesByUserId(id) + } + + async findHomologationResource(id: ResourceModel['user_id']): Promise< ResourceModel[]>{ + return this.repo.findHomologationResource(id) + } +} \ No newline at end of file diff --git a/src/services/resource.service.ts b/src/services/resource.service.ts index 585b44f..fed1532 100644 --- a/src/services/resource.service.ts +++ b/src/services/resource.service.ts @@ -27,6 +27,10 @@ export class ResourceService { return this.repo.active(id) } + async setResourceState (id: ResourceModel['id']): Promise<ResourceModel> { + return this.repo.setResourceState(id) + } + async allResourceByUser(id_user: ResourceModel['user_id']): Promise <ResourceModel[]>{ return this.repo.allResourceByUser(id_user) } diff --git a/src/services/role.service.ts b/src/services/role.service.ts index 68206bc..1c606af 100644 --- a/src/services/role.service.ts +++ b/src/services/role.service.ts @@ -32,4 +32,6 @@ export class RoleService{ return this.repo.delete(id) } + + } \ No newline at end of file diff --git a/src/services/submission.service.ts b/src/services/submission.service.ts index 9e561c1..7f8bf87 100644 --- a/src/services/submission.service.ts +++ b/src/services/submission.service.ts @@ -19,6 +19,10 @@ export class SubmissionService { return this.repo.answer(submission) } + async setIsAccepted (id: SubmissionModel['id']): Promise<SubmissionInput> { + return this.repo.setIsAccepted(id) + } + async delete(id: SubmissionModel['id']): Promise<SubmissionInput> { return this.repo.delete(id) } -- GitLab