This commit is contained in:
phaichayon
2026-06-16 17:01:29 +07:00
parent 90ee59d388
commit 0a484e0b45
28 changed files with 6483 additions and 277 deletions

View File

@@ -0,0 +1,144 @@
# Task D.1: Enquiry Assignment and CRM Role Stabilization
## 1. Files Added
- `src/app/api/crm/enquiries/[id]/_schemas.ts`
- `src/app/api/crm/enquiries/[id]/assign/route.ts`
- `src/app/api/crm/enquiries/[id]/reassign/route.ts`
- `src/features/crm/enquiries/components/enquiry-assignment-dialog.tsx`
- `drizzle/0008_clean_justin_hammer.sql`
- `drizzle/meta/0008_snapshot.json`
## 2. Files Modified
- `src/db/schema.ts`
- `src/lib/auth/rbac.ts`
- `src/app/dashboard/crm/enquiries/page.tsx`
- `src/app/dashboard/crm/enquiries/[id]/page.tsx`
- `src/features/crm/enquiries/api/types.ts`
- `src/features/crm/enquiries/api/service.ts`
- `src/features/crm/enquiries/api/mutations.ts`
- `src/features/crm/enquiries/server/service.ts`
- `src/features/crm/enquiries/components/enquiry-columns.tsx`
- `src/features/crm/enquiries/components/enquiries-table.tsx`
- `src/features/crm/enquiries/components/enquiry-listing.tsx`
- `src/features/crm/enquiries/components/enquiry-detail.tsx`
- `src/features/crm/enquiries/components/enquiry-cell-action.tsx`
- `src/features/users/api/types.ts`
- `src/features/users/schemas/user.ts`
- `src/features/users/components/user-form-sheet.tsx`
- `src/app/api/users/_lib.ts`
- `src/app/api/users/route.ts`
- `src/app/api/organizations/route.ts`
- `src/features/foundation/auth-context/service.ts`
## 3. Schema Added
Added assignment fields to `crm_enquiries`:
- `assigned_to_user_id`
- `assigned_at`
- `assigned_by`
- `assignment_remark`
Rules implemented:
- assignee must belong to the same organization
- assigner is the current user
- latest assignment timestamp is persisted
- assignment remark is optional
## 4. API Routes Added
- `POST /api/crm/enquiries/[id]/assign`
- `POST /api/crm/enquiries/[id]/reassign`
Payload:
```ts
{
assignedToUserId: string;
remark?: string;
}
```
Behavior:
- requires organization access
- enforces `crm.enquiry.assign` or `crm.enquiry.reassign`
- validates assignee organization membership
- rejects assign on already-assigned enquiry
- rejects reassign on unassigned enquiry
## 5. Permissions Added
- `crm.enquiry.assign`
- `crm.enquiry.reassign`
CRM business-role set was also stabilized around:
- `sales_manager`
- `sales`
- `sales_support`
- `department_manager`
- `top_manager`
Legacy IT-CENTER business roles were removed from active runtime paths and defaults.
## 6. UI Added
Enquiry detail now supports:
- `Assign Sales`
- `Reassign Sales`
- assigned sales metadata display
Enquiry list now shows:
- `Assigned Sales` column
Assignment dialog now includes:
- `Sales User`
- `Remark`
The sales-user dropdown is populated from organization memberships instead of hardcoded values.
## 7. Audit Integration
Assignment writes audit logs under:
- `entityType = crm_enquiry`
Actions added:
- `assign`
- `reassign`
Audit payload shape:
- `beforeData.oldAssignedToUserId`
- `afterData.newAssignedToUserId`
- `afterData.remark`
## 8. Membership / Permission Stabilization
Workspace membership management now uses CRM-aligned business roles instead of the old template roles.
Updated areas:
- user API types and validation
- membership defaults
- organization-management fallbacks
- auth-context business-role fallback
## 9. Remaining Risks
- current `sales` access still operates at organization scope; there is not yet a server-enforced “own or assigned only” data policy
- old database rows that still carry removed legacy business-role strings may need a one-time data backfill if they exist in a real environment
- assignable-user filtering currently accepts organization admins plus sales-oriented roles; if future CRM staffing rules become stricter, that policy should move into a dedicated assignment rule layer
## 10. Verification
- `npx tsc --noEmit`
- `npx oxlint` on changed Task D.1 files