From 7a7bc4197a9d58436c0453002fe7b9b52e247032 Mon Sep 17 00:00:00 2001 From: Rogee Date: Fri, 5 Jun 2026 04:06:45 +0800 Subject: [PATCH] docs: record nested conversations checkpoint --- docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md b/docs/CHATWOOT_PARITY_DEVELOPMENT_PLAN.md index f98a507f..f5a08c95 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: `af57482 feat(crm): align contact note payloads`. +- Latest implementation checkpoint: `fb775b7 feat(crm): align nested conversation payloads`. - Worktree status at this planning checkpoint: clean. - `go test ./...` passes. - Route dump succeeds with `TOTAL: 820` after adding the Chatwoot-compatible `PUT` contact note update route. @@ -79,16 +79,17 @@ This ledger records the committed parity checkpoints that future slices should b | `8eed2f1 feat(crm): persist contact data imports` | Advanced B4 import/data-import parity: added Chatwoot-shaped `data_imports` fields and migration, changed contacts import missing-file errors to `422`, successful imports to empty `200 OK`, persisted import lifecycle states/counts/errors, and made CSV import merge/update existing contacts by identifier/email/phone with labels/custom attributes. | Focused import tests passed; handler/service/repository/router package tests passed; full `go test ./...` passed; `git diff --check` passed. | Continue B4.6 with contacts export async artifact/download/notification parity, then notes serializer depth, Meilisearch-backed CRM search, and frontend smoke fixtures. | | `47c2b80 feat(crm): persist contact export artifacts` | Advanced B4 export parity: `POST /contacts/export` now creates a persisted `contact_exports` artifact, stores Chatwoot default/requested CSV columns with UTF-8 BOM, supports label/filter export inputs, exposes a local download URL, and creates a user notification with export metadata. | Focused export tests passed; handler/service/repository/router package tests passed; regenerated route dump `TOTAL: 819`; route parity remains `262 exact, 0 missing`; full `go test ./...` passed; `git diff --check` passed. | Continue B4 with real email delivery for export completion if required by mailer infrastructure, contact/company notes payload depth, Meilisearch-backed CRM search, and frontend smoke fixtures. | | `af57482 feat(crm): align contact note payloads` | Advanced B4 notes parity: contact notes now return raw Chatwoot note arrays/objects with nested agent payloads, flat and nested `note.content` requests are accepted, create/update/show avoid the Go API envelope, delete returns empty `200 OK`, note deletion hard-deletes like Chatwoot, company note payloads include user metadata, and the `PUT` note update route is registered. | Focused notes/API tests passed; full `go test ./...` passed; route dump regenerated with `TOTAL: 820`; tracked route parity remains `262 exact, 0 missing`; `git diff --check` passed. | Continue B4 with nested contact/company conversations payload depth, CRM Meilisearch search shape, frontend smoke fixtures, and deferred export email delivery. | +| `fb775b7 feat(crm): align nested conversation payloads` | Advanced B4 nested CRM conversation parity: contact and company conversations now render Chatwoot's `{ payload: [conversation partial] }` shape with nested `meta.sender`, `messages`, `last_non_activity_message`, account/inbox IDs, timestamps, priority, labels, and unread fields from the shared conversation serializer. Company conversations now follow the enterprise controller's latest-20, `last_activity_at DESC` behavior instead of paginated raw models. | Focused nested conversation handler tests passed; focused handler/service/repository/router tests passed; escalated full `go test ./...` passed after sandbox socket limits blocked local-only auth/middleware tests; `git diff --check` passed. No route changes; route dump remains `TOTAL: 820`. | Continue B4 with CRM Meilisearch search shape, stricter import label validation, frontend smoke fixtures, and deferred export email delivery. | ## Next Slice Contract Completed implementation slice: B4 contact merge, contact import, contact export, and notes checkpoints 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, and Chatwoot-shaped contact/company notes for the CRM flows. -Next implementation slice: continue B4 with nested contact/company conversations payload depth and Meilisearch-backed CRM search. Keep B3 in review for delivery/storage side-effect parity, and keep real SMTP/email delivery for export completion tied to the broader mailer infrastructure work. +Next implementation slice: continue B4 with Meilisearch-backed CRM search and stricter import label validation. Keep B3 in review for delivery/storage side-effect parity, and keep real SMTP/email delivery for export completion tied to the broader mailer infrastructure work. | Step | Required result | Reference source | Verification | | --- | --- | --- | --- | -| N1 | Finish remaining contact/company behavior gaps: nested conversations depth and any export email-delivery side effects not covered by the persisted notification. | Chatwoot contacts and enterprise companies controllers/Jbuilder views/frontend API clients. | Handler/service tests assert status codes, persistence, and exact `{ payload }` or `{ meta, payload }` shape. | +| N1 | Finish remaining contact/company behavior gaps: stricter import label validation and any export email-delivery side effects not covered by the persisted notification. | Chatwoot contacts and enterprise companies controllers/Jbuilder views/frontend API clients. | Handler/service tests assert status codes, persistence, and exact `{ payload }` or `{ meta, payload }` shape. | | N2 | Move CRM search behavior to Meilisearch-backed document shape instead of DB/LIKE as the final path. | 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. | @@ -135,8 +136,9 @@ Current B4 contacts/companies checkpoint: - Added Chatwoot-shaped `data_imports` persistence for contact CSV imports. Missing `import_file` now returns `422 { error: "failed to import contacts" }`, successful imports return empty `200 OK`, import state/count/error fields are recorded, and CSV rows merge/update existing contacts by identifier/email/phone while preserving labels and unknown/custom columns in contact attributes. - Added persisted contact export artifacts for `POST /contacts/export`: default/requested column handling, label/filter export inputs, UTF-8 BOM CSV content, local download URL, row counts, and a user notification carrying file metadata. - Added Chatwoot note serializer parity for contact notes: raw array/object responses, nested agent payloads, flat and nested note request bodies, empty `200 OK` destroy, hard-delete semantics, and `PUT`/`PATCH` update routes. Company note payloads now include nested user metadata. +- Added nested contact/company conversation serializer parity: both endpoints now return `{ payload: [...] }` arrays built from the shared Chatwoot conversation partial, including nested sender metadata, latest message payloads, `last_non_activity_message`, labels, timestamps, priority, and unread fields. Company conversations are limited to the latest 20 by `last_activity_at DESC` like the enterprise controller. - Route dump is now `TOTAL: 820` and tracked route parity is `262 exact, 0 missing`. -- Remaining B4 gaps: nested contact/company conversations payload depth, CRM Meilisearch search shape, stricter import label validation against account labels, real SMTP/email delivery for export completion, and frontend smoke validation. +- Remaining B4 gaps: CRM Meilisearch search shape, stricter import label validation against account labels, real SMTP/email delivery for export completion, and frontend smoke validation. Active B4 task board: @@ -151,7 +153,7 @@ Active B4 task board: | B4.6b | Contacts export artifact/download behavior. | Contacts export controller and `Account::ContactsExportJob`. | Done | `47c2b80`; export request persists CSV artifact, download URL, label/filter data, row count, and notification metadata. | | B4.6c | Contacts export email delivery. | `AdministratorNotifications::AccountNotificationMailer#contact_export_complete`. | Todo | Real mailer delivery is wired once mail infrastructure work reaches P5.4; current checkpoint persists notification metadata only. | | B4.7a | Contact/company notes payload depth. | Contact notes controller/Jbuilder, company notes frontend consumer. | Done | `af57482`; raw contact note array/object fixtures, nested user payloads, empty destroy response, and company note user metadata tests. | -| B4.7b | Contact/company conversations payload depth. | Nested conversations controllers and Jbuilder views. | Todo | Payload fixtures match Chatwoot serializers for nested CRM views. | +| B4.7b | Contact/company conversations payload depth. | Nested conversations controllers and Jbuilder views. | Done | `fb775b7`; nested CRM conversation payload fixtures cover shared conversation partial fields, latest messages, sender metadata, and company latest-20 ordering. | | B4.8 | CRM search through Meilisearch document shape. | Chatwoot frontend search usage and local Meilisearch engine. | Todo | Mocked Meilisearch tests cover contacts/companies and DB fallback is not the final path. | | B4.9 | Reused frontend CRM smoke. | `reference/chatwoot` dashboard contacts/companies screens. | Todo | Contact list/search/show/edit/labels/company relation flows run without frontend adapters. | @@ -687,3 +689,4 @@ Verification milestone gates: - 2026-06-05: B4 contact import/data-import checkpoint committed as `8eed2f1 feat(crm): persist contact data imports`; contact imports now persist Chatwoot-shaped `data_imports`, missing `import_file` returns `422`, successful imports return empty `200 OK`, lifecycle counts/errors are recorded, and CSV rows merge/update existing contacts by identifier/email/phone while applying labels and custom attributes. Focused import tests, handler/service/repository/router package tests, full `go test ./...`, and `git diff --check` passed. - 2026-06-05: B4 contact export artifact checkpoint committed as `47c2b80 feat(crm): persist contact export artifacts`; `POST /contacts/export` now persists `contact_exports`, generates Chatwoot default/requested CSV columns with UTF-8 BOM, supports label/filter export inputs, stores a download URL and row count, and creates a user notification with file metadata. Focused export tests, handler/service/repository/router package tests, regenerated route dump `TOTAL: 819`, route parity `262 exact, 0 missing`, full `go test ./...`, and `git diff --check` passed. - 2026-06-05: B4 contact/company notes checkpoint committed as `af57482 feat(crm): align contact note payloads`; contact note index/create/show/update now returns Chatwoot raw note JSON with nested agent payloads, accepts flat and nested note params, destroy returns empty `200 OK` and hard-deletes notes, company notes include nested user metadata, and the Rails-compatible `PUT` note update route is registered. Focused notes/API tests, full `go test ./...`, regenerated route dump `TOTAL: 820`, route parity `262 exact, 0 missing`, and `git diff --check` passed. +- 2026-06-05: B4 nested contact/company conversations checkpoint committed as `fb775b7 feat(crm): align nested conversation payloads`; contact and company nested conversation endpoints now return Chatwoot `{ payload: [...] }` conversation partials with nested sender metadata, latest message payloads, `last_non_activity_message`, labels, timestamps, priority, account/inbox fields, and company latest-20 ordering by `last_activity_at DESC`. Focused nested conversation tests, focused handler/service/repository/router tests, escalated full `go test ./...`, and `git diff --check` passed. Route dump unchanged at `TOTAL: 820`.