Files
alla-allaos-fullstack/docs/implementation/task-d1-enquiry-assignment-role-stabilization.md
phaichayon 0a484e0b45 task-i
2026-06-16 17:01:29 +07:00

3.7 KiB

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:

{
  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