> ## Documentation Index
> Fetch the complete documentation index at: https://docs.quinnsambal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Projects

<style>
  {`
    [class*="max-w-none"][class*="table"] {
      display: block !important;
      overflow-x: auto !important;
      max-width: 100% !important;
      width: 100% !important;
      flex-grow: 0 !important;
    }
    [class*="max-w-none"][class*="table"] > table {
      width: 100% !important;
      max-width: 100% !important;
      table-layout: fixed !important;
    }
    .mermaid {
      max-width: 100% !important;
      overflow-x: auto !important;
    }
    article svg[role="img"] {
      max-width: 100% !important;
      height: auto !important;
    }
    article img, .prose img {
      max-width: 100% !important;
      height: auto !important;
    }
    img[src*="LOGO"], img[src*="logo"] {
      max-width: 120px !important;
      max-height: 40px !important;
      width: auto !important;
      height: auto !important;
      object-fit: contain !important;
    }
    `}
</style>

***

title: "Projects"
description: "Manajemen proyek dengan timeline, milestones, budget tracking, team assignment, task management, time tracking, dan auto-invoice di SNISHOP ERP."
---------------------------------------------------------------------------------------------------------------------------------------------------------------

# Projects

<img src="https://mintcdn.com/quinnofspicy/7mQVU6fsgRvm4pNL/docs/mintlify/screenshots/productivity/projects.png?fit=max&auto=format&n=7mQVU6fsgRvm4pNL&q=85&s=93f22c2c9c1464675e0c72fddee7d51d" alt="Projects" width="1920" height="1080" data-path="docs/mintlify/screenshots/productivity/projects.png" />

Halaman Projects mengelola seluruh siklus hidup proyek — dari planning hingga completion. Dibangun di atas `Projects.jsx` (778 baris) dengan integrasi langsung ke CRM (Customer), HR (CompanyMember), dan Finance (Invoice).

Setiap proyek memiliki budget tracking, payment progress, milestone yang bisa dipantau secara realtime, serta dukungan untuk task management, time tracking, dan recurring tasks. Saat proyek baru dibuat, sistem otomatis membuat invoice terkait di modul Finance.

## Arsitektur Komponen

```mermaid theme={null}
graph TD
    A[Projects.jsx<br/>778 lines] --> B[Stats Dashboard<br/>4 Metrics]
    A --> C[Project List<br/>Grid View]
    A --> D[ProjectForm<br/>Modal]
    A --> E[ProjectCard]
    A --> F[ProjectDetailModal<br/>Full Detail View]
    A --> G[Status Filter]
    A --> H[Search Bar]
    
    B --> B1[Total Projects]
    B --> B2[In Progress]
    B --> B3[Completed]
    B --> B4[Total Budget]
    
    D --> I[Customer Selector<br/>CRM Integration]
    D --> J[Team Member Selector<br/>HR Integration]
    D --> K[Milestone Editor<br/>Array of milestones]
    D --> L[Budget & Date Inputs]
    
    E --> E1[Project Name]
    E --> E2[Client Name]
    E --> E3[Progress Bar]
    E --> E4[Budget & Payment]
    E --> E5[Team Avatars]
    E --> E6[Status Badge]
    E --> E7[Timeline]
    
    A --> M[base44.entities.Project]
    A --> N[base44.entities.Customer]
    A --> O[base44.entities.CompanyMember]
    A --> P[base44.entities.Invoice]
    A --> Q[base44.entities.Task]
    A --> R[base44.entities.TimeEntry]
    A --> S[base44.entities.RecurringTask]
```

## Entity Relationship Diagram

```mermaid theme={null}
erDiagram
    Project ||--o{ Task : "memiliki tasks"
    Project ||--o{ TimeEntry : "mencatat waktu"
    Project ||--o{ Milestone : "memiliki milestones"
    Project }o--|| Customer : "dimiliki oleh klien"
    Project }o--|| Company : "berada di perusahaan"
    Project }o--o{ CompanyMember : "memiliki tim"
    Project }o--o| Invoice : "terhubung invoice"

    Task ||--o{ Task : "parent/sub-tasks"
    Task ||--o{ TimeEntry : "dicatat waktunya"
    Task ||--o{ Comment : "memiliki komentar"
    Task }o--o{ Label : "dilabeli"
    Task }o--|| Workspace : "berada di workspace"
    Task }o--o| RecurringTask : "dibuat dari recurring"
    Task }o--o| CompanyMember : "ditugaskan ke"

    TimeEntry }o--|| User : "dicatat oleh"
    TimeEntry }o--o| Task : "terkait tugas"

    RecurringTask }o--|| Workspace : "berada di workspace"
    RecurringTask }o--o| CompanyMember : "ditugaskan ke"

    Comment }o--|| User : "dibuat oleh"
    Comment ||--o| Comment : "parent/reply"

    Label }o--|| User : "dimiliki oleh"
    Label }o--|| Workspace : "berada di workspace"

    Workspace }o--|| Company : "milik perusahaan"
    Workspace }o--|| User : "dimiliki oleh"

    Project {
        string company_id FK
        string name "nama proyek"
        string description "deskripsi"
        string client_id FK_Customer
        string client_name "denormalized"
        string project_manager_id FK_CompanyMember
        date start_date "tanggal mulai"
        date end_date "deadline"
        number budget "nilai proyek"
        number actual_cost "biaya aktual"
        enum status "status proyek"
        enum priority "prioritas"
        number progress "0-100"
        array team_members "employee IDs"
        array milestones "daftar milestone"
        array attachments "file terlampir"
        array tags "tag proyek"
    }

    Task {
        string workspace_id FK
        string company_id FK
        string title "judul tugas"
        string content "deskripsi tugas"
        enum status "status tugas"
        enum priority "prioritas"
        datetime due_date "tenggat waktu"
        string assignee_id FK_CompanyMember
        array tags "label tugas"
        number estimated_time "estimasi menit"
        number actual_time "waktu aktual menit"
        boolean is_time_tracked "tracking aktif"
        array time_entries "log waktu"
        string parent_task_id FK_Task
        array sub_tasks "sub-task IDs"
        string recurring_task_id FK
        datetime completed_at "waktu selesai"
        boolean reminder_sent "pengingat terkirim"
        string google_event_id "ID Google Calendar"
        object reminder_config "konfigurasi notifikasi"
    }

    TimeEntry {
        string company_id FK
        string user_id FK
        string project_id FK
        string task_id FK
        date entry_date "tanggal"
        time start_time "waktu mulai"
        time end_time "waktu selesai"
        number duration_minutes "durasi"
        string description "deskripsi pekerjaan"
        boolean billable "dapat ditagihkan"
        boolean is_approved "sudah disetujui"
        string approved_by FK
        enum status "status approval"
    }

    RecurringTask {
        string task_id FK
        string workspace_id FK
        string title "judul template"
        string content "deskripsi"
        enum frequency "frekuensi"
        number interval "interval"
        array days_of_week "hari dalam minggu"
        number day_of_month "tanggal dalam bulan"
        datetime start_date "mulai"
        datetime end_date "berakhir"
        boolean is_active "aktif"
        datetime last_generated "terakhir dibuat"
        enum priority "prioritas"
        string assignee_id FK
    }
```

***

## Entity: Project

Entitas utama yang merepresentasikan sebuah proyek klien. Terintegrasi langsung dengan CRM untuk data klien, HR untuk tim, dan Finance untuk invoice.

### Schema Tabel

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `company_id` | string (FK) | Ya | ID perusahaan tempat proyek berada |
| `name` | string | Ya | Nama proyek yang akan ditampilkan |
| `description` | string | Tidak | Deskripsi lengkap dan scope pekerjaan proyek |
| `client_id` | string (FK → Customer) | Tidak | ID klien/pemilik proyek dari modul CRM |
| `client_name` | string | Tidak | Nama klien (denormalized untuk performa query) |
| `project_manager_id` | string (FK → CompanyMember) | Tidak | ID project manager yang bertanggung jawab |
| `start_date` | date | Ya | Tanggal mulai proyek |
| `end_date` | date | Tidak | Deadline atau tanggal selesai proyek |
| `budget` | number | Tidak | Total nilai proyek dalam Rupiah |
| `actual_cost` | number | Tidak | Biaya aktual yang sudah dikeluarkan (default: 0) |
| `status` | enum | Tidak | Status proyek (default: `planning`) |
| `priority` | enum | Tidak | Tingkat prioritas proyek (default: `medium`) |
| `progress` | number (0-100) | Tidak | Persentase penyelesaian proyek (default: 0) |
| `team_members` | array\<string> | Tidak | Array of employee IDs dari CompanyMember |
| `milestones` | array\<object> | Tidak | Daftar target per fase proyek |
| `attachments` | array\<string> | Tidak | Array of file attachment URLs |
| `tags` | array\<string> | Tidak | Tag untuk kategorisasi proyek |

### Sub-Object: Milestone

Setiap objek dalam array `milestones` memiliki struktur sebagai berikut:

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `name` | string | Ya | Nama milestone |
| `description` | string | Tidak | Detail deliverable dari milestone |
| `due_date` | date | Tidak | Target tanggal penyelesaian |
| `status` | enum | Tidak | Status: `pending` atau `completed` |
| `completed_date` | date | Tidak | Tanggal aktual saat milestone selesai |

***

## Entity: Task

Entitas tugas yang bisa berdiri sendiri di workspace atau terhubung ke proyek. Mendukung sub-tasks hierarkis, time tracking, integrasi Google Calendar, dan recurring tasks.

### Schema Tabel

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `workspace_id` | string (FK) | Ya | ID workspace tempat tugas berada |
| `company_id` | string (FK) | Tidak | ID perusahaan (null untuk personal) |
| `title` | string | Ya | Judul tugas |
| `content` | string | Tidak | Deskripsi detail tugas |
| `status` | enum | Tidak | Status tugas (default: `todo`) |
| `priority` | enum | Tidak | Tingkat prioritas (default: `medium`) |
| `due_date` | datetime | Tidak | Tanggal dan waktu tenggat |
| `assignee_id` | string (FK → CompanyMember) | Tidak | ID anggota tim yang ditugaskan |
| `tags` | array\<string> | Tidak | Label/tag tugas |
| `estimated_time` | number | Tidak | Estimasi waktu pengerjaan dalam menit |
| `actual_time` | number | Tidak | Waktu aktual yang dihabiskan dalam menit |
| `is_time_tracked` | boolean | Tidak | Apakah time tracking aktif (default: false) |
| `time_entries` | array\<object> | Tidak | Log waktu pengerjaan (embedded) |
| `parent_task_id` | string (FK → Task) | Tidak | ID parent task untuk sub-tasks |
| `sub_tasks` | array\<string> | Tidak | Array of sub-task IDs |
| `recurring_task_id` | string (FK → RecurringTask) | Tidak | ID recurring task jika dibuat otomatis |
| `completed_at` | datetime | Tidak | Timestamp saat tugas diselesaikan |
| `reminder_sent` | boolean | Tidak | Apakah pengingat sudah dikirim (default: false) |
| `google_event_id` | string | Tidak | ID event pada Google Calendar |
| `reminder_config` | object | Tidak | Konfigurasi notifikasi sebelum tugas jatuh tempo |

### Sub-Object: Time Entry (Embedded di Task)

| Field | Tipe | Deskripsi |
| - | - | - |
| `start` | datetime | Waktu mulai sesi kerja |
| `end` | datetime | Waktu selesai sesi kerja |
| `duration` | number | Durasi dalam menit |

***

## Entity: TimeEntry

Entitas terpisah untuk pencatatan waktu kerja (timesheet) yang terhubung ke proyek dan tugas. Digunakan untuk tracking billable hours dan approval workflow.

### Schema Tabel

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `company_id` | string (FK) | Ya | ID perusahaan |
| `user_id` | string (FK → User) | Ya | ID pengguna yang mencatat waktu |
| `project_id` | string (FK → Project) | Tidak | ID proyek yang dikerjakan |
| `task_id` | string (FK → Task) | Tidak | ID tugas yang dikerjakan |
| `entry_date` | date | Ya | Tanggal pencatatan waktu |
| `start_time` | time | Tidak | Waktu mulai (format HH:MM) |
| `end_time` | time | Tidak | Waktu selesai (format HH:MM) |
| `duration_minutes` | number | Ya | Durasi kerja dalam menit |
| `description` | string | Tidak | Deskripsi pekerjaan yang dilakukan |
| `billable` | boolean | Tidak | Apakah waktu dapat ditagihkan ke klien (default: false) |
| `is_approved` | boolean | Tidak | Apakah sudah disetujui manager (default: false) |
| `approved_by` | string (FK → User) | Tidak | ID user yang menyetujui |
| `status` | enum | Tidak | Status approval (default: `submitted`) |

***

## Entity: RecurringTask

Template tugas berulang yang secara otomatis membuat instance Task baru sesuai frekuensi yang ditentukan. Berguna untuk tugas rutin seperti daily standup, weekly report, atau monthly review.

### Schema Tabel

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `task_id` | string (FK → Task) | Tidak | ID tugas template |
| `workspace_id` | string (FK) | Ya | ID workspace tempat recurring berada |
| `title` | string | Ya | Judul tugas berulang |
| `content` | string | Tidak | Deskripsi detail |
| `frequency` | enum | Ya | Frekuensi: `daily`, `weekly`, `monthly`, `yearly` |
| `interval` | number | Tidak | Interval frekuensi (default: 1) |
| `days_of_week` | array\<number> | Tidak | Hari dalam minggu (0-6) untuk weekly |
| `day_of_month` | number | Tidak | Tanggal dalam bulan untuk monthly |
| `start_date` | datetime | Ya | Tanggal mulai recurring |
| `end_date` | datetime | Tidak | Tanggal berakhirnya recurring |
| `is_active` | boolean | Tidak | Status aktif recurring (default: true) |
| `last_generated` | datetime | Tidak | Timestamp terakhir instance dibuat |
| `priority` | enum | Tidak | Prioritas tugas (default: `medium`) |
| `assignee_id` | string (FK → CompanyMember) | Tidak | ID anggota tim yang ditugaskan |

***

## Entity: Comment

Sistem komentar yang mendukung threaded replies dan mention. Dapat dipasang pada task maupun note.

### Schema Tabel

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `entity_type` | enum | Ya | Jenis entitas: `task` atau `note` |
| `entity_id` | string | Ya | ID dari task atau note yang dikomentari |
| `workspace_id` | string (FK) | Tidak | ID workspace |
| `content` | string | Ya | Isi komentar |
| `user_id` | string (FK → User) | Ya | ID pengguna yang berkomentar |
| `user_name` | string | Tidak | Nama pengguna (denormalized) |
| `user_email` | string | Tidak | Email pengguna (denormalized) |
| `mentions` | array\<string> | Tidak | Array of user\_ids yang di-mention |
| `parent_comment_id` | string (FK → Comment) | Tidak | ID parent comment untuk threaded replies |
| `edited_at` | datetime | Tidak | Timestamp terakhir komentar diedit |

***

## Entity: Label

Label/tag berwarna untuk kategorisasi task dan organisasi workspace.

### Schema Tabel

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `name` | string | Ya | Nama label |
| `color` | string | Tidak | Warna hex label (default: `#9CA3AF`) |
| `icon` | string | Tidak | Icon emoji label (default: 🏷️) |
| `description` | string (max 1000) | Tidak | Penjelasan kegunaan label |
| `user_id` | string (FK → User) | Ya | ID pemilik label |
| `workspace_id` | string (FK) | Tidak | ID workspace |

***

## Entity: Workspace

Workspace adalah ruang kerja yang mengelompokkan tasks, labels, dan recurring tasks. Bisa bersifat personal atau tim.

### Schema Tabel

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `company_id` | string (FK) | Tidak | ID perusahaan (null untuk personal workspace) |
| `name` | string | Ya | Nama workspace |
| `description` | string | Tidak | Deskripsi workspace |
| `icon` | string | Tidak | Icon workspace |
| `color` | string | Tidak | Warna tema workspace (default: `#2563eb`) |
| `owner_id` | string (FK → User) | Ya | ID pemilik workspace |
| `is_personal` | boolean | Tidak | Apakah workspace pribadi (default: false) |
| `settings` | object | Tidak | Pengaturan workspace |

### Sub-Object: Workspace Settings

| Field | Tipe | Default | Deskripsi |
| - | - | - | - |
| `allow_public_sharing` | boolean | false | Izinkan berbagi publik |
| `default_task_priority` | enum | `medium` | Prioritas default task baru |

***

## Status Proyek

```mermaid theme={null}
stateDiagram-v2
    [*] --> Planning: Proyek dibuat
    Planning --> InProgress: Work dimulai
    InProgress --> OnHold: Ada kendala/pause
    OnHold --> InProgress: Work dilanjutkan
    InProgress --> Completed: Semua milestone tercapai
    Planning --> OnHold: Ditunda sebelum mulai
    Planning --> Cancelled: Proyek dibatalkan
    OnHold --> Cancelled: Dibatalkan saat pause
    InProgress --> Cancelled: Dibatalkan saat berjalan
    OnHold --> Completed: Direct completion
    Completed --> [*]
    Cancelled --> [*]
```

| Status | Warna | Ikon | Deskripsi |
| - | - | - | - |
| `planning` | Abu-abu | 📋 | Proyek sedang tahap persiapan, belum dimulai |
| `in_progress` | Biru | 🔵 | Proyek sedang berjalan aktif |
| `completed` | Hijau | ✅ | Proyek selesai dan ditutup |
| `on_hold` | Oranye | ⏸️ | Proyek dihentikan sementara |
| `cancelled` | Merah | ❌ | Proyek dibatalkan dan tidak dilanjutkan |

***

## Status Tugas (Task)

```mermaid theme={null}
stateDiagram-v2
    [*] --> Todo: Task dibuat
    Todo --> InProgress: Pengerjaan dimulai
    InProgress --> Completed: Pekerjaan selesai
    Completed --> Done: Diverifikasi/di-review
    Todo --> Done: Langsung selesai (quick task)
    InProgress --> Todo: Dikembalikan ke antrian
    Done --> [*]
```

| Status | Warna | Ikon | Deskripsi |
| - | - | - | - |
| `todo` | Abu-abu | 📝 | Tugas belum dikerjakan, masuk antrian |
| `in_progress` | Biru | 🔵 | Tugas sedang dalam pengerjaan aktif |
| `completed` | Hijau | ✅ | Pekerjaan selesai, menunggu review |
| `done` | Hijau Tua | ✔️ | Tugas selesai dan sudah diverifikasi |

***

## Status Time Entry (Approval)

```mermaid theme={null}
stateDiagram-v2
    [*] --> Submitted: Time entry dicatat
    Submitted --> Approved: Manager menyetujui
    Submitted --> Rejected: Manager menolak
    Rejected --> Submitted: Direvisi dan diajukan ulang
    Approved --> [*]
```

| Status | Deskripsi |
| - | - |
| `submitted` | Time entry sudah diajukan dan menunggu approval |
| `approved` | Time entry disetujui oleh manager/approver |
| `rejected` | Time entry ditolak dan perlu direvisi |

***

## Prioritas (Project & Task)

| Nilai | Label | Warna | Ikon | Deskripsi |
| - | - | - | - | - |
| `low` | Rendah | Abu-abu | 🔽 | Tidak mendesak, dikerjakan saat ada waktu |
| `medium` | Sedang | Biru | ➡️ | Prioritas normal, sesuai jadwal |
| `high` | Tinggi | Oranye | 🔼 | Penting dan perlu perhatian segera |
| `urgent` | Mendesak | Merah | ⚡ | Sangat penting, harus diselesaikan segera |

***

## Frekuensi Recurring Task

| Nilai | Label | Deskripsi |
| - | - | - |
| `daily` | Harian | Tugas dibuat ulang setiap hari (atau setiap N hari sesuai interval) |
| `weekly` | Mingguan | Tugas dibuat ulang setiap minggu pada hari tertentu |
| `monthly` | Bulanan | Tugas dibuat ulang setiap bulan pada tanggal tertentu |
| `yearly` | Tahunan | Tugas dibuat ulang setiap tahun |

***

## Budget & Payment Tracking

```mermaid theme={null}
flowchart TD
    A[Project Created<br/>budget = Rp 100.000.000] --> B[Invoice Auto-Created<br/>paid_amount = 0]
    B --> C[Client Pays<br/>Rp 30.000.000]
    C --> D[paid_amount = 30.000.000]
    D --> E["paymentProgress = 30%"]
    E --> F[Client Pays Again<br/>Rp 50.000.000]
    F --> G[paid_amount = 80.000.000]
    G --> H["paymentProgress = 80%"]
    H --> I[Final Payment<br/>Rp 20.000.000]
    I --> J[paid_amount = 100.000.000]
    J --> K["paymentProgress = 100%<br/>Fully Paid ✅"]
```

Payment progress dihitung dengan rumus:

```
paymentProgress = (paid_amount / budget) × 100%
remaining = budget - paid_amount
```

### Contoh Tracking

| Proyek | Budget | Paid | Remaining | Progress | Status |
| - | - | - | - | - | - |
| Website Redesign | Rp 50.000.000 | Rp 50.000.000 | Rp 0 | 100% | ✅ Fully Paid |
| Mobile App | Rp 150.000.000 | Rp 75.000.000 | Rp 75.000.000 | 50% | 🔵 In Progress |
| Branding Package | Rp 30.000.000 | Rp 10.000.000 | Rp 20.000.000 | 33% | 🟡 Partial |
| SEO Campaign | Rp 20.000.000 | Rp 0 | Rp 20.000.000 | 0% | 🔴 Unpaid |

### Cost Variance Tracking

Proyek juga mendukung tracking biaya aktual vs budget:

```
costVariance = budget - actual_cost
variancePercent = (costVariance / budget) × 100%
```

| Kondisi | Arti | Tindakan |
| - | - | - |
| `costVariance > 0` | Under budget — proyek lebih efisien | Dokumentasikan best practice |
| `costVariance = 0` | On budget — sesuai perencanaan | Tidak ada tindakan khusus |
| `costVariance < 0` | Over budget — perlu investigasi | Review scope creep dan efisiensi |

***

## Stats Dashboard

| Metrik | Perhitungan | Deskripsi |
| - | - | - |
| **Total Projects** | `projects.length` | Jumlah seluruh proyek |
| **In Progress** | `filter(status === 'in_progress').length` | Proyek aktif |
| **Completed** | `filter(status === 'completed').length` | Proyek selesai |
| **Total Budget** | `Σ projects[].budget` | Akumulasi nilai seluruh proyek |

***

## Auto-Invoice Integration

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Projects
    participant InvoiceEntity
    participant Finance

    User->>Projects: Create Project
    Projects->>Projects: Validate budget > 0
    Projects->>Projects: Prepare Invoice data
    Note over Projects: client_id, budget as amount,<br/>status = 'draft'
    Projects->>InvoiceEntity: Create Invoice
    InvoiceEntity-->>Projects: Invoice ID
    Projects->>Projects: Link invoice_id to project
    Finance-->>User: Invoice visible di modul Finance
    Note over Finance: Invoice bisa di-edit,<br/>sent, dan tracked
```

Saat proyek baru dibuat, sistem otomatis membuat entitas **Invoice** yang terhubung:

| Invoice Field | Source | Deskripsi |
| - | - | - |
| `client_id` | `project.client_id` | Klien yang sama |
| `amount` | `project.budget` | Nilai = budget proyek |
| `status` | `'draft'` | Status awal draft |
| `description` | `project.name` | Referensi ke proyek |

***

## Milestone Management

```mermaid theme={null}
gantt
    title Contoh Milestones Proyek
    dateFormat  YYYY-MM-DD
    section Fase 1
    Research & Planning    :2026-10-01, 14d
    Wireframing           :2026-10-15, 7d
    section Fase 2
    UI Design             :2026-10-22, 14d
    Frontend Dev          :2026-11-05, 21d
    section Fase 3
    Backend Integration   :2026-11-26, 14d
    Testing & QA          :2026-12-10, 7d
    Launch                :2026-12-17, 0d
```

Setiap milestone memiliki:

| Field | Tipe | Deskripsi |
| - | - | - |
| `name` | string | Nama milestone |
| `description` | string | Detail deliverable |
| `due_date` | date | Target tanggal selesai |
| `status` | enum | `pending`, `completed` |
| `completed_date` | date | Tanggal aktual saat milestone selesai |

### Flow Penyelesaian Milestone

```mermaid theme={null}
sequenceDiagram
    participant PM as Project Manager
    participant Project
    participant Milestone
    participant Team

    PM->>Project: Buat milestone baru
    Project->>Milestone: Set status = 'pending'
    Milestone-->>Team: Notifikasi milestone baru
    
    Team->>Team: Kerjakan deliverable
    Team->>PM: Laporkan penyelesaian
    
    PM->>Milestone: Review deliverable
    alt Deliverable diterima
        PM->>Milestone: Set status = 'completed'
        PM->>Milestone: Set completed_date = today
        Milestone->>Project: Update progress
        Project-->>PM: Progress bar updated
    else Deliverabel perlu revisi
        PM->>Team: Request revisi
        Team->>Team: Perbaiki deliverable
    end
```

***

## Task Management

### Membuat dan Menugaskan Task

```mermaid theme={null}
sequenceDiagram
    participant PM as Project Manager
    participant ProjectModule
    participant TaskEntity
    participant Assignee
    participant Notification

    PM->>ProjectModule: Buka detail proyek
    PM->>ProjectModule: Klik "Tambah Task"
    ProjectModule->>TaskEntity: Create Task
    Note over TaskEntity: title, content, priority,<br/>due_date, estimated_time
    TaskEntity->>TaskEntity: Set status = 'todo'
    PM->>TaskModule: Assign ke anggota tim
    TaskEntity->>Assignee: Set assignee_id
    TaskEntity->>Notification: Kirim notifikasi
    Notification-->>Assignee: "Tugas baru ditugaskan"
    
    Assignee->>TaskEntity: Update status = 'in_progress'
    Assignee->>TaskEntity: Log time entries
    Assignee->>TaskEntity: Update status = 'completed'
    TaskEntity->>Notification: Notifikasi ke PM
    Notification-->>PM: "Tugas selesai, perlu review"
    
    PM->>TaskEntity: Review & set status = 'done'
    TaskEntity->>Notification: Notifikasi ke Assignee
    Notification-->>Assignee: "Tugas diverifikasi"
```

### Sub-Task Hierarchy

Task mendukung struktur hierarki parent-child untuk decomposisi pekerjaan yang lebih detail:

```mermaid theme={null}
graph TD
    T1[Parent Task<br/>Desain UI Homepage] --> T2[Sub-task 1<br/>Wireframe layout]
    T1 --> T3[Sub-task 2<br/>Mockup high-fidelity]
    T1 --> T4[Sub-task 3<br/>Design system update]
    T3 --> T5[Sub-sub-task<br/>Komponen button]
    T3 --> T6[Sub-sub-task<br/>Komponen card]
```

Setiap task dapat memiliki:

* **Parent task** (`parent_task_id`) — referensi ke task induk
* **Sub-tasks** (`sub_tasks`) — array of child task IDs
* Hierarki bisa multi-level (nested)

### Time Tracking pada Task

```mermaid theme={null}
flowchart LR
    A[Task dengan<br/>is_time_tracked = true] --> B[Mulai Timer<br/>start_time]
    B --> C[Sedang Mengerjakan]
    C --> H[Stop Timer<br/>end_time]
    H --> D[Hitung duration]
    D --> E[Simpan ke<br/>time_entries array]
    E --> F[Update actual_time]
    F --> G{estimated_time<br/>tercapai?}
    G -->|Ya| H1[Task selesai]
    G -->|Belum| C
```

***

## Recurring Tasks

Recurring tasks memungkinkan pembuatan tugas otomatis berdasarkan jadwal yang ditentukan.

### Konfigurasi Recurring

| Pola | Contoh | Field yang Digunakan |
| - | - | - |
| Setiap hari | Daily standup | `frequency: daily`, `interval: 1` |
| Setiap 3 hari | Sprint review | `frequency: daily`, `interval: 3` |
| Setiap minggu (Senin) | Weekly report | `frequency: weekly`, `days_of_week: [1]` |
| Setiap 2 minggu | Bi-weekly sync | `frequency: weekly`, `interval: 2` |
| Setiap bulan (tgl 1) | Monthly report | `frequency: monthly`, `day_of_month: 1` |
| Setiap tahun | Annual review | `frequency: yearly` |

### Flow Recurring Task Generation

```mermaid theme={null}
sequenceDiagram
    participant Scheduler
    participant RecurringTask
    participant TaskEntity
    participant Assignee

    loop Setiap interval
        Scheduler->>RecurringTask: Check last_generated
        RecurringTask->>RecurringTask: Hitung tanggal berikutnya
        alt is_active = true AND dalam rentang
            RecurringTask->>TaskEntity: Create instance Task
            Note over TaskEntity: Copy title, content, priority<br/>Set recurring_task_id
            TaskEntity->>TaskEntity: Set status = 'todo'
            TaskEntity->>Assignee: Assign ke assignee_id
            RecurringTask->>RecurringTask: Update last_generated
        else Tidak aktif atau di luar rentang
            Scheduler->>Scheduler: Skip
        end
    end
```

***

## Time Entry & Timesheet

### Flow Pencatatan Waktu

```mermaid theme={null}
sequenceDiagram
    participant Employee
    participant TimeEntryModule
    participant ProjectModule
    participant Manager

    Employee->>TimeEntryModule: Catat waktu kerja
    Note over TimeEntryModule: project_id, task_id,<br/>entry_date, duration,<br/>description, billable
    TimeEntryModule->>TimeEntryModule: Set status = 'submitted'
    TimeEntryModule->>Manager: Notifikasi approval
    
    Manager->>TimeEntryModule: Review time entry
    alt Disetujui
        Manager->>TimeEntryModule: Set status = 'approved'
        Manager->>TimeEntryModule: Set is_approved = true
        TimeEntryModule->>ProjectModule: Update actual_cost
    else Ditolak
        Manager->>TimeEntryModule: Set status = 'rejected'
        TimeEntryModule-->>Employee: Notifikasi revisi
    end
```

### Billable vs Non-Billable

| Tipe | Deskripsi | Pengaruh |
| - | - | - |
| Billable (`billable: true`) | Waktu yang dapat ditagihkan ke klien | Meningkatkan `paid_amount` dan revenue |
| Non-Billable (`billable: false`) | Waktu internal, tidak ditagihkan | Masuk biaya operasional |

***

## Team Assignment

```mermaid theme={null}
flowchart LR
    A[Project] --> B[team_members array]
    B --> C1[CompanyMember #1<br/>Project Manager]
    B --> C2[CompanyMember #2<br/>Designer]
    B --> C3[CompanyMember #3<br/>Developer]
    B --> C4[CompanyMember #4<br/>QA Engineer]
    
    C1 & C2 & C3 & C4 --> D[ProjectCard<br/>Avatar Badges]
```

Anggota tim dipilih dari entity **CompanyMember** dan disimpan di field `team_members` (array of IDs). Setiap anggota bisa dilihat di ProjectCard dengan avatar badge.

### Peran dalam Proyek

| Peran | Deskripsi | Akses |
| - | - | - |
| **Project Manager** (`project_manager_id`) | Bertanggung jawab atas keseluruhan proyek | Full access: edit, assign, approve |
| **Team Member** (`team_members[]`) | Anggota tim yang mengerjakan tugas | Read + update task status |
| **Viewer** | Stakeholder yang memantau progress | Read-only access |

***

## Komentar & Kolaborasi

Sistem komentar mendukung diskusi pada task dengan fitur mention dan threaded replies.

```mermaid theme={null}
flowchart TD
    A[User menulis komentar<br/>pada Task] --> B{Ada mention?}
    B -->|Ya| C[Kirim notifikasi ke<br/>user yang di-mention]
    B -->|Tidak| D[Simpan komentar]
    C --> D
    D --> E{Ada parent_comment_id?}
    E -->|Ya| F[Jadikan reply dari<br/>komentar parent]
    E -->|Tidak| G[Komentar top-level]
    F --> H[Tampilkan di thread]
    G --> H
```

***

## Integrasi Lintas Modul

| Modul | Entity | Fungsi | Data Flow |
| - | - | - | - |
| CRM | Customer | Pemilihan klien proyek | Customer → Project (client\_id, client\_name) |
| HR | CompanyMember | Assignment tim proyek | CompanyMember → Project (team\_members) |
| HR | CompanyMember | Assignment tugas | CompanyMember → Task (assignee\_id) |
| Finance | Invoice | Auto-create invoice saat proyek dibuat | Project → Invoice (budget → amount) |
| Finance | TimeEntry | Billable hours tracking | TimeEntry → Invoice (billable hours) |
| Productivity | Task | Task management per proyek | Project → Task (via workspace) |
| Productivity | Workspace | Organisasi task dan label | Workspace → Task, Label, RecurringTask |
| Dashboard | — | Widget ringkasan proyek | Project stats → Dashboard widget |

***

## Filter & Pencarian

| Filter | Opsi | Deskripsi |
| - | - | - |
| **Status** | All, Planning, In Progress, Completed, On Hold, Cancelled | Filter berdasarkan status proyek |
| **Priority** | All, Low, Medium, High, Urgent | Filter berdasarkan prioritas |
| **Search** | Pencarian berdasarkan nama proyek | Full-text search |
| **Tags** | Filter berdasarkan tag | Filter proyek berdasarkan tag |

***

## RBAC Permission Matrix

Berikut adalah matriks hak akses berdasarkan peran terhadap entitas Projects dan Task:

| Aksi | Admin | Project Manager | Team Member | Viewer |
| - | - | - | - | - |
| **Project** | | | | |
| Create project | ✅ | ✅ | ❌ | ❌ |
| Edit project | ✅ | ✅ | ❌ | ❌ |
| Delete project | ✅ | ❌ | ❌ | ❌ |
| View all projects | ✅ | ✅ | ✅ | ✅ |
| Change project status | ✅ | ✅ | ❌ | ❌ |
| Set budget | ✅ | ✅ | ❌ | ❌ |
| Assign team members | ✅ | ✅ | ❌ | ❌ |
| Manage milestones | ✅ | ✅ | ❌ | ❌ |
| **Task** | | | | |
| Create task | ✅ | ✅ | ✅ | ❌ |
| Edit own task | ✅ | ✅ | ✅ | ❌ |
| Edit any task | ✅ | ✅ | ❌ | ❌ |
| Delete task | ✅ | ✅ | ❌ | ❌ |
| Assign task | ✅ | ✅ | ❌ | ❌ |
| Change task status | ✅ | ✅ | ✅ | ❌ |
| **Time Entry** | | | | |
| Create time entry | ✅ | ✅ | ✅ | ❌ |
| Approve time entry | ✅ | ✅ | ❌ | ❌ |
| View all time entries | ✅ | ✅ | ❌ | ❌ |
| **Comment** | | | | |
| Add comment | ✅ | ✅ | ✅ | ❌ |
| Edit own comment | ✅ | ✅ | ✅ | ❌ |
| Delete any comment | ✅ | ❌ | ❌ | ❌ |

***

## Cara Akses

Dari sidebar, klik menu **Productivity** > **Projects**.

***

## Flow Penggunaan

### Membuat Proyek Baru

1. Buka halaman Projects dari sidebar — lihat ringkasan stats di bagian atas
2. Klik **"Proyek Baru"** untuk membuka modal form
3. Isi nama proyek, deskripsi, pilih klien dari daftar Customer
4. Tentukan budget proyek, tanggal mulai, dan deadline
5. Set prioritas proyek sesuai urgensi
6. Tambahkan milestones sebagai target progress per fase
7. Assign anggota tim dari daftar CompanyMember
8. Tambahkan tag untuk kategorisasi
9. Klik **Simpan** — invoice otomatis dibuat di modul Finance
10. Proyek baru muncul dengan status `planning`

### Mengelola Task dalam Proyek

1. Buka detail proyek dari ProjectCard atau ProjectDetailModal
2. Klik **"Tambah Task"** untuk membuat tugas baru
3. Isi judul, deskripsi, prioritas, dan tenggat waktu
4. Assign tugas ke anggota tim yang tersedia
5. Set estimasi waktu pengerjaan
6. Aktifkan time tracking jika perlu (`is_time_tracked: true`)
7. Buat sub-tasks untuk decomposisi pekerjaan yang lebih detail
8. Monitor progress task melalui status updates

### Mencatat Waktu Kerja

1. Buka modul Time Entry dari sidebar
2. Pilih proyek dan tugas yang dikerjakan
3. Isi tanggal, waktu mulai/selesai, atau durasi langsung
4. Tandai sebagai `billable` jika dapat ditagihkan ke klien
5. Ajukan untuk approval (status: `submitted`)
6. Manager mereview dan approve/reject

### Menyelesaikan Proyek

1. Pastikan semua milestone berstatus `completed`
2. Pastikan semua task berstatus `done`
3. Verifikasi total `actual_cost` vs `budget`
4. Update `progress` ke 100%
5. Ubah status proyek ke `completed`
6. Lakukan retrospective dan catat pelajaran untuk proyek berikutnya

***

## Tips

* Selalu isi `client_name` denormalized supaya card tetap tampil cepat tanpa perlu join ke Customer entity
* Gunakan status `on_hold` daripada menghapus proyek — data tetap tersimpan dan bisa dilanjutkan nanti
* Review payment progress secara mingguan untuk memastikan cashflow proyek sehat
* Di akhir proyek, lakukan retrospective dan catat pelajaran untuk proyek berikutnya
* Break down proyek besar menjadi 5-7 milestones supaya progress lebih terukur
* Assign minimal 1 project manager per proyek untuk koordinasi tim
* Gunakan `tags` untuk kategorisasi proyek (misalnya: `web`, `mobile`, `design`, `urgent`)
* Manfaatkan recurring tasks untuk aktivitas rutin seperti daily standup atau weekly report
* Track time secara konsisten agar data billable akurat untuk invoice
* Gunakan sub-tasks untuk decomposisi pekerjaan yang kompleks menjadi bagian yang manageable
* Set `reminder_config` pada task penting agar tidak ada tenggat yang terlewat
* Integrasi Google Calendar (`google_event_id`) membantu sinkronisasi deadline ke kalender pribadi
* Monitor `costVariance` secara berkala untuk mendeteksi over-budget lebih dini
* Gunakan label berwarna untuk visualisasi cepat prioritas dan kategori task di workspace

***

## Enum Reference

### Ringkasan Semua Enum

| Entity | Field | Nilai yang Valid | Default |
| - | - | - | - |
| Project | `status` | `planning`, `in_progress`, `on_hold`, `completed`, `cancelled` | `planning` |
| Project | `priority` | `low`, `medium`, `high`, `urgent` | `medium` |
| Project.milestones | `status` | `pending`, `completed` | — |
| Task | `status` | `todo`, `in_progress`, `completed`, `done` | `todo` |
| Task | `priority` | `low`, `medium`, `high`, `urgent` | `medium` |
| TimeEntry | `status` | `submitted`, `approved`, `rejected` | `submitted` |
| RecurringTask | `frequency` | `daily`, `weekly`, `monthly`, `yearly` | — |
| RecurringTask | `priority` | `low`, `medium`, `high`, `urgent` | `medium` |
| Comment | `entity_type` | `task`, `note` | — |
| Workspace.settings | `default_task_priority` | `low`, `medium`, `high`, `urgent` | `medium` |
| Document | `category` | `contract`, `invoice`, `report`, `presentation`, `spreadsheet`, `other` | `other` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.