From 9bdb781f340fb0f86f811c9078c6406e0d5cbb35 Mon Sep 17 00:00:00 2001 From: Muhammad Zhafran Ilham Date: Mon, 8 Jun 2026 04:38:51 +0700 Subject: [PATCH] feat: menambah dan memperbarui skema database untuk project, project member, dan task lms internify --- .../migration.sql | 116 +++++++++++++++ prisma/schema.prisma | 135 ++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 prisma/migrations/20260607213625_lms_scheme_preparation/migration.sql diff --git a/prisma/migrations/20260607213625_lms_scheme_preparation/migration.sql b/prisma/migrations/20260607213625_lms_scheme_preparation/migration.sql new file mode 100644 index 0000000..f837704 --- /dev/null +++ b/prisma/migrations/20260607213625_lms_scheme_preparation/migration.sql @@ -0,0 +1,116 @@ +-- AlterTable +ALTER TABLE `admin` ADD COLUMN `professional_bio` TEXT NULL, + ADD COLUMN `profile_picture` TEXT NULL, + MODIFY `role` ENUM('admin', 'intern') NOT NULL DEFAULT 'admin'; + +-- CreateTable +CREATE TABLE `user` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `id_mahasiswa` INTEGER NOT NULL, + `id_lamaran_magang` INTEGER NOT NULL, + `full_name` VARCHAR(255) NOT NULL, + `email` VARCHAR(255) NOT NULL, + `password` TEXT NOT NULL, + `role` ENUM('admin', 'intern') NOT NULL DEFAULT 'intern', + `professional_bio` TEXT NULL, + `is_active` BOOLEAN NOT NULL DEFAULT true, + `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updated_at` DATETIME(3) NOT NULL, + + UNIQUE INDEX `user_id_mahasiswa_key`(`id_mahasiswa`), + UNIQUE INDEX `user_id_lamaran_magang_key`(`id_lamaran_magang`), + UNIQUE INDEX `user_email_key`(`email`), + INDEX `user_email_idx`(`email`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `project` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `id_admin` INTEGER NOT NULL, + `project_icon` ENUM('code', 'chart', 'cloud', 'mobile', 'gear', 'users', 'clipboard', 'speedometer', 'lightbulb', 'shield') NOT NULL DEFAULT 'code', + `project_name` VARCHAR(255) NOT NULL, + `description` TEXT NOT NULL, + `start_date` DATE NOT NULL, + `end_date` DATE NOT NULL, + `max_members` INTEGER NOT NULL DEFAULT 8, + `status` ENUM('active', 'completed', 'archived') NOT NULL DEFAULT 'active', + `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updated_at` DATETIME(3) NOT NULL, + + INDEX `project_id_admin_foreign`(`id_admin`), + INDEX `project_status_idx`(`status`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `project_member` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `id_project` INTEGER NOT NULL, + `id_user` INTEGER NOT NULL, + `status` ENUM('active', 'removed') NOT NULL DEFAULT 'active', + `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updated_at` DATETIME(3) NOT NULL, + + INDEX `project_member_id_project_foreign`(`id_project`), + INDEX `project_member_id_user_foreign`(`id_user`), + INDEX `project_member_status_idx`(`status`), + UNIQUE INDEX `project_member_id_project_id_user_key`(`id_project`, `id_user`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `task` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `id_project` INTEGER NOT NULL, + `title` VARCHAR(255) NOT NULL, + `description` TEXT NOT NULL, + `deadline_at` DATETIME(3) NOT NULL, + `submission_type` ENUM('file_upload', 'url_link') NOT NULL, + `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updated_at` DATETIME(3) NOT NULL, + + INDEX `task_id_project_foreign`(`id_project`), + INDEX `task_deadline_at_idx`(`deadline_at`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `task_submission` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `id_task` INTEGER NOT NULL, + `id_user` INTEGER NOT NULL, + `file_path` TEXT NULL, + `url_link` TEXT NULL, + `submitted_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updated_at` DATETIME(3) NOT NULL, + + INDEX `task_submission_id_task_foreign`(`id_task`), + INDEX `task_submission_id_user_foreign`(`id_user`), + UNIQUE INDEX `task_submission_id_task_id_user_key`(`id_task`, `id_user`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- AddForeignKey +ALTER TABLE `user` ADD CONSTRAINT `user_id_mahasiswa_foreign` FOREIGN KEY (`id_mahasiswa`) REFERENCES `mahasiswa`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `user` ADD CONSTRAINT `user_id_lamaran_magang_foreign` FOREIGN KEY (`id_lamaran_magang`) REFERENCES `lamaran_magang`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `project` ADD CONSTRAINT `project_id_admin_foreign` FOREIGN KEY (`id_admin`) REFERENCES `admin`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `project_member` ADD CONSTRAINT `project_member_id_project_foreign` FOREIGN KEY (`id_project`) REFERENCES `project`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `project_member` ADD CONSTRAINT `project_member_id_user_foreign` FOREIGN KEY (`id_user`) REFERENCES `user`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `task` ADD CONSTRAINT `task_id_project_foreign` FOREIGN KEY (`id_project`) REFERENCES `project`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `task_submission` ADD CONSTRAINT `task_submission_id_task_foreign` FOREIGN KEY (`id_task`) REFERENCES `task`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `task_submission` ADD CONSTRAINT `task_submission_id_user_foreign` FOREIGN KEY (`id_user`) REFERENCES `user`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1ee42f3..e226758 100755 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -23,6 +23,11 @@ model Admin { password String @db.Text signature String? @db.Text // singature untuk identifikasi auth jwt (best practice) + profile_picture String? @db.Text + professional_bio String? @db.Text + + projects Project[] + @@map("admin") } @@ -47,6 +52,7 @@ model LamaranMagang { created_at DateTime @default(now()) update_at DateTime + user User? batch_data Batch? @relation(fields: [batch], references: [id], map: "lamaran_magang_batch_foreign") mahasiswa Mahasiswa @relation(fields: [id_mahasiswa], references: [id], map: "lamaran_magang_id_mahasiswa_foreign") lowongan_magang LowonganMagang @relation(fields: [id_lowongan_magang], references: [id], map: "lamaran_magang_id_lowongan_magang_foreign") @@ -95,6 +101,7 @@ model Mahasiswa { motivasi String @db.Text relevant_skills String @db.VarChar(255) + user User? lamaran_magang LamaranMagang[] @@map("mahasiswa") @@ -170,8 +177,107 @@ model Batch { @@map("batch") } +model User { + id Int @id @default(autoincrement()) + id_mahasiswa Int @unique + id_lamaran_magang Int @unique + full_name String @db.VarChar(255) + email String @unique @db.VarChar(255) + password String @db.Text + role Role @default(intern) + professional_bio String? @db.Text + is_active Boolean @default(true) + created_at DateTime @default(now()) + updated_at DateTime @updatedAt + + mahasiswa Mahasiswa @relation(fields: [id_mahasiswa], references: [id], map: "user_id_mahasiswa_foreign") + lamaran_magang LamaranMagang @relation(fields: [id_lamaran_magang], references: [id], map: "user_id_lamaran_magang_foreign") + project_members ProjectMember[] + task_submissions TaskSubmission[] + + @@index([email]) + @@map("user") +} + +model Project { + id Int @id @default(autoincrement()) + id_admin Int //mentor project + project_icon ProjectIcon @default(code) + project_name String @db.VarChar(255) + description String @db.Text + start_date DateTime @db.Date + end_date DateTime @db.Date + max_members Int @default(8) + status ProjectStatus @default(active) + created_at DateTime @default(now()) + updated_at DateTime @updatedAt + + admin Admin @relation(fields: [id_admin], references: [id], map: "project_id_admin_foreign") + members ProjectMember[] + tasks Task[] + + @@index([id_admin], map: "project_id_admin_foreign") + @@index([status]) + @@map("project") +} + +model ProjectMember { + id Int @id @default(autoincrement()) + id_project Int + id_user Int + status ProjectMemberStatus @default(active) + created_at DateTime @default(now()) + updated_at DateTime @updatedAt + + project Project @relation(fields: [id_project], references: [id], map: "project_member_id_project_foreign") + user User @relation(fields: [id_user], references: [id], map: "project_member_id_user_foreign") + + @@unique([id_project, id_user]) + @@index([id_project], map: "project_member_id_project_foreign") + @@index([id_user], map: "project_member_id_user_foreign") + @@index([status]) + @@map("project_member") +} + +model Task { + id Int @id @default(autoincrement()) + id_project Int + title String @db.VarChar(255) + description String @db.Text + deadline_at DateTime + submission_type SubmissionType + created_at DateTime @default(now()) + updated_at DateTime @updatedAt + + project Project @relation(fields: [id_project], references: [id], map: "task_id_project_foreign") + submissions TaskSubmission[] + + @@index([id_project], map: "task_id_project_foreign") + @@index([deadline_at]) + @@map("task") +} + +model TaskSubmission { + id Int @id @default(autoincrement()) + id_task Int + id_user Int + file_path String? @db.Text + url_link String? @db.Text + submitted_at DateTime @default(now()) + updated_at DateTime @updatedAt + + task Task @relation(fields: [id_task], references: [id], map: "task_submission_id_task_foreign") + user User @relation(fields: [id_user], references: [id], map: "task_submission_id_user_foreign") + + @@unique([id_task, id_user]) + @@index([id_task], map: "task_submission_id_task_foreign") + @@index([id_user], map: "task_submission_id_user_foreign") + @@map("task_submission") +} + enum Role { admin + intern } enum StudentRole { @@ -193,3 +299,32 @@ enum PaidStatus { paid unpaid } + +enum ProjectIcon { + code + chart + cloud + mobile + gear + users + clipboard + speedometer + lightbulb + shield +} + +enum ProjectStatus { + active + completed + archived +} + +enum ProjectMemberStatus { + active + removed +} + +enum SubmissionType { + file_upload + url_link +}