diff --git a/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md b/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md index 04b382ee..786a9a65 100644 --- a/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md +++ b/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md @@ -17,6 +17,7 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc ## Current Baseline - Latest implementation checkpoint: `0e83e8d feat(inboxes): align chatwoot inbox serializers`. +- Latest documentation checkpoint before this consolidation: `1f6ec3e docs: record inbox serializer checkpoint`. - Worktree status at this planning checkpoint: clean after docs checkpoint. - `go test ./...` passes. - Route dump succeeds with `TOTAL: 821` after adding the Chatwoot-compatible `PATCH` inbox update route. @@ -168,6 +169,25 @@ Active B5 task board: | B5.4 | Inbox member payload and round-robin side effects. | `InboxMembersController`, `Inbox#add_members/remove_members`. | Todo | Account-scoped and nested member routes return `{ payload }` agents and update membership idempotently. | | B5.5 | Channel-specific config depth. | WebWidget/API/Telegram/Email/WhatsApp/SMS/LINE channel models/controllers. | Todo | Channel create/update/show tests cover frontend settings screens. | +B5.2 execution breakdown: + +| Step | Implementation target | Reference source | Required tests | Status | +| --- | --- | --- | --- | --- | +| B5.2a | Add a request binder that accepts JSON, urlencoded form, and multipart FormData from the reused dashboard inbox screens. It must parse top-level settings plus nested keys such as `channel[type]`, `channel[website_url]`, `channel[selected_feature_flags][]`, and `csat_config[...]`. | `reference/chatwoot/app/javascript/dashboard/store/modules/inboxes/channelActions.js`, `reference/chatwoot/app/javascript/dashboard/store/modules/inboxes.js` | Handler tests for website multipart create, API JSON create, Telegram JSON create without explicit name, and settings update. | Next | +| B5.2b | Normalize channel type aliases from frontend slugs and Rails class names into the local storage format while keeping serializers Rails-compatible. | `reference/chatwoot/app/models/channel/*`, `_inbox.json.jbuilder` | Serializer tests prove stored slug returns `Channel::*` and unknown channel types are rejected with frontend-readable validation errors. | Todo | +| B5.2c | Persist core inbox settings sent by `permitted_params`: greeting, email collection, CSAT flag/config, auto-assignment, working-hours flag, out-of-office message, timezone, post-resolve messages, single-conversation lock, sender name type, business name, and portal ID. | `reference/chatwoot/app/controllers/api/v1/accounts/inboxes_controller.rb`, inbox settings Vue screens | Create/update tests reload the inbox and assert fields survive round trip in Chatwoot payload names. | Todo | +| B5.2d | Persist channel-specific settings into dedicated fields where they exist and `channel_config` where GoChat has no first-class column yet. | WebWidget/API/Telegram/LINE/Twilio/Email channel models and settings screens | Tests cover web widget `website_url/widget_color/welcome_*`, API `webhook_url`, Telegram `bot_token`, and LINE `line_channel_id` shapes. | Todo | +| B5.2e | Preserve backward compatibility for internal tests and existing local callers that still construct `service.CreateInboxRequest` with `channel_type` and simple fields. | Existing Go service callers and handler tests | Existing `TestInbox*` suite stays green. | Todo | + +B5.2 exit command set: + +```bash +env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/handler/api/v1 -run 'TestInboxHandler_ChatwootSerializerParity|TestInbox' -count=1 +env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./internal/service -run Inbox -count=1 +env GOCACHE=/tmp/gochat-gocache GOMODCACHE=/tmp/gochat-gomodcache go test ./... +git diff --check +``` + Active B4 task board: | ID | Task | Reference source | Status | Exit gate | @@ -247,6 +267,28 @@ Work proceeds top-down unless a failing test or frontend blocker forces a narrow | B11 | Captain/Copilot deep behavior. | Chatwoot Captain/Copilot controllers, services, frontend clients. | Assistant/tool/document/scenario/copilot thread/task tests and feature gates. | Todo | | B12 | Frontend smoke harness. | `reference/chatwoot` frontend. | Repeatable smoke command and checked gap report. | Todo | +Remaining slice landing plan: + +| Slice | First implementation checkpoint | Follow-up checkpoints | Done classification rule | +| --- | --- | --- | --- | +| B6 | Compare current Meilisearch document fields and global/entity search payloads against Chatwoot frontend consumers. | Add optional live Meilisearch integration gate, tighten account-scoped filters, and document DB fallback as development-only. | Done only after mocked tests and live-shape review prove search payloads work without DB-only assumptions. | +| B7 | SLA policy CRUD and applied-SLA persistence for new conversations. | Business-hours timer math, first/next/resolution breach events, capacity-aware assignment policy binding, report/list payloads. | Done only after lifecycle state tests cover active, hit, missed, and active-with-misses transitions. | +| B8 | Account-side CSAT list/metrics/review-note payload parity. | Resolve-triggered survey send idempotency, report/download filters, public/update lock regression, channel-specific send hooks. | Done only after account APIs, public APIs, and resolve listener agree on one message-linked response model. | +| B9 | Macro execution side effects for labels, status, assignee/team, priority, private notes, and attachments. | Automation rule condition/action parity, execution logs, webhook delivery retry, email transcript delivery, stop-on-match semantics. | Done only after actions mutate real conversations and async external actions are retryable or explicitly feature-gated. | +| 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. | +| 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. | + +Per-slice documentation rule: + +| Checkpoint type | Required doc update | +| --- | --- | +| Implementation commit | Add a commit ledger row, update the active task board status, add or refresh the current checkpoint bullets, and record verification commands. | +| Route change | Regenerate `docs/parity/gochat_routes.txt`; regenerate `docs/parity/route_parity.md` when tracked route sets change; update route counts in Current Baseline. | +| Serializer or request contract change | Link the `reference/chatwoot` controller/view/frontend client and add the fixture or handler test name that proves the contract. | +| Enterprise feature checkpoint | Update both the enterprise tracking table and the relevant B7-B11 remaining-slice row so the paid-feature scope stays visible. | +| Deferred gap | Keep the parent slice in `Review` or `Doing`; add a named follow-up instead of silently marking `Done`. | + ## Phase 0: Test And Route Baseline Status: done. @@ -722,3 +764,8 @@ Verification milestone gates: - 2026-06-05: B4 CRM Meilisearch checkpoint committed as `202da19 feat(crm): route crm search through meilisearch`; contact and company CRM search now routes non-empty queries through the configured search service, resolves Meilisearch result IDs back through account-scoped repositories to preserve Chatwoot CRM list payloads, wires the search reader in app bootstrap, and adds company document fallback coverage to global DB search. Focused search/service/repository/API tests, full `go test ./...`, and `git diff --check` passed. Route dump unchanged at `TOTAL: 820`. - 2026-06-05: B4 contact import label validation checkpoint committed as `653db81 feat(crm): validate imported contact labels`; CSV import now matches Chatwoot's approved-label guard by rejecting rows whose `labels` column contains labels absent from the account, preserving valid rows, recording failed row counts on `data_imports`, and preventing arbitrary tag creation from CSV input. Focused import/service/API tests, full `go test ./...`, and `git diff --check` passed. Route dump unchanged at `TOTAL: 820`. - 2026-06-05: B4 contact export email checkpoint committed as `c2766fe feat(crm): email contact export completions`; completed contact exports now invoke a Chatwoot-style `contact_export_complete` mailer boundary for the requesting user's email, using the export download URL and subject `Your contact's export file is available to download.`, while retaining the persisted notification. Focused export/service/API tests, full `go test ./...`, and `git diff --check` passed. Route dump unchanged at `TOTAL: 820`. +- 2026-06-05: B4 frontend CRM API smoke checkpoint committed as `ad29dc3 test(crm): cover chatwoot frontend crm smoke`; the handler-level flow mirrors the reused Chatwoot dashboard contacts/companies clients across CRUD, search, labels, contactable inboxes, notes, nested conversations, and company relation flows. Focused smoke tests, handler package tests, full `go test ./...`, and `git diff --check` passed. +- 2026-06-05: B4 documentation checkpoint committed as `c256e27 docs: record crm frontend smoke checkpoint`; B4 moved to Review with browser validation deferred to B12/M7. +- 2026-06-05: B5 inbox serializer checkpoint committed as `0e83e8d feat(inboxes): align chatwoot inbox serializers`; inbox list now returns `{ payload: [...] }`, show/create/update/reset-secret return raw Chatwoot-style inbox payloads, channel slugs serialize as `Channel::*`, avatar delete returns empty `200 OK`, async delete message matches Chatwoot, and `PATCH /api/v1/accounts/:account_id/inboxes/:inbox_id` was added. Focused inbox tests, handler package tests, route dump `TOTAL: 821`, route parity, full `go test ./...`, and `git diff --check` passed. +- 2026-06-05: B5 documentation checkpoint committed as `1f6ec3e docs: record inbox serializer checkpoint`; B5.1 is Done and B5.2 multipart/JSON `channel[...]` create/update binding is the next active implementation slice. +- 2026-06-05: Planning tracker expanded for handoff continuity. B5.2 now has executable substeps, B6-B12 have explicit first checkpoints and Done rules, and every future checkpoint has a required documentation update rule.