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

# Performance reviews

<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: "Performance Reviews — Penilaian Kinerja"
description: "Penilaian kinerja dengan competency assessment, KPI linking, AI helper, dan rating distribution di SNISHOP ERP."
------------------------------------------------------------------------------------------------------------------------------

# Performance Reviews — Penilaian Kinerja

<img src="https://mintcdn.com/quinnofspicy/e4f_upKhVWcjsUmM/docs/mintlify/screenshots/hr/performance-reviews.png?fit=max&auto=format&n=e4f_upKhVWcjsUmM&q=85&s=80b93c7c97499246e993d4aa4fb23f8d" alt="Performance Reviews" width="1920" height="1080" data-path="docs/mintlify/screenshots/hr/performance-reviews.png" />

Halaman Performance Reviews mengelola penilaian kinerja karyawan secara periodik. Sistem menggabungkan competency assessment (skor 1-5) dan KPI achievement menjadi overall score (0-100) dengan auto-rating. Dilengkapi AI helper untuk membantu reviewer menulis penilaian.

## Arsitektur

```mermaid theme={null}
flowchart TB
    subgraph TABS["3 Tab"]
        REV[Tab: Reviews<br/>Daftar Penilaian]
        HIS[Tab: History<br/>Per Karyawan]
        SUM[Tab: Summary<br/>Distribusi & Dept]
    end

    subgraph FORM["Review Form"]
        COMP[Competency Assessment<br/>Skor 1-5 per kompetensi]
        KPIF[KPI Achievement<br/>Auto-link dari CompanyKPI]
        SCORE[Overall Score<br/>60% competency + 40% KPI]
        RATING[Auto Rating<br/>5 level]
        AI[ReviewAIHelper<br/>Sidebar AI]
    end

    subgraph ENTITIES["Entitas"]
        PR[PerformanceReview]
        CK[CompanyKPI]
        CM[CompanyMember]
    end

    REV --> FORM
    FORM --> COMP
    FORM --> KPIF
    KPIF --> CK
    COMP --> SCORE
    KPIF --> SCORE
    SCORE --> RATING
    FORM --> AI
    FORM --> PR
    HIS --> PR
    SUM --> PR
```

## Akses Halaman

URL: `/performance-reviews`

## Tiga Tab Utama

| Tab | Label | Konten |
| - | - | - |
| `reviews` | Penilaian | Daftar review cards dengan detail lengkap |
| `history` | Riwayat | Historis penilaian per karyawan |
| `summary` | Ringkasan | Distribusi rating + performa departemen |

## Entitas: PerformanceReview

| Field | Tipe | Deskripsi |
| - | - | - |
| `company_id` | string | ID perusahaan |
| `employee_id` | string | ID karyawan |
| `employee_name` | string | Nama karyawan |
| `review_period` | string | Periode review (YYYY-MM) |
| `review_type` | enum | Jenis review |
| `reviewer_id` | string | ID reviewer |
| `reviewer_name` | string | Nama reviewer |
| `review_date` | date | Tanggal review |
| `competencies` | array | Daftar kompetensi dengan skor |
| `kpi_achievement` | array | Pencapaian KPI |
| `overall_score` | number | Skor keseluruhan (0-100) |
| `rating` | enum | Rating akhir |
| `strengths` | array | Daftar kekuatan |
| `areas_for_improvement` | array | Area perbaikan |
| `development_plan` | array | Rencana pengembangan |
| `reviewer_comments` | string | Komentar reviewer |
| `employee_comments` | string | Komentar karyawan |
| `status` | enum | Status review |

## Jenis Review

| Tipe | Label | Frekuensi |
| - | - | - |
| `probation` | Probasi | Saat masa percobaan berakhir |
| `quarterly` | Triwulanan | Setiap 3 bulan |
| `mid_year` | Tengah Tahun | Setiap 6 bulan |
| `annual` | Tahunan | Setiap 12 bulan |

## Perhitungan Overall Score

Overall score dihitung dari kombinasi competency assessment dan KPI achievement:

```
overall_score = (competency_avg / 5 × 60) + (kpi_achievement_avg / 100 × 40)
```

| Komponen | Bobot | Sumber |
| - | - | - |
| **Competency Average** | 60% | Rata-rata skor kompetensi (skala 1-5, dinormalisasi ke 0-100) |
| **KPI Achievement Average** | 40% | Rata-rata persentase pencapaian KPI |

### Auto Rating

| Skor | Rating | Label |
| - | - | - |
| ≥ 90 | `outstanding` | Luar Biasa |
| ≥ 80 | `exceeds_expectations` | Melampaui Ekspektasi |
| ≥ 70 | `meets_expectations` | Sesuai Ekspektasi |
| ≥ 50 | `needs_improvement` | Perlu Perbaikan |
| \< 50 | `unsatisfactory` | Tidak Memuaskan |

## Competency Assessment

Reviewer menilai karyawan pada daftar kompetensi yang bisa dikustomisasi:

| Field per Kompetensi | Tipe | Deskripsi |
| - | - | - |
| `competency_name` | string | Nama kompetensi (misal "Kepemimpinan", "Kerjasama Tim") |
| `score` | number | Skor 1-5 |
| `comments` | string | Komentar per kompetensi |

### Contoh Kompetensi

| Kompetensi | Deskripsi |
| - | - |
| Kepemimpinan | Kemampuan memimpin dan memotivasi tim |
| Kerjasama Tim | Kemampuan bekerja sama dengan rekan |
| Komunikasi | Kejelasan dan efektivitas komunikasi |
| Problem Solving | Kemampuan menyelesaikan masalah |
| Inisiatif | Kemampuan mengambil inisiatif |
| Kualitas Kerja | Konsistensi dan kualitas hasil kerja |
| Disiplin | Ketepatan waktu dan kepatuhan |

## KPI Achievement

KPI achievement di-link otomatis dari entitas `CompanyKPI`:

```javascript theme={null}
linkedKPI = kpis.find(k => 
  k.employee_id === review.employee_id && 
  k.period === review.review_period
)
```

| Field per KPI | Tipe | Deskripsi |
| - | - | - |
| `kpi_name` | string | Nama KPI |
| `target` | number | Target yang ditetapkan |
| `actual` | number | Realisasi aktual |
| `achievement_percentage` | number | `(actual / target) × 100%` |
| `weight` | number | Bobot KPI ini |

### Entitas: CompanyKPI

| Field | Tipe | Deskripsi |
| - | - | - |
| `company_id` | string | ID perusahaan |
| `employee_id` | string | ID karyawan |
| `period` | string | Periode KPI |
| `rating` | enum | `outstanding`, `exceeds_expectations`, `meets_expectations`, `needs_improvement`, `unsatisfactory` |
| `overall_score` | number | Skor keseluruhan |
| `metrics` | array | Daftar metrik `[{name, target, actual, weight}]` |

## Review Form

### Struktur Form

```
┌─────────────────────────────────────────────────────┬──────────────┐
│  REVIEW FORM                                        │  AI HELPER   │
│                                                     │  SIDEBAR     │
│  ┌───────────────────────────────────────────────┐  │              │
│  │ Employee: [dropdown]                          │  │  ┌────────┐  │
│  │ Review Type: [probation/quarterly/...]        │  │  │ Saran  │  │
│  │ Period: [YYYY-MM]                             │  │  │ AI untuk│  │
│  ├───────────────────────────────────────────────┤  │  │ kompetensi│
│  │ COMPETENCY ASSESSMENT                         │  │  └────────┘  │
│  │ [+ Tambah Kompetensi]                         │  │  ┌────────┐  │
│  │ ┌──────────────────────┬──────┬───────────┐   │  │  │ Saran  │  │
│  │ │ Kompetensi           │ Skor │ Komentar  │   │  │  │ strengths│
│  │ ├──────────────────────┼──────┼───────────┤   │  │  └────────┘  │
│  │ │ Kepemimpinan         │  4   │ ...       │   │  │  ┌────────┐  │
│  │ │ Kerjasama Tim        │  5   │ ...       │   │  │  │ Saran  │  │
│  │ │ Komunikasi           │  3   │ ...       │   │  │  │ develop.│  │
│  │ └──────────────────────┴──────┴───────────┘   │  │  └────────┘  │
│  ├───────────────────────────────────────────────┤  │              │
│  │ KPI ACHIEVEMENT (auto-linked)                 │  │              │
│  │ ┌──────────┬────────┬────────┬────────────┐   │  │              │
│  │ │ KPI      │ Target │ Aktual │ Achievement│   │  │              │
│  │ ├──────────┼────────┼────────┼────────────┤   │  │              │
│  │ │ Sales    │ 100    │ 120    │ 120%       │   │  │              │
│  │ └──────────┴────────┴────────┴────────────┘   │  │              │
│  ├───────────────────────────────────────────────┤  │              │
│  │ Overall Score: 78.4                           │  │              │
│  │ Auto Rating: meets_expectations               │  │              │
│  ├───────────────────────────────────────────────┤  │              │
│  │ Strengths: [tag, tag, tag]                    │  │              │
│  │ Areas for Improvement: [tag, tag]             │  │              │
│  │ Development Plan:                             │  │              │
│  │   Goal: [...] Action: [...] Timeline: [...]   │  │              │
│  │ Reviewer Comments: [...]                      │  │              │
│  └───────────────────────────────────────────────┘  │              │
└─────────────────────────────────────────────────────┴──────────────┘
```

## AI Review Helper (ReviewAIHelper)

Sidebar AI membantu reviewer menulis penilaian yang lebih objektif dan konstruktif:

| Fitur AI | Deskripsi |
| - | - |
| **Competency Suggestions** | Saran nama kompetensi dan deskripsi |
| **Strengths Generation** | Generate daftar kekuatan berdasarkan data |
| **Improvement Areas** | Saran area perbaikan yang konstruktif |
| **Reviewer Comments** | Template komentar reviewer |
| **Development Plan** | Saran rencana pengembangan |

AI menggunakan `base44.integrations.Core.InvokeLLM` untuk menghasilkan saran berbasis data kinerja karyawan.

## Tab History: Riwayat Per Karyawan

Menampilkan historis penilaian untuk setiap karyawan dalam format timeline:

| Info per Review | Detail |
| - | - |
| Periode | Bulan/tahun |
| Jenis Review | probation/quarterly/mid\_year/annual |
| Overall Score | Skor 0-100 |
| Rating | Badge warna sesuai level |
| Reviewer | Nama reviewer |
| Kompetensi | Ringkasan skor per kompetensi |

## Tab Summary: Ringkasan

### Distribusi Rating

Chart distribusi rating seluruh karyawan:

```
Outstanding          ██ 2 orang
Exceeds Expectations █████ 5 orang
Meets Expectations   ████████████ 12 orang
Needs Improvement    ███ 3 orang
Unsatisfactory       █ 1 orang
```

### Performa per Departemen

Aggregasi skor rata-rata per departemen:

| Departemen | Avg Score | Rating Dominan |
| - | - | - |
| Produksi | 76.5 | meets\_expectations |
| Penjualan | 82.3 | exceeds\_expectations |
| Keuangan | 79.1 | meets\_expectations |

## Status Review

| Status | Deskripsi |
| - | - |
| `draft` | Sedang dibuat, belum disubmit |
| `submitted` | Sudah disubmit oleh reviewer |
| `finalized` | Sudah difinalisasi oleh HR |
| `acknowledged` | Sudah dibaca dan diakui oleh karyawan |

## Development Plan

Setiap review bisa menyertakan rencana pengembangan:

| Field | Tipe | Deskripsi |
| - | - | - |
| `goal` | string | Tujuan pengembangan |
| `action` | string | Tindakan yang akan dilakukan |
| `timeline` | string | Target waktu |
| `support_needed` | string | Dukungan yang dibutuhkan |

## Integrasi dengan Payroll

Rating dari performance review mempengaruhi bonus KPI di payroll:

```mermaid theme={null}
flowchart LR
    PR[Performance Review] -->|rating| KPI[CompanyKPI]
    KPI -->|bonus percentage| PAY[Payroll]
    PAY -->|kpi_bonus| SLIP[Slip Gaji]
```

| Rating | Bonus % |
| - | - |
| Outstanding | 20% |
| Exceeds Expectations | 15% |
| Meets Expectations | 10% |
| Needs Improvement | 5% |
| Unsatisfactory | 0% |

***

## Entity Schema — Performance Reviews

### Entity Relationship Diagram

```mermaid theme={null}
erDiagram
    Employee ||--o{ PerformanceReview : "dinilai dalam"
    Employee ||--o{ CompanyKPI : "memiliki"
    Employee ||--|| CompanyMember : "terdaftar sebagai"
    CompanyMember ||--o{ PerformanceReview : "melakukan review"
    KPITemplate ||--o{ CompanyKPI : "template acuan"
    CompanyKPI ||--o| PerformanceReview : "referensi pencapaian"

    Employee {
        string company_id PK
        string employee_id UK
        string full_name
        string email
        string phone
        enum department
        string position
        enum employment_type
        date hire_date
        number salary
        enum status
    }

    CompanyMember {
        string company_id PK
        string user_id FK
        string user_email
        string user_name
        enum role
        string employee_id FK
        string department
        string position
        enum status
    }

    PerformanceReview {
        string company_id FK
        string employee_id FK
        string employee_name
        string review_period
        enum review_type
        string reviewer_id FK
        string reviewer_name
        date review_date
        string description
        array competencies
        array kpi_achievement
        number overall_score
        enum rating
        array strengths
        array areas_for_improvement
        array development_plan
        string reviewer_comments
        string employee_comments
        boolean employee_acknowledged
        datetime acknowledged_at
        enum status
    }

    CompanyKPI {
        string company_id FK
        string employee_id FK
        string employee_name
        string employee_email
        string period
        string template_id FK
        string template_name
        string description
        array metrics
        number overall_score
        number attendance_score
        enum rating
        string reviewer_id FK
        string reviewer_name
        string reviewer_notes
        string employee_notes
        enum status
        boolean auto_generated
        datetime finalized_at
        string evidence_url
        string evidence_note
    }

    KPITemplate {
        string company_id PK
        string template_name
        string description
        array applicable_roles
        array applicable_departments
        array default_metrics
        boolean is_active
        boolean auto_calculate
        enum calculation_frequency
    }
```

### Tabel Schema: PerformanceReview

| # | Field | Tipe | Required | Deskripsi |
| - | - | - | - | - |
| 1 | `company_id` | string | **Ya** | ID perusahaan pemilik data |
| 2 | `employee_id` | string | **Ya** | ID karyawan yang dinilai |
| 3 | `employee_name` | string | Tidak | Nama lengkap karyawan |
| 4 | `review_period` | string | **Ya** | Periode review (contoh: `'Q1 2025'`, `'2024-Annual'`) |
| 5 | `review_type` | enum | Tidak | Jenis review: `probation`, `quarterly`, `mid_year`, `annual` (default: `quarterly`) |
| 6 | `reviewer_id` | string | **Ya** | ID reviewer (biasanya supervisor) |
| 7 | `reviewer_name` | string | Tidak | Nama lengkap reviewer |
| 8 | `review_date` | date | Tidak | Tanggal pelaksanaan review |
| 9 | `description` | string | Tidak | Ringkasan umum performa karyawan (maks 1000 karakter) |
| 10 | `competencies` | array | Tidak | Daftar kompetensi: `[{competency_name, description, score (1-5), comments}]` |
| 11 | `kpi_achievement` | array | Tidak | Pencapaian KPI: `[{kpi_name, target, actual, achievement_percentage, weight}]` |
| 12 | `overall_score` | number | Tidak | Skor keseluruhan (0–100), hasil formula 60% kompetensi + 40% KPI |
| 13 | `rating` | enum | Tidak | Rating akhir: `outstanding`, `exceeds_expectations`, `meets_expectations`, `needs_improvement`, `unsatisfactory` |
| 14 | `strengths` | array | Tidak | Daftar kekuatan karyawan (array of string) |
| 15 | `areas_for_improvement` | array | Tidak | Daftar area yang perlu ditingkatkan (array of string) |
| 16 | `development_plan` | array | Tidak | Rencana pengembangan: `[{goal, action, timeline, support_needed}]` |
| 17 | `reviewer_comments` | string | Tidak | Komentar umum dari reviewer |
| 18 | `employee_comments` | string | Tidak | Komentar/tanggapan dari karyawan |
| 19 | `employee_acknowledged` | boolean | Tidak | Status acknowledgment karyawan (default: `false`) |
| 20 | `acknowledged_at` | datetime | Tidak | Timestamp saat karyawan acknowledge review |
| 21 | `status` | enum | Tidak | Status review: `draft`, `submitted`, `acknowledged`, `finalized` (default: `draft`) |

### Tabel Schema: CompanyKPI (21 Field)

| # | Field | Tipe | Required | Deskripsi |
| - | - | - | - | - |
| 1 | `company_id` | string | **Ya** | ID perusahaan pemilik data |
| 2 | `employee_id` | string | **Ya** | ID member (CompanyMember.id) |
| 3 | `employee_name` | string | Tidak | Nama lengkap karyawan |
| 4 | `employee_email` | string | Tidak | Email karyawan |
| 5 | `period` | string | **Ya** | Periode KPI format YYYY-MM (contoh: `'2025-04'`) |
| 6 | `template_id` | string | Tidak | ID template KPI yang digunakan sebagai acuan |
| 7 | `template_name` | string | Tidak | Nama template KPI |
| 8 | `description` | string | Tidak | Penjelasan konteks evaluasi KPI (maks 1000 karakter) |
| 9 | `metrics` | array | **Ya** | Daftar metrik: `[{name, description, target, actual, unit, weight (0-100), score}]` |
| 10 | `overall_score` | number | Tidak | Weighted average score (0–100) |
| 11 | `attendance_score` | number | Tidak | Skor kehadiran (0–100) |
| 12 | `rating` | enum | Tidak | Rating: `outstanding`, `exceeds`, `meets`, `needs_improvement`, `unsatisfactory` |
| 13 | `reviewer_id` | string | Tidak | ID reviewer yang mengevaluasi |
| 14 | `reviewer_name` | string | Tidak | Nama lengkap reviewer |
| 15 | `reviewer_notes` | string | Tidak | Catatan dari reviewer |
| 16 | `employee_notes` | string | Tidak | Catatan dari karyawan |
| 17 | `status` | enum | Tidak | Status KPI: `draft`, `submitted`, `reviewed`, `finalized` (default: `draft`) |
| 18 | `auto_generated` | boolean | Tidak | Apakah KPI di-generate otomatis (default: `false`) |
| 19 | `finalized_at` | datetime | Tidak | Timestamp saat KPI difinalisasi |
| 20 | `evidence_url` | string | Tidak | URL bukti/file pendukung pencapaian KPI |
| 21 | `evidence_note` | string | Tidak | Catatan singkat tentang bukti yang dilampirkan (maks 500 karakter) |

### Tabel Schema: KPITemplate

| # | Field | Tipe | Required | Deskripsi |
| - | - | - | - | - |
| 1 | `company_id` | string | **Ya** | ID perusahaan pemilik template |
| 2 | `template_name` | string | **Ya** | Nama template KPI |
| 3 | `description` | string | Tidak | Penjelasan template, tujuan, dan metrik utama (maks 1000 karakter) |
| 4 | `applicable_roles` | array | Tidak | Role yang menggunakan template (contoh: Sales, Engineer, Manager) |
| 5 | `applicable_departments` | array | Tidak | Departemen yang menggunakan template |
| 6 | `default_metrics` | array | **Ya** | Metrik default: `[{metric_name, description, default_target, unit, weight, calculation_method, auto_source}]` |
| 7 | `is_active` | boolean | Tidak | Status aktif template (default: `true`) |
| 8 | `auto_calculate` | boolean | Tidak | Otomatis hitung KPI setiap hari (default: `true`) |
| 9 | `calculation_frequency` | enum | Tidak | Frekuensi hitung: `daily`, `weekly`, `monthly` (default: `daily`) |

### Sub-Schema: default\_metrics (KPITemplate)

| Field | Tipe | Deskripsi |
| - | - | - |
| `metric_name` | string | Nama metrik |
| `description` | string | Deskripsi metrik |
| `default_target` | number | Target default |
| `unit` | string | Satuan pengukuran |
| `weight` | number | Bobot persentase (0–100) |
| `calculation_method` | enum | Metode hitung: `manual`, `auto_from_attendance`, `auto_from_sales`, `auto_from_projects` |
| `auto_source` | object | Sumber data otomatis: `{entity, field, aggregation (sum/count/average/percentage)}` |

***

## State Machine — Review Lifecycle

```mermaid theme={null}
stateDiagram-v2
    [*] --> draft: Review dibuat\n(Reviewer/HR)

    draft --> submitted: Submit review\n(Reviewer menyelesaikan\npenilaian kompetensi & KPI)

    submitted --> acknowledged: Karyawan acknowledge\n(membaca & menyetujui\nhasil review)

    acknowledged --> finalized: HR finalisasi\n(kalibrasi selesai,\nbonus payroll dikunci)

    submitted --> draft: Revisi\n(Reviewer menarik\nkembali untuk perbaikan)

    finalized --> [*]
    acknowledged --> [*]

    state draft {
        [*] --> InputKompetensi
        InputKompetensi --> InputKPI
        InputKPI --> HitungSkor
        HitungSkor --> [*]
    }

    state acknowledged {
        [*] --> BacaReview
        BacaReview --> TambahKomentar
        TambahKomentar --> Konfirmasi
        Konfirmasi --> [*]
    }
```

### Transisi Status

| Dari | Ke | Trigger | Aktor |
| - | - | - | - |
| — | `draft` | Review baru dibuat | Reviewer / HR |
| `draft` | `submitted` | Reviewer submit setelah mengisi semua kompetensi & KPI | Reviewer |
| `submitted` | `draft` | Reviewer menarik kembali untuk revisi | Reviewer |
| `submitted` | `acknowledged` | Karyawan membaca dan acknowledge review | Employee |
| `acknowledged` | `finalized` | HR menyelesaikan kalibrasi dan mengunci hasil | HR Admin |

***

## Sequence Diagram — Evaluasi KPI

```mermaid theme={null}
sequenceDiagram
    participant E as Employee
    participant R as Reviewer<br/>(Supervisor)
    participant SYS as SNISHOP ERP
    participant KPI as CompanyKPI
    participant AI as ReviewAIHelper

    Note over SYS: Periode review dimulai<br/>(quarterly/mid_year/annual)

    SYS->>KPI: Query KPI karyawan<br/>WHERE employee_id & period
    KPI-->>SYS: Return metrics[]

    SYS->>SYS: Hitung overall_score<br/>= (competency_avg/5 × 60) + (kpi_avg/100 × 40)
    SYS->>SYS: Tentukan auto_rating<br/>berdasarkan skor

    SYS->>R: Tampilkan form review<br/>+ data KPI ter-link
    R->>SYS: Input skor kompetensi (1-5)
    SYS->>AI: Kirim data kompetensi & KPI
    AI-->>R: Saran strengths, improvement,<br/>development plan

    R->>SYS: Simpan review (status: draft)
    SYS-->>E: Notifikasi review tersedia
```

## Sequence Diagram — Review Submission & Acknowledgment

```mermaid theme={null}
sequenceDiagram
    participant R as Reviewer
    participant SYS as SNISHOP ERP
    participant PR as PerformanceReview
    participant E as Employee
    participant HR as HR Admin

    R->>SYS: Submit review
    SYS->>PR: Update status → submitted
    SYS->>PR: Set review_date = NOW()
    SYS-->>E: Notifikasi: review telah disubmit

    E->>SYS: Buka review
    SYS->>PR: Return review detail
    E->>SYS: Tambah employee_comments
    E->>SYS: Acknowledge review
    SYS->>PR: Update status → acknowledged
    SYS->>PR: Set employee_acknowledged = true
    SYS->>PR: Set acknowledged_at = NOW()
    SYS-->>R: Notifikasi: review di-acknowledge

    HR->>SYS: Review calibration batch
    SYS->>PR: Return daftar review submitted/acknowledged
    HR->>SYS: Finalisasi review
    SYS->>PR: Update status → finalized
    SYS-->>E: Notifikasi: review telah difinalisasi
```

## Sequence Diagram — Kalibrasi Rating

```mermaid theme={null}
sequenceDiagram
    participant HR as HR Admin
    participant SYS as SNISHOP ERP
    participant PR as PerformanceReview
    participant PAY as Payroll

    HR->>SYS: Buka tab Summary
    SYS->>PR: Aggregate semua review<br/>per periode
    SYS-->>HR: Distribusi rating &<br/>avg score per departemen

    HR->>SYS: Filter review by department
    SYS-->>HR: Daftar review departemen

    Note over HR: Kalibrasi lintas departemen<br/>pastikan rating distribusinya wajar

    HR->>SYS: Adjust rating (jika perlu)
    SYS->>PR: Update rating & overall_score

    HR->>SYS: Finalisasi batch review
    SYS->>PR: Update status → finalized

    SYS->>PAY: Kirim rating ke payroll<br/>untuk perhitungan bonus KPI
    PAY-->>SYS: Konfirmasi bonus calculated
```

***

## Enum Tables

### Enum: review\_status (PerformanceReview)

| Nilai | Label | Deskripsi |
| - | - | - |
| `draft` | Draft | Sedang dibuat, belum disubmit. Reviewer masih mengisi kompetensi & KPI. |
| `submitted` | Disubmit | Sudah disubmit oleh reviewer, menunggu acknowledgment karyawan. |
| `acknowledged` | Diakui | Karyawan sudah membaca dan acknowledge review. |
| `finalized` | Difinalisasi | HR telah menyelesaikan kalibrasi, hasil dikunci untuk payroll. |

### Enum: kpi\_status (CompanyKPI)

| Nilai | Label | Deskripsi |
| - | - | - |
| `draft` | Draft | KPI sedang disusun, belum disubmit. |
| `submitted` | Disubmit | KPI sudah disubmit untuk review. |
| `reviewed` | Direview | Reviewer sudah mengevaluasi KPI. |
| `finalized` | Difinalisasi | KPI dikunci, tidak dapat diubah. |

### Enum: rating\_scale

| Nilai | Label (ID) | Rentang Skor | Bobot Bonus Payroll |
| - | - | - | - |
| `outstanding` | Luar Biasa | ≥ 90 | 20% |
| `exceeds_expectations` | Melampaui Ekspektasi | ≥ 80 | 15% |
| `meets_expectations` | Sesuai Ekspektasi | ≥ 70 | 10% |
| `needs_improvement` | Perlu Perbaikan | ≥ 50 | 5% |
| `unsatisfactory` | Tidak Memuaskan | \< 50 | 0% |

### Enum: review\_type

| Nilai | Label | Frekuensi | Deskripsi |
| - | - | - | - |
| `probation` | Probasi | Saat masa percobaan berakhir | Evaluasi karyawan baru di akhir masa percobaan |
| `quarterly` | Triwulanan | Setiap 3 bulan | Evaluasi periodik tiap kuartal |
| `mid_year` | Tengah Tahun | Setiap 6 bulan | Evaluasi pertengahan tahun |
| `annual` | Tahunan | Setiap 12 bulan | Evaluasi komprehensif akhir tahun |

### Enum: review\_period

| Format | Contoh | Deskripsi |
| - | - | - |
| `YYYY-MM` | `2025-04` | Periode bulanan |
| `Q[N] YYYY` | `Q1 2025` | Periode kuartalan |
| `YYYY-Annual` | `2024-Annual` | Periode tahunan |

### Enum: calculation\_method (KPITemplate)

| Nilai | Deskripsi |
| - | - |
| `manual` | Input manual oleh reviewer/karyawan |
| `auto_from_attendance` | Otomatis dari data absensi |
| `auto_from_sales` | Otomatis dari data penjualan |
| `auto_from_projects` | Otomatis dari data proyek |

### Enum: calculation\_frequency (KPITemplate)

| Nilai | Deskripsi |
| - | - |
| `daily` | Dihitung otomatis setiap hari |
| `weekly` | Dihitung otomatis setiap minggu |
| `monthly` | Dihitung otomatis setiap bulan |

***

## RBAC — Hak Akses Performance Reviews

| Operasi | Admin | Owner | Supervisor | HR Admin | Employee |
| - | - | - | - | - | - |
| **Create** PerformanceReview | ✅ | ✅ | ✅ (tim sendiri) | ✅ | ❌ |
| **Read** PerformanceReview | ✅ | ✅ | ✅ (tim sendiri) | ✅ | ✅ (milik sendiri) |
| **Update** PerformanceReview | ✅ | ✅ | ✅ (tim sendiri) | ✅ | ❌ |
| **Delete** PerformanceReview | ✅ | ✅ | ✅ (tim sendiri) | ✅ | ❌ |
| **Acknowledge** Review | ❌ | ❌ | ❌ | ❌ | ✅ (milik sendiri) |
| **Finalize** Review | ✅ | ✅ | ❌ | ✅ | ❌ |
| **Create** CompanyKPI | ✅ | ✅ | ✅ (tim sendiri) | ✅ | ✅ (milik sendiri) |
| **Read** CompanyKPI | ✅ | ✅ | ✅ (tim sendiri) | ✅ | ✅ (milik sendiri) |
| **Update** CompanyKPI | ✅ | ✅ | ✅ (tim sendiri) | ✅ | ✅ (milik sendiri) |
| **Delete** CompanyKPI | ✅ | ✅ | ✅ (tim sendiri) | ✅ | ❌ |
| **CRUD** KPITemplate | ✅ | ✅ | ❌ | ✅ | ❌ (read-only) |

### RLS Policy Summary

| Entitas | Kondisi Akses |
| - | - |
| **PerformanceReview** | `company_id` = user's `active_company_id` ATAU `created_by_id` = user.id ATAU role = `admin` |
| **CompanyKPI** | `company_id` = user's `active_company_id` ATAU `created_by_id` = user.id ATAU `employee_email` = user.email ATAU role = `admin` |
| **KPITemplate** | Terbuka (tidak ada RLS restriction) |
| **Employee** | `company_id` = user's `active_company_id` ATAU `created_by_id` = user.id ATAU `user_id` = user.id ATAU role = `admin` |


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