145 lines
3.7 KiB
Markdown
145 lines
3.7 KiB
Markdown
# 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
|