docs: detail agent capacity parity plan
This commit is contained in:
@@ -17,8 +17,8 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc
|
||||
## Current Baseline
|
||||
|
||||
- Latest implementation checkpoint: `f0aae79 feat(inboxes): deepen channel config parity`.
|
||||
- Latest documentation checkpoint before this consolidation: `1f6ec3e docs: record inbox serializer checkpoint`.
|
||||
- Worktree status at this planning checkpoint: clean after the matching docs checkpoint.
|
||||
- Latest documentation checkpoint before this consolidation: `8fd40ec docs: record channel config checkpoint`.
|
||||
- Worktree status at this planning checkpoint: clean after the matching docs checkpoint; next active slice is B5.5c AgentCapacityPolicy/InboxCapacityLimit parity.
|
||||
- `go test ./...` passes.
|
||||
- Route dump succeeds with `TOTAL: 821` after adding the Chatwoot-compatible `PATCH` inbox update route.
|
||||
- Route parity artifacts now exist under `docs/parity/` and are generated by `cmd/route_parity`.
|
||||
@@ -35,7 +35,7 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc
|
||||
| Phase 1 | Meilisearch search engine | Review | live Meilisearch integration and document-shape parity still need reference verification |
|
||||
| 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 | Planned | excluded SSO family must stay out of scope; all other enterprise features remain included |
|
||||
| Phase 4 | Enterprise feature completion | Doing | excluded SSO family must stay out of scope; all other enterprise features remain included |
|
||||
| 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 | route/JSON/frontend smoke harness not complete |
|
||||
@@ -90,12 +90,13 @@ This ledger records the committed parity checkpoints that future slices should b
|
||||
| `945782e feat(inboxes): persist chatwoot working hours` | Completed B5.3 working-hours parity for the generic inbox update flow: inbox create initializes Chatwoot default weekly schedule where the table exists, inbox update accepts frontend `working_hours` JSON with string/empty time fields from `timeSlotTransform`, persists schedules in `working_hours`, serializes `working_hours` from the relation, and preserves `working_hours_enabled`, `out_of_office_message`, and timezone behavior. | `go test ./internal/handler/api/v1 -run 'TestInboxHandler_ChatwootSerializerParity\|TestInboxHandler_ChatwootCreateUpdateRequestBinding\|TestInbox' -count=1`; `go test ./internal/service -run 'Inbox\|WorkingHour' -count=1`; `go test ./internal/handler/api/v1 -count=1`; escalated `go test ./...`; `git diff --check`. | Continue B5.4 with inbox member payload and round-robin membership side effects, then B5.5 channel-specific config depth. |
|
||||
| `82167f5 feat(inboxes): align chatwoot inbox members` | Completed B5.4 inbox member parity for reused dashboard agent assignment flows: account-scoped and nested member endpoints now return Chatwoot `{ payload: [agent] }` responses, agent payloads expose frontend-required user fields, duplicate adds are idempotent, create adds only missing users, and update performs a diff so preserved rows are not recreated unnecessarily. | `go test ./internal/handler/api/v1 -run InboxMember -count=1`; `go test ./internal/service -run InboxMember -count=1`; `go test ./internal/repository -run InboxMember -count=1`; `go test ./internal/handler/api/v1 -count=1`; `go test ./...`; `git diff --check`. | Continue B5.5 with deeper channel-specific config parity and InboxLimit enforcement on channel creation. |
|
||||
| `f0aae79 feat(inboxes): deepen channel config parity` | Advanced B5.5 channel config parity: generic inbox JSON updates now hoist flat frontend SMTP/IMAP/channel setting keys into `channel_config`, the serializer exposes deeper Email, WhatsApp, LINE, SMS, and Twilio voice/config fields, channel defaults match Chatwoot closer for WebWidget/API/Email/WhatsApp, and the Twilio frontend create route accepts nested `twilio_channel` payloads while returning the raw Chatwoot inbox serializer. | `go test ./internal/handler/api/v1 -run 'TestInboxHandler_Chatwoot(ChannelSpecificConfigDepth\|CreateUpdateRequestBinding\|SerializerParity)\|TestTwilioChannel_Create' -count=1`; `go test ./internal/service -run Inbox -count=1`; `go test ./internal/handler/api/v1 -count=1`; `go test ./...`; `git diff --check`. | Continue B5.5 with InboxLimit enforcement and any remaining channel-specific route response cleanup. |
|
||||
| `8fd40ec docs: record channel config checkpoint` | Recorded the B5.5 channel config checkpoint and kept the route count at `TOTAL: 821` with tracked route parity still at 262 exact and 0 missing. | Documentation-only checkpoint after the B5.5 channel config implementation. | Next active slice is B5.5c AgentCapacityPolicy/InboxCapacityLimit route, serializer, and service parity. |
|
||||
|
||||
## Next Slice Contract
|
||||
|
||||
Completed implementation slice: B5.1-B5.4 now cover inbox serializer shape, Chatwoot frontend create/update binding, working-hours persistence, out-of-office behavior, and inbox member assignment payload/mutation semantics. B4 remains in review after contact/company CRUD payloads, relations, labels, merge, import/export, notes, nested conversations, Meilisearch CRM search, and API smoke coverage landed.
|
||||
|
||||
Next implementation slice: continue B5.5 channel-specific config depth and InboxLimit enforcement. Keep B3 and B4 in review for delivery/storage side-effect parity and real browser frontend validation.
|
||||
Next implementation slice: B5.5c AgentCapacityPolicy/InboxCapacityLimit parity. Keep B3 and B4 in review for delivery/storage side-effect parity and real browser frontend validation.
|
||||
|
||||
| Step | Required result | Reference source | Verification |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -103,7 +104,7 @@ Next implementation slice: continue B5.5 channel-specific config depth and Inbox
|
||||
| N2 | Accept Chatwoot frontend inbox create/update request bodies, including multipart FormData and `channel[...]` nested params. | `dashboard/store/modules/inboxes.js#buildInboxData`, `InboxesController#permitted_params`. | Done by `ee93546`; handler tests cover website multipart create, API JSON create, Telegram no-name create, and settings update request bodies. |
|
||||
| N3 | Persist inbox working hours and out-of-office behavior with Chatwoot defaults. | `OutOfOffisable`, `Inbox#OFFISABLE_ATTRS`, settings pages. | Done by `945782e`; update tests prove weekly schedule persistence and service tests prove out-of-office behavior. |
|
||||
| N4 | Align inbox member payloads and membership mutation semantics. | `InboxMembersController`, `Inbox#add_members/remove_members`, dashboard `inboxMembers.js`. | Done by `82167f5`; account-scoped and nested member routes return `{ payload: [agent] }`, create is add-only/idempotent, update is diff-based, and delete returns empty `200 OK`. |
|
||||
| N5 | Deepen channel-specific config flows and enforce inbox limits. | WebWidget/API/Telegram/Email/WhatsApp/SMS/LINE channel models/controllers, enterprise inbox limits. | Channel create/update/show tests cover frontend settings screens and paid inbox limits block over-quota creation with Chatwoot-compatible errors. |
|
||||
| N5 | Land AgentCapacityPolicy/InboxCapacityLimit Chatwoot API parity. | `reference/chatwoot/config/routes.rb:123-127`, enterprise agent capacity policy and inbox limit controllers/views/models. | Policy CRUD returns raw Chatwoot payloads; nested inbox-limit and user routes are registered; tests cover duplicate/negative/wrong-account limits, `assigned_agent_count`, and route artifacts are regenerated if routes change. |
|
||||
| N6 | Update this tracker after every implementation checkpoint. | This document. | `git diff --check`; `go test ./...` for Go changes. |
|
||||
|
||||
Current B2 profile checkpoint:
|
||||
@@ -218,6 +219,27 @@ B5.5 planned breakdown:
|
||||
| B5.5c | Enforce enterprise InboxLimit during inbox/channel creation and return frontend-compatible over-limit errors. | Chatwoot enterprise inbox limit policy/model behavior. | Service/handler tests cover under-limit create, at-limit rejection, and account-scoped counting. | Todo |
|
||||
| B5.5d | Keep route artifacts unchanged unless new Chatwoot-compatible routes are registered; regenerate route dump only on route changes. | `cmd/dump_routes`, `cmd/route_parity`. | `git diff --check`; `go test ./...`; route dump if needed. | Todo |
|
||||
|
||||
B5.5c AgentCapacityPolicy / InboxCapacityLimit parity contract:
|
||||
|
||||
| Area | Chatwoot reference contract | Current Go gap | Required landing work |
|
||||
| --- | --- | --- | --- |
|
||||
| Policy routes | `reference/chatwoot/config/routes.rb:123-127` exposes `/api/v1/accounts/:account_id/agent_capacity_policies`, nested `/:policy_id/users`, and nested `/:policy_id/inbox_limits`. | Go registers only policy CRUD through `RegisterAgentCapacityRoutes`; the old local `/inboxes/:inbox_id/inbox_limits` handler is not the Chatwoot enterprise route. | Register nested Chatwoot-compatible `users` and `inbox_limits` routes under `agent_capacity_policies`; keep old routes only as compatibility surfaces. |
|
||||
| Policy request/response | Enterprise controller accepts `{ agent_capacity_policy: { name, description, exclusion_rules } }`; index/show/create/update return raw policy JSON, destroy is `head :ok`; `assignment_logic` is not a permitted Chatwoot field. | Go response helpers wrap policy payloads in `{ success, data }` or pagination meta, and service creation currently requires `assignment_logic`. | Add raw Chatwoot serializers, accept wrapped and flat bodies where useful, make `assignment_logic` optional/defaulted for storage compatibility, and keep update wrapper-compatible. |
|
||||
| Policy serializer | `_agent_capacity_policy.json.jbuilder` emits `id`, `name`, `description`, `exclusion_rules`, Unix `created_at`, Unix `updated_at`, `account_id`, `assigned_agent_count`, and `inbox_capacity_limits`. | Repository does not preload `InboxCapacityLimits`; response exposes model timestamps and local fields directly; assigned count is not serialized in Chatwoot shape. | Add a serializer boundary that preloads capacity limits, counts assigned users through account users, and emits Unix timestamps plus `inbox_capacity_limits`. |
|
||||
| Inbox capacity limits | Nested `inbox_limits#create/update/destroy` lives under a current account policy, validates current-account inbox, prevents duplicate inbox assignment, requires `conversation_limit >= 0`, create returns raw limit JSON, update also emits `inbox_name`, destroy is `204 No Content`. | Existing `InboxCapacityLimit` model exists, but no nested handler/service/repo flow is wired; old `InboxLimit` model/handler has a different path and shape. | Add repo/service methods for create/update/delete under policy/account scope, duplicate and negative-limit errors, raw create/update serializers, and 204 destroy. |
|
||||
| Enforcement | Capacity policies and inbox limits must feed assignment and auto-assignment limits before the feature can leave Review. | Current B5.5c first pass is API/data parity; assignment enforcement is still in P4.4/P4.9. | Land CRUD/data/API first, then wire manual and automatic assignment enforcement in the B7/P4.4 capacity checkpoint. |
|
||||
| Route artifacts | Adding nested Chatwoot routes changes Go route inventory. | Route dump currently remains `TOTAL: 821`. | If routes change, regenerate `docs/parity/gochat_routes.txt`; run `cmd/route_parity`; update route count and parity summary in this document. |
|
||||
|
||||
B5.5c implementation checkpoints:
|
||||
|
||||
| Step | Implementation target | Verification gate | Status |
|
||||
| --- | --- | --- | --- |
|
||||
| B5.5c.1 | Policy serializer and CRUD response shape: raw index/object payloads, Unix timestamps, optional `assignment_logic`, wrapped create/update body support. | Handler tests assert no `{ success, data }` envelope and no required `assignment_logic`. | Todo |
|
||||
| B5.5c.2 | Repository/service preload and helpers for `InboxCapacityLimit`, current-account policy/inbox validation, duplicate guard, and non-negative `conversation_limit`. | Service tests cover success, duplicate, wrong-account inbox, wrong-policy limit, and negative limit. | Todo |
|
||||
| B5.5c.3 | Nested `POST/PUT/DELETE /agent_capacity_policies/:policy_id/inbox_limits` endpoints with Chatwoot create/update/delete payload/status behavior. | Handler flow creates a policy, creates a limit, rejects duplicate, updates limit with `inbox_name`, deletes with 204, and list/show include `inbox_capacity_limits`. | Todo |
|
||||
| B5.5c.4 | Nested policy users endpoints for assignment-policy membership parity. | Handler/service tests cover add/remove/list users and `assigned_agent_count`. | Todo |
|
||||
| B5.5c.5 | Route artifacts and full regression pass. | Route dump/parity regenerated if routes changed; `go test ./internal/handler/api/v1 -run AgentCapacity -count=1`; `go test ./internal/service -run AgentCapacity -count=1`; `go test ./internal/router -count=1`; `go test ./...`; `git diff --check`. | Todo |
|
||||
|
||||
B5.5 channel config matrix after `f0aae79`:
|
||||
|
||||
| Channel | Create/update support now covered | Serializer fields now covered | Remaining gap |
|
||||
@@ -590,8 +612,8 @@ Enterprise tracking table:
|
||||
| P4.1 | SLA policies/events | `internal/model/sla_policy.go`, `internal/model/sla_event.go`, `internal/service/sla_policy_service.go`, `internal/service/sla_event_service.go`, `internal/handler/api/v1/sla_policy_handler.go` | Compare with Chatwoot SLA behavior; wire lifecycle events and breach tracking; add frontend payload tests. | Todo |
|
||||
| P4.2 | Audit logs | `internal/model/audit.go`, `internal/service/audit_service.go`, `internal/repository/audit_repo.go`, `internal/handler/api/v1/audit_handler.go` | Ensure every mutating enterprise/core action emits audit events and filters match Chatwoot. | Todo |
|
||||
| P4.3 | Custom roles/permissions | `internal/model/custom_role.go`, `internal/service/custom_role_service.go`, `internal/middleware/role_check.go`, `internal/handler/api/v1/custom_role_handler.go` | Align permission keys, inherited roles, authorization failures, and admin UX payloads. | Todo |
|
||||
| P4.4 | Agent capacity | `internal/model/agent_capacity_policy.go`, `internal/service/agent_capacity_policy_service.go`, `internal/handler/api/v1/agent_capacity_handler.go`, `internal/autoassignment/*` | Enforce capacity in assignment path and auto-assignment; add limit tests. | Todo |
|
||||
| P4.5 | Inbox limits | `internal/model/inbox_limit.go`, `internal/service/inbox_limit_service.go`, `internal/repository/inbox_limit_repo.go`, `internal/handler/api/v1/inbox_limit_handler.go` | Enforce account/inbox usage limits and frontend-compatible responses. | Todo |
|
||||
| P4.4 | Agent capacity | `internal/model/agent_capacity_policy.go`, `internal/service/agent_capacity_policy_service.go`, `internal/handler/api/v1/agent_capacity_handler.go`, `internal/autoassignment/*` | First align AgentCapacityPolicy API, serializers, nested users, and `InboxCapacityLimit` data contracts; then enforce capacity in manual/auto assignment. | Doing |
|
||||
| P4.5 | Inbox limits | `internal/model/agent_capacity_policy.go` `InboxCapacityLimit`, plus legacy `internal/model/inbox_limit.go`, `internal/service/inbox_limit_service.go`, `internal/repository/inbox_limit_repo.go`, `internal/handler/api/v1/inbox_limit_handler.go` | Implement Chatwoot enterprise nested `agent_capacity_policies/:policy_id/inbox_limits` first; keep legacy `/inboxes/:inbox_id/inbox_limits` from blocking but do not treat it as parity. | Doing |
|
||||
| P4.6 | Captain/Copilot | `internal/model/captain_models.go`, `internal/model/copilot_models.go`, `internal/service/captain_*`, `internal/service/copilot_*`, `internal/handler/api/v1/captain_*`, `internal/handler/api/v1/copilot_handler.go` | Complete assistant, tools, scenarios, documents, responses, inbox bindings, suggestions, and streaming compatibility. | Todo |
|
||||
| P4.7 | CSAT | `internal/csat/*`, `internal/automation/csat_survey_*`, `internal/handler/api/v1/csat_*`, `internal/service/csat_metrics_service.go` | Wire resolve-triggered survey send, public update flow, metrics, review notes, filters. | Todo |
|
||||
| P4.8 | Automation and macros | `internal/automation/*`, `internal/handler/api/v1/automation_rule_handler.go`, `internal/handler/api/v1/macro_handler.go` | Finish action side effects, execution logs, webhook/email transcript delivery, and rule trigger coverage. | Todo |
|
||||
@@ -814,3 +836,4 @@ Verification milestone gates:
|
||||
- 2026-06-05: B5.3 working-hours checkpoint committed as `945782e feat(inboxes): persist chatwoot working hours`; generic inbox create/update now initializes default working hours, accepts the reused frontend's `working_hours` payload with string and empty time fields, persists the weekly schedule relation, serializes working hours from the relation, and covers out-of-office detection. Focused inbox/working-hour tests, handler package tests, escalated full `go test ./...`, and `git diff --check` passed. Route dump unchanged at `TOTAL: 821`.
|
||||
- 2026-06-05: B5.4 inbox members checkpoint committed as `82167f5 feat(inboxes): align chatwoot inbox members`; account-scoped and nested inbox member routes now return Chatwoot `{ payload: [agent] }` responses, serialize assigned users with agent partial fields including `custom_role_id`, make create add-only/idempotent, make update diff-based, and keep delete as empty `200 OK`. Focused inbox member handler/service/repository tests, handler package tests, full `go test ./...`, and `git diff --check` passed. Route dump unchanged at `TOTAL: 821`.
|
||||
- 2026-06-05: B5.5 channel config depth checkpoint committed as `f0aae79 feat(inboxes): deepen channel config parity`; generic inbox JSON updates now hoist flat SMTP/IMAP/channel settings into channel config, Email/WhatsApp/LINE/SMS/Twilio serializers expose deeper Chatwoot frontend fields, WebWidget/API/Email/WhatsApp defaults are closer to Chatwoot, and Twilio channel create accepts nested `twilio_channel` payloads while returning the raw inbox serializer. Focused channel-depth tests, service inbox tests, handler package tests, full `go test ./...`, and `git diff --check` passed. Route dump unchanged at `TOTAL: 821`.
|
||||
- 2026-06-05: B5.5c planning contract added for AgentCapacityPolicy/InboxCapacityLimit parity; the next slice now tracks exact Chatwoot route sources, raw policy and inbox-limit serializers, optional `assignment_logic`, nested `users` and `inbox_limits` routes, duplicate/wrong-account/non-negative validation gates, and route artifact regeneration rules before implementation starts.
|
||||
|
||||
Reference in New Issue
Block a user