diff --git a/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md b/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md index 189ccc58..5eb6e61d 100644 --- a/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md +++ b/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md @@ -16,7 +16,7 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc ## Current Baseline -- Latest implementation checkpoint: `7aa3362 feat(profile): support chatwoot settings updates`. +- Latest implementation checkpoint: `9f89cbf feat(conversations): align chatwoot message serializers`. - Worktree status at this planning checkpoint: clean. - `go test ./...` passes. - Route dump succeeds with `TOTAL: 805` after Chatwoot root auth/session routes were added. @@ -71,12 +71,13 @@ This ledger records the committed parity checkpoints that future slices should b | `56a8c5b feat(profile): align chatwoot user serializer` | Aligned `/api/v1/profile`, profile update, avatar delete/update, availability, auto-offline, and reset-access-token responses to Chatwoot's raw `api/v1/models/_user.json.jbuilder` shape. Added user/account/account_user fields and personal access-token persistence needed by the serializer. | Focused profile/API tests passed; sandboxed `go test ./...` hit socket restrictions; escalated full `go test ./...` passed; `git diff --check` passed. | Continue B2 with `/auth/sign_in`, `/auth/validate_token`, auth headers/cookie contract, and current-user payload fixtures. | | `e59f9f3 feat(auth): add chatwoot session routes` | Added root `/auth/sign_in`, `/auth/validate_token`, `/auth/sign_out`, and `/auth/password` routes consumed by the reused Chatwoot frontend. Sign-in now emits DeviseTokenAuth-compatible `access-token`, `token-type`, `client`, `expiry`, and `uid` headers and returns raw `{ data: user }`; validate-token returns `{ payload: { success, data } }`. | Focused auth/profile tests passed; route dump regenerated with `TOTAL: 805`; route parity remained `251 exact, 0 missing`; escalated full `go test ./...` passed; `git diff --check` passed. | Continue B2 with profile settings update parity: `display_name`, `message_signature`, `ui_settings`, password update, and multipart avatar handling. | | `7aa3362 feat(profile): support chatwoot settings updates` | Completed profile settings update parity for `display_name`, `message_signature`, `ui_settings`, `phone_number` custom attributes, password changes with current-password verification, and multipart `profile[...]` FormData including avatar file input. | Focused profile tests passed; escalated full `go test ./...` passed; `git diff --check` passed. | B2 core auth/profile fixtures are complete enough to move next to conversations/messages serializer parity. | +| `9f89cbf feat(conversations): align chatwoot message serializers` | Added Chatwoot conversation/message serializer boundary for dashboard list/show/filter, message index, message create/update/retry, status toggle payloads, display-id route resolution, outgoing/private message defaults, `echo_id`, `content_attributes`, and conversation/message parity migration fields. | Focused conversation/message handler tests passed; full `go test ./...` passed; `git diff --check` passed. | Continue B3 with delete/update status parity, multipart attachment create, team assignment response parity, and deeper message finder before moving to contacts/companies. | ## Next Slice Contract -Completed implementation slice: B2 profile-side serializer parity now returns the Chatwoot raw user payload for profile reads and mutations. +Completed implementation slice: B3 first checkpoint now returns Chatwoot dashboard-compatible conversation/message payloads for the core inbox flows. -Next implementation slice: move to Q4/B3 conversations/messages serializer and behavior fixtures. +Next implementation slice: continue Q4/B3 conversations/messages behavior fixtures for remaining mutation and attachment gaps. | Step | Required result | Reference source | Verification | | --- | --- | --- | --- | @@ -96,6 +97,17 @@ Current B2 profile checkpoint: - Added Chatwoot root auth/session routes. `/auth/sign_in` now accepts normalized email/password login, emits the auth headers stored by frontend `cw_d_session_info`, and returns the profile serializer under `data`. `/auth/validate_token` validates the same `access-token` header and returns the frontend-expected `payload.data` shape. `/auth/sign_out` revokes the refresh session. - Added profile settings update support for JSON and multipart form payloads produced by `dashboard/api/auth.js`: `profile[display_name]`, `profile[message_signature]`, `profile[avatar]`, JSON `profile.ui_settings`, `profile.phone_number`, and password update fields now persist and return the raw Chatwoot user serializer. +Current B3 conversation/message checkpoint: + +- Conversation list now returns Chatwoot's `index.json.jbuilder` shape: `{ data: { meta, payload } }`, with `payload` entries built from `api/v1/conversations/partials/_conversation.json.jbuilder` fields such as `meta.sender`, `messages`, `labels`, timestamps, status, priority, and unread count. +- Conversation show/create/update/priority/labels responses now return raw conversation payloads instead of the Go `{success,data}` envelope for frontend-consumed dashboard endpoints. +- Conversation route IDs now resolve by account-scoped `display_id` first, with legacy primary-key fallback, and new conversations receive account-scoped display IDs. +- Message list now returns Chatwoot's `{ meta, payload }` shape with contact/assignee metadata and serialized messages matching `api/v1/models/_message.json.jbuilder` field names. +- Message create accepts the reused frontend payload from `dashboard/api/inbox/message.js`, including omitted `message_type`, `private`, `echo_id`, JSON or multipart `content_attributes`, and defaults to outgoing text messages like Chatwoot's dashboard composer. +- Message create/update/retry return raw Chatwoot message payloads with numeric `message_type` values expected by `shared/constants/messages.js`. +- Added migration `000018_add_conversation_message_parity_fields` for display-id routing and message serializer fields such as `echo_id`, `status`, and JSON attributes. +- Remaining B3 gaps: message delete should return the deleted-message payload instead of `204`; API-inbox status update semantics need deeper parity; multipart attachment create currently only preserves form fields and still needs full attachment persistence; team assignment should render the team payload rather than conversation fallback; message finder pagination needs `before/after` behavior verification. + ## Immediate Execution Queue This is the ordered queue for the next implementation slices. Do not skip the route and test gates even when working on deeper business behavior. @@ -146,7 +158,7 @@ Work proceeds top-down unless a failing test or frontend blocker forces a narrow | --- | --- | --- | --- | --- | | B1 | Webhook ingress route and handler parity. | `reference/chatwoot/config/routes.rb:614-624`, `reference/chatwoot/app/controllers/webhooks/*`, `reference/chatwoot/app/controllers/api/v1/webhooks_controller.rb` | Provider lookup tests, router route dump, `go test ./...`. | Done | | 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. | Todo | +| 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. | Doing | | B4 | Contact/company behavior fixtures. | Chatwoot contact/company controllers, merge/import/export/notes/labels. | Fixture tests for CRUD/search/merge/relation/import-export shells. | 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. | Todo | | B6 | Meilisearch live-shape review. | Chatwoot frontend search usage and search controllers. | Meilisearch-backed response fixtures plus optional live integration gate. | Todo | @@ -620,3 +632,4 @@ Verification milestone gates: - 2026-06-05: Tightened LINE webhook signature parity. `/webhooks/line/:line_channel_id` now rejects missing signatures when a `channel_secret` is configured and only persists signed payloads whose `X-Line-Signature` matches the raw request body. Focused webhook tests and full `go test ./...` passed. - 2026-06-05: Completed WhatsApp route-level webhook verification coverage. `/webhooks/whatsapp/:phone_number` now has tests for verify-token challenge echo, signed Cloud API POST persistence, and missing `X-Hub-Signature-256` rejection without message persistence. Focused webhook tests and full `go test ./...` passed. - 2026-06-05: Finalized P6.7 provider classification. Twitter CRC now returns `sha256=` like Chatwoot, Twitter route-level CRC/event tests exist, Instagram rejects unsigned signed-required event payloads without persistence, and Telegram, SMS/Twilio, Instagram, Shopify, and the already completed providers are marked Done in the webhook ingress tracker. Focused webhook/API tests and full `go test ./...` passed. +- 2026-06-05: Started B3 dashboard conversation/message serializer parity. Conversation list/filter/show/create/update and message list/create/update/retry now return Chatwoot frontend payload shapes instead of the Go response envelope; message creation accepts frontend composer JSON/multipart fields and preserves `echo_id`/`content_attributes`; account-scoped conversation `display_id` routing is now generated and resolved. Verified focused conversation/message handler tests, full `go test ./...`, and `git diff --check`.