Files
alla-allaos-fullstack/plans/hotfix-1-customer.md
2026-06-18 08:58:01 +07:00

327 lines
5.9 KiB
Markdown

# Hotfix: Add Customer Sub Group to Customer Form
## Goal
เพิ่ม field `Customer Sub Group` ในหน้า Add / Edit Customer
โดยใช้ master option category:
```txt
crm_customer_sub_group
```
และต้อง filter ตาม `Customer Group` ที่เลือก
Relationship:
```txt
crm_customer_group
↓ parent
crm_customer_sub_group
```
---
## Must Read
```txt
src/features/crm/customers/**
src/features/foundation/master-options/**
src/app/api/foundation/master-options/route.ts
src/db/schema.ts
src/db/seeds/foundation.seed.ts
```
---
## Scope 1: Data Model Check
ตรวจสอบว่า customer schema มี field สำหรับ sub group แล้วหรือยัง
Expected field:
```txt
customerSubGroup
```
หรือถ้าใช้ naming เดิม:
```txt
custSubGroup
```
Rules:
* ถ้ามี field อยู่แล้ว ให้ reuse
* ถ้ายังไม่มี ให้เพิ่ม field ใหม่แบบไม่กระทบข้อมูลเดิม
* field เป็น optional
* เก็บเป็น master option code/value ตาม pattern เดิมของ customerGroup
---
## Scope 2: Master Option Category
เพิ่ม/ยืนยัน category:
```txt
crm_customer_sub_group
```
Sub group ต้องมี parent relationship กับ group:
```txt
crm_customer_group.id
crm_customer_sub_group.parentId
```
Rules:
* parentId ต้องชี้ไป customer group option
* sub group dropdown ต้อง filter ด้วย parentId
* ถ้ายังไม่ได้เลือก customer group ให้ disable sub group dropdown
---
## Scope 3: Seed Data
อัปเดต:
```txt
src/db/seeds/foundation.seed.ts
```
เพิ่ม seed category:
```txt
crm_customer_group
crm_customer_sub_group
```
ตัวอย่าง:
```txt
crm_customer_group:
- industrial
- construction
- government
- dealer
- other
crm_customer_sub_group:
- factory
- warehouse
- logistics
- contractor
- consultant
- state_enterprise
- government_agency
- reseller
- other
```
Relationship ตัวอย่าง:
```txt
industrial
- factory
- warehouse
- logistics
construction
- contractor
- consultant
government
- state_enterprise
- government_agency
dealer
- reseller
other
- other
```
Rules:
* seed idempotent
* no hardcoded organizationId
* parent option must be created before child options
* child options must set parentId
* do not duplicate options if seed runs again
---
## Scope 4: Customer Schema / Zod
Update:
```txt
src/features/crm/customers/schemas/customer.schema.ts
```
Add:
```ts
customerSubGroup: z.string().optional().nullable()
```
หรือใช้ field name ที่มีอยู่จริง เช่น:
```ts
custSubGroup: z.string().optional().nullable()
```
Rules:
* Create Customer ต้องรับ field นี้ได้
* Edit Customer ต้อง load ค่าเดิมได้
* ถ้าเปลี่ยน customerGroup แล้ว customerSubGroup ไม่อยู่ใต้ parent ใหม่ ให้ clear ค่า customerSubGroup
---
## Scope 5: API / Server Service
Update:
```txt
src/features/crm/customers/server/service.ts
src/app/api/crm/customers/route.ts
src/app/api/crm/customers/[id]/route.ts
src/features/crm/customers/api/types.ts
```
Rules:
* create customer save customerSubGroup
* update customer save customerSubGroup
* list/detail return customerSubGroup
* validate sub group parent matches selected group ถ้าทำได้ง่าย
* if invalid parent-child relation, return user-safe error
---
## Scope 6: Customer Form UI
Update:
```txt
src/features/crm/customers/components/customer-form-sheet.tsx
```
Add field:
```txt
Customer Group
Customer Sub Group
```
Behavior:
* Customer Group dropdown uses `crm_customer_group`
* Customer Sub Group dropdown uses `crm_customer_sub_group`
* Customer Sub Group filtered by selected group option `parentId`
* If no Customer Group selected:
* disable Customer Sub Group
* placeholder: "Select customer group first"
* If Customer Group changes:
* reset Customer Sub Group
* If edit mode:
* load existing Customer Group
* load filtered Customer Sub Group
* selected value must display correctly
---
## Scope 7: Customer List / Detail
Update if relevant:
```txt
src/features/crm/customers/components/customer-columns.tsx
src/features/crm/customers/components/customer-detail.tsx
```
Display:
```txt
Customer Group
Customer Sub Group
```
If label lookup is available, show label instead of raw code.
---
## Scope 8: Query Freshness
After create/update:
* invalidate customer list
* invalidate customer detail
* form closes after success
* table/detail show new customer sub group immediately
Follow existing CRUD freshness rule.
---
## Scope 9: Regression Check
Verify:
* create customer with group + sub group
* create customer without sub group
* edit customer group changes and sub group resets
* edit customer retains valid sub group
* invalid sub group under another group is rejected or cleared
* customer list/detail displays value
---
## Explicit Non-Scope
Do NOT implement:
```txt
Customer group management UI
Inline create master option
Large RBAC rewrite
Customer import/export
Dashboard changes
Report changes
```
---
## Output
After completion, summarize:
1. Files Added
2. Files Modified
3. Schema Field Used/Added
4. Master Options Seeded
5. Form Behavior Added
6. Parent/Child Filtering Behavior
7. Validation Added
8. Verification Result
9. Remaining Risks
---
## Definition of Done
* Add/Edit Customer has Customer Sub Group field
* Customer Sub Group uses `crm_customer_sub_group`
* Sub Group filters by selected Customer Group parent
* Changing Customer Group resets invalid Sub Group
* Create customer saves Sub Group
* Edit customer saves Sub Group
* Detail/list can show Sub Group
* Mutation refreshes customer table/detail