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

# Documents

<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: "Documents — Manajemen Dokumen"
description: "Manajemen dokumen terpusat dengan Cloudinary upload, image compression, 6 kategori, search, sharing, versioning, approval workflow, dan access control di SNISHOP ERP."
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

# Documents — Manajemen Dokumen

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

Halaman Documents adalah pusat penyimpanan dan manajemen seluruh dokumen bisnis kamu. Dibangun di atas `Documents.jsx` (377 baris) dengan integrasi **Cloudinary** untuk upload file dan **image compression** untuk optimasi ukuran file sebelum upload.

Sistem ini mendukung 6 kategori dokumen, pencarian full-text, filter berdasarkan kategori, organising dokumen ke dalam folder, versioning dokumen, sharing dokumen ke user tertentu, penguncian dokumen, tanggal kedaluwarsa, dan access control melalui `ERPAccessGuard`.

## Fitur Utama

* **Upload & Compression** — Upload file ke Cloudinary dengan kompresi otomatis untuk gambar
* **6 Kategori Dokumen** — Klasifikasi dokumen ke dalam kategori yang terstruktur
* **Folder Organisation** — Kelompokkan dokumen ke dalam folder virtual
* **Versioning** — Lacak versi dokumen secara otomatis
* **Sharing & Collaboration** — Bagikan dokumen ke user tertentu berdasarkan email
* **Document Locking** — Kunci dokumen untuk mencegah perubahan tidak sah
* **Expiry Tracking** — Tandai dokumen dengan tanggal kedaluwarsa
* **Tagging System** — Tambahkan tag untuk klasifikasi tambahan
* **Search & Filter** — Cari dokumen berdasarkan nama, deskripsi, kategori, dan tag
* **Access Control** — Permission berbasis role melalui ERPAccessGuard

## Arsitektur Komponen

```mermaid theme={null}
graph TD
    A[Documents.jsx<br/>377 lines] --> B[ERPAccessGuard<br/>module=documents]
    A --> C[Upload Pipeline]
    A --> D[Document List<br/>Grid/Table View]
    A --> E[Category Filter<br/>6 kategori]
    A --> F[Search Bar]
    A --> G[Document Preview<br/>Modal]
    A --> K[Folder Navigation]
    A --> L[Share Dialog]
    A --> M[Version History]
    
    C --> C1[File Selection<br/>Input file]
    C --> C2[Image Compression<br/>Canvas API]
    C --> C3[Cloudinary Upload<br/>preset: snishop_erp]
    C --> C4[Metadata Save<br/>base44 entity]
    
    D --> H[Document Card]
    H --> H1[Thumbnail Preview]
    H --> H2[File Name / Title]
    H --> H3[Category Badge]
    H --> H4[File Size]
    H --> H5[Upload Date]
    H --> H6[Download/Delete Actions]
    H --> H7[Version Indicator]
    H --> H8[Lock Status Icon]
    H --> H9[Tag Badges]
    
    A --> I[base44.entities.Document]
    A --> J[Cloudinary API]
    A --> N[base44.entities.ApprovalRequest]
    A --> O[base44.entities.WorkflowAutomation]
```

## Entity Relationship Diagram

```mermaid theme={null}
erDiagram
    Document {
        string company_id "ID perusahaan (null untuk personal)"
        string title "Judul dokumen"
        string description "Deskripsi dokumen"
        string category "contract|invoice|report|presentation|spreadsheet|other"
        string file_url "URL file dokumen"
        string file_type "pdf, docx, xlsx, etc"
        number file_size "Ukuran file dalam bytes"
        array tags "Daftar tag dokumen"
        array shared_with "Email user yang bisa akses"
        string folder "Nama folder"
        number version "Nomor versi dokumen"
        boolean is_locked "Status penguncian dokumen"
        date expiry_date "Tanggal kedaluwarsa"
    }

    User {
        string email "Email pengguna"
        string full_name "Nama lengkap"
        string role "admin|user"
        string subscription_plan "free|pro|business|advanced|enterprise"
        string active_company_id "ID perusahaan aktif"
    }

    Workspace {
        string company_id "ID perusahaan"
        string name "Nama workspace"
        string description "Deskripsi workspace"
        string owner_id "ID pemilik workspace"
        boolean is_personal "Apakah workspace pribadi"
    }

    WorkspaceMember {
        string workspace_id "ID workspace"
        string user_id "ID pengguna"
        string role "owner|admin|member|viewer"
        string invited_by "Email pengundang"
        datetime joined_at "Waktu bergabung"
    }

    ApprovalWorkflow {
        string company_id "ID perusahaan"
        string workflow_name "Nama alur persetujuan"
        string description "Penjelasan workflow"
        string document_type "expense_request|leave_request|purchase_order|discount_request|budget_adjustment"
        array approval_levels "Daftar level persetujuan"
        boolean is_active "Status aktif workflow"
    }

    ApprovalRequest {
        string company_id "ID perusahaan"
        string workflow_id "ID ApprovalWorkflow"
        string document_type "Tipe dokumen"
        string document_id "ID dokumen yang diminta persetujuan"
        string requester_id "User yang mengajukan"
        date submission_date "Tanggal pengajuan"
        number current_approval_level "Level persetujuan saat ini"
        array approval_history "Riwayat persetujuan"
        string overall_status "pending|approved|rejected|on_hold"
        date final_approval_date "Tanggal persetujuan final"
    }

    Comment {
        string entity_type "task|note"
        string entity_id "ID entitas yang dikomentari"
        string workspace_id "ID workspace"
        string content "Isi komentar"
        string user_id "ID pengguna"
        string user_name "Nama pengguna"
        array mentions "User IDs yang di-mention"
        string parent_comment_id "ID komentar parent"
    }

    Label {
        string name "Nama label"
        string color "Warna label"
        string icon "Icon label"
        string description "Penjelasan label"
        string user_id "ID pemilik label"
        string workspace_id "ID workspace"
    }

    WorkflowAutomation {
        string company_id "ID perusahaan"
        string user_id "Email pemilik workflow"
        string name "Nama workflow automation"
        string trigger_type "Jenis trigger"
        array actions "Daftar aksi"
        boolean is_active "Status aktif"
    }

    Document ||--o{ ApprovalRequest : "memiliki"
    Document }o--|| User : "diupload oleh"
    Document }o--|| Document : "versi sebelumnya"
    Document }o--o{ User : "shared_with"
    Document }o--|| Workspace : "berada di"
    ApprovalRequest ||--|| ApprovalWorkflow : "menggunakan"
    ApprovalRequest }o--|| User : "diajukan oleh"
    Workspace ||--o{ WorkspaceMember : "memiliki anggota"
    WorkspaceMember }o--|| User : "anggota adalah"
    Workspace ||--o{ Comment : "memiliki komentar"
    Workspace ||--o{ Label : "memiliki label"
    WorkflowAutomation }o--|| User : "dimiliki oleh"
```

## Entity Schema — Document

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `title` | string | **Ya** | Judul dokumen — nama yang ditampilkan dalam daftar dan pencarian |
| `file_url` | string | **Ya** | URL file dokumen yang tersimpan di Cloudinary |
| `company_id` | string | Tidak | ID perusahaan (null untuk dokumen personal) |
| `description` | string | Tidak | Deskripsi atau catatan tentang dokumen |
| `category` | enum | Tidak | Kategori dokumen — default: `other` |
| `file_type` | string | Tidak | Tipe file: pdf, docx, xlsx, dll |
| `file_size` | number | Tidak | Ukuran file dalam bytes |
| `tags` | array\<string> | Tidak | Daftar tag untuk klasifikasi tambahan |
| `shared_with` | array\<string> | Tidak | Array email user yang memiliki akses ke dokumen |
| `folder` | string | Tidak | Nama folder virtual untuk organisir dokumen |
| `version` | number | Tidak | Nomor versi dokumen — default: 1, auto-increment |
| `is_locked` | boolean | Tidak | Status penguncian dokumen — default: false |
| `expiry_date` | date | Tidak | Tanggal kedaluwarsa dokumen (format: YYYY-MM-DD) |

## Entity Schema — ApprovalRequest

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `company_id` | string | **Ya** | ID perusahaan |
| `workflow_id` | string | **Ya** | ID ApprovalWorkflow yang digunakan |
| `document_type` | string | **Ya** | Tipe dokumen yang diminta persetujuan |
| `document_id` | string | **Ya** | ID dokumen yang diminta persetujuan |
| `requester_id` | string | **Ya** | User yang mengajukan persetujuan |
| `submission_date` | datetime | Tidak | Tanggal dan waktu pengajuan |
| `amount` | number | Tidak | Jumlah terkait (jika ada, misalnya nominal invoice) |
| `description` | string | Tidak | Deskripsi pengajuan persetujuan |
| `current_approval_level` | number | Tidak | Level persetujuan saat ini — default: 1 |
| `approval_history` | array\<object> | Tidak | Riwayat persetujuan per level |
| `overall_status` | enum | Tidak | Status keseluruhan — default: `pending` |
| `final_approval_date` | datetime | Tidak | Tanggal persetujuan final |

### Sub-field: approval\_history\[]

| Field | Tipe | Deskripsi |
| - | - | - |
| `level` | number | Urutan level persetujuan |
| `approver_id` | string | ID user approver di level ini |
| `approval_date` | datetime | Tanggal keputusan diberikan |
| `status` | enum | `approved`, `rejected`, atau `pending` |
| `comments` | string | Catatan dari approver |

## Entity Schema — ApprovalWorkflow

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `company_id` | string | **Ya** | ID perusahaan |
| `workflow_name` | string | **Ya** | Nama alur persetujuan |
| `document_type` | enum | **Ya** | Tipe dokumen yang memerlukan persetujuan |
| `approval_levels` | array\<object> | **Ya** | Daftar level persetujuan |
| `description` | string | Tidak | Penjelasan mengenai proses dan aturan workflow (max 1000 karakter) |
| `amount_limits` | object | Tidak | Limit jumlah untuk setiap level (level\_1, level\_2, level\_3) |
| `is_active` | boolean | Tidak | Status aktif workflow — default: true |

### Sub-field: approval\_levels\[]

| Field | Tipe | Deskripsi |
| - | - | - |
| `level` | number | Urutan tingkat persetujuan |
| `approver_role` | string | Role yang dapat melakukan persetujuan |
| `approver_ids` | array\<string> | User ID spesifik sebagai approver (opsional) |
| `required_approvals` | number | Jumlah persetujuan yang diperlukan — default: 1 |
| `parallel_approval` | boolean | Apakah persetujuan bisa dilakukan secara parallel — default: false |

## Entity Schema — WorkspaceMember

| Field | Tipe | Wajib | Deskripsi |
| - | - | - | - |
| `workspace_id` | string | **Ya** | ID workspace |
| `user_id` | string | **Ya** | ID pengguna |
| `role` | enum | Tidak | Peran dalam workspace — default: `member` |
| `invited_by` | string | Tidak | Email pengguna yang mengundang |
| `joined_at` | datetime | Tidak | Waktu bergabung |
| `description` | string | Tidak | Catatan tambahan mengenai anggota (max 1000 karakter) |
| `permissions` | object | Tidak | Konfigurasi permission detail |

### Sub-field: permissions

| Field | Tipe | Default | Deskripsi |
| - | - | - | - |
| `can_create_tasks` | boolean | true | Dapat membuat task baru |
| `can_edit_tasks` | boolean | true | Dapat mengedit task |
| `can_delete_tasks` | boolean | false | Dapat menghapus task |
| `can_invite_members` | boolean | false | Dapat mengundang anggota baru |
| `can_access_all_tasks` | boolean | false | Akses ke semua task terlepas dari assignment |

## 6 Kategori Dokumen

| Kategori | Ikon | Kegunaan | Contoh Dokumen |
| - | - | - | - |
| `contract` | 📄 | Kontrak dan perjanjian | Kontrak supplier, perjanjian kerjasama, MoU |
| `invoice` | 🧾 | Invoice dan tagihan | Invoice penjualan, tagihan pembelian, faktur pajak |
| `report` | 📊 | Laporan dan analisis | Laporan keuangan, laporan penjualan, audit report |
| `presentation` | 📽️ | Presentasi dan slide | Deck presentasi investor, pitch deck, proposal |
| `spreadsheet` | 📈 | Spreadsheet dan data | Budget planning, inventory data, price list |
| `other` | 📁 | Dokumen lainnya | Foto produk, desain kemasan, SOP, dokumen pendukung |

## Enum Reference — Document.category

| Nilai | Deskripsi |
| - | - |
| `contract` | Dokumen kontrak, perjanjian, MoU, dan surat perjanjian hukum |
| `invoice` | Invoice penjualan/pembelian, tagihan, dan faktur |
| `report` | Laporan keuangan, operasional, audit, dan analisis |
| `presentation` | Materi presentasi, slide deck, dan proposal visual |
| `spreadsheet` | Data spreadsheet, tabel, budget, dan perhitungan |
| `other` | Dokumen lain yang tidak masuk kategori di atas |

## Enum Reference — ApprovalRequest.overall\_status

| Nilai | Deskripsi |
| - | - |
| `pending` | Pengajuan sedang menunggu persetujuan dari approver |
| `approved` | Semua level persetujuan telah disetujui |
| `rejected` | Salah satu level menolak pengajuan |
| `on_hold` | Pengajuan ditunda sementara oleh approver |

## Enum Reference — ApprovalWorkflow\.document\_type

| Nilai | Deskripsi |
| - | - |
| `expense_request` | Permintaan pengeluaran dana |
| `leave_request` | Permintaan cuti karyawan |
| `purchase_order` | Pesanan pembelian ke supplier |
| `discount_request` | Permintaan pemberian diskon |
| `budget_adjustment` | Penyesuaian anggaran |

## Enum Reference — WorkspaceMember.role

| Nilai | Deskripsi |
| - | - |
| `owner` | Pemilik workspace — akses penuh termasuk manajemen billing |
| `admin` | Administrator — dapat mengelola anggota dan konfigurasi |
| `member` | Anggota standar — dapat membuat dan mengedit konten |
| `viewer` | Hanya dapat melihat konten, tidak dapat mengedit |

## Document Lifecycle — State Diagram

```mermaid theme={null}
stateDiagram-v2
    [*] --> Draft: Upload dokumen baru

    Draft --> Review: Submit untuk review
    Draft --> Draft: Edit metadata / versi

    Review --> Approved: Semua approver menyetujui
    Review --> Rejected: Approver menolak
    Review --> On_Hold: Ditunda sementara
    Review --> Draft: Revisi diperlukan

    On_Hold --> Review: Lanjutkan proses review
    On_Hold --> Draft: Kembali ke draft untuk revisi

    Rejected --> Draft: Revisi dan resubmit
    Rejected --> [*]: Arsipkan (dibatalkan)

    Approved --> Active: Dokumen aktif digunakan
    Active --> Archived: Kedaluwarsa / tidak relevan
    Active --> Locked: Kunci dokumen
    Locked --> Active: Buka kunci dokumen
    Active --> New_Version: Upload versi baru

    New_Version --> Active: Versi baru aktif
    New_Version --> Review: Versi baru perlu review

    Archived --> Active: Restore dari arsip
    Archived --> [*]: Hapus permanen

    Locked --> Archived: Arsipkan dokumen terkunci
```

### Penjelasan State

| State | Deskripsi |
| - | - |
| **Draft** | Dokumen baru diupload, metadata sedang dilengkapi |
| **Review** | Dokumen diajukan untuk persetujuan melalui approval workflow |
| **Approved** | Dokumen telah disetujui oleh semua approver |
| **Active** | Dokumen aktif digunakan dan dapat diakses oleh pihak yang berwenang |
| **On\_Hold** | Proses review ditunda sementara, menunggu informasi tambahan |
| **Rejected** | Dokumen ditolak oleh approver, perlu revisi |
| **Locked** | Dokumen dikunci (`is_locked = true`) untuk mencegah perubahan |
| **Archived** | Dokumen diarsipkan karena sudah kedaluwarsa atau tidak relevan |
| **New\_Version** | Versi baru sedang diupload, menunggu aktivasi |

## Upload Pipeline

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant D as Documents.jsx
    participant Canvas as Canvas API
    participant Cloud as Cloudinary
    participant DB as Base44

    U->>D: Pilih file (drag & drop / browse)
    D->>D: Validasi file type & size
    D->>D: Baca file sebagai DataURL
    
    alt File adalah gambar
        D->>Canvas: Load image ke canvas
        Canvas->>Canvas: Resize ke max 800px
        Canvas->>Canvas: Compress quality 0.8
        Canvas-->>D: Compressed blob
    end
    
    D->>Cloud: Upload via unsigned upload preset
    Note over Cloud: Folder: snishop_erp/documents
    Cloud-->>D: { secure_url, public_id, bytes }
    
    D->>DB: Create Document entity
    Note over DB: title, category, file_url,<br/>file_type, file_size, folder,<br/>tags, version=1
    DB-->>D: Document saved
    D->>D: Refresh document list
```

### Image Compression Details

| Parameter | Nilai | Deskripsi |
| - | - | - |
| Max width/height | 800px | Gambar lebih besar di-resize proporsional |
| Quality | 0.8 (80%) | Kompresi JPEG quality |
| Format | Auto-detect | JPEG, PNG, WebP didukung |
| Method | Canvas API | `canvas.toBlob(callback, type, quality)` |

### File Type Support

| Tipe File | Extension | Upload | Preview |
| - | - | - | - |
| JPEG | .jpg, .jpeg | ✅ | ✅ Thumbnail |
| PNG | .png | ✅ | ✅ Thumbnail |
| WebP | .webp | ✅ | ✅ Thumbnail |
| PDF | .pdf | ✅ | ✅ PDF viewer |
| DOCX | .docx | ✅ | ❌ Download only |
| XLSX | .xlsx | ✅ | ❌ Download only |

## Sharing & Collaboration Flow

```mermaid theme={null}
sequenceDiagram
    participant Owner as Dokumen Owner
    participant UI as Documents.jsx
    participant DB as Base44
    participant Recipient as Penerima Share

    Owner->>UI: Klik tombol "Share" pada dokumen
    UI->>UI: Tampilkan dialog share
    Owner->>UI: Masukkan email penerima
    UI->>UI: Validasi format email
    UI->>DB: Update shared_with array
    Note over DB: Push email ke array shared_with
    DB-->>UI: Document updated
    UI->>UI: Tampilkan konfirmasi berhasil

    Recipient->>UI: Buka halaman Documents
    UI->>DB: Query documents WHERE shared_with contains email
    DB-->>UI: Return shared documents
    UI->>UI: Tampilkan dokumen yang di-share
    Note over Recipient: Dapat view & download,<br/>tidak dapat delete
```

### Aturan Sharing

| Aspek | Aturan |
| - | - |
| **Akses** | User dalam `shared_with` dapat melihat dan download dokumen |
| **Format** | Identifikasi penerima berdasarkan email |
| **Permission** | Penerima hanya bisa view dan download, tidak bisa edit metadata atau delete |
| **Visibility** | Dokumen yang di-share tetap muncul di daftar owner |
| **Revoking** | Hapus email dari array `shared_with` untuk mencabut akses |

## Version Control Flow

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant UI as Documents.jsx
    participant Cloud as Cloudinary
    participant DB as Base44

    U->>UI: Pilih dokumen yang ingin di-update
    UI->>DB: Get current document
    DB-->>UI: Document (version: N)
    UI->>UI: Cek is_locked status

    alt Dokumen terkunci
        UI-->>U: Error: Dokumen sedang dikunci
    else Dokumen tidak terkunci
        U->>UI: Upload file baru (versi terbaru)
        UI->>Cloud: Upload file baru
        Cloud-->>UI: { secure_url, file_size }
        UI->>DB: Update document
        Note over DB: file_url = new_url<br/>file_size = new_size<br/>version = N + 1
        DB-->>UI: Document updated
        UI->>UI: Refresh & tampilkan versi baru
    end
```

### Aturan Versioning

| Aspek | Aturan |
| - | - |
| **Auto-increment** | Field `version` otomatis bertambah setiap kali file di-update |
| **Lock protection** | Dokumen yang `is_locked = true` tidak dapat di-update |
| **File replacement** | File lama di Cloudinary tetap ada, `file_url` diupdate ke file baru |
| **Size tracking** | `file_size` diupdate sesuai file baru |
| **Default version** | Dokumen baru dimulai dari `version = 1` |

## Approval Workflow Flow

```mermaid theme={null}
sequenceDiagram
    participant Req as Requester
    participant UI as Documents.jsx
    participant DB as Base44
    participant App as Approver

    Req->>UI: Submit dokumen untuk approval
    UI->>DB: Create ApprovalRequest
    Note over DB: overall_status = pending<br/>current_approval_level = 1
    DB-->>UI: Request created

    UI->>App: Notifikasi: ada pengajuan baru
    
    App->>UI: Buka detail ApprovalRequest
    UI->>DB: Get request + approval_history
    
    alt Approve
        App->>UI: Klik "Approve"
        UI->>DB: Update approval_history
        Note over DB: status = approved<br/>Push ke approval_history
        alt Ada level berikutnya
            DB->>DB: current_approval_level++
            DB->>App: Notifikasi ke approver level berikutnya
        else Level terakhir
            DB->>DB: overall_status = approved
            DB->>DB: final_approval_date = now
            DB->>Req: Notifikasi: dokumen disetujui
        end
    else Reject
        App->>UI: Klik "Reject" + komentar
        UI->>DB: Update approval_history
        Note over DB: status = rejected
        DB->>DB: overall_status = rejected
        DB->>Req: Notifikasi: dokumen ditolak
    end
```

## Search & Filter

```mermaid theme={null}
flowchart TD
    A[All Documents] --> B{Category Filter?}
    B -->|Selected| C[Filter by category]
    B -->|All| D[Show all categories]
    C --> E{Search Query?}
    D --> E
    E -->|Ada| F[Filter by title/description/tags<br/>case-insensitive match]
    E -->|Kosong| G[Tampilkan semua]
    F --> H{Folder Filter?}
    G --> H
    H -->|Selected| I[Filter by folder]
    H -->|All| J[Show all folders]
    I --> K[Sorted by created_at DESC]
    J --> K
```

| Filter | Opsi | Deskripsi |
| - | - | - |
| **Kategori** | All, Contract, Invoice, Report, Presentation, Spreadsheet, Other | Filter berdasarkan jenis dokumen |
| **Search** | Text input | Pencarian berdasarkan judul, deskripsi, dan tag |
| **Folder** | All, \[daftar folder] | Filter berdasarkan folder virtual |
| **Sort** | Terbaru, Terlama, Nama A-Z | Urutan tampilan |
| **Status** | All, Active, Locked, Expired | Filter berdasarkan status dokumen |

## Access Control

```mermaid theme={null}
flowchart LR
    A[User Access] --> B{ERPAccessGuard<br/>module=documents}
    B -->|Granted| C[Full Access]
    B -->|Denied| D[Redirect / Blocked]
    
    C --> C1[View Documents]
    C --> C2[Upload New]
    C --> C3[Edit Metadata]
    C --> C4[Delete Documents]
    C --> C5[Share Documents]
    C --> C6[Lock/Unlock]
    C --> C7[Manage Versions]
```

### RBAC Permission Table

| Role | View | Upload | Edit Metadata | Delete | Share | Lock/Unlock | Manage Versions |
| - | - | - | - | - | - | - | - |
| **Owner** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| **Admin** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| **Inventory** | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
| **Finance** | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **Kasir** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |

### Permission Detail

| Aksi | Deskripsi |
| - | - |
| **View** | Melihat daftar dokumen, preview, dan download |
| **Upload** | Mengupload dokumen baru ke sistem |
| **Edit Metadata** | Mengubah judul, deskripsi, kategori, tag, folder |
| **Delete** | Menghapus dokumen dari sistem (soft delete) |
| **Share** | Membagikan dokumen ke user lain via email |
| **Lock/Unlock** | Mengunci atau membuka kunci dokumen |
| **Manage Versions** | Mengupload versi baru dari dokumen yang ada |

## Stats Dashboard

| Metrik | Perhitungan | Deskripsi |
| - | - | - |
| **Total Dokumen** | `documents.length` | Jumlah seluruh dokumen |
| **Total Ukuran** | `SUM(file_size)` | Total ukuran semua file |
| **Dokumen Bulan Ini** | `filter(created_at this month)` | Dokumen baru bulan ini |
| **Kategori Terbanyak** | `mode(category)` | Kategori dengan dokumen terbanyak |
| **Dokumen Terkunci** | `filter(is_locked = true)` | Jumlah dokumen yang dikunci |
| **Dokumen Kedaluwarsa** | `filter(expiry_date < today)` | Dokumen yang sudah melewati tanggal kedaluwarsa |
| **Shared Documents** | `filter(shared_with.length > 0)` | Dokumen yang dibagikan ke user lain |
| **Total Versi** | `SUM(version - 1)` | Total update versi across semua dokumen |

## Folder Organisation

Dokumen dapat diorganisir ke dalam folder virtual menggunakan field `folder`. Folder bersifat flat (tidak ada sub-folder bersarang) dan ditentukan oleh nama string.

| Fitur | Deskripsi |
| - | - |
| **Buat folder** | Ketik nama folder baru saat upload atau edit dokumen |
| **Pindah dokumen** | Edit field `folder` pada dokumen untuk memindahkan ke folder lain |
| **Lihat isi folder** | Klik folder di sidebar/navigasi untuk melihat dokumen di dalamnya |
| **Hapus folder** | Kosongkan field `folder` pada semua dokumen di folder tersebut |
| **Nama folder** | Case-sensitive, disarankan menggunakan nama yang konsisten |

### Contoh Struktur Folder

```
📁 Kontrak
  ├── Kontrak Supplier PT ABC - 2026.pdf
  └── MoU Partnership XYZ.docx
📁 Invoice
  ├── INV-2026-001.pdf
  └── INV-2026-002.pdf
📁 Laporan Keuangan
  ├── Q1-2026.xlsx
  └── Annual-Report-2025.pdf
📁 Sertifikat
  ├── Halal-MUI-2026.pdf
  └── ISO-9001-Certificate.pdf
```

## Document Locking & Expiry

### Penguncian Dokumen

Field `is_locked` digunakan untuk mencegah perubahan pada dokumen penting. Dokumen yang terkunci:

* Tidak dapat di-update versinya
* Metadata tidak dapat diubah
* Tetap dapat dilihat dan di-download
* Hanya role Owner dan Admin yang dapat mengunci/membuka kunci

### Tanggal Kedaluwarsa

Field `expiry_date` menandai kapan dokumen dianggap tidak berlaku lagi:

* Dokumen kedaluwarsa tetap tersimpan tetapi ditandai dengan badge khusus
* Dapat difilter untuk menampilkan dokumen yang sudah/sedang kedaluwarsa
* Berguna untuk kontrak, sertifikat, dan dokumen legal yang memiliki masa berlaku
* Tidak otomatis dihapus — perlu tindakan manual untuk arsip atau hapus

## Integrasi Lintas Modul

| Modul | Entity | Fungsi |
| - | - | - |
| **Finance** | Invoice, FinancialRecord | Dokumen invoice dan receipt terkait transaksi keuangan |
| **Inventory** | CompanyProduct | Dokumen sertifikat halal, izin edar produk |
| **HR** | CompanyMember | Dokumen kontrak kerja, sertifikat karyawan |
| **CRM** | Customer | Dokumen kontrak dan perjanjian dengan customer |
| **Legal** | — | Dokumen hukum perusahaan (akta, SIUP, NPWP) |
| **Approval** | ApprovalRequest, ApprovalWorkflow | Workflow persetujuan untuk dokumen bisnis |
| **Automation** | WorkflowAutomation | Trigger otomatis saat dokumen baru diupload atau status berubah |
| **Asset** | Asset | Dokumen terkait aset: sertifikat, bukti pembelian, garansi |

## Flow Penggunaan

```mermaid theme={null}
flowchart LR
    A[Buka Documents] --> B[Lihat Daftar<br/>Dokumen]
    B --> C{Aksi}
    C -->|Upload| D[Klik Upload<br/>Pilih File]
    D --> E[Isi Metadata<br/>judul, kategori, folder, tag]
    E --> F[Compress & Upload<br/>ke Cloudinary]
    F --> G[Dokumen Tersimpan]
    
    C -->|Search| H[Gunakan Search<br/>atau Filter]
    H --> I[Lihat Hasil]
    
    C -->|Download| J[Klik Download<br/>pada Dokumen]
    J --> K[File Terdownload]

    C -->|Share| L[Klik Share]
    L --> L1[Masukkan Email]
    L1 --> L2[Dokumen Terbagi]
    
    C -->|Delete| M[Klik Delete]
    M --> N[Konfirmasi]
    N --> O[Dokumen Dihapus]

    C -->|Version| P[Upload Versi Baru]
    P --> Q[Version Auto-increment]
```

## Cara Akses

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

## Flow Penggunaan Detail

1. Buka halaman Documents dari sidebar — lihat statistik dokumen di atas
2. Gunakan **filter kategori** untuk menyaring dokumen berdasarkan jenis
3. Gunakan **search bar** untuk mencari dokumen berdasarkan judul, deskripsi, atau tag
4. Gunakan **filter folder** untuk melihat dokumen dalam folder tertentu
5. Klik **"Upload Dokumen"** untuk mengupload file baru
6. Pilih file dari komputer (drag & drop atau browse)
7. Sistem otomatis **compress** jika file berupa gambar
8. Isi **judul**, **kategori**, **folder**, **tag**, dan **deskripsi** dokumen
9. Klik **Upload** — file diupload ke Cloudinary dan metadata disimpan
10. Dokumen baru muncul di daftar dengan thumbnail preview
11. Klik dokumen untuk **preview** detail, **download**, **share**, atau **delete**
12. Gunakan **lock** untuk mengunci dokumen penting agar tidak diubah
13. Set **expiry\_date** untuk dokumen yang memiliki masa berlaku

## Tips

* **Gunakan kategori yang konsisten** — supaya dokumen mudah ditemukan saat dibutuhkan, terutama saat audit atau review legal
* **Beri judul dokumen yang deskriptif** — contoh: "Kontrak Supplier PT ABC - 2026" lebih baik daripada "kontrak\_final\_revisi3.pdf"
* **Upload sertifikat dan izin edar** ke kategori `other` atau buat kategori khusus supaya mudah diakses saat ada inspeksi
* **Manfaatkan deskripsi** untuk menambahkan konteks: nomor kontrak, tanggal berlaku, pihak terkait
* **Gunakan folder** untuk mengelompokkan dokumen berdasarkan proyek, departemen, atau periode waktu
* **Tambahkan tag** untuk klasifikasi silang — satu dokumen bisa memiliki banyak tag meskipun hanya satu kategori
* **Set expiry\_date** pada kontrak dan sertifikat supaya kamu diingatkan sebelum dokumen kedaluwarsa
* **Lock dokumen penting** yang sudah final untuk mencegah perubahan tidak sengaja
* **Share dokumen** via email daripada mengirim file berulang — semua orang akses versi yang sama
* **Review dokumen secara berkala** — hapus atau arsipkan dokumen yang sudah tidak relevan
* **File gambar otomatis di-compress** — tidak perlu compress manual sebelum upload, sistem sudah menangani optimasi ukuran
* **Gunakan versioning** — upload versi baru daripada menimpa file lama, supaya ada jejak perubahan


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