feat(custom-roles): align chatwoot permissions
This commit is contained in:
@@ -16,9 +16,9 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc
|
||||
|
||||
## Current Baseline
|
||||
|
||||
- Latest implementation checkpoint: `feat(audit): cover operational mutations`.
|
||||
- Latest documentation checkpoint: `docs: land remaining parity tracker`.
|
||||
- Worktree status at this implementation checkpoint: B10.2 audit writer coverage now includes automation rules, macros, custom roles, CSAT review notes, inbox create/update, conversation update/assignment/status/delete, SLA policy CRUD, AgentCapacityPolicy CRUD, capacity users, and inbox capacity limits; the tracker now carries executable contracts for B10.3 CustomRole parity, B10.4 InboxLimit enforcement, B11 Captain/Copilot, and B12 reused-frontend smoke validation.
|
||||
- Latest implementation checkpoint: `feat(custom-roles): align chatwoot permissions`.
|
||||
- Latest documentation checkpoint: this checkpoint, recorded with the B10.3 CustomRole implementation.
|
||||
- Worktree status at this implementation checkpoint: B10.3 aligns CustomRole API payloads, Chatwoot permission arrays, AccountUser custom-role resolution, delete nullification, and admin gates; next active slice is B10.4 InboxLimit/account-limit create-path enforcement.
|
||||
- `go test ./...` passes.
|
||||
- Route dump succeeds with `TOTAL: 830` after adding the Chatwoot-compatible applied-SLA index route.
|
||||
- Route parity artifacts now exist under `docs/parity/` and are generated by `cmd/route_parity`.
|
||||
@@ -44,10 +44,9 @@ Next ordered checkpoints:
|
||||
|
||||
| Order | Slice | Required outcome | Primary verification |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | B10.3 | CustomRole permission behavior and AccountUser role resolution match Chatwoot. | Permission matrix tests plus admin/non-admin handler tests. |
|
||||
| 2 | B10.4 | Remaining InboxLimit/account-limit create-path behavior is aligned. | Inbox/channel create tests for over-limit behavior and frontend-readable errors. |
|
||||
| 3 | B11 | Captain/Copilot enterprise screens have real persistence and safe LLM feature gates. | Captain/Copilot handler/service fixtures and disabled-state tests. |
|
||||
| 4 | B12 | Reused Chatwoot frontend smoke runs repeatably against GoChat. | Checked smoke command plus gap report under `docs/parity/`. |
|
||||
| 1 | B10.4 | Remaining InboxLimit/account-limit create-path behavior is aligned. | Inbox/channel create tests for over-limit behavior and frontend-readable errors. |
|
||||
| 2 | B11 | Captain/Copilot enterprise screens have real persistence and safe LLM feature gates. | Captain/Copilot handler/service fixtures and disabled-state tests. |
|
||||
| 3 | B12 | Reused Chatwoot frontend smoke runs repeatably against GoChat. | Checked smoke command plus gap report under `docs/parity/`. |
|
||||
|
||||
## Execution Snapshot
|
||||
|
||||
@@ -57,7 +56,7 @@ Next ordered checkpoints:
|
||||
| Phase 1 | Meilisearch search engine | Review | B6 payload parity, optional live gate, and DB-fallback hardening are implemented; an actual live Meilisearch run is optional and environment-dependent |
|
||||
| Phase 2 | Route and controller parity audit | Doing | Ruby/Bundler unavailable, so Chatwoot route extraction currently uses static `routes.rb` fallback |
|
||||
| Phase 3 | Data and serializer parity | Doing | JSON fixture coverage is partial and still endpoint-family based |
|
||||
| Phase 4 | Enterprise feature completion | Doing | B7, B8, and frontend-critical B9 automation/macros are in Review; B10 audit/custom roles/remaining limits is the next active slice |
|
||||
| Phase 4 | Enterprise feature completion | Doing | B7, B8, B9, and B10.1-B10.3 are in Review; B10.4 remaining limits is the next active slice |
|
||||
| Phase 5 | Background jobs and integrations | Planned | durable worker choice and job parity are open |
|
||||
| Phase 6 | Core placeholder burn-down | Doing | account/contact/conversation/message/inbox placeholder groups remain broad |
|
||||
| Phase 7 | Verification harness | Planned | search live gate and reused-frontend smoke harness are not complete |
|
||||
@@ -145,12 +144,13 @@ This ledger records the committed parity checkpoints that future slices should b
|
||||
| `feat(audit): record enterprise mutations` | Completed B10.2a audit writer boundary and first enterprise mutation coverage: `AuditService.Record` now creates account-associated audit rows with actor, request UUID, remote address, action, auditable type/id, and JSON changes; automation-rule create/update/delete/clone/toggle, macro create/update/delete, custom-role create/update/delete, and CSAT review-note update call the shared writer. | `go test ./internal/handler/api/v1 -run 'CustomRole\|AutomationRule\|Macro\|CsatSurvey' -count=1`; `go test ./internal/service -run Audit -count=1`; `go test ./internal/handler/api/v1 -count=1`; `go test ./...`; `git diff --check`. No route changes; route dump remains `TOTAL: 830`. | Continue B10.2b inbox/conversation/SLA/capacity audit writer coverage, then B10.3 CustomRole permission parity. |
|
||||
| `feat(audit): cover operational mutations` | Completed B10.2b audit writer coverage for the remaining named operational mutations: inbox create/update, conversation update/delete/assign/status, SLA policy create/update/delete, AgentCapacityPolicy create/update/delete, inbox capacity limit create/update/delete, and capacity-policy user assignment/removal now call the shared audit writer. | `go test ./internal/handler/api/v1 -run 'SlaPolicy\|AgentCapacity\|Inbox\|Conversation' -count=1`; `go test ./internal/service -run Audit -count=1`; `go test ./internal/handler/api/v1 -count=1`; `go test ./...`; `git diff --check`. No route changes; route dump remains `TOTAL: 830`. | Continue B10.3 CustomRole permission-key/account-user parity and B10.4 remaining InboxLimit create-path enforcement. |
|
||||
| `docs: land remaining parity tracker` | Converted the immediate remaining plan into executable tracking contracts: B10.3 now lists CustomRole reference files, permission-array migration, AccountUser role resolution, delete nullification, admin gates, and test exits; B10.4 records InboxLimit create-path enforcement; B11/B12 now have route/persistence/feature-gate and smoke-report landing rules. | Documentation-only checkpoint; `git diff --check` passed. | Start B10.3 implementation from the recorded CustomRole contract. |
|
||||
| `feat(custom-roles): align chatwoot permissions` | Completed B10.3 CustomRole parity: custom roles now accept and serialize Chatwoot permission arrays, raw list/show/create/update/delete payloads match the enterprise Jbuilder views, admin gates are enforced, `AccountUser.role` stays `agent` while `custom_role_id` drives custom permissions, profile account payloads include `custom_role_id/custom_role/permissions`, and delete clears related account users. | `go test ./internal/handler/api/v1 -run CustomRole -count=1`; `go test ./internal/service -run 'CustomRole\|RBAC' -count=1`; `go test ./internal/model -run 'CustomRole\|AccountUser' -count=1`; `go test ./internal/middleware -run AccountScope -count=1`; handler/service/model packages passed; full verification recorded below. No route changes; route dump remains `TOTAL: 830`. | Continue B10.4 remaining InboxLimit/account-limit create-path enforcement. |
|
||||
|
||||
## Next Slice Contract
|
||||
|
||||
Completed implementation slice: B10.2 now covers the shared audit writer boundary and the named representative enterprise/core mutation set from the tracker.
|
||||
Completed implementation slice: B10.3 now aligns CustomRole permission arrays, serializers, account-user role resolution, delete nullification, and admin access.
|
||||
|
||||
Next implementation slice: continue B10.3 CustomRole permission-key/account-user parity, then B10.4 remaining InboxLimit create-path enforcement. B9.3 delayed/durable worker scheduling and B9.4 macro attachment depth remain named Phase 5 follow-ups.
|
||||
Next implementation slice: continue B10.4 remaining InboxLimit create-path enforcement. B9.3 delayed/durable worker scheduling and B9.4 macro attachment depth remain named Phase 5 follow-ups.
|
||||
|
||||
| Step | Required result | Reference source | Verification |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -396,7 +396,7 @@ Upcoming enterprise task boards:
|
||||
| B9 | B9.4 | Review deeper macro attachments/files and durable queued execution once the worker path is selected. | Chatwoot macro attachments and `MacrosExecutionJob`. | Attachment/file tests or explicit durable-worker split. | Todo |
|
||||
| B10 | B10.1 | Align audit log serializer, filters, pagination, actor/request metadata, and admin route behavior. | Chatwoot enterprise audit controllers/models. | Audit list tests plus representative mutation writer tests. | Done by `feat(audit): align chatwoot audit log payloads`; writer coverage continues in B10.2 |
|
||||
| B10 | B10.2 | Add audit writer coverage for representative core and enterprise mutations: inbox, conversation assignment/status, SLA policy, capacity policy, custom role, automation, macro, CSAT review notes. | Chatwoot audit hooks and current Go service mutation points. | Mutation tests assert audit rows with actor, auditable type/id, account, IP/request metadata where available. | Done by `feat(audit): record enterprise mutations` and `feat(audit): cover operational mutations` |
|
||||
| B10 | B10.3 | Align CustomRole permission keys, account-user role resolution, deletion nullification, and authorization failure payloads. | Chatwoot custom role controllers/policies and permission constants. | Permission matrix tests for admin/non-admin/custom-role access. | Todo |
|
||||
| B10 | B10.3 | Align CustomRole permission keys, account-user role resolution, deletion nullification, and authorization failure payloads. | Chatwoot custom role controllers/policies and permission constants. | Permission matrix tests for admin/non-admin/custom-role access. | Done by `feat(custom-roles): align chatwoot permissions` |
|
||||
| B10 | B10.4 | Review remaining InboxLimit/account-limit create-path enforcement outside capacity policies. | Chatwoot enterprise account/inbox limit policies. | Inbox/channel create tests for over-limit behavior and frontend-readable errors. | Todo |
|
||||
| B11 | B11.1 | Align Captain assistant CRUD, inbox bindings, responses, documents, scenarios, and custom tools payloads. | Captain controllers/services/frontend clients under `reference/chatwoot`. | Handler/service fixtures for every Captain dashboard client path. | Todo |
|
||||
| B11 | B11.2 | Align Copilot threads, messages, tasks, preferences, playground/tool-call behavior, and disabled-state feature gates. | Copilot controllers/services/frontend clients under `reference/chatwoot`. | Copilot handler/service tests for persistence, disabled LLM state, and frontend payloads. | Todo |
|
||||
@@ -613,7 +613,7 @@ B10 admin and limits breakdown:
|
||||
| --- | --- | --- | --- | --- |
|
||||
| B10.1 | Align audit list filters, serializer fields, and pagination before broadening writers. | Chatwoot enterprise audit controller/model. | Audit handler tests for account scope, action/auditable filters, actor metadata, and pagination. | Done by `feat(audit): align chatwoot audit log payloads` |
|
||||
| B10.2 | Add audit writer coverage for representative core and enterprise mutations: inbox, conversation assignment/status, SLA policy, capacity policy, custom role, automation, macro, CSAT review notes. | Chatwoot audit hooks and current Go service mutation points. | Mutation tests assert audit rows with actor, auditable type/id, account, IP/request metadata where available. | Done by `feat(audit): record enterprise mutations` and `feat(audit): cover operational mutations` |
|
||||
| B10.3 | Align custom role permission keys, serializers, delete-nullification behavior, and AccountUser permission resolution. | Chatwoot enterprise custom roles policy/model/controller. | Permission matrix tests and handler tests for admin/non-admin access. | Todo |
|
||||
| B10.3 | Align custom role permission keys, serializers, delete-nullification behavior, and AccountUser permission resolution. | Chatwoot enterprise custom roles policy/model/controller. | Permission matrix tests and handler tests for admin/non-admin access. | Done by `feat(custom-roles): align chatwoot permissions` |
|
||||
| B10.4 | Review legacy InboxLimit routes versus Chatwoot account-level limit behavior and enforce create limits in inbox/channel creation paths. | Chatwoot enterprise inbox limit behavior, existing capacity-limit implementation. | Inbox/channel creation tests cover under-limit and over-limit frontend-readable errors. | Todo |
|
||||
|
||||
B10.1 current checkpoint:
|
||||
@@ -642,7 +642,7 @@ B10.2a current checkpoint:
|
||||
- The handler-level audit writer is non-blocking for HTTP responses but logs skipped audit writes, keeping product mutations available while still making missing audit rows visible in tests/logs.
|
||||
- Automation rule create/update/delete/clone/toggle now write `AutomationRule` audit rows, matching the enterprise audit concern that audits automation rules associated with the account.
|
||||
- Macro create/update/delete now write `Macro` audit rows, matching the enterprise macro audit concern.
|
||||
- CustomRole create/update/delete now write `CustomRole` audit rows for this Go enterprise scope. Chatwoot custom roles are still tracked for deeper B10.3 permission and deletion-nullification parity.
|
||||
- CustomRole create/update/delete now write `CustomRole` audit rows for this Go enterprise scope. B10.3 later completed the deeper permission-array and deletion-nullification parity.
|
||||
- CSAT review-note update now writes a `CsatSurveyResponse` update audit row, covering the enterprise reporting mutation exposed in the reused reports screen.
|
||||
- Inbox/channel, conversation assignment/status, SLA policy, and AgentCapacityPolicy writer coverage remain explicit B10.2b work rather than being hidden under this boundary checkpoint.
|
||||
|
||||
@@ -697,6 +697,31 @@ env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./...
|
||||
git diff --check
|
||||
```
|
||||
|
||||
B10.3 current checkpoint:
|
||||
|
||||
- `reference/chatwoot/enterprise/app/controllers/api/v1/accounts/custom_roles_controller.rb`, `enterprise/app/models/custom_role.rb`, `enterprise/app/models/enterprise/account_user.rb`, `enterprise/app/views/api/v1/models/_custom_role.json.jbuilder`, `enterprise/app/views/api/v1/models/_account_user.json.jbuilder`, dashboard `customRole.js`, and `permissionsHelper.js` were used as the reference contract.
|
||||
- CustomRole create/update now accepts `custom_role.permissions` as Chatwoot string arrays and stores new rows as JSON arrays while retaining legacy JSON-map reads for old local rows.
|
||||
- CustomRole list/show/create/update now return raw Chatwoot custom-role serializers with array `permissions` and no local `{ success, data, meta }` envelope; destroy returns empty `200 OK`.
|
||||
- CustomRole admin gates now require administrator/super_admin role and focused handler tests cover non-admin denial.
|
||||
- `AccountUser.role` remains `agent` for custom-role users. `custom_role_id > 0` drives `HasCustomRole`, RBAC policy construction, AccountScope custom-role permission loading, and profile account payload permissions.
|
||||
- Profile account payloads now include enterprise `custom_role_id`, `custom_role`, and `permissions` values matching Chatwoot's enterprise account-user partial and `AccountUser#permissions` extension.
|
||||
- CustomRole delete clears related `account_users.custom_role_id` and keeps those users as agents, matching `dependent: :nullify` behavior.
|
||||
- Migration `000023_align_custom_role_permissions` updates the default permission storage from `{}` to `[]` for new deployments and existing empty rows.
|
||||
|
||||
B10.3 verification:
|
||||
|
||||
```bash
|
||||
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/handler/api/v1 -run CustomRole -count=1
|
||||
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/service -run 'CustomRole|RBAC' -count=1
|
||||
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/model -run 'CustomRole|AccountUser' -count=1
|
||||
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/middleware -run AccountScope -count=1
|
||||
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/handler/api/v1 -count=1
|
||||
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/service -count=1
|
||||
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/model -count=1
|
||||
env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./...
|
||||
git diff --check
|
||||
```
|
||||
|
||||
B10.4 InboxLimit landing contract:
|
||||
|
||||
| Area | Chatwoot reference contract | Current Go gap to close | Required landing work |
|
||||
@@ -861,7 +886,7 @@ Remaining slice landing plan:
|
||||
| B7 | Done: assignment capacity enforcement, SLA policy CRUD payload parity, applied-SLA conversation persistence, idempotent SLA breach lifecycle, applied-SLA report/list payload parity, and SLA miss notification fan-out. | Capacity-aware assignment policy binding review and durable SLA job scheduling remain broader Phase 5/P4.9 follow-ups, not hidden SLA gaps. | Review after `d23f3f0`; move to Done only after assignment policy binding review is either implemented or split out of B7. |
|
||||
| B8 | Done: account-side CSAT list/metrics/review-note payload parity, public submit/update idempotency, resolve-triggered generic survey message send, and CSV download filters/columns. | Channel-specific WhatsApp/Twilio template send hooks and durable queueing are tracked under Phase 5. | Review after `b36cf07`; move to Done only after channel-specific send hooks are either implemented or formally split as external integration scope. |
|
||||
| B9 | Done: B9.1 automation rule CRUD/listener/log/external-action parity and B9.2 macro frontend CRUD/execute side effects. | Delayed actions, durable queued worker scheduling, and deeper macro attachment/file parity remain named B9.3/B9.4 follow-ups. | Review after `feat(macros): align chatwoot macro payloads`; move to Done only after durable worker/attachment gaps are implemented or formally split out. |
|
||||
| B10 | Audit list payload and audit writer boundary for representative mutating core resources. | CustomRole permission-key parity, AccountUser permission resolution, InboxLimit enforcement in inbox/channel creation paths. | Done only after authorization tests prove admin-only surfaces and non-admin denial shapes match Chatwoot. |
|
||||
| B10 | Done: audit list payload, audit writer boundary for representative mutating core resources, CustomRole permission-key parity, AccountUser permission resolution, admin gates, and delete nullification. | InboxLimit enforcement in inbox/channel creation paths. | Done only after B10.4 create-limit tests prove over-limit behavior and frontend-readable errors match Chatwoot. |
|
||||
| B11 | Captain Assistant CRUD, inbox binding, responses, documents, and custom tools payload fixtures. | Copilot threads/messages/tasks, playground/tool-call behavior, document sync/embedding feature gates, streaming fallback. | Done only after LLM-dependent behavior is either implemented behind config or safely stubbed with frontend-compatible disabled states. |
|
||||
| B12 | Boot reused Chatwoot frontend against GoChat auth/profile/inbox/conversation/contact flows. | Add smoke paths for widget init/message, public CSAT, reports, and enterprise screens as B7-B11 land. | Done only after the smoke command is repeatable and writes a checked gap report. |
|
||||
|
||||
@@ -1389,3 +1414,4 @@ Verification milestone gates:
|
||||
- 2026-06-05: B10.2a audit writer checkpoint prepared as `feat(audit): record enterprise mutations`; a shared `AuditService.Record` boundary now writes account-associated audit rows with actor/request metadata and JSON changes, and automation-rule, macro, custom-role, and CSAT review-note mutations call it. Focused CustomRole/AutomationRule/Macro/CsatSurvey handler tests, audit service tests, handler package tests, full `go test ./...`, and `git diff --check` passed. Next slice is B10.2b inbox/conversation/SLA/capacity writer coverage, then B10.3 CustomRole permission parity.
|
||||
- 2026-06-05: B10.2b operational audit checkpoint prepared as `feat(audit): cover operational mutations`; inbox create/update, conversation update/delete/assignment/status, SLA policy CRUD, AgentCapacityPolicy CRUD, nested inbox capacity limits, and capacity-policy users now call the shared audit writer. Focused SLA/capacity/inbox/conversation handler tests, audit service tests, handler package tests, full `go test ./...`, and `git diff --check` passed. B10.2 moves to Review; next slice is B10.3 CustomRole permission parity.
|
||||
- 2026-06-05: Remaining parity tracker checkpoint prepared as `docs: land remaining parity tracker`; the document now carries executable landing contracts for B10.3 CustomRole permission arrays/account-user resolution/delete nullification, B10.4 account/inbox limit create-path enforcement, B11 Captain/Copilot persistence and feature gates, and B12 reused Chatwoot frontend smoke reporting. Documentation-only checkpoint; `git diff --check` passed.
|
||||
- 2026-06-05: B10.3 CustomRole checkpoint prepared as `feat(custom-roles): align chatwoot permissions`; custom roles now accept/serialize Chatwoot permission arrays, return raw enterprise Jbuilder payloads, enforce administrator-only access, keep custom-role account users as `role=agent` with `custom_role_id`, load custom-role permissions through RBAC/AccountScope, expose profile account `custom_role_id/custom_role/permissions`, and nullify account users on role delete. Focused CustomRole/RBAC/model/AccountScope tests, handler/service/model package tests, and full verification were run before commit; sandboxed middleware package tests still require socket-capable execution for miniredis. Next slice is B10.4 InboxLimit create-path enforcement.
|
||||
|
||||
Reference in New Issue
Block a user