task-h.1 complate

This commit is contained in:
phaichayon
2026-06-16 14:25:26 +07:00
parent edee45375e
commit 9ae41e4f2c
14 changed files with 2238 additions and 201 deletions

251
plans/task-d.1.md Normal file
View File

@@ -0,0 +1,251 @@
# Task D.1: Enquiry Assignment + CRM Role Permission Stabilization
## Goal
เพิ่มระบบ Assign Sales ให้ Enquiry และปรับ Role/Permission ให้รองรับ ALLA OS CRM ไม่ใช่เฉพาะ IT-CENTER template
## Must Read
```txt
docs/implementation/task-a-template-audit.md
docs/implementation/task-b-template-audit.md
docs/implementation/task-b1-foundation-stabilization.md
src/features/crm/enquiries/**
src/features/crm/customers/**
src/features/foundation/**
src/lib/auth/rbac.ts
src/db/schema.ts
src/db/seeds/foundation.seed.ts
```
## Scope 1: Audit Current Enquiry Assignment
ตรวจสอบว่า `crm_enquiries` มี field เหล่านี้หรือยัง:
```txt
assignedToUserId
assignedAt
assignedBy
assignmentRemark
```
ตรวจสอบ UI:
```txt
Assign Sales
Reassign Sales
My Enquiries
Assigned Enquiries
```
ตรวจสอบ permission:
```txt
crm.enquiry.assign
crm.enquiry.reassign
```
ถ้าไม่มี ให้ implement ตาม scope ถัดไป
## Scope 2: Schema
เพิ่ม field ใน `crm_enquiries`:
```txt
assignedToUserId
assignedAt
assignedBy
assignmentRemark
```
Rules:
* assignedToUserId อ้างถึง user ใน organization เดียวกัน
* assignedBy คือ current user
* assignedAt คือเวลาที่ assign ล่าสุด
* assignmentRemark optional
* soft delete ไม่เกี่ยวกับ assignment
## Scope 3: API
เพิ่ม route:
```txt
POST /api/crm/enquiries/[id]/assign
POST /api/crm/enquiries/[id]/reassign
```
Payload:
```ts
{
assignedToUserId: string
remark?: string
}
```
Rules:
* ต้อง require organization access
* ต้อง validate assignee อยู่ใน organization เดียวกัน
* assign/reassign ต้อง audit
* assign ครั้งแรกใช้ action = assign
* เปลี่ยนคนใช้ action = reassign
## Scope 4: Permission
เพิ่ม permission:
```txt
crm.enquiry.assign
crm.enquiry.reassign
```
Role recommendation:
```txt
super_admin: all permissions
organization_admin: all crm permissions
sales_manager: read/create/update/assign/reassign enquiry
sales: read/create/update own/assigned enquiry
sales_support: read/create/update enquiry
viewer: read only
```
อย่า hardcode เฉพาะ IT-CENTER roles
## Scope 5: UI
ใน Enquiry Detail เพิ่ม action:
```txt
Assign Sales
Reassign Sales
```
แสดงเมื่อ:
```txt
user has crm.enquiry.assign หรือ crm.enquiry.reassign
```
แสดงข้อมูล:
```txt
Assigned Sales
Assigned At
Assigned By
Assignment Remark
```
ใน Enquiry List เพิ่ม column:
```txt
Assigned Sales
```
## Scope 6: Form
ใช้ Sheet/Dialog pattern
Field:
```txt
Sales User
Remark
```
Sales User dropdown ต้องดึงจาก users/memberships ใน organization ปัจจุบัน
ห้าม hardcode user
## Scope 7: Audit
Audit entity:
```txt
crm_enquiry
```
Actions:
```txt
assign
reassign
```
beforeData:
```txt
oldAssignedToUserId
```
afterData:
```txt
newAssignedToUserId
remark
```
## Scope 8: Membership/Permission Stabilization
ตรวจ Workspace Membership UI ว่ายังเป็น IT-CENTER template อยู่หรือไม่
ถ้ายังเป็น IT-CENTER ให้เพิ่ม CRM permissions เข้าไปก่อน โดยไม่ลบของเดิมทันที
เพิ่ม permission groups:
```txt
crm.customer.*
crm.contact.*
crm.enquiry.*
crm.quotation.*
crm.approval.*
crm.document_template.*
```
อย่างน้อยต้องมี:
```txt
crm.enquiry.read
crm.enquiry.create
crm.enquiry.update
crm.enquiry.delete
crm.enquiry.assign
crm.enquiry.reassign
```
## ห้ามทำ
```txt
Quotation assignment
Approval assignment
Notification
Dashboard KPI
Report
Major RBAC rewrite
```
## Output
สรุป:
1. Files Added
2. Files Modified
3. Schema Added
4. API Routes Added
5. Permissions Added
6. UI Added
7. Audit Integration
8. Remaining Risks
## Definition of Done
* Enquiry assign sales ได้
* Reassign sales ได้
* Enquiry list แสดง assigned sales
* Enquiry detail แสดง assigned sales
* Permission guard ทำงาน
* super_admin เห็นปุ่ม assign
* audit log ถูกสร้าง
* ไม่กระทบ Customer/Quotation/Approval

302
plans/task-h.1.md Normal file
View File

@@ -0,0 +1,302 @@
# Task H.1: PDF Generation Stabilization
## Goal
Stabilize Task H PDF generation before starting Task I.
Task H already added:
* pdfme server-side generation
* preview/download PDF APIs
* approved PDF generation
* approved snapshot persistence
* approved PDF attachment metadata
* quotation detail PDF actions
Task H.1 focuses on validation, hardening, and documentation.
---
## Must Read
```txt
docs/implementation/technical-debt.md
docs/adr/0008-attachment-storage-strategy.md
src/features/foundation/pdf-generator/**
src/features/foundation/document-template/**
src/features/crm/quotations/document/**
src/features/crm/quotations/**
src/features/foundation/approval/**
src/app/api/crm/quotations/[id]/pdf-preview/route.ts
src/app/api/crm/quotations/[id]/pdf-download/route.ts
src/app/api/crm/quotations/[id]/approved-pdf/route.ts
src/db/schema.ts
```
---
## Scope 1: Smoke Test With Real Quotation
Create or identify one real quotation record in dev database.
The record must include:
```txt
customer
contact
enquiry optional
at least one item
quotation customer role
scope topic
exclusion topic
payment topic
approved status or approval flow completed
```
Then verify:
```txt
Preview PDF
Download PDF
Generate Approved PDF
View Approved PDF
```
If no real record exists, create a minimal seed/dev fixture.
Rules:
* dev fixture must be organization-scoped
* do not hardcode organizationId
* do not pollute production seed
* place fixture under dev-only seed or clearly named script
---
## Scope 2: PDF Output Validation
Check generated PDF for:
```txt
file opens correctly
page count is reasonable
customer block appears
quotation code appears
item table appears
total amount appears
scope/exclusion/payment appears
approval block appears
signature placeholder appears
```
If layout breaks:
* adjust mapping normalization
* adjust template input preparation
* do not rewrite template designer
* do not hardcode quotation-specific hacks into generic pdf generator
---
## Scope 3: Approved PDF API Validation
Validate:
```txt
GET /api/crm/quotations/[id]/pdf-preview
GET /api/crm/quotations/[id]/pdf-download
POST /api/crm/quotations/[id]/approved-pdf
GET /api/crm/quotations/[id]/approved-pdf
```
Expected behavior:
* preview returns inline PDF
* download returns attachment PDF
* approved-pdf POST only works for approved quotation
* approved-pdf GET returns stored file if available
* non-approved quotation cannot generate approved PDF
---
## Scope 4: Persistence Validation
After approved PDF generation verify:
```txt
quotation.approvedPdfUrl populated
quotation.approvedSnapshot populated
quotation.approvedTemplateVersionId populated
quotation attachment metadata created or updated
audit log generated
file exists in public/generated/quotations/<organizationId>/
```
If any part is missing, fix only the persistence pipeline.
---
## Scope 5: Permission Validation
Verify permissions:
```txt
crm.quotation.pdf.preview
crm.quotation.pdf.download
crm.quotation.pdf.generate_approved
```
Check behavior for:
```txt
super_admin
admin
regular user with permission
regular user without permission
```
Do not rewrite RBAC model.
---
## Scope 6: Error Handling
Improve user-safe/server-safe errors for:
```txt
template not found
template version not found
mapping missing
quotation not approved
generated file missing
pdfme generation error
local storage write error
permission denied
```
Rules:
* API must return meaningful status codes
* UI should show readable toast/message
* do not expose stack trace to client
---
## Scope 7: Documentation / ADR
Update:
```txt
docs/implementation/technical-debt.md
```
Confirm or add:
```txt
pdfme font fallback workaround
local filesystem storage limitation
missing object storage abstraction
approved PDF lifecycle not immutable yet
no full E2E test in CI yet
```
Create ADR if not exists:
```txt
docs/adr/0009-approved-document-storage-lifecycle.md
```
Include:
```txt
Current:
local public/generated storage
Decision:
acceptable for development/MVP only
Future:
object storage abstraction
signed URL
immutable approved artifacts
retention policy
```
---
## Scope 8: Optional Small Fix
If approval finalization already has a clean hook point, add a non-blocking TODO or optional manual trigger note for:
```txt
auto-generate approved PDF after final approval
```
Do not force automatic generation in Task H.1 if it risks breaking approval flow.
---
## ห้ามทำ
```txt
object storage production
signed URL service
template designer
mapping editor
email notification
report
dashboard KPI
large refactor
```
---
## Output
After completion, summarize:
1. Files Added
2. Files Modified
3. Smoke Test Record Used
4. PDF APIs Verified
5. Persistence Verified
6. Permission Verified
7. Error Handling Improved
8. ADR / Technical Debt Updated
9. Remaining Risks
10. Task I Readiness
---
## Definition of Done
Task H.1 passes when:
✔ PDF preview works with a real quotation
✔ PDF download works with a real quotation
✔ Approved PDF generation works for approved quotation
✔ Approved PDF GET returns stored PDF
✔ Non-approved quotation cannot generate approved PDF
✔ approvedSnapshot is saved
✔ approvedPdfUrl is saved
✔ approvedTemplateVersionId is saved
✔ attachment metadata is created/updated
✔ audit log exists for approved PDF generation
✔ permissions are enforced
✔ errors are user-safe
✔ storage lifecycle ADR exists
✔ ready for Task I