task-h.1 complate
This commit is contained in:
24
docs/adr/0009-approved-document-storage-lifecycle.md
Normal file
24
docs/adr/0009-approved-document-storage-lifecycle.md
Normal file
@@ -0,0 +1,24 @@
|
||||
Status:
|
||||
accepted
|
||||
|
||||
Context:
|
||||
Task H introduced server-side PDF generation for quotation preview, download, and approved-document persistence.
|
||||
Task H.1 validated the full path with a real quotation fixture and confirmed that approved artifacts currently persist to local disk under `public/generated/...`.
|
||||
|
||||
Decision:
|
||||
- Keep approved quotation PDFs on local filesystem storage for development and MVP use.
|
||||
- Persist the generated file path on the quotation row via `approved_pdf_url`.
|
||||
- Persist `approved_snapshot` and `approved_template_version_id` alongside the stored file path so the approved artifact can be traced back to the data and template used at generation time.
|
||||
- Treat this storage model as acceptable only for local/dev and early MVP deployment, not as the final production storage architecture.
|
||||
|
||||
Consequences:
|
||||
- Preview/download/generate-approved flows can ship now without blocking on object storage integration.
|
||||
- Approved PDF persistence works with the current dashboard and static file serving model.
|
||||
- Local public storage is simple, but it does not provide immutability guarantees, signed access control, retention policy, or durable storage semantics expected for long-lived production artifacts.
|
||||
|
||||
Future:
|
||||
- introduce an object-storage abstraction shared by generated documents and manual attachments
|
||||
- support signed URLs or another private delivery strategy where required
|
||||
- define immutable approved artifact rules and whether regeneration is allowed
|
||||
- add retention/cleanup policy for superseded or regenerated artifacts
|
||||
- move approved-PDF generation to an async job when post-approval auto-generation is introduced
|
||||
@@ -2,234 +2,137 @@
|
||||
|
||||
## After Task D
|
||||
|
||||
### 1. Database FK
|
||||
|
||||
Customer / Contact / Enquiry ยัง enforce relationship ด้วย application logic
|
||||
### Database foreign keys
|
||||
Customer, contact, and enquiry relationships are still enforced mainly in application logic.
|
||||
|
||||
Future:
|
||||
- add FK constraints after the CRM schema settles
|
||||
- review cascade behavior before enabling hard relational enforcement
|
||||
|
||||
* เพิ่ม FK หลัง schema stable
|
||||
|
||||
### 2. Date Input
|
||||
|
||||
Form ยังใช้ text input แบบ YYYY-MM-DD
|
||||
### Date input UX
|
||||
Several forms still use plain `YYYY-MM-DD` text/date inputs.
|
||||
|
||||
Future:
|
||||
- move to a shared date picker pattern
|
||||
- standardize timezone handling for CRM forms
|
||||
|
||||
* เปลี่ยนเป็น Date Picker กลางของระบบ
|
||||
|
||||
### 3. Customer Related Enquiries Pagination
|
||||
|
||||
หน้า customer detail แสดง related enquiries แล้ว แต่ยังไม่มี pagination
|
||||
### Related enquiry pagination
|
||||
Customer detail can show related enquiries, but that view still has no dedicated pagination strategy.
|
||||
|
||||
Future:
|
||||
- add paging once real data volume grows
|
||||
|
||||
* เพิ่มเมื่อข้อมูลเริ่มเยอะ
|
||||
|
||||
### 4. Follow-up Activity
|
||||
|
||||
Activity timeline ยังพึ่ง audit payload
|
||||
### Follow-up activity timeline
|
||||
Activity history still relies heavily on audit payloads instead of a curated domain timeline.
|
||||
|
||||
Future:
|
||||
|
||||
* ทำ combined activity view/service
|
||||
|
||||
---
|
||||
- build a combined activity view/service for CRM interactions
|
||||
|
||||
## After Task E
|
||||
|
||||
### 5. Mixed Tax Rollup
|
||||
|
||||
Quotation item รองรับ taxRate ต่อรายการแล้ว
|
||||
|
||||
Current:
|
||||
|
||||
* quotation summary ยังใช้ header tax calculation
|
||||
### Mixed tax rollup
|
||||
Quotation items support per-line tax input, but summary calculation still assumes a header-centric tax model.
|
||||
|
||||
Future:
|
||||
- support mixed-tax aggregation from actual item rows
|
||||
- align document totals and reporting with per-line tax logic
|
||||
|
||||
* รองรับ mixed tax per line
|
||||
* aggregate tax จาก item จริง
|
||||
|
||||
Priority:
|
||||
|
||||
* Medium
|
||||
|
||||
### 6. Attachment Storage
|
||||
|
||||
Attachment ยังเป็น metadata-only
|
||||
|
||||
Current:
|
||||
|
||||
* เก็บเฉพาะ metadata
|
||||
### Attachment storage abstraction
|
||||
Quotation attachments started as metadata-only and approved PDFs now write to local disk, but there is still no real storage abstraction.
|
||||
|
||||
Future:
|
||||
- introduce a provider abstraction
|
||||
- support upload/download lifecycle consistently across manual attachments and generated artifacts
|
||||
- define migration strategy for existing local/public paths
|
||||
|
||||
* storage provider abstraction
|
||||
* upload service
|
||||
* download endpoint
|
||||
* permission check
|
||||
|
||||
Priority:
|
||||
|
||||
* High
|
||||
|
||||
### 7. Revision Snapshot
|
||||
|
||||
Revision copy:
|
||||
|
||||
* header
|
||||
* items
|
||||
* customers
|
||||
* topics
|
||||
|
||||
Current:
|
||||
|
||||
* ไม่ copy follow-ups
|
||||
* ไม่ copy attachments
|
||||
### Revision snapshot coverage
|
||||
Revision copy currently focuses on quotation header, items, customers, and topics.
|
||||
|
||||
Future:
|
||||
- decide whether follow-ups and attachments belong in revision snapshots
|
||||
- define immutable vs mutable child-data behavior across revisions
|
||||
|
||||
* กำหนด revision snapshot strategy ให้ชัดเจน
|
||||
|
||||
Priority:
|
||||
|
||||
* Medium
|
||||
|
||||
### 8. CRM Foreign Keys
|
||||
|
||||
Customer
|
||||
Contact
|
||||
Enquiry
|
||||
Quotation
|
||||
|
||||
Current:
|
||||
|
||||
* ใช้ organization validation ใน application layer
|
||||
### CRM foreign keys
|
||||
Core CRM tables still depend on organization-scoped validation in service code.
|
||||
|
||||
Future:
|
||||
|
||||
* เพิ่ม FK เมื่อ schema stable
|
||||
* review cascade strategy
|
||||
|
||||
Priority:
|
||||
|
||||
* High
|
||||
|
||||
### 9. Approval Workflow Pending
|
||||
|
||||
Quotation stabilization in Task E.1 only prepares:
|
||||
|
||||
* approval-ready statuses
|
||||
* revision guard
|
||||
* placeholder submit-for-approval action
|
||||
|
||||
Current:
|
||||
|
||||
* no approval table
|
||||
* no approval requester/approver history
|
||||
* no multi-step approval rule
|
||||
* no approval notification
|
||||
|
||||
Future:
|
||||
|
||||
* introduce approval aggregate in Task F
|
||||
* separate workflow state from quotation commercial state where needed
|
||||
* define approver resolution by branch / amount / role
|
||||
|
||||
Priority:
|
||||
|
||||
* High
|
||||
- add FK constraints after schema churn slows down
|
||||
- review delete and soft-delete interactions first
|
||||
|
||||
## After Task F
|
||||
|
||||
### Approval Permission Sync
|
||||
Existing memberships may not automatically receive new approval permissions.
|
||||
### Permission sync for existing memberships
|
||||
New permissions are defined in code, but old membership rows may still hold stale permission arrays.
|
||||
|
||||
Future:
|
||||
- add permission sync script
|
||||
- admin UI for role/permission management
|
||||
- add a permission sync/backfill command
|
||||
- provide admin tooling for role and permission maintenance
|
||||
|
||||
### Approval Workflow Config UI
|
||||
Approval workflow is seeded but not configurable from UI.
|
||||
### Approval workflow configuration UI
|
||||
Approval workflows are seeded and usable, but still not configurable from the dashboard.
|
||||
|
||||
Future:
|
||||
- workflow setup screen
|
||||
- step editor
|
||||
- approver role mapping
|
||||
- build workflow setup screens
|
||||
- add step editing and role mapping management
|
||||
|
||||
### Approval Notification
|
||||
Approval workflow has no email/line notification yet.
|
||||
### Approval notifications
|
||||
Approval flow has no queue-backed notification channel yet.
|
||||
|
||||
Future:
|
||||
- notification queue
|
||||
- approval reminder
|
||||
- add notification jobs
|
||||
- support reminders and escalation policy
|
||||
|
||||
## After Task G
|
||||
|
||||
### Document Mapping Editor
|
||||
Template mappings are seeded and readable, but not yet manageable from UI.
|
||||
### Document mapping editor
|
||||
Template mappings are seeded and readable, but not manageable from UI.
|
||||
|
||||
Future:
|
||||
- mapping CRUD UI
|
||||
- table column editor
|
||||
- publish/draft template workflow
|
||||
- add mapping CRUD for admins
|
||||
- support table column editing
|
||||
- add draft/publish template workflow
|
||||
|
||||
### pdfme Render Parity
|
||||
Document preview is application-native, not pixel-perfect `pdfme` rendering.
|
||||
### Product-specific template resolution
|
||||
Quotation document template resolution still defaults to a coarse product selection strategy.
|
||||
|
||||
Future:
|
||||
- server-side pdfme render pipeline
|
||||
- preview image generation
|
||||
- schema validation against live template versions
|
||||
- define clearer rules for crane, dock door, solar, and service-specific templates
|
||||
|
||||
### Approved PDF Persistence
|
||||
Approved snapshot preparation exists, but no binary file generation or storage write-back yet.
|
||||
## After Task H / H.1
|
||||
|
||||
### Font compatibility fallback
|
||||
PDF generation now uses vendored Cordia TTF files from `public/fonts`, which fixed the TTC runtime issue, but generator-side fallback normalization still remains as a safety net.
|
||||
|
||||
Future:
|
||||
- approved PDF generator
|
||||
- storage abstraction
|
||||
- immutable approved artifact URL on quotation
|
||||
- keep validating Thai text metrics against designer output
|
||||
- remove fallback normalization only after render parity is proven stable
|
||||
|
||||
## After Task H
|
||||
|
||||
### Font Render Parity
|
||||
`pdfme` generation currently falls back from `cordia/cordiaBold` to standard fonts when TTC-backed runtime rendering is not reliable.
|
||||
### Local filesystem storage
|
||||
Approved PDFs currently persist under `public/generated/quotations/<organizationId>/`.
|
||||
|
||||
Future:
|
||||
- package or vendor the exact Cordia font assets in a generator-friendly format
|
||||
- remove fallback normalization
|
||||
- verify Thai text metrics against the original designer output
|
||||
- replace local public storage for production with object storage
|
||||
- add signed/private delivery where required
|
||||
- define backup and cleanup expectations
|
||||
|
||||
### Local PDF Storage
|
||||
Approved PDFs currently persist to local `public/generated/...` paths.
|
||||
### Approved artifact immutability
|
||||
Approved PDF persistence exists, but the lifecycle is not immutable by policy yet.
|
||||
|
||||
Future:
|
||||
- object storage provider abstraction
|
||||
- signed/private delivery strategy
|
||||
- retention and regeneration policy
|
||||
- define whether regeneration is allowed after approval
|
||||
- version approved artifacts explicitly if regeneration must remain possible
|
||||
- document which snapshot fields are contractual records
|
||||
|
||||
### Post-Approval Automation
|
||||
### Post-approval automation
|
||||
Approved PDF generation is still manual by design.
|
||||
|
||||
Future:
|
||||
- optional auto-generate hook after final approval
|
||||
- retry-safe job queue for PDF generation
|
||||
- add a non-blocking auto-generation hook after final approval
|
||||
- move heavy generation/retry behavior to a background job when needed
|
||||
|
||||
## After Task G
|
||||
### PDF pipeline test coverage
|
||||
Task H.1 added dev fixture and HTTP verification scripts, but there is still no CI-backed E2E coverage for the PDF pipeline.
|
||||
|
||||
### Template Mapping Editor
|
||||
Mapping CRUD UI ยังไม่มี
|
||||
Future: ทำ mapping editor สำหรับ admin
|
||||
|
||||
### Canvas-Accurate PDF Preview
|
||||
Preview ปัจจุบันเป็น native app preview ไม่ใช่ pdfme canvas rendering
|
||||
Future: เพิ่ม pdfme renderer preview
|
||||
|
||||
### Product-Specific Template Rule
|
||||
ตอนนี้ใช้ productType = default
|
||||
Future: define rule สำหรับ crane/dockdoor/solarcell
|
||||
|
||||
### PDF Binary Generation
|
||||
ยังไม่มี generate/download/store PDF
|
||||
Future: Task H
|
||||
Future:
|
||||
- promote fixture verification into automated test coverage
|
||||
- add regression checks for template mappings, storage persistence, and permission enforcement
|
||||
|
||||
Reference in New Issue
Block a user