410 lines
7.3 KiB
Markdown
410 lines
7.3 KiB
Markdown
# Task D: Enquiry Production Module
|
|
|
|
## ALLA OS CRM vNext
|
|
|
|
คุณคือ Senior Full-stack Engineer
|
|
ให้ implement Enquiry production module โดยต่อยอดจาก Task A, B, B.1, C
|
|
|
|
## ต้องอ่านก่อน
|
|
|
|
```txt
|
|
docs/implementation/task-a-template-audit.md
|
|
docs/implementation/task-b-template-audit.md
|
|
docs/implementation/task-b1-foundation-stabilization.md
|
|
|
|
Layout.md
|
|
AGENTS.md
|
|
.agents/skills/kiranism-shadcn-dashboard
|
|
|
|
src/db/schema.ts
|
|
src/features/foundation/**
|
|
src/features/crm/customers/**
|
|
src/app/dashboard/crm/**
|
|
```
|
|
|
|
## เป้าหมาย
|
|
|
|
สร้าง production module สำหรับ:
|
|
|
|
```txt
|
|
Enquiry
|
|
Enquiry Follow-up / Activity
|
|
Customer + Contact linkage
|
|
```
|
|
|
|
ยังไม่ทำ:
|
|
|
|
```txt
|
|
Quotation production
|
|
Approval production
|
|
PDF Generator
|
|
Report
|
|
Dashboard KPI จริง
|
|
```
|
|
|
|
## Core Rules
|
|
|
|
```txt
|
|
organizationId = tenant boundary
|
|
branchId = business sub-scope
|
|
```
|
|
|
|
ทุก enquiry ต้องมี `organizationId`
|
|
|
|
`branchId` ใช้เป็น optional business/document scope
|
|
|
|
ห้ามใช้ mock CRM service
|
|
|
|
ห้าม import จาก:
|
|
|
|
```txt
|
|
src/features/crm-demo/**
|
|
src/constants/mock-api*
|
|
```
|
|
|
|
## Business Flow
|
|
|
|
Enquiry คือ Sales Opportunity ก่อนออกใบเสนอราคา
|
|
|
|
```txt
|
|
Customer
|
|
└─ Contact
|
|
└─ Enquiry
|
|
└─ Quotation ใน Task ถัดไป
|
|
```
|
|
|
|
1 Customer มีหลาย Enquiry ได้
|
|
1 Enquiry อ้างอิง Contact ได้
|
|
1 Enquiry ต่อไปจะมีหลาย Quotation ได้ แต่ Task D ยังไม่ต้องสร้าง Quotation
|
|
|
|
## Scope D1: Enquiry Schema
|
|
|
|
เพิ่ม production schema ใน `src/db/schema.ts`
|
|
|
|
ตารางหลัก:
|
|
|
|
```txt
|
|
crm_enquiries
|
|
```
|
|
|
|
Fields ขั้นต่ำ:
|
|
|
|
```txt
|
|
id
|
|
organizationId
|
|
branchId
|
|
code
|
|
|
|
customerId
|
|
contactId
|
|
|
|
title
|
|
description
|
|
requirement
|
|
projectName
|
|
projectLocation
|
|
|
|
productType
|
|
status
|
|
priority
|
|
leadChannel
|
|
|
|
estimatedValue
|
|
chancePercent
|
|
expectedCloseDate
|
|
|
|
competitor
|
|
source
|
|
notes
|
|
|
|
isHotProject
|
|
isActive
|
|
|
|
createdAt
|
|
updatedAt
|
|
deletedAt
|
|
createdBy
|
|
updatedBy
|
|
```
|
|
|
|
Rules:
|
|
|
|
* `organizationId` required
|
|
* `customerId` required
|
|
* `contactId` optional
|
|
* `code` unique ภายใน organization
|
|
* `status`, `productType`, `priority`, `leadChannel` ใช้ master options
|
|
* code ใช้ document sequence `enquiry -> ENQ`
|
|
* create/update/delete ต้อง audit log
|
|
* ห้ามสร้าง quotation table ใน Task D
|
|
|
|
## Scope D2: Enquiry Follow-up Schema
|
|
|
|
เพิ่ม table:
|
|
|
|
```txt
|
|
crm_enquiry_followups
|
|
```
|
|
|
|
Fields ขั้นต่ำ:
|
|
|
|
```txt
|
|
id
|
|
organizationId
|
|
enquiryId
|
|
followupDate
|
|
followupType
|
|
contactId
|
|
outcome
|
|
notes
|
|
nextFollowupDate
|
|
nextAction
|
|
createdAt
|
|
updatedAt
|
|
deletedAt
|
|
createdBy
|
|
updatedBy
|
|
```
|
|
|
|
Rules:
|
|
|
|
* follow-up ต้องอยู่ใน organization เดียวกับ enquiry
|
|
* mutation ต้อง audit
|
|
* ใช้สำหรับ activity timeline ของ enquiry
|
|
|
|
## Scope D3: Enquiry API
|
|
|
|
สร้าง route handlers:
|
|
|
|
```txt
|
|
src/app/api/crm/enquiries/route.ts
|
|
src/app/api/crm/enquiries/[id]/route.ts
|
|
src/app/api/crm/enquiries/[id]/followups/route.ts
|
|
src/app/api/crm/enquiries/[id]/followups/[followupId]/route.ts
|
|
```
|
|
|
|
รองรับ:
|
|
|
|
```txt
|
|
GET list
|
|
POST create
|
|
GET detail
|
|
PATCH update
|
|
DELETE soft delete
|
|
|
|
GET followups
|
|
POST followup
|
|
PATCH followup
|
|
DELETE followup
|
|
```
|
|
|
|
Rules:
|
|
|
|
* ใช้ `requireOrganizationAccess`
|
|
* ใช้ permission helper
|
|
* filter ด้วย organizationId เสมอ
|
|
* customer/contact ต้องอยู่ใน organization เดียวกัน
|
|
* create enquiry ต้อง generate code
|
|
* ทุก mutation ต้อง audit
|
|
|
|
Permissions แนะนำ:
|
|
|
|
```txt
|
|
crm.enquiry.read
|
|
crm.enquiry.create
|
|
crm.enquiry.update
|
|
crm.enquiry.delete
|
|
crm.enquiry.followup.read
|
|
crm.enquiry.followup.create
|
|
crm.enquiry.followup.update
|
|
crm.enquiry.followup.delete
|
|
```
|
|
|
|
## Scope D4: Enquiry Feature Layer
|
|
|
|
สร้าง:
|
|
|
|
```txt
|
|
src/features/crm/enquiries/api/types.ts
|
|
src/features/crm/enquiries/api/service.ts
|
|
src/features/crm/enquiries/api/queries.ts
|
|
src/features/crm/enquiries/api/mutations.ts
|
|
src/features/crm/enquiries/schemas/enquiry.schema.ts
|
|
src/features/crm/enquiries/server/service.ts
|
|
src/features/crm/enquiries/components/**
|
|
```
|
|
|
|
ใช้ pattern จาก:
|
|
|
|
```txt
|
|
src/features/products/**
|
|
src/features/users/**
|
|
src/features/crm/customers/**
|
|
```
|
|
|
|
## Scope D5: Enquiry UI
|
|
|
|
แทน placeholder routes:
|
|
|
|
```txt
|
|
/dashboard/crm/enquiries
|
|
/dashboard/crm/enquiries/[id]
|
|
```
|
|
|
|
List page ต้องมี:
|
|
|
|
```txt
|
|
PageContainer
|
|
DataTable
|
|
search
|
|
status filter
|
|
product type filter
|
|
priority filter
|
|
branch filter
|
|
customer filter
|
|
create button
|
|
edit action
|
|
view action
|
|
soft delete action
|
|
```
|
|
|
|
Detail page ใช้ Layout.md Template A
|
|
|
|
Tabs:
|
|
|
|
```txt
|
|
Overview
|
|
Follow-ups
|
|
Activity
|
|
Related Quotations Placeholder
|
|
```
|
|
|
|
## Scope D6: Enquiry Form
|
|
|
|
ใช้:
|
|
|
|
```txt
|
|
useAppForm
|
|
Zod
|
|
Sheet/Dialog pattern
|
|
React Query mutation
|
|
```
|
|
|
|
Create/Edit fields:
|
|
|
|
```txt
|
|
customerId
|
|
contactId
|
|
title
|
|
description
|
|
requirement
|
|
projectName
|
|
projectLocation
|
|
branchId
|
|
productType
|
|
status
|
|
priority
|
|
leadChannel
|
|
estimatedValue
|
|
chancePercent
|
|
expectedCloseDate
|
|
competitor
|
|
source
|
|
isHotProject
|
|
notes
|
|
```
|
|
|
|
Rules:
|
|
|
|
* customer dropdown ดึงจาก production customer API
|
|
* contact dropdown filter ตาม customer ที่เลือก
|
|
* status/productType/priority/leadChannel ดึงจาก master options
|
|
* branch ดึงจาก branch scope/master options
|
|
* ห้าม hardcode option ใน form
|
|
|
|
## Scope D7: Follow-up UI
|
|
|
|
ใน Enquiry Detail tab: Follow-ups
|
|
|
|
ต้องมี:
|
|
|
|
```txt
|
|
followup list
|
|
create followup
|
|
edit followup
|
|
delete followup
|
|
next followup date
|
|
next action
|
|
outcome
|
|
```
|
|
|
|
ใช้ Sheet/Dialog pattern
|
|
|
|
## Scope D8: Activity Timeline
|
|
|
|
ใน Enquiry Detail เพิ่ม Activity tab
|
|
|
|
อ่าน audit log จาก `tr_audit_logs`
|
|
|
|
ใช้:
|
|
|
|
```txt
|
|
entityType = crm_enquiry
|
|
entityId = enquiry.id
|
|
```
|
|
|
|
และ follow-up audit ถ้าเหมาะสม
|
|
|
|
## Scope D9: Customer Detail Integration
|
|
|
|
ใน Customer Detail page เพิ่ม section/tab หรือ related placeholder ให้เห็น Enquiry ที่เกี่ยวข้องกับ customer
|
|
|
|
ยังไม่ต้องทำ dashboard KPI
|
|
|
|
## ห้ามทำใน Task D
|
|
|
|
```txt
|
|
Quotation schema
|
|
Quotation API
|
|
Approval schema
|
|
Approval workflow
|
|
PDF generation
|
|
Report
|
|
Dashboard KPI จริง
|
|
Notification
|
|
```
|
|
|
|
## Output หลังทำเสร็จ
|
|
|
|
สรุป:
|
|
|
|
1. Files Added
|
|
2. Files Modified
|
|
3. Schema Added
|
|
4. API Routes Added
|
|
5. UI Routes Completed
|
|
6. Permissions Used
|
|
7. Audit Integration
|
|
8. Document Sequence Integration
|
|
9. Customer/Contact Integration
|
|
10. Remaining Risks
|
|
11. Task E Readiness
|
|
|
|
## Definition of Done
|
|
|
|
Task D ผ่านเมื่อ:
|
|
|
|
* Enquiry schema พร้อม
|
|
* Enquiry follow-up schema พร้อม
|
|
* Enquiry list ใช้ production data
|
|
* Enquiry detail ใช้ production data
|
|
* Enquiry create/edit/delete ใช้งานได้
|
|
* Follow-up create/edit/delete ใช้งานได้
|
|
* ใช้ organizationId ทุก query
|
|
* customer/contact ต้องอยู่ organization เดียวกัน
|
|
* ใช้ master options ใน status/productType/priority/leadChannel
|
|
* ใช้ document sequence ตอนสร้าง enquiry
|
|
* ใช้ audit log ทุก mutation
|
|
* ไม่ import mock CRM
|
|
* ไม่ทำ Quotation/Approval
|