docs: record inbox serializer checkpoint

This commit is contained in:
2026-06-05 04:49:48 +08:00
parent 0e83e8d8b7
commit 1f6ec3edb3
+30 -10
View File
@@ -16,10 +16,10 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc
## Current Baseline
- Latest implementation checkpoint: `ad29dc3 test(crm): cover chatwoot frontend crm smoke`.
- Latest implementation checkpoint: `0e83e8d feat(inboxes): align chatwoot inbox serializers`.
- Worktree status at this planning checkpoint: clean after docs checkpoint.
- `go test ./...` passes.
- Route dump succeeds with `TOTAL: 820` after adding the Chatwoot-compatible `PUT` contact note update route.
- 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`.
- Tracked frontend-critical route audit covers 262 Chatwoot routes: 262 exact, 0 method-compatible, 0 parameter-compatible, 0 missing.
- `/api/v1/widget` stubs are burned down and public inbox/contact/conversation/message core flows are backed by real handlers.
@@ -84,19 +84,20 @@ This ledger records the committed parity checkpoints that future slices should b
| `653db81 feat(crm): validate imported contact labels` | Completed the remaining B4 import validation gap: contact CSV import now validates `labels` against existing account labels before creating/updating contacts, rejects rows with unknown labels, records failed row counts, preserves canonical existing label names, and no longer creates arbitrary account tags from import input. | Focused import/service/API tests passed; full `go test ./...` passed; `git diff --check` passed. No route changes; route dump remains `TOTAL: 820`. | Continue B4 with frontend CRM smoke fixtures and deferred export email delivery. |
| `c2766fe feat(crm): email contact export completions` | Completed B4 contact export email delivery: the completed export artifact now triggers a Chatwoot-style `contact_export_complete` mailer boundary for the requesting user's email, using the same subject and download URL semantics while preserving the existing persisted notification. The default mailer reads Chatwoot-compatible SMTP env vars and no-ops when SMTP is not configured. | Focused export/service/API tests passed; full `go test ./...` passed; `git diff --check` passed. No route changes; route dump remains `TOTAL: 820`. | Continue B4 with frontend CRM smoke fixtures. |
| `ad29dc3 test(crm): cover chatwoot frontend crm smoke` | Closed the B4 CRM API smoke gap with a repeatable handler-level flow that mirrors the reused Chatwoot dashboard contact/company clients: contact create/list/search/show/update/custom-attribute deletion/labels/contactable-inboxes/notes/conversations plus company create/list/search/show/update/custom-attribute deletion/contact attach/list/search/notes/conversations. | `go test ./internal/handler/api/v1 -run TestChatwootFrontendCRMSmoke -count=1`; `go test ./internal/handler/api/v1 -count=1`; `go test ./...`; `git diff --check`. | Move B4 to review. True browser Playwright validation with the reused frontend remains tracked by B12/M7. |
| `0e83e8d feat(inboxes): align chatwoot inbox serializers` | Started B5 inbox/channel parity by rendering Chatwoot `api/v1/models/_inbox.json.jbuilder`-style payloads for inbox list/show/create/update/reset-secret flows, mapping local channel slugs to `Channel::*` class names, exposing channel-specific settings from `channel_config`, returning Chatwoot's async delete message, making avatar delete empty `200 OK`, and adding the frontend-used `PATCH /inboxes/:id` route. | `go test ./internal/handler/api/v1 -run 'TestInboxHandler_ChatwootSerializerParity|TestInbox' -count=1`; `go test ./internal/handler/api/v1 -count=1`; regenerated `docs/parity/gochat_routes.txt` (`TOTAL: 821`); `go run ./cmd/route_parity`; `go test ./...`; `git diff --check`. | Continue B5 with create/update request binding for Chatwoot multipart `channel[...]` payloads, working-hours/settings persistence, inbox members, and channel-specific config depth. |
## Next Slice Contract
Completed implementation slice: B4 contact merge, contact import, contact export, notes, nested conversation payloads, Meilisearch-first CRM search, and frontend CRM API smoke now cover contact/company CRUD payloads, company-contact relations, contact labels, label filtering, avatar deletion, selected custom-attribute deletion, company destroy-custom-attributes, dashboard contact merge behavior, persisted contact import lifecycle behavior, persisted contact export artifacts, Chatwoot-shaped contact/company notes, nested contact/company conversations, and the reused dashboard contacts/companies API call sequence.
Next implementation slice: start B5 inbox/channel behavior fixtures. Keep B3 and B4 in review for delivery/storage side-effect parity and real browser frontend validation.
Next implementation slice: continue B5 inbox/channel behavior fixtures. Keep B3 and B4 in review for delivery/storage side-effect parity and real browser frontend validation.
| Step | Required result | Reference source | Verification |
| --- | --- | --- | --- |
| N1 | Finish remaining contact/company behavior gaps with frontend API smoke validation. | Chatwoot contacts and enterprise companies controllers/Jbuilder views/frontend API clients. | Done by `ad29dc3`; handler test asserts the dashboard contact/company API sequence without adapters. |
| N2 | Harden CRM Meilisearch behavior by extending indexed contact/company fields as new frontend cases are found. | Chatwoot search usage and local Meilisearch decision. | Search tests run against mocked Meilisearch engine and preserve CRM payload contracts. |
| N3 | Preserve completed auth/profile/conversation/message fixtures while expanding the CRM suite. | Existing focused tests and Chatwoot frontend clients. | Existing auth/profile/conversation/message focused tests remain green. |
| N4 | Regenerate route artifacts after route changes; current route dump is `TOTAL: 820` and tracked route parity is `262 exact, 0 missing`. | `cmd/dump_routes`, `cmd/route_parity`. | Route commands run when applicable. |
| N1 | Align inbox list/show/create/update/delete/avatar/reset-secret serializer shapes. | `InboxesController`, `api/v1/models/_inbox.json.jbuilder`, dashboard inbox store. | Done by `0e83e8d`; list returns `{ payload: [...] }`, item responses are raw inbox payloads, channel slugs serialize as `Channel::*`, and route dump is `TOTAL: 821`. |
| 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`. | Handler tests cover website/API/telegram create and settings update request bodies. |
| N3 | Persist inbox settings and working hours with Chatwoot defaults. | `OutOfOffisable`, `Inbox#OFFISABLE_ATTRS`, settings pages. | Update tests prove greeting, CSAT, auto-assignment, timezone, sender, business name, and weekly schedule behavior. |
| N4 | Deepen inbox member/channel-specific flows. | `InboxMembersController`, channel controllers/models. | Member list/update and channel config tests return frontend-compatible payloads. |
| N5 | Update this tracker after every implementation checkpoint. | This document. | `git diff --check`; `go test ./...` for Go changes. |
Current B2 profile checkpoint:
@@ -148,6 +149,25 @@ Current B4 contacts/companies checkpoint:
- Route dump is now `TOTAL: 820` and tracked route parity is `262 exact, 0 missing`.
- Remaining B4 review gap: real browser validation is not yet run and remains in B12/M7; API-level CRM frontend contract coverage is present.
Current B5 inbox/channel checkpoint:
- Inbox list now follows Chatwoot `index.json.jbuilder` and returns `{ payload: [inbox] }` instead of the older `{ inboxes, meta }` envelope expected by earlier local tests.
- Inbox show/create/update/reset-secret style responses now render raw Chatwoot inbox payloads rather than raw Go models; delete returns `Your inbox deletion request will be processed in some time.` and avatar delete returns an empty `200 OK`.
- Local channel slugs are serialized to frontend-required Rails channel class names such as `Channel::WebWidget`, `Channel::Api`, `Channel::Telegram`, and `Channel::TwilioSms`.
- Channel-specific fields stored in `channel_config` are surfaced in the inbox payload for web widget, API, Telegram, Facebook/Instagram/TikTok, Twilio, Email, and WhatsApp-style keys.
- Added the frontend-used `PATCH /api/v1/accounts/:account_id/inboxes/:inbox_id` route alias; route dump is now `TOTAL: 821`, and tracked route parity remains regenerated with zero missing tracked routes.
- Remaining B5 gaps: Chatwoot multipart `channel[...]` create/update binding, durable working-hours update behavior, full inbox settings persistence, inbox member payload depth, channel-specific creation/config parity, and inbox limit enforcement.
Active B5 task board:
| ID | Task | Reference source | Status | Exit gate |
| --- | --- | --- | --- | --- |
| B5.1 | Inbox CRUD serializer and route shape. | `InboxesController`, `_inbox.json.jbuilder`, dashboard inbox store/API. | Done | `0e83e8d`; serializer parity test, route dump `TOTAL: 821`, full tests. |
| B5.2 | Inbox create/update request binding and settings persistence. | `buildInboxData`, `permitted_params`, settings pages. | Todo | JSON and multipart `channel[...]` requests persist core inbox/channel settings. |
| B5.3 | Working hours and out-of-office parity. | `OutOfOffisable`, working hour controller/model. | Todo | Weekly schedule create/update/show and `out_of_office` tests match Chatwoot semantics. |
| 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. |
Active B4 task board:
| ID | Task | Reference source | Status | Exit gate |
@@ -218,7 +238,7 @@ Work proceeds top-down unless a failing test or frontend blocker forces a narrow
| B2 | Auth/profile serializer fixtures. | `reference/chatwoot/app/controllers/api/v1/profile*`, frontend auth client. | Fixture tests for login/current user/profile/availability/settings. | Done |
| B3 | Conversation/message serializer and behavior fixtures. | Chatwoot conversation/message controllers, entities, jobs. | Fixture tests for list/show/create/update/private notes/attachments/status/assignment. | Review |
| B4 | Contact/company behavior fixtures. | Chatwoot contact/company controllers, merge/import/export/notes/labels. | Fixture tests for CRUD/search/merge/relation/import-export shells and frontend CRM API smoke. | Review |
| B5 | Inbox/channel behavior fixtures. | Chatwoot inbox/channel controllers and channel models. | Fixture tests for inbox CRUD, settings, business hours, members, avatar, channel config. | Todo |
| B5 | Inbox/channel behavior fixtures. | Chatwoot inbox/channel controllers and channel models. | Fixture tests for inbox CRUD, settings, business hours, members, avatar, channel config. | Doing |
| B6 | Meilisearch live-shape review. | Chatwoot frontend search usage and search controllers. | Meilisearch-backed response fixtures plus optional live integration gate. | Todo |
| B7 | SLA and assignment capacity. | Chatwoot enterprise SLA and assignment policy behavior. | Unit/integration tests for SLA state, breach, assignment capacity, policy selection. | Todo |
| B8 | CSAT account-side completion. | Chatwoot CSAT survey responses, reports, downloads, listeners. | Metrics/list/review/download/send idempotency tests. | Todo |
@@ -440,7 +460,7 @@ Serializer parity work plan:
| S1 | Auth and profile | `reference/chatwoot/app/controllers/api/v1/profile*`, frontend auth API usage | fixture tests for current user/profile payloads | Done |
| S2 | Conversations and messages | `reference/chatwoot/app/controllers/api/v1/accounts/conversations*`, serializers/entities | fixture tests for index/show/message create/update | Review |
| S3 | Contacts and companies | `reference/chatwoot/app/controllers/api/v1/accounts/contacts*`, `companies*` | fixture tests for list/show/search/merge/relation payloads | Doing |
| S4 | Inboxes and channels | `reference/chatwoot/app/controllers/api/v1/accounts/inboxes*`, channel controllers | fixture tests for inbox CRUD, channel settings, widget config | Todo |
| S4 | Inboxes and channels | `reference/chatwoot/app/controllers/api/v1/accounts/inboxes*`, channel controllers | fixture tests for inbox CRUD, channel settings, widget config | Doing |
| S5 | Notifications and settings | `reference/chatwoot/app/controllers/api/v1/accounts/notifications*` | fixture tests for notification list/actions/settings | Todo |
| S6 | Reports and CSAT | `reference/chatwoot/app/controllers/api/v1/accounts/reports*`, `csat_survey_responses*` | fixture tests for report filters and CSAT metrics/list | Todo |
| S7 | Widget/public | `reference/chatwoot/app/controllers/api/v1/widget*`, `public/api/v1*` | widget smoke fixtures and public flow tests | Doing |
@@ -580,7 +600,7 @@ Tracking table:
| P6.2 | Contact APIs | `docs/ROUTE_GAP_ANALYSIS.md`, contact handlers/services | Finish merge, import/export/data-import, notes serializer depth, and Meilisearch-backed CRM search. | Doing |
| P6.3 | Conversation APIs | `docs/ROUTE_GAP_ANALYSIS.md`, conversation handlers/services | Implement frontend-critical filters, assignment, status, snooze, merge, bulk actions. | Todo |
| P6.4 | Message APIs | `docs/ROUTE_GAP_ANALYSIS.md`, message handlers/services | Implement create/list/delete, private notes, attachments, source attribution, events. | Todo |
| P6.5 | Inbox APIs | `docs/ROUTE_GAP_ANALYSIS.md`, inbox handlers/services | Implement CRUD, assignable agents, avatar, campaigns, channel settings, reset secret. | Todo |
| P6.5 | Inbox APIs | `docs/ROUTE_GAP_ANALYSIS.md`, inbox handlers/services | Implement CRUD, assignable agents, avatar, campaigns, channel settings, reset secret. | Doing |
| P6.6 | Widget/public APIs | `docs/ROUTE_GAP_ANALYSIS.md`, widget/channel provider code, `chatwootParityStub` routes | Widget/public frontend-critical route behavior is handler-backed, including public inbox flow, direct uploads/attachments, and public CSAT survey submission. | Done |
| P6.7 | Webhook ingress | `internal/router/router.go`, `internal/handler/webhook/*`, channel providers | Replace generic placeholder with provider-specific verified ingestion and dispatch. | Done |