Like 0

Revision 6b38f5477773c0c6f8e94a28509629f4dfc03626

HANDOVER_FE_DAILY_ACTIVITY_REPORT.md Raw

Handover FE — Daily Activity Report (PDF)

Status: backend selesai (commit 6d006cc, seeder 3a85112). Tidak ada perubahan di middleware_socket-gateway.


1. Ringkasan

Download PDF laporan daily activity per project. Pola persis seperti hierarchy report:

  1. FE POST bikin job → status QUEUED
  2. Worker BullMQ generate PDF → PROCESSING → READY / FAILED
  3. Setiap perubahan status dipush lewat socket event document-download:updated
  4. FE ambil file lewat GET /:jobId/download (blob, bukan lewat socket)

Tidak ada persentase progres — hanya status. Sama seperti hierarchy.


2. Endpoint

Semua di bawah workspace path, butuh login + membership workspace:

POST   /api/workspaces/:workspaceId/daily-activity-reports
GET    /api/workspaces/:workspaceId/daily-activity-reports
POST   /api/workspaces/:workspaceId/daily-activity-reports/:jobId/retry
DELETE /api/workspaces/:workspaceId/daily-activity-reports/:jobId
GET    /api/workspaces/:workspaceId/daily-activity-reports/:jobId/download

Authz: member workspace dan harus punya role MEMBER / OWNER / ADMIN di project target. Project di luar workspace path → 404 Project not found in workspace.


3. Create job

POST /api/workspaces/:workspaceId/daily-activity-reports
Content-Type: application/json
{
  "scope_id": "uuid-project",
  "period_type": "ALL",
  "period_index": "ALL",
  "start_date": "2026-11-01T00:00:00.000Z",
  "end_date": "2026-11-07T23:59:59.999Z"
}
Field Wajib Keterangan
scope_id ya id project (report ini project-only, tidak ada scope_type)
period_type ya WEEKLY | MONTHLY | CUSTOM | ALL
period_index tidak label granularitas, lihat §4
start_date / end_date tidak window eksplisit; CUSTOM pakai ini verbatim, WEEKLY/MONTHLY fallback ke tanggal project, ALL diabaikan

Response = row job:

{
  "id": "uuid",
  "project_id": "uuid-project",
  "period_type": "ALL",
  "period_index": "ALL",
  "start_date": null,
  "end_date": null,
  "seq": 1,
  "file_name": "001/PRJ/ALL/2026113",
  "status": "QUEUED",
  "s3_key": null,
  "error_message": null,
  "requested_by": "uuid-user",
  "generated_at": null,
  "queued_at": "2026-11-03T02:11:04.518Z",
  "generated_day": "20261103",
  "cleared_at": null,
  "updated_at": "2026-11-03T02:11:04.518Z"
}

file_name dipakai sebagai doc number di footer PDF (Page X of Y di kanan, logo ConsDoc di kiri). Slash di-strip hanya saat download.


4. period_index & label periode di PDF

Subtitle PDF = header.periodLabel yang dibentuk backend:

period_type period_index window.label Subtitle PDF
WEEKLY W3 Week 3 Week 3 Report : 12 Januari 2025 - 18 Januari 2025
WEEKLY ALWK All week All week Report : …
MONTHLY M4 Month 4 Month 4 Report : …
MONTHLY ALMT All month All month Report : …
CUSTOM CSM (default) Custom Custom Report : 5 Januari 2025 - 12 Januari 2025
ALL ALL (default) — All Data

FE tinggal kirim period_index sesuai pilihan user. Kalau kosong: ALL → ALL, sisanya → CSM.

ALL = seluruh daily activity project, tanpa clamp tanggal project. Daily activity yang diisi setelah endDate project tetap ikut (project belum CLOSED).


5. List / inbox

GET /api/workspaces/:workspaceId/daily-activity-reports?tab=in_process&page=1&limit=20
Query Default Keterangan
scope_id — kalau diisi, inbox cuma project itu (di-assert dulu)
tab in_process in_process = QUEUED/PROCESSING/FAILED; files_ready = READY
page 1
limit 20 max 100
{
  "data": [
    {
      "id": "uuid",
      "seq": 1,
      "file_name": "001/PRJ/ALL/2026113",
      "status": "READY",
      "error_message": null,
      "generated_at": "2026-11-03T02:11:09.201Z",
      "queued_at": "2026-11-03T02:11:04.518Z"
    }
  ],
  "meta": { "page": 1, "limit": 20, "total": 1 }
}

Urut queued_at desc. Row yang sudah di-clear tidak pernah muncul.

Catatan: list belum mengembalikan project_id / period_type / period_index. Kalau FE mau menampilkan label periode per baris di inbox, bilang — tiga field tinggal ditambahkan ke select.


6. Socket

Reuse client yang sudah ada di FE:

web_consdoc/src/clients/document-download/document-download-socket.client.ts

Event: document-download:updated (konstanta DOCUMENT_DOWNLOAD_SOCKET_EVENTS.UPDATED).

{
  change: 'created' | 'status',
  source: 'daily-activities-report',   // beda dari hierarchy
  item: {
    id: string,
    project_id: string,
    period_type: string,
    period_index: string,
    seq: number,
    file_name: string,
    status: 'QUEUED' | 'PROCESSING' | 'READY' | 'FAILED' | 'CANCELLED',
    error_message: string | null,
    generated_at: string | null,
    queued_at: string
  }
}

Filter payload.source === 'daily-activities-report' di hook. Audience = semua member workspace project itu (bukan per-user khusus), jadi beberapa tab bisa menerima event yang sama.

Tidak ada event created terpisah yang perlu ditangani selain yang sudah ada di client — backend mengirim change: 'created' untuk row baru, change: 'status' untuk transisi status.


7. Download

GET /api/workspaces/:workspaceId/daily-activity-reports/:jobId/download

Response application/pdf dengan header:

Content-Disposition: attachment; filename="001-PRJ-ALL-2026113.pdf"

Ambil sebagai blob (responseType: 'blob') lalu URL.createObjectURL. Hanya status: READY yang bisa; selain itu 404 Report job not found.


8. Retry & clear

Retry — hanya FAILED:

POST .../:jobId/retry

→ status balik QUEUED, error_message di-null-kan. seq dan file_name tidak diregenerasi (nama file beku sejak create).

Clear download — soft delete:

DELETE .../:jobId
  • QUEUED / PROCESSING → jadi CANCELLED + cleared_at diisi (worker skip)
  • READY / FAILED / CANCELLED → cleared_at diisi, objek S3 dihapus best-effort
  • Nomor file tidak pernah dipakai ulang karena seq menghitung row yang sudah di-clear juga

9. Isi PDF

Header: breadcrumb agendaName → programName (kiri) + tanggal report (kanan), title Progress Report - <project>, subtitle label periode, garis pemisah, heading Daily Activities + Record your daily activities on Consdoc.

Tabel per hari (banner tanggal biru muda, header tabel ikut berulang saat pindah halaman):

Time Activity Division guest Shared Action plan

Aturan data:

  • Time = HH:mm – HH:mm (en dash)
  • Division guest = nama divisi tamu; — kalau kosong
  • Shared = teks berwarna, bukan pill: VISIBLE TO TEAM (biru) untuk PUBLIC, NO (abu) untuk PRIVATE
  • Action plan = nama item action-plan yang di-link, digabung , ; — kalau tidak ada
  • note tidak ditampilkan
  • Tanggal banner: Senin, 03 Nov 2026 (nama hari Indonesia + bulan singkat)
  • Kosong → satu baris No daily activity in this period

10. Aturan visibility (penting untuk ekspektasi user)

PDF tidak menampilkan semua baris. Filter per row:

Kondisi Tampil?
PUBLIC ya, selalu
PRIVATE, dibuat oleh user yang request ya
PRIVATE, user lain, requester OWNER/ADMIN workspace ya
PRIVATE, user lain, requester MEMBER biasa tidak

Artinya dua user bisa generate report periode sama dan dapat isi berbeda. Kalau user komplain "kok baris saya hilang", cek role-nya di workspace.


11. Error

Kasus Status Body
Project bukan milik workspace path 404 Project not found in workspace
Role project kurang 403 You do not have required role perform action
Retry job bukan FAILED 400 Only FAILED jobs can be retried
Job tidak ada / sudah clear 404 Report job not found
Job belum READY saat download 404 Report job not found
Generate gagal row FAILED error_message berisi pesan Gotenberg/Chromium

error_message dipotong 65000 char. Tampilkan di UI untuk tab in_process.


12. Yang belum ada

  • Tidak ada progres persentase, tidak ada estimasi durasi.
  • Tidak ada filter per-user di inbox (semua row project/workspace terlihat).
  • Belum ada endpoint untuk preview HTML (hanya PDF).
  • File lama tidak otomatis expire; umur file tergantung lifecycle S3.