# Task L.1: CRM Multi-Role User Assignment & Scope Management

## Objective

Extend Task L authorization foundation so one user can hold multiple CRM role profiles within the same organization.

Business decision:

```txt
1 User = Many CRM Roles
```

Examples:

```txt
Sales Manager + Sales
CRM Admin + Department Manager
Sales Support + Marketing
```

This task adds role assignment persistence, assignment UI, and updates effective CRM access resolution.

---

# Background

Task L introduced:

```txt
crmRoleProfiles
memberships.branchScopeIds
memberships.productTypeScopeIds
resolved CRM access helper
CRM Settings > Roles
```

Current limitation:

```txt
membership.businessRole = single role
```

This is not enough for real business operation.

Task L.1 moves CRM role assignment into a dedicated model while keeping membership as organization access.

---

# Target Model

Membership remains organization-level access:

```txt
memberships
- userId
- organizationId
- role
- permissions
```

CRM role assignments become CRM-specific authorization rows:

```txt
crm_user_role_assignments
- id
- organizationId
- userId
- roleProfileId
- branchScopeMode
- branchScopeIds
- productTypeScopeMode
- productTypeScopeIds
- isPrimary
- isActive
- assignedBy
- assignedAt
- createdAt
- updatedAt
- deletedAt
```

---

# Scope L1.1 Schema

Add table:

```txt
crm_user_role_assignments
```

Fields:

```txt
id
organizationId
userId
roleProfileId

branchScopeMode
branchScopeIds

productTypeScopeMode
productTypeScopeIds

isPrimary
isActive

assignedBy
assignedAt

createdAt
updatedAt
deletedAt
```

Recommended scope modes:

```txt
all
selected
none
inherit
```

Unique constraint:

```txt
organizationId + userId + roleProfileId
```

Rules:

* one user can have many role profiles
* same role profile cannot be duplicated for the same user/org
* only one primary CRM role per user/org
* soft delete supported
* old `membership.businessRole` remains temporarily for compatibility

---

# Scope L1.2 Migration / Backfill

Backfill existing users.

For each membership:

```txt
membership.businessRole
```

create one CRM role assignment matching the role profile.

Rules:

* if businessRole has a matching `crmRoleProfiles.code`, create assignment
* if no matching role profile exists, skip and log warning
* set `isPrimary = true`
* branch/product scope from membership fields if available
* idempotent migration
* no duplicate assignments

---

# Scope L1.3 Effective CRM Access Resolver

Update resolved access helper.

Old:

```txt
membership.businessRole
+
membership.permissions
+
roleProfile.permissions
```

New:

```txt
membership
+
all active crm_user_role_assignments
+
all assigned crmRoleProfiles
+
direct membership.permissions
```

Permission behavior:

```txt
effectivePermissions = union(all roleProfile.permissions, membership.permissions)
```

Ownership behavior:

Use most permissive access among active role profiles:

```txt
own
team
branch
organization
all
```

Branch scope behavior:

```txt
if any role has all -> all
else union selected branchScopeIds
else none
```

Product type scope behavior:

```txt
if any role has all -> all
else union selected productTypeScopeIds
else none
```

Approval authority:

```txt
effectiveApprovalAuthority = union(all roleProfile.approvalAuthority)
```

Primary role:

```txt
used for display only
not permission limit
```

---

# Scope L1.4 User Assignment UI

Add page or tab:

```txt
CRM Settings
└─ User Role Assignments
```

or add tab inside existing user detail:

```txt
Users
└─ CRM Roles
```

Recommended UI:

```txt
User
Assigned CRM Roles
Branch Scope
Product Type Scope
Primary Role
Status
Actions
```

Actions:

```txt
Assign Role
Edit Scope
Set Primary
Deactivate Assignment
Reactivate Assignment
Remove Assignment
```

---

# Scope L1.5 Assignment Form

Fields:

```txt
User
Role Profile
Branch Scope Mode
Branches
Product Type Scope Mode
Product Types
Primary
Active
```

Behavior:

* role profile dropdown from active `crmRoleProfiles`
* branch options from `crm_branch`
* product type options from `crm_product_type`
* if scope mode = all, disable selected list
* if scope mode = selected, require at least one selected option
* if primary = true, unset other primary role assignments for same user/org

---

# Scope L1.6 API Routes

Add:

```txt
GET    /api/crm/settings/user-role-assignments
POST   /api/crm/settings/user-role-assignments
PATCH  /api/crm/settings/user-role-assignments/[id]
DELETE /api/crm/settings/user-role-assignments/[id]
```

Optional:

```txt
GET /api/crm/settings/users/[userId]/role-assignments
```

All APIs must:

```txt
requireOrganizationAccess
requirePermission("crm.role.assignment.manage")
filter by organizationId
audit mutations
return user-safe errors
```

---

# Scope L1.7 Permissions

Add permissions:

```txt
crm.role.assignment.read
crm.role.assignment.create
crm.role.assignment.update
crm.role.assignment.delete
crm.role.assignment.manage
```

Grant default to:

```txt
system_admin
crm_admin
```

Optional read to:

```txt
sales_manager
department_manager
top_manager
```

---

# Scope L1.8 Audit

Audit entity type:

```txt
crm_user_role_assignment
```

Actions:

```txt
create
update
delete
activate
deactivate
set_primary
scope_update
```

Audit payload should include:

```txt
userId
roleProfileId
branchScopeMode
branchScopeIds
productTypeScopeMode
productTypeScopeIds
isPrimary
isActive
```

---

# Scope L1.9 Compatibility Layer

Keep `membership.businessRole` temporarily.

Rules:

* do not remove column yet
* do not rely on it when role assignments exist
* fallback to `membership.businessRole` only when user has no active CRM role assignment
* document deprecation

Add technical debt:

```txt
membership.businessRole is deprecated for CRM authorization after Task L.1.
```

---

# Scope L1.10 Server-Side Enforcement Migration

Update all CRM modules to use resolved multi-role access:

```txt
Leads
Enquiries
Customers
Contacts
Quotations
Approvals
Dashboard
Settings
Reports if present
```

Priority:

1. Leads / Enquiries
2. Quotations
3. Dashboard
4. Approval
5. Customers / Contacts
6. Settings

Rules:

* no UI-only enforcement
* all list/detail/action routes must check resolved CRM access
* pricing visibility must remain permission-based

---

# Scope L1.11 Verification Matrix

Create verification cases:

## Marketing + Sales Support

Expected:

```txt
can view leads
can create support quotation if permission exists
cannot approve
cannot view revenue unless granted
```

## Sales + Sales Manager

Expected:

```txt
can see own sales records
can see team records if manager role scope allows
can create quotation
can approve only if role profile has authority
```

## CRM Admin + Department Manager

Expected:

```txt
can manage CRM settings
can approve department-level workflow
can view configured analytics
```

## Sales with Crane + Bangkok Scope

Expected:

```txt
can see Crane Bangkok records
cannot see Solar Rayong records
```

---

# Scope L1.12 Documentation / ADR

Create ADR:

```txt
docs/adr/0014-crm-multi-role-user-assignment.md
```

Document:

```txt
1 user = many CRM roles
membership is organization access
crm_user_role_assignments is CRM authorization
permission union rule
scope union rule
primary role display-only rule
businessRole deprecation
```

Update:

```txt
docs/implementation/technical-debt.md
```

---

# Explicit Non-Scope

Do NOT implement:

```txt
Keycloak group sync
External identity role sync
Team hierarchy module
Advanced ABAC rules
Approval delegation
Temporary role expiration
Role request workflow
```

---

# Output

After completion, summarize:

1. Files Added
2. Files Modified
3. Schema Added
4. Migration / Backfill
5. Resolver Changes
6. UI Added
7. API Added
8. Permissions Added
9. Audit Added
10. Verification Result
11. Remaining Risks

---

# Definition of Done

Task L.1 is complete when:

* user can have multiple CRM role assignments
* each assignment can have branch/product scope
* one primary role can be selected
* effective permissions are unioned from all active roles
* effective branch/product scope is resolved correctly
* membership.businessRole is no longer primary CRM authorization source
* role assignment UI works
* role assignment API works
* all CRM critical routes use multi-role resolver
* audit logs are created for assignment changes
* ADR 0014 exists
