> ## 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.

# Goal tracking

<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: "Goal Tracking — Pencapaian Target"
description: "Tracking target kuantitatif dengan value-based progress, visualisasi gauge, kategori multi-dimensi, dan integrasi cross-module di SNISHOP ERP."
-------------------------------------------------------------------------------------------------------------------------------------------------------------

# Goal Tracking — Pencapaian Target

<img src="https://mintcdn.com/quinnofspicy/e4f_upKhVWcjsUmM/docs/mintlify/screenshots/productivity/goal-tracking.png?fit=max&auto=format&n=e4f_upKhVWcjsUmM&q=85&s=c584ccf6a000191421f288808177d3e8" alt="Goal Tracking" width="1920" height="1080" data-path="docs/mintlify/screenshots/productivity/goal-tracking.png" />

Halaman Goal Tracking memantau progress target-target kuantitatif bisnis kamu — dari revenue, jumlah customer, produksi, hingga target custom lainnya. Dibangun di atas `GoalTracking.jsx` (340 baris) dengan pendekatan **value-based tracking**: setiap goal memiliki `current_value` dan `target_value` yang dihitung menjadi persentase progress secara realtime.

Berbeda dengan Goals (yang menggunakan metodologi OKR kualitatif), halaman ini fokus pada angka konkret dan visualisasi gauge yang langsung menunjukkan seberapa dekat kamu dengan target.

## Arsitektur Komponen

```mermaid theme={null}
graph TD
    A[GoalTracking.jsx<br/>340 lines] --> B[Stats Dashboard<br/>4 KPI Cards]
    A --> C[Goal List<br/>Grid View]
    A --> D[Goal Form<br/>Modal]
    A --> E[Progress Gauge<br/>Circular/Radial]
    
    B --> B1[Total Goals]
    B --> B2[Completed]
    B --> B3[In Progress]
    B --> B4[Avg Progress]
    
    C --> F[Goal Card]
    F --> F1[Progress Bar]
    F --> F2[Category Badge]
    F --> F3[Value Display<br/>current / target]
    F --> F4[Status Indicator]
    
    D --> G[Category Selector<br/>6 kategori]
    D --> H[Value Input<br/>current + target]
    D --> I[Date Range Picker]
    
    A --> J[base44.entities.Goal]
    A --> K[base44.entities.CompanyKPI]
```

## Entity Goal

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `title` | string | Ya | Nama target (contoh: "Revenue Q4 2026") |
| `description` | string | Tidak | Deskripsi detail target |
| `category` | enum | Ya | Kategori target (6 opsi) |
| `current_value` | number | Ya | Nilai saat ini |
| `target_value` | number | Ya | Nilai target yang ingin dicapai |
| `unit` | string | Tidak | Satuan (Rp, unit, %, orang, dll) |
| `start_date` | date | Ya | Tanggal mulai tracking |
| `end_date` | date | Ya | Deadline target |
| `status` | enum | Ya | `active`, `completed`, `paused` |
| `progress` | number | Auto | `(current_value / target_value) × 100` |
| `company_id` | FK → Company | Ya | Scope perusahaan |
| `created_by` | FK → User | Tidak | Pembuat target |
| `created_at` | datetime | Auto | Timestamp pembuatan |
| `updated_at` | datetime | Auto | Timestamp update terakhir |

## Kategori Target

| Kategori | Ikon | Kegunaan | Contoh Target |
| - | - | - | - |
| `revenue` | 💰 | Target pendapatan | "Revenue Rp 500Jt di Q4" |
| `customers` | 👥 | Target jumlah customer | "1000 customer aktif" |
| `production` | 🏭 | Target produksi | "Produksi 50.000 unit/bulan" |
| `sales` | 📈 | Target penjualan | "500 transaksi/hari" |
| `marketing` | 📣 | Target marketing | "10.000 followers Instagram" |
| `custom` | 🎯 | Target custom | "Customer satisfaction > 90%" |

## Status Goal

```mermaid theme={null}
stateDiagram-v2
    [*] --> Active: Goal dibuat
    Active --> Completed: current_value ≥ target_value
    Active --> Paused: Owner pause manual
    Paused --> Active: Owner resume
    Active --> [*]: Goal dihapus
    Completed --> Active: Owner reset untuk target baru
```

| Status | Warna | Deskripsi |
| - | - | - |
| `active` | Hijau | Target sedang dikejar, progress berjalan |
| `completed` | Biru | Target tercapai (current ≥ target) |
| `paused` | Kuning | Target dihentikan sementara |

## Perhitungan Progress

```mermaid theme={null}
flowchart TD
    A[current_value] --> C{target_value > 0?}
    B[target_value] --> C
    C -->|Ya| D["progress = (current / target) × 100"]
    C -->|Tidak| E["progress = 0"]
    D --> F{progress > 100?}
    F -->|Ya| G["Cap di 100% untuk display"]
    F -->|Tidak| H[Tampilkan apa adanya]
    G --> I[Update Goal Card]
    H --> I
    E --> I
```

### Contoh Perhitungan

| Goal | Current | Target | Unit | Progress | Status |
| - | - | - | - | - | - |
| Revenue Q4 | Rp 375.000.000 | Rp 500.000.000 | Rupiah | 75% | 🟢 Active |
| Customer Baru | 850 | 1.000 | orang | 85% | 🟢 Active |
| Produksi Harian | 1.200 | 1.500 | unit | 80% | 🟢 Active |
| Instagram Followers | 12.500 | 10.000 | followers | 100% | 🔵 Completed |
| Satisfaction Score | 78 | 90 | % | 86.7% | 🟢 Active |

## Visualisasi Progress Gauge

```mermaid theme={null}
graph LR
    subgraph "Gauge Components"
        A[Circular Progress<br/>SVG Circle] --> B[Percentage Text<br/>Bold Center]
        A --> C[Color Coding<br/>Dynamic]
    end
    
    subgraph "Color Thresholds"
        D[0-25% → Merah<br/>Baru dimulai]
        E[26-50% → Kuning<br/>Dalam progress]
        F[51-75% → Biru<br/>Mendekati target]
        G[76-100% → Hijau<br/>Hampir/selesai]
    end
    
    C --> D & E & F & G
```

## Stats Dashboard

| Metrik | Perhitungan | Deskripsi |
| - | - | - |
| **Total Goals** | `goals.length` | Jumlah seluruh target aktif |
| **Completed** | `goals.filter(s => s.status === 'completed').length` | Target yang sudah tercapai |
| **In Progress** | `goals.filter(s => s.status === 'active').length` | Target yang sedang dikejar |
| **Avg Progress** | `Σ progress / goals.length` | Rata-rata progress semua target |

## Integrasi dengan CompanyKPI

```mermaid theme={null}
sequenceDiagram
    participant GT as GoalTracking
    participant KPI as CompanyKPI
    participant DB as Base44

    GT->>DB: Fetch goals
    DB-->>GT: Goal list
    GT->>DB: Fetch CompanyKPI
    DB-->>GT: KPI data
    GT->>GT: Match KPI → Goal by category
    GT->>GT: Update current_value from KPI
    Note over GT: Auto-sync jika KPI diupdate
```

Goal Tracking bisa menarik data dari entity `CompanyKPI` untuk mengupdate `current_value` secara otomatis. Misalnya, jika ada KPI "Revenue" yang terupdate dari modul Finance, goal dengan kategori `revenue` bisa otomatis mendapat update `current_value`.

## Flow Penggunaan

```mermaid theme={null}
flowchart LR
    A[Buat Goal Baru] --> B[Tentukan Kategori]
    B --> C[Set Target Value]
    C --> D[Set Current Value<br/>atau sync dari KPI]
    D --> E[Tentukan Periode]
    E --> F[Simpan]
    F --> G[Monitor Progress<br/>Secara Berkala]
    G --> H{Target Tercapai?}
    H -->|Ya| I[Status: Completed]
    H -->|Belum| G
```

## Cara Akses

Dari sidebar, klik menu **Productivity** > **Goal Tracking**.

## Flow Penggunaan Detail

1. Buka halaman Goal Tracking dari sidebar — lihat stats dashboard di atas
2. Klik **"Tambah Target"** untuk membuat goal baru
3. Pilih **kategori** target (revenue, customers, production, sales, marketing, custom)
4. Isi **judul** dan **deskripsi** target
5. Tentukan **target\_value** (angka yang ingin dicapai)
6. Isi **current\_value** (posisi saat ini) — bisa diupdate manual atau sync dari KPI
7. Pilih **satuan** (unit) yang sesuai: Rupiah, unit, persen, orang, dll
8. Set **periode** target (start\_date dan end\_date)
9. Klik **Simpan** — goal masuk daftar dengan status `active`
10. Monitor progress secara berkala, update `current_value` saat ada perubahan

## Tips

* **Pecah target besar menjadi target kecil** — daripada "Revenue 1M/tahun", buat "Revenue 250Jt/quarter" supaya lebih terukur dan memotivasi
* **Update current\_value secara rutin** — minimal seminggu sekali agar progress gauge mencerminkan kondisi aktual
* **Gunakan kategori yang konsisten** — jangan mencampuradukkan kategori supaya filter dan stats tetap akurat
* **Set deadline realistis** — target tanpa deadline cenderung tidak pernah tercapai
* **Manfaatkan integrasi KPI** — untuk target yang datanya sudah ada di CompanyKPI, gunakan auto-sync supaya tidak perlu update manual
* **Review goal yang paused** — jika terlalu banyak goal paused, evaluasi apakah target terlalu ambisius atau ada kendala resources

***

## Entity Schema Reference

### ER Diagram — Goal Tracking Entities

```mermaid theme={null}
erDiagram
    User ||--o{ Goal : "membuat/memiliki"
    User ||--o{ PersonalGoal : "memiliki"
    User ||--o{ CompanyKPI : "dinilai"
    User ||--o{ Task : "mengerjakan"

    Company ||--o{ Goal : "memiliki"
    Company ||--o{ CompanyKPI : "memiliki"
    Company ||--o{ KPITemplate : "menggunakan"
    Company ||--o{ Task : "memiliki"

    Goal }o--o{ Task : "milestone/ditugaskan"
    Goal }o--o| CompanyKPI : "sync current_value"
    Goal }o--o| Goal : "parent_goal (rekursif)"
    PersonalGoal }o--o{ Task : "related_tasks"
    CompanyKPI }o--o| KPITemplate : "template_id"
    Task }o--o| RecurringTask : "recurring_task_id"
    Task }o--o| Task : "parent_task_id (sub-task)"

    Goal {
        string id PK
        string company_id FK "nullable"
        enum goal_type "personal|team|company"
        string title
        string description
        enum category "revenue|productivity|quality|growth|efficiency|custom"
        enum target_type "number|percentage|boolean"
        number target_value
        number current_value "default 0"
        string unit "Rp, unit, %, jam, dll"
        date start_date
        date end_date
        enum status "not_started|in_progress|completed|failed|cancelled"
        number progress_percentage "default 0"
        string owner_id FK "email pemilik"
        string[] assigned_to "array email"
        object[] milestones "sub-target"
        boolean is_recurring "default false"
        enum recurrence_pattern "daily|weekly|monthly|quarterly|yearly"
        boolean notification_enabled "default true"
        enum notification_frequency "daily|weekly|milestone"
    }

    PersonalGoal {
        string id PK
        string user_id FK
        string title
        string description
        enum goal_type "okr|smart_goal|general"
        enum category "career|health|learning|personal|financial|relationship"
        string target_metric
        string current_metric
        number target_value
        number current_value "default 0"
        date deadline
        enum priority "low|medium|high"
        enum status "active|paused|completed|abandoned"
        number progress_percentage "default 0"
        object[] milestones
        string[] related_tasks "task IDs"
        string notes
    }

    CompanyKPI {
        string id PK
        string company_id FK
        string employee_id FK
        string employee_name
        string employee_email
        string period "YYYY-MM"
        string template_id FK
        string template_name
        string description
        object[] metrics "name, target, actual, weight, score"
        number overall_score "0-100"
        number attendance_score "0-100"
        enum rating "outstanding|exceeds|meets|needs_improvement|unsatisfactory"
        string reviewer_id FK
        string reviewer_name
        string reviewer_notes
        string employee_notes
        enum status "draft|submitted|reviewed|finalized"
        boolean auto_generated "default false"
        datetime finalized_at
        string evidence_url
        string evidence_note
    }

    KPITemplate {
        string id PK
        string company_id FK
        string template_name
        string description
        string[] applicable_roles
        string[] applicable_departments
        object[] default_metrics "metric_name, default_target, unit, weight"
        boolean is_active "default true"
        boolean auto_calculate "default true"
        enum calculation_frequency "daily|weekly|monthly"
    }

    Task {
        string id PK
        string workspace_id FK
        string company_id FK "nullable"
        string title
        string content "rich text HTML"
        enum status "todo|in_progress|completed|done"
        enum priority "low|medium|high|urgent"
        datetime due_date
        string assignee_id FK
        string[] tags
        number estimated_time "menit"
        number actual_time "menit"
        boolean is_time_tracked "default false"
        string parent_task_id FK "sub-task"
        string[] sub_tasks "task IDs"
        string recurring_task_id FK
        datetime completed_at
        boolean reminder_sent "default false"
        string google_event_id
        object reminder_config
    }

    RecurringTask {
        string id PK
        string task_id FK "template task"
        string workspace_id FK
        string title
        string content
        enum frequency "daily|weekly|monthly|yearly"
        number interval "default 1"
        number[] days_of_week
        number day_of_month
        datetime start_date
        datetime end_date
        boolean is_active "default true"
        datetime last_generated
        enum priority "low|medium|high|urgent"
        string assignee_id FK
    }
```

### Tabel Schema — Goal

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `id` | string (UUID) | PK | auto-generated | Primary key |
| `company_id` | string (UUID) | — | null | ID perusahaan (null untuk personal goal) |
| `goal_type` | enum | — | `personal` | Tipe goal: `personal`, `team`, `company` |
| `title` | string | ✓ | — | Judul goal |
| `description` | string | — | — | Deskripsi detail goal |
| `category` | enum | — | `custom` | Kategori: `revenue`, `productivity`, `quality`, `growth`, `efficiency`, `custom` |
| `target_type` | enum | — | `number` | Tipe target: `number`, `percentage`, `boolean` |
| `target_value` | number | ✓ | — | Nilai target yang ingin dicapai |
| `current_value` | number | — | 0 | Progress/nilai saat ini |
| `unit` | string | — | — | Satuan (Rp, unit, %, jam, dll) |
| `start_date` | date | ✓ | — | Tanggal mulai tracking |
| `end_date` | date | ✓ | — | Deadline target |
| `status` | enum | — | `not_started` | Status: `not_started`, `in_progress`, `completed`, `failed`, `cancelled` |
| `progress_percentage` | number | — | 0 | Progress dalam persen (0-100) |
| `owner_id` | string | — | — | Email pemilik goal |
| `assigned_to` | string\[] | — | — | Array email yang di-assign ke goal ini |
| `milestones` | object\[] | — | — | Sub-target dengan `title`, `target_value`, `due_date`, `completed`, `completed_at` |
| `is_recurring` | boolean | — | false | Apakah goal berulang |
| `recurrence_pattern` | enum | — | — | Pola pengulangan: `daily`, `weekly`, `monthly`, `quarterly`, `yearly` |
| `notification_enabled` | boolean | — | true | Notifikasi progress diaktifkan |
| `notification_frequency` | enum | — | `weekly` | Frekuensi notifikasi: `daily`, `weekly`, `milestone` |

### Tabel Schema — PersonalGoal

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `id` | string (UUID) | PK | auto-generated | Primary key |
| `user_id` | string (UUID) | ✓ | — | ID pengguna pemilik tujuan |
| `title` | string | ✓ | — | Judul tujuan personal |
| `description` | string | — | — | Deskripsi detail tujuan |
| `goal_type` | enum | — | `smart_goal` | Metodologi: `okr`, `smart_goal`, `general` |
| `category` | enum | — | — | Kategori: `career`, `health`, `learning`, `personal`, `financial`, `relationship` |
| `target_metric` | string | ✓ | — | Metrik target (misal: "menyelesaikan buku", "menambah skill coding") |
| `current_metric` | string | — | — | Metrik saat ini |
| `target_value` | number | — | — | Nilai target numerik (opsional) |
| `current_value` | number | — | 0 | Nilai saat ini |
| `deadline` | date | ✓ | — | Tanggal deadline |
| `priority` | enum | — | `medium` | Prioritas: `low`, `medium`, `high` |
| `status` | enum | — | `active` | Status: `active`, `paused`, `completed`, `abandoned` |
| `progress_percentage` | number | — | 0 | Progress dalam persen |
| `milestones` | object\[] | — | — | Milestone dengan `milestone_title`, `target_date`, `completed`, `completed_date` |
| `related_tasks` | string\[] | — | — | Task IDs yang terkait dengan goal ini |
| `notes` | string | — | — | Catatan tambahan |

### Tabel Schema — CompanyKPI

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `id` | string (UUID) | PK | auto-generated | Primary key |
| `company_id` | string (UUID) | ✓ | — | ID perusahaan |
| `employee_id` | string (UUID) | ✓ | — | ID member (CompanyMember.id) |
| `employee_name` | string | — | — | Nama karyawan |
| `employee_email` | string | — | — | Email karyawan |
| `period` | string | ✓ | — | Periode YYYY-MM (contoh: "2025-04") |
| `template_id` | string (UUID) | — | — | ID template KPI yang digunakan |
| `template_name` | string | — | — | Nama template KPI |
| `description` | string | — | — | Penjelasan konteks evaluasi KPI (maks 1000 karakter) |
| `metrics` | object\[] | ✓ | — | Array metrik: `name`, `description`, `target`, `actual`, `unit`, `weight`, `score` |
| `overall_score` | number | — | — | Skor rata-rata tertimbang (0-100) |
| `attendance_score` | number | — | — | Skor kehadiran (0-100) |
| `rating` | enum | — | — | Rating: `outstanding`, `exceeds`, `meets`, `needs_improvement`, `unsatisfactory` |
| `reviewer_id` | string (UUID) | — | — | ID reviewer/penilai |
| `reviewer_name` | string | — | — | Nama reviewer |
| `reviewer_notes` | string | — | — | Catatan reviewer |
| `employee_notes` | string | — | — | Catatan karyawan |
| `status` | enum | — | `draft` | Status: `draft`, `submitted`, `reviewed`, `finalized` |
| `auto_generated` | boolean | — | false | Apakah di-generate otomatis dari template |
| `finalized_at` | datetime | — | — | Timestamp saat difinalisasi |
| `evidence_url` | string | — | — | URL bukti/file pendukung pencapaian KPI |
| `evidence_note` | string | — | — | Catatan tentang bukti yang dilampirkan (maks 500 karakter) |

### Tabel Schema — KPITemplate

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `id` | string (UUID) | PK | auto-generated | Primary key |
| `company_id` | string (UUID) | ✓ | — | ID perusahaan |
| `template_name` | string | ✓ | — | Nama template KPI |
| `description` | string | — | — | Penjelasan template KPI (maks 1000 karakter) |
| `applicable_roles` | string\[] | — | — | Role yang menggunakan template (Sales, Engineer, Manager, dll) |
| `applicable_departments` | string\[] | — | — | Departemen yang menggunakan template |
| `default_metrics` | object\[] | ✓ | — | Metrik default: `metric_name`, `description`, `default_target`, `unit`, `weight`, `calculation_method`, `auto_source` |
| `is_active` | boolean | — | true | Status aktif template |
| `auto_calculate` | boolean | — | true | Otomatis calculate KPI setiap periode |
| `calculation_frequency` | enum | — | `daily` | Frekuensi kalkulasi: `daily`, `weekly`, `monthly` |

### Tabel Schema — Task

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `id` | string (UUID) | PK | auto-generated | Primary key |
| `workspace_id` | string (UUID) | ✓ | — | ID workspace scope task |
| `company_id` | string (UUID) | — | null | ID perusahaan (null untuk personal) |
| `title` | string | ✓ | — | Judul task |
| `content` | string | — | — | Deskripsi detail (rich text HTML) |
| `status` | enum | — | `todo` | Status: `todo`, `in_progress`, `completed`, `done` |
| `priority` | enum | — | `medium` | Prioritas: `low`, `medium`, `high`, `urgent` |
| `due_date` | datetime | — | — | Deadline task |
| `assignee_id` | string (UUID) | — | — | ID user yang ditugaskan |
| `tags` | string\[] | — | — | Label untuk kategorisasi |
| `estimated_time` | number | — | — | Estimasi waktu pengerjaan (menit) |
| `actual_time` | number | — | — | Waktu aktual yang dihabiskan (menit) |
| `is_time_tracked` | boolean | — | false | Apakah waktu di-track |
| `time_entries` | object\[] | — | — | Array time entry: `start`, `end`, `duration` |
| `parent_task_id` | string (UUID) | — | — | ID parent task (untuk sub-tasks) |
| `sub_tasks` | string\[] | — | — | Array of sub-task IDs |
| `recurring_task_id` | string (UUID) | — | — | ID recurring task jika dibuat otomatis |
| `completed_at` | datetime | — | — | Timestamp saat task selesai |
| `reminder_sent` | boolean | — | false | Apakah pengingat sudah dikirim |
| `google_event_id` | string | — | — | ID event pada Google Calendar |
| `reminder_config` | object | — | — | Konfigurasi notifikasi sebelum tugas |

### Tabel Schema — RecurringTask

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `id` | string (UUID) | PK | auto-generated | Primary key |
| `task_id` | string (UUID) | — | — | ID tugas template |
| `workspace_id` | string (UUID) | ✓ | — | ID workspace |
| `title` | string | ✓ | — | Judul recurring task |
| `content` | string | — | — | Deskripsi detail |
| `frequency` | enum | ✓ | — | Frekuensi: `daily`, `weekly`, `monthly`, `yearly` |
| `interval` | number | — | 1 | Interval pengulangan (1 = setiap, 2 = setiap 2x, dst) |
| `days_of_week` | number\[] | — | — | Hari dalam seminggu (0-6) untuk frekuensi weekly |
| `day_of_month` | number | — | — | Tanggal dalam sebulan untuk frekuensi monthly |
| `start_date` | datetime | ✓ | — | Tanggal mulai recurring |
| `end_date` | datetime | — | — | Tanggal berakhir (null = tanpa batas) |
| `is_active` | boolean | — | true | Status aktif recurring task |
| `last_generated` | datetime | — | — | Timestamp terakhir task di-generate |
| `priority` | enum | — | `medium` | Prioritas: `low`, `medium`, `high`, `urgent` |
| `assignee_id` | string (UUID) | — | — | ID user yang ditugaskan |

***

## State Machine — Goal Lifecycle

```mermaid theme={null}
stateDiagram-v2
    [*] --> not_started : Goal dibuat

    not_started --> in_progress : User mulai mengerjakan
    not_started --> cancelled : User batalkan goal

    in_progress --> in_progress : Update current_value
    in_progress --> in_progress : Progress tracking
    in_progress --> completed : current_value >= target_value
    in_progress --> failed : deadline terlewat & progress < target
    in_progress --> cancelled : User batalkan goal

    completed --> in_progress : User reset untuk target baru
    completed --> [*] : Goal diarsipkan

    failed --> in_progress : User extend deadline & lanjutkan
    failed --> [*] : Goal dihapus

    cancelled --> [*] : Goal dihapus

    state in_progress {
        [*] --> tracking
        tracking --> milestone_25 : 25% tercapai
        milestone_25 --> milestone_50 : 50% tercapai
        milestone_50 --> milestone_75 : 75% tercapai
        milestone_75 --> milestone_100 : 100% tercapai
        milestone_100 --> [*]
    }

    note right of in_progress
        Progress = (current_value / target_value) x 100%
        Notifikasi otomatis pada setiap milestone
    end note

    note right of completed
        Trigger: current_value >= target_value
        Status otomatis berubah menjadi completed
    end note

    note right of failed
        Trigger: end_date < today AND status = in_progress
        Cron job memeriksa setiap hari
    end note
```

### Transisi Status Goal

| Dari | Ke | Trigger | Deskripsi |
| - | - | - | - |
| `[*]` | `not_started` | Create goal | Goal baru dibuat, belum dimulai |
| `not_started` | `in_progress` | User mulai | User mulai mengerjakan goal |
| `not_started` | `cancelled` | User batal | User membatalkan goal sebelum dimulai |
| `in_progress` | `completed` | `current_value >= target_value` | Target tercapai secara otomatis |
| `in_progress` | `failed` | `end_date < today` | Deadline terlewat tanpa target tercapai |
| `in_progress` | `cancelled` | User batal | User membatalkan goal yang sedang berjalan |
| `failed` | `in_progress` | User extend deadline | User mengaktifkan ulang dengan deadline baru |
| `completed` | `in_progress` | User reset | User reset goal untuk target baru |

***

## Sequence Diagrams

### 1. Goal Creation Flow

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant FE as Frontend (GoalTracking.jsx)
    participant API as Backend API
    participant DB as Database (Base44)
    participant NOTIF as Notification Service

    U->>FE: Klik "Tambah Target"
    FE->>FE: Tampilkan Goal Form modal
    U->>FE: Isi form (title, category, target_value, current_value, unit, start_date, end_date)
    U->>FE: Klik "Simpan"

    FE->>API: POST /api/goals
    Note over FE,API: Payload: {title, category, target_value, current_value, unit, start_date, end_date, description}

    API->>API: Validasi required fields (title, target_value, start_date, end_date)
    API->>API: Validasi category ∈ {revenue, productivity, quality, growth, efficiency, custom}
    API->>API: Validasi target_value > 0
    API->>API: Validasi end_date > start_date

    API->>DB: INSERT INTO goals (status = not_started)
    DB-->>API: Return created record

    API->>NOTIF: Trigger: Goal baru dibuat
    NOTIF-->>U: "Target '{title}' berhasil dibuat"

    API-->>FE: 201 Created
    FE->>FE: Tambahkan goal ke daftar
    FE->>FE: Render progress gauge (0%)
    FE->>FE: Update stats dashboard
```

### 2. Progress Tracking Flow

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant FE as Frontend (GoalTracking.jsx)
    participant API as Backend API
    participant DB as Database (Base44)
    participant CALC as Progress Engine
    participant KPI as CompanyKPI Service
    participant NOTIF as Notification Service

    U->>FE: Update current_value pada Goal Card
    FE->>API: PATCH /api/goals/{id}
    Note over FE,API: Payload: {current_value: new_value}

    API->>DB: SELECT goal WHERE id = {id}
    DB-->>API: Return goal data

    API->>CALC: Calculate progress
    CALC->>CALC: progress = (current_value / target_value) x 100%
    CALC->>CALC: Cap progress di 100% untuk display

    alt progress >= 100%
        CALC->>API: Set status = "completed"
        API->>DB: UPDATE status = "completed"
        API->>NOTIF: Trigger: Goal tercapai!
        NOTIF-->>U: "Selamat! Target '{title}' telah tercapai 100%"
    else milestone tercapai (25%, 50%, 75%)
        CALC->>NOTIF: Trigger milestone alert
        NOTIF-->>U: "Target '{title}' sudah {milestone}% tercapai"
    end

    API->>DB: UPDATE current_value, progress_percentage
    DB-->>API: Return updated record

    API-->>FE: 200 OK
    FE->>FE: Update progress gauge (animasi)
    FE->>FE: Update value display (current / target)
    FE->>FE: Update stats dashboard
```

### 3. KPI Auto-Sync Flow

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant FE as Frontend (GoalTracking.jsx)
    participant API as Backend API
    participant DB as Database (Base44)
    participant KPI as CompanyKPI Service
    participant GT as Goal Tracking Engine

    Note over U,GT: Skenario: Auto-sync current_value dari CompanyKPI

    KPI->>DB: UPDATE CompanyKPI (actual value berubah dari modul lain)
    Note over KPI: Misal: modul Finance update revenue actual

    KPI->>API: Trigger: KPI value updated
    API->>GT: Check related goals

    GT->>DB: SELECT goals WHERE category MATCHES KPI metric
    DB-->>GT: Return matching goals

    loop Setiap goal yang terkait
        GT->>GT: Match KPI metric → goal category
        GT->>GT: Map unit KPI → goal unit
        GT->>DB: UPDATE goal SET current_value = KPI.actual
        GT->>GT: Recalculate progress_percentage
    end

    GT->>API: Return updated goals
    API-->>FE: Push update (realtime)
    FE->>FE: Re-render progress gauges

    Note over U,GT: Alternatif: Manual sync oleh user

    U->>FE: Klik "Sync dari KPI"
    FE->>API: POST /api/goals/{id}/sync-kpi
    API->>DB: Fetch CompanyKPI metrics
    DB-->>API: Return KPI data
    API->>API: Match KPI → Goal by category
    API->>DB: UPDATE goal SET current_value = KPI.actual
    API-->>FE: 200 OK (updated goal)
    FE->>FE: Update progress gauge
```

### 4. Milestone Tracking Flow

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant FE as Frontend
    participant API as Backend API
    participant DB as Database
    participant MS as Milestone Engine
    participant NOTIF as Notification Service

    Note over U,NOTIF: Skenario: Goal dengan milestones (sub-target)

    U->>FE: Buat goal dengan milestones
    FE->>API: POST /api/goals
    Note over FE,API: Payload: {title, milestones: [{title, target_value, due_date}, ...]}
    API->>DB: INSERT goal + milestones
    DB-->>API: Return created record

    loop Progress update berkala
        U->>FE: Update current_value
        FE->>API: PATCH /api/goals/{id}
        API->>MS: Check milestones

        loop Setiap milestone
            MS->>MS: Check current_value >= milestone.target_value
            alt Milestone tercapai
                MS->>DB: UPDATE milestone SET completed = true, completed_at = now()
                MS->>NOTIF: Trigger: Milestone tercapai!
                NOTIF-->>U: "Milestone '{milestone.title}' tercapai!"
            end
        end

        API-->>FE: 200 OK
        FE->>FE: Update milestone checklist
    end
```

***

## Enum Tables

### goal\_type (Goal)

| Value | Label (ID) | Deskripsi | Contoh Use Case |
| - | - | - | - |
| `personal` | Personal | Target individu | "Selesaikan sertifikasi AWS" |
| `team` | Tim | Target bersama satu tim | "Tim sales tutup 50 deal/bulan" |
| `company` | Perusahaan | Target level perusahaan | "Revenue perusahaan Rp 10M/tahun" |

### category (Goal)

| Value | Label (ID) | Ikon | Deskripsi | Contoh Target |
| - | - | - | - | - |
| `revenue` | Pendapatan | 💰 | Target pendapatan/omzet | "Revenue Rp 500Jt di Q4" |
| `productivity` | Produktivitas | ⚡ | Target efisiensi kerja | "Produksi 50.000 unit/bulan" |
| `quality` | Kualitas | 🏆 | Target mutu produk/layanan | "Defect rate \< 1%" |
| `growth` | Pertumbuhan | 📈 | Target ekspansi bisnis | "1000 customer aktif" |
| `efficiency` | Efisiensi | 🔧 | Target penghematan resources | "Kurangi biaya operasional 20%" |
| `custom` | Custom | 🎯 | Target custom sesuai kebutuhan | "Customer satisfaction > 90%" |

### target\_type (Goal)

| Value | Label (ID) | Deskripsi | Contoh |
| - | - | - | - |
| `number` | Angka | Target berupa nilai numerik absolut | "Revenue Rp 500.000.000" |
| `percentage` | Persentase | Target berupa persentase | "Customer satisfaction > 90%" |
| `boolean` | Boolean | Target ya/tidak (tercapai atau tidak) | "Luncurkan fitur baru sebelum Q4" |

### goal\_status (Goal)

| Value | Label (ID) | Warna | Deskripsi | Kondisi |
| - | - | - | - | - |
| `not_started` | Belum Dimulai | Abu-abu | Goal sudah dibuat tapi belum dikerjakan | Default saat goal pertama kali dibuat |
| `in_progress` | Sedang Berjalan | Hijau | Goal sedang dikejar, progress berjalan | User mulai mengerjakan atau progress > 0% |
| `completed` | Tercapai | Biru | Goal berhasil dicapai | `current_value >= target_value` |
| `failed` | Gagal | Merah | Goal gagal dicapai dalam deadline | `end_date < today` dan progress \< target |
| `cancelled` | Dibatalkan | Abu-abu gelap | Goal dibatalkan oleh user | User memilih membatalkan goal |

### recurrence\_pattern (Goal)

| Value | Label (ID) | Deskripsi | Contoh |
| - | - | - | - |
| `daily` | Harian | Berulang setiap hari | "Update laporan harian" |
| `weekly` | Mingguan | Berulang setiap minggu | "Review progress mingguan" |
| `monthly` | Bulanan | Berulang setiap bulan | "Target penjualan bulanan" |
| `quarterly` | Kuartalan | Berulang setiap kuartal (3 bulan) | "Revenue target per kuartal" |
| `yearly` | Tahunan | Berulang setiap tahun | "Target pendapatan tahunan" |

### notification\_frequency (Goal)

| Value | Label (ID) | Deskripsi | Kapan Notifikasi Dikirim |
| - | - | - | - |
| `daily` | Harian | Notifikasi setiap hari | Setiap pagi, ringkasan progress |
| `weekly` | Mingguan | Notifikasi setiap minggu | Setiap awal minggu, ringkasan progress |
| `milestone` | Per Milestone | Notifikasi saat milestone tercapai | Saat 25%, 50%, 75%, 100% tercapai |

### personal\_goal\_type (PersonalGoal)

| Value | Label (ID) | Deskripsi | Contoh |
| - | - | - | - |
| `okr` | OKR | Objectives and Key Results | "O: Tingkatkan skill. KR: Selesaikan 3 kursus" |
| `smart_goal` | SMART Goal | Specific, Measurable, Achievable, Relevant, Time-bound | "Baca 12 buku dalam 1 tahun" |
| `general` | Umum | Target umum tanpa metodologi khusus | "Jadi lebih sehat" |

### personal\_goal\_category (PersonalGoal)

| Value | Label (ID) | Deskripsi | Contoh |
| - | - | - | - |
| `career` | Karir | Target pengembangan karir | "Promosi ke senior developer" |
| `health` | Kesehatan | Target kesehatan dan kebugaran | "Turun 5 kg dalam 3 bulan" |
| `learning` | Pembelajaran | Target belajar skill baru | "Selesaikan kursus machine learning" |
| `personal` | Personal | Target pengembangan diri | "Baca 24 buku tahun ini" |
| `financial` | Keuangan | Target keuangan pribadi | "Tabung Rp 50 juta tahun ini" |
| `relationship` | Relasi | Target hubungan dan networking | "Hadiri 2 event networking/bulan" |

### personal\_goal\_status (PersonalGoal)

| Value | Label (ID) | Warna | Deskripsi |
| - | - | - | - |
| `active` | Aktif | Hijau | Tujuan sedang dijalankan |
| `paused` | Dijeda | Kuning | Tujuan sementara dihentikan |
| `completed` | Selesai | Biru | Tujuan berhasil dicapai |
| `abandoned` | Ditinggalkan | Abu-abu | Tujuan ditinggalkan tanpa dicapai |

### priority (PersonalGoal & Task)

| Value | Label (ID) | Warna Badge | Deskripsi | SLA Review |
| - | - | - | - | - |
| `high` | Tinggi | Merah | Prioritas tinggi, harus segera ditangani | Harian |
| `medium` | Sedang | Kuning | Prioritas normal, timeline standar | Mingguan |
| `low` | Rendah | Hijau | Prioritas rendah, bisa ditunda | Bulanan |

### task\_priority (Task)

| Value | Label (ID) | Warna Badge | Deskripsi | SLA |
| - | - | - | - | - |
| `urgent` | Mendesak | Merah gelap | Harus diselesaikan segera | Hari ini |
| `high` | Tinggi | Merah | Prioritas tinggi | 1-2 hari |
| `medium` | Sedang | Kuning | Prioritas normal | 3-7 hari |
| `low` | Rendah | Hijau | Bisa dikerjakan nanti | > 7 hari |

### task\_status (Task)

| Value | Label (ID) | Deskripsi |
| - | - | - |
| `todo` | Belum Dikerjakan | Task baru dibuat, belum mulai |
| `in_progress` | Sedang Dikerjakan | Task sedang aktif dikerjakan |
| `completed` | Selesai | Task sudah selesai |
| `done` | Selesai (Final) | Task selesai dan dikonfirmasi |

### kpi\_status (CompanyKPI)

| Value | Label (ID) | Deskripsi |
| - | - | - |
| `draft` | Draft | KPI masih dalam tahap penyusunan |
| `submitted` | Diajukan | KPI sudah diajukan oleh karyawan untuk direview |
| `reviewed` | Direview | KPI sudah direview oleh reviewer/manager |
| `finalized` | Difiksalkan | KPI sudah difinalisasi dan menjadi penilaian resmi |

### kpi\_rating (CompanyKPI)

| Value | Label (ID) | Rentang Skor | Deskripsi |
| - | - | - | - |
| `outstanding` | Luar Biasa | 90-100 | Melampaui semua ekspektasi secara signifikan |
| `exceeds` | Melebihi | 75-89 | Melebihi target yang ditetapkan |
| `meets` | Sesuai | 60-74 | Memenuhi target sesuai ekspektasi |
| `needs_improvement` | Perlu Peningkatan | 40-59 | Di bawah target, perlu peningkatan |
| `unsatisfactory` | Tidak Memuaskan | 0-39 | Jauh di bawah target, evaluasi diperlukan |

### calculation\_method (KPITemplate)

| Value | Label (ID) | Deskripsi | Sumber Data |
| - | - | - | - |
| `manual` | Manual | Input manual oleh user/karyawan | User input |
| `auto_from_attendance` | Otomatis dari Kehadiran | Dihitung dari data absensi | Entity Attendance |
| `auto_from_sales` | Otomatis dari Penjualan | Dihitung dari data penjualan | Entity POS/Orders |
| `auto_from_projects` | Otomatis dari Proyek | Dihitung dari progress proyek | Entity Project |

### calculation\_frequency (KPITemplate)

| Value | Label (ID) | Deskripsi |
| - | - | - |
| `daily` | Harian | KPI dihitung ulang setiap hari |
| `weekly` | Mingguan | KPI dihitung ulang setiap minggu |
| `monthly` | Bulanan | KPI dihitung ulang setiap bulan |

### frequency (RecurringTask)

| Value | Label (ID) | Deskripsi | Contoh |
| - | - | - | - |
| `daily` | Harian | Task dibuat ulang setiap hari | "Daily standup reminder" |
| `weekly` | Mingguan | Task dibuat ulang setiap minggu | "Weekly report" |
| `monthly` | Bulanan | Task dibuat ulang setiap bulan | "Monthly inventory check" |
| `yearly` | Tahunan | Task dibuat ulang setiap tahun | "Annual license renewal" |

***

## RBAC — Hak Akses Goal Tracking

| Role | Create | Read | Update | Delete | Deskripsi |
| - | - | - | - | - | - |
| **Admin** | ✓ | ✓ | ✓ | ✓ | Akses penuh ke semua goal dalam perusahaan |
| **Manager** | ✓ | ✓ | ✓ | ✗ | Dapat membuat dan mengelola goal tim, tidak bisa hapus |
| **Staff** | ✓ | ✓ | ✓ (own) | ✗ | Dapat membuat goal sendiri, update goal sendiri |
| **Viewer** | ✗ | ✓ | ✗ | ✗ | Hanya bisa melihat goal (read-only) |

### Row-Level Security (RLS)

| Operasi | Kondisi Akses | Deskripsi |
| - | - | - |
| **Create** | `company_id = user.active_company_id` AND `company_id IS NOT NULL` | User harus berada dalam perusahaan yang aktif |
| **Read** | `company_id = user.active_company_id` OR `owner_id = current_user` OR `role = admin` | User bisa baca goal perusahaan atau goal pribadi |
| **Update** | `company_id = user.active_company_id` OR `owner_id = current_user` OR `role = admin` | Owner goal atau admin perusahaan |
| **Delete** | `company_id = user.active_company_id` OR `owner_id = current_user` OR `role = admin` | Owner goal atau admin perusahaan |

### Data Isolation

```mermaid theme={null}
graph LR
    subgraph TENANT["Multi-Tenant Isolation"]
        C1["Company A"] --> G1["Goals A"]
        C1 --> KPI1["CompanyKPI A"]
        C1 --> T1["Tasks A"]
        C1 --> TPL1["KPI Templates A"]

        C2["Company B"] --> G2["Goals B"]
        C2 --> KPI2["CompanyKPI B"]
        C2 --> T2["Tasks B"]
        C2 --> TPL2["KPI Templates B"]
    end

    U1["User 1 (Company A)"] --> C1
    U2["User 2 (Company B)"] --> C2
    U3["Admin"] --> C1
    U3 --> C2

    style TENANT fill:#f0f9ff,stroke:#3b82f6
    style C1 fill:#dcfce7,stroke:#22c55e
    style C2 fill:#fef3c7,stroke:#f59e0b
```

### Hak Akses per Entity

| Entity | Admin | Manager | Staff | Viewer |
| - | - | - | - | - |
| **Goal** | Full CRUD | Create + Read + Update (all) | Create + Read + Update (own) | Read only |
| **PersonalGoal** | Full CRUD | Full CRUD (own) | Full CRUD (own) | Read (own) |
| **CompanyKPI** | Full CRUD | Create + Read + Update | Read (own) + Update (own) | Read (own) |
| **KPITemplate** | Full CRUD | Create + Read + Update | Read only | Read only |
| **Task** | Full CRUD | Create + Read + Update (all) | Create + Read + Update (own/assigned) | Read only |
| **RecurringTask** | Full CRUD | Create + Read + Update | Read only | Read only |


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