327 lines
5.9 KiB
Markdown
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
|