𝗕𝘂𝗶𝗹𝗱𝗶𝗻𝗴 𝗮 𝗣𝗿𝗼𝗷𝗲𝗰𝘁 𝗠𝗮𝗻𝗮𝗴𝗲𝗺𝗲𝗻𝘁 𝗧𝗼𝗼𝗹 𝘄𝗶𝘁𝗵 𝗣𝗿𝗶𝘀𝗺𝗮

I am building a collaborative project management tool like Trello.

I am using React, Express.js, PostgreSQL, and Socket.io. Before I write any backend routes, I must design the database schema.

The schema is the foundation. If the schema is wrong, the whole app fails. Here is my breakdown of the Prisma schema design.

𝗧𝗵𝗲 𝗠𝗼𝗱𝗲𝗹𝘀

• User: Stores names, emails, and passwords. I use cuid() for IDs. This creates long, unique strings. It is better than numbers because it does not leak your user count in the URL.

• Project: Holds the project name and description. I made the description optional using a question mark.

• ProjectMember: This is a junction table. It links Users to Projects. Since one user can join many projects, and one project has many users, you need this middle table to manage the many-to-many relationship. I added a unique constraint to prevent the same user from joining a project twice.

• Board: Tasks live inside boards. Boards live inside projects. This hierarchy makes drag-and-drop easy. Moving a task between columns is just a single field update.

• Task: This is the core model. It has two different relations to the User model:

• Comment: Users can leave comments on tasks. I named the relation "author" instead of "user" to keep the code readable.

• Notification: A simple model to track messages for users.

𝗧𝗲𝗰𝗵𝗻𝗶𝗰𝗮𝗹 𝗟𝗲𝘀𝘀𝗼𝗻𝘀 𝗟𝗲𝗮𝗿𝗻𝘁

I ran into several errors while building this. Watch out for these:

The schema is now migrated. Next, I will build the Express backend and Socket.io setup for real-time updates.

Membangun Alat Manajemen Proyek dari Nol: Dimulai dengan Skema Prisma

Membangun alat manajemen proyek adalah cara yang luar biasa untuk mempelajari berbagai konsep pengembangan perangkat lunak, mulai dari desain database hingga implementasi frontend yang kompleks. Dalam seri ini, kita akan membangun alat manajemen proyek full-stack dari awal.

Kita akan menggunakan teknologi modern seperti:

Langkah pertama dalam membangun aplikasi apa pun adalah menentukan struktur datanya. Di sinilah Prisma Schema memainkan peran penting. Skema ini akan menjadi sumber kebenaran tunggal (single source of truth) untuk model data kita dan hubungan antar entitas.

Menentukan Skema Prisma

Mari kita mulai dengan mendefinisikan model-model utama yang kita butuhkan: User, Project, Task, Comment, dan Attachment.

Berikut adalah skema awal kita:

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String    @unique
  password      String
  image         String?
  projects      Project[]
  tasks         Task[]
  comments      Comment[]
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
}

model Project {
  id          String   @id @default(cuid())
  name        String
  description String?
  status      ProjectStatus @default(PLANNING)
  ownerId     String
  owner       User     @relation(fields: [ownerId], references: [id])
  tasks       Task[]
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}

enum ProjectStatus {
  PLANNING
  ACTIVE
  COMPLETED
  ARCHIVED
}

model Task {
  id          String   @id @default(cuid())
  title       String
  description String?
  status      TaskStatus @default(TODO)
  priority    Priority @default(MEDIUM)
  projectId   String
  project     Project  @relation(fields: [projectId], references: [id])
  assigneeId  String?
  assignee    User?    @relation(fields: [assigneeId], references: [id])
  comments    Comment[]
  attachments Attachment[]
  dueDate     DateTime?
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}

enum TaskStatus {
  TODO
  IN_PROGRESS
  DONE
}

enum Priority {
  LOW
  MEDIUM
  HIGH
}

model Comment {
  id        String   @id @default(cuid())
  content   String
  taskId    String
  task      Task     @relation(fields: [taskId], references: [id])
  userId    String
  user      User     @relation(fields: [userId], references: [id])
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model Attachment {
  id        String   @id @default(cuid())
  url       String
  name      String
  taskId    String
  task      Task     @relation(fields: [taskId], references: [id])
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

Penjelasan Model

Mari kita bedah model-model yang telah kita buat:

1. Model User

Model ini mewakili pengguna yang akan menggunakan aplikasi kita. Setiap pengguna memiliki email yang unik untuk autentikasi. Pengguna dapat memiliki banyak Project, Task, dan Comment.

2. Model Project

Proyek adalah wadah besar untuk tugas-tugas. Setiap proyek dimiliki oleh seorang User (sebagai owner). Kita juga menggunakan enum untuk ProjectStatus guna membatasi status proyek hanya pada nilai tertentu seperti PLANNING, ACTIVE, COMPLETED, atau ARCHIVED.

3. Model Task

Tugas adalah unit kerja terkecil dalam proyek kita. Sebuah tugas terikat pada satu Project dan dapat ditugaskan kepada satu User (assignee). Kita menggunakan enum untuk TaskStatus dan Priority untuk memberikan struktur pada manajemen tugas.

4. Model Comment

Untuk kolaborasi, kita memerlukan fitur komentar. Pengguna dapat memberikan komentar pada tugas tertentu. Setiap komentar terhubung ke satu Task dan satu User.

5. Model Attachment

Tugas sering kali membutuhkan dokumen atau gambar pendukung. Model Attachment memungkinkan kita menyimpan URL file yang terkait dengan tugas tertentu.

Hubungan (Relationships)

Dalam skema di atas, kita telah menerapkan beberapa jenis relasi:

Dengan skema ini, kita telah membangun fondasi yang kuat untuk aplikasi manajemen proyek kita. Pada artikel berikutnya, kita akan mulai mengatur lingkungan pengembangan dan melakukan migrasi database pertama kita menggunakan Prisma.