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:
- FE
POSTbikin job → statusQUEUED - Worker BullMQ generate PDF →
PROCESSING→READY/FAILED - Setiap perubahan status dipush lewat socket event
document-download:updated - 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 keselect.
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→ jadiCANCELLED+cleared_atdiisi (worker skip)READY/FAILED/CANCELLED→cleared_atdiisi, objek S3 dihapus best-effort- Nomor file tidak pernah dipakai ulang karena
seqmenghitung 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 kosongShared= teks berwarna, bukan pill:VISIBLE TO TEAM(biru) untukPUBLIC,NO(abu) untukPRIVATEAction plan= nama item action-plan yang di-link, digabung,;—kalau tidak adanotetidak 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.