docs: land chatwoot parity tracking plan

This commit is contained in:
2026-06-05 07:55:03 +08:00
parent 330f875f95
commit 64926db464
+63 -2
View File
@@ -17,8 +17,8 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc
## Current Baseline
- Latest implementation checkpoint: `4f85ef1 feat(sla): align applied sla reports`.
- Latest documentation checkpoint before this update: `0c6cf1d docs: record sla breach lifecycle checkpoint`.
- Worktree status at this planning checkpoint: clean after the matching implementation checkpoint; next active slice is B7 SLA business-hours and notification parity review.
- Latest documentation checkpoint before this update: `330f875 docs: record applied sla reports checkpoint`.
- Worktree status at this planning checkpoint: clean after `330f875`; next active slice is B7 SLA business-hours and notification parity review.
- `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`.
@@ -27,6 +27,30 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc
- Handler test stability fixes are committed into the baseline before feature parity work continues.
- `.codegraph/` is generated indexing output and is not part of tracked product code.
## Planning Control Board
This document is the active tracker. The older Hermes plans remain source notes only; each future slice must be represented here before or inside the matching implementation commit.
Current operating rules:
- Implement from the local `reference/chatwoot` source first, then update this tracker with the exact files or behavior inspected.
- Keep each checkpoint small enough to verify with focused tests plus `go test ./...`.
- Commit implementation and documentation together unless the checkpoint is explicitly documentation-only.
- Do not mark a slice `Done` while side effects, async jobs, permission gates, payload shape, or frontend smoke coverage are still untracked.
- Search-related work must target Meilisearch; DB fallback is only a local development escape hatch.
- SSO, SAML, LDAP, and OIDC are excluded; all other enterprise features remain in scope.
Next ordered checkpoints:
| Order | Slice | Required outcome | Primary verification |
| --- | --- | --- | --- |
| 1 | B7.6 | SLA business-hours timer math and breach notification fan-out match Chatwoot or have named job-boundary gaps. | Focused applied-SLA lifecycle/notification tests, service package tests, `go test ./...`. |
| 2 | B8 | CSAT account/public/report/send behavior matches Chatwoot enough for the reused frontend. | CSAT handler/service/listener tests, public update tests, CSV/report tests. |
| 3 | B9 | Automation rules and macros mutate conversations through real side effects with execution logs. | Rule listener tests, macro execute tests, action-service retry/log tests. |
| 4 | B10 | Audit, CustomRole, and remaining InboxLimit surfaces enforce Chatwoot admin behavior. | Permission matrix tests, audit writer/list tests, inbox/account limit tests. |
| 5 | B11 | Captain/Copilot enterprise screens have real persistence and safe LLM feature gates. | Captain/Copilot handler/service fixtures and disabled-state tests. |
| 6 | B12 | Reused Chatwoot frontend smoke runs repeatably against GoChat. | Checked smoke command plus gap report under `docs/parity/`. |
## Execution Snapshot
| Phase | Name | Status | Blocking gaps |
@@ -100,6 +124,7 @@ This ledger records the committed parity checkpoints that future slices should b
| `a11bb96 feat(sla): persist applied sla on conversations` | Completed the first B7.3 applied-SLA persistence slice: conversation create/update now accept Chatwoot enterprise `sla_policy_id`, validate account ownership and replacement/removal rules, create one `applied_slas` row when a policy is attached, keep status-only updates idempotent for existing SLA conversations, and serialize `applied_sla` in conversation payloads using Chatwoot's applied-SLA partial fields. | `go test ./internal/service -run 'ConversationService_.*Sla\|ConversationService_Update\|ConversationService_Create' -count=1`; `go test ./internal/handler/api/v1 -run 'ConversationCrudTestSuite/Test(Update_WithSlaPolicy\|Update_Success\|Create_Success)' -count=1`; `go test ./internal/service -run 'Conversation\|AppliedSla\|Sla' -count=1`; `go test ./internal/handler/api/v1 -run 'ConversationCrudTestSuite\|SlaPolicy' -count=1`; `go test ./internal/service -count=1`; `go test ./internal/handler/api/v1 -count=1`; `go test ./...`; `git diff --check`. No route changes; route dump remains `TOTAL: 829`. | Continue B7.4 with idempotent SLA event/timer lifecycle and then B7.5 applied-SLA report/list payload parity. |
| `213bf2b feat(sla): make sla breach events idempotent` | Completed B7.4 timer/breach lifecycle core parity: SLA thresholds now use Chatwoot seconds units, FRT/NRT/RT checks treat the exact threshold as breached, missed events are idempotent by `applied_sla_id`, `event_type`, and `meta`, NRT events store the last incoming message ID in `meta`, and resolved active/active-with-misses applied SLAs transition to `hit` or `missed`. | `go test ./internal/service -run 'AppliedSlaService\|ConversationService_Create_AppliesSlaPolicy' -count=1`; `go test ./internal/handler/api/v1 -run 'SlaPolicy\|ConversationCrudTestSuite/TestUpdate_WithSlaPolicy' -count=1`; `go test ./internal/service -run 'AppliedSla\|Sla\|Conversation' -count=1`; `go test ./internal/handler/api/v1 -run 'SlaPolicy\|ConversationCrudTestSuite' -count=1`; `go test ./internal/service -count=1`; `go test ./internal/handler/api/v1 -count=1`; `go test ./...`; `git diff --check`. No route changes; route dump remains `TOTAL: 829`. | Continue B7.5 with applied-SLA report/list payload parity, then review notifications/business-hours depth. |
| `4f85ef1 feat(sla): align applied sla reports` | Completed B7.5 applied-SLA report/list payload parity for the reused Chatwoot SLA reports screen: added `GET /api/v1/accounts/:account_id/applied_slas`, aligned the index `{ payload, meta }` shape, filtered missed reports by date/inbox/team/SLA policy/label/assignee, returned Chatwoot applied-SLA/conversation/SLA-event fields, changed metrics to raw `total_applied_slas`, `number_of_sla_misses`, and `hit_rate`, and changed download to the breached-conversation CSV. | `go test ./internal/service -run 'SlaPolicyService_.*AppliedSla\|AppliedSlaReport' -count=1`; `go test ./internal/handler/api/v1 -run 'SlaPolicyHandler_.*AppliedSla' -count=1`; `go test ./internal/service -count=1`; `go test ./internal/handler/api/v1 -count=1`; `go run ./cmd/dump_routes > docs/parity/gochat_routes.txt`; `go run ./cmd/route_parity`; `go test ./...`; `go test ./cmd/route_parity -count=1`; `git diff --check`. Route dump is now `TOTAL: 830`; route parity tracks 277 routes with 270 exact, 7 parameter-compatible, and 0 missing. | Continue B7 with business-hours timer math and SLA notification delivery review before closing the SLA package. |
| `330f875 docs: record applied sla reports checkpoint` | Recorded the B7.5 applied-SLA reports checkpoint in this tracker and made B7.6 the active follow-up. | Documentation-only checkpoint after the applied-SLA report/list implementation verification. | Continue B7.6 with business-hours timer math and SLA notification delivery. |
## Next Slice Contract
@@ -330,6 +355,41 @@ B7.5 implementation notes:
- If the index route is added, run `go run ./cmd/dump_routes > docs/parity/gochat_routes.txt` and `go run ./cmd/route_parity` before committing.
- Exit commands for the implementation checkpoint should include focused applied-SLA handler/service tests, `go test ./...`, and `git diff --check`.
Upcoming enterprise task boards:
| Slice | Step | Implementation target | Reference source | Required tests | Status |
| --- | --- | --- | --- | --- | --- |
| B8 | B8.1 | Align account-side CSAT survey response index, metrics, filters, pagination, and review-note payloads. | `reference/chatwoot/app/controllers/api/v1/accounts/csat_survey_responses_controller.rb`, CSAT Jbuilder/views, dashboard reports clients. | Handler/service tests for list, metrics, review note update, date/agent/inbox/team/rating filters. | Todo |
| B8 | B8.2 | Align public CSAT submit/update flow, lock window, message linkage, and one-response-per-message behavior. | `reference/chatwoot/app/controllers/public/api/v1/csat_survey_controller.rb`, CSAT response model/services. | Public handler tests for submit, update within window, update after lock, duplicate response rejection. | Todo |
| B8 | B8.3 | Wire resolve-triggered CSAT survey send with idempotency and channel-aware message creation. | Chatwoot CSAT listener/jobs and inbox CSAT settings. | Listener tests prove one CSAT message per resolved conversation and no send when disabled. | Todo |
| B8 | B8.4 | Align CSAT downloads/export payloads used by reports screens. | CSAT report/download controller paths and frontend report API. | CSV/download tests cover filters and frontend column names. | Todo |
| B9 | B9.1 | Align automation rule CRUD payloads, validation, condition groups, and event names. | Chatwoot automation rule controllers/models and dashboard automation builder. | Handler/service tests for create/update/list/show/delete and validation errors. | Todo |
| B9 | B9.2 | Implement automation action side effects for labels, status, priority, assignee/team, custom attributes, private notes, and snooze. | Chatwoot automation action services/listeners. | Rule listener tests assert real conversation mutations and stop-on-match behavior. | Todo |
| B9 | B9.3 | Add durable execution logs, delayed actions, webhook delivery, and email transcript delivery boundaries. | Chatwoot automation jobs and webhook/transcript actions. | Worker/action tests cover retryable external actions and observable failures. | Todo |
| B9 | B9.4 | Align macro CRUD/availability and macro execution side effects. | Chatwoot macros controller/model/action execution. | Macro handler/service tests cover frontend payloads and conversation mutations. | 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. | Todo |
| B10 | B10.2 | 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 | 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 |
| B11 | B11.3 | Add document sync/embedding/LLM job boundaries where external dependencies are required. | Captain/Copilot jobs and document services. | Worker tests or explicit feature-gated fallback tests. | Todo |
| B12 | B12.1 | Add a repeatable command to run the reused Chatwoot frontend against GoChat. | `reference/chatwoot` frontend boot/auth/API clients. | Smoke command documented and runnable locally. | Todo |
| B12 | B12.2 | Cover login, inbox list/settings, conversation list/detail/message send, contact/company views, widget init/message, public CSAT, SLA/CSAT reports, and enterprise admin screens. | Dashboard route usage and frontend stores/API modules. | Smoke report checked into `docs/parity/` with pass/fail gaps. | Todo |
Hermes plan material now mapped:
- `.hermes/plans/2025-05-24-global-search-meilisearch.md` maps to Phase 1/B6. The Meilisearch interface, config, documents, indexing hooks, reindex command, payload shape, and live gate are already tracked here. Remaining search work is only future payload gaps discovered by frontend smoke or route expansion.
- `.hermes/plans/2026-05-24-automation-macro-csat.md` maps to B8 and B9. CSAT model/service/listener/handlers, automation rule handlers, macro handlers, route wiring, action side effects, and durable jobs are tracked above instead of relying on the Hermes-era checklist.
Next checkpoint contract for B7.6:
| Step | Required investigation | Landing rule |
| --- | --- | --- |
| B7.6a | Compare Go `AppliedSlaService` target-time calculation with Chatwoot `Sla::EvaluateAppliedSlaService` and business-hours helpers. | If `only_during_business_hours` changes timer math in Rails, add Go tests proving closed-hour/weekend skipping or record the exact missing job/helper gap. |
| B7.6b | Compare Go `SlaEvent` creation with Chatwoot `SlaEvent#create_notifications`. | New SLA miss events create notifications for participants, account administrators, and assignee with Chatwoot notification types, deduped by user/event. |
| B7.6c | Compare SLA processing jobs with current Go worker boundaries. | Any missing async schedule/retry behavior is named in Phase 5, not hidden under B7 Done. |
| B7.6d | Update this tracker and commit after implementation. | B7.6 row moves to Done or Review with named deferred job gaps, and verification commands are recorded. |
Active B4 task board:
| ID | Task | Reference source | Status | Exit gate |
@@ -928,3 +988,4 @@ Verification milestone gates:
- 2026-06-05: B7 applied-SLA persistence checkpoint committed as `a11bb96 feat(sla): persist applied sla on conversations`; conversation create/update now accepts `sla_policy_id`, validates SLA policy account ownership plus Chatwoot replacement/removal rules, creates exactly one active `applied_slas` record, keeps status-only updates idempotent for existing SLA conversations, and includes Chatwoot-style `applied_sla` payload fields in conversation responses. Focused conversation/SLA service and handler tests, full `go test ./...`, and `git diff --check` passed. Next B7 checkpoint is SLA timer/breach lifecycle with idempotent FRT/NRT/RT events.
- 2026-06-05: B7 SLA breach lifecycle checkpoint committed as `213bf2b feat(sla): make sla breach events idempotent`; SLA thresholds now use Chatwoot seconds units, exact-threshold checks count as breached, FRT/NRT/RT miss events are idempotent by applied SLA, event type, and meta, NRT events store last incoming `message_id`, and resolved applied SLAs transition to `hit` or `missed`. Focused applied-SLA lifecycle tests, handler SLA/conversation tests, full `go test ./...`, and `git diff --check` passed. Next B7 checkpoint is applied-SLA report/list payload parity.
- 2026-06-05: B7 applied-SLA reports checkpoint committed as `4f85ef1 feat(sla): align applied sla reports`; account applied-SLA index/metrics/download now match Chatwoot's reports controller and frontend SLA reports API, including missed-only table/download semantics, shared filters, `{ payload, meta }` index shape, raw metrics keys, and breached-conversation CSV. Focused applied-SLA service/handler tests, service and handler package tests, full `go test ./...`, route dump `TOTAL: 830`, route parity `270 exact, 7 parameter-compatible, 0 missing`, `go test ./cmd/route_parity -count=1`, and `git diff --check` passed. Next B7 checkpoint is business-hours timer math and SLA notification delivery review.
- 2026-06-05: Development tracker was normalized for handoff continuity after `330f875 docs: record applied sla reports checkpoint`; the current baseline now points at the latest implementation and documentation checkpoints, the planning control board records the next ordered B7-B12 checkpoints, Hermes search/automation/CSAT notes are mapped into active slices, and B7.6 has an explicit investigation/landing contract.