Skip to content

Commit c2709f7

Browse files
AchoArnoldCopilotgreptile-apps[bot]
authored
feat: add contacts management and thread resolution (NdoleStudio#957)
* docs: add contacts feature implementation plan Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8dd82cae-8bc6-4eaa-9b90-95073720c577 * feat(api): add Contact entity and ContactProperties jsonb type Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(api): wrap contact property errors Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(api): add ContactDetails to message threads Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(api): add ContactRepository with GORM implementation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(api): add contact store/update/index requests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(api): keep contact sanitization ordered Move sanitizeUniqueStrings into the shared requests helper. Preserve first-seen ordering after normalization. Add a direct ToContacts nil-properties regression test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(api): add contact validator Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(api): accept common CSV MIME types Allow .csv extension only; accept common browser MIME fallbacks for uploads. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(api): add ContactService with cached contact-map resolution Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(api): opt in contact resolution Add contacts query parsing and optional ContactDetails enrichment through a contact map provider. DI passes nil until Task 8 wires ContactService. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(api): add ContactHandler and wire contacts into DI container - Add ContactHandler with authenticated /v1/contacts routes: GET/POST /v1/contacts, POST /v1/contacts/upload, PUT/DELETE /v1/contacts/:contactID. - Load user-scoped contact before Update/Delete so a missing or cross-user contact returns 404 (avoids the repo's zero-row Delete returning 204 while advertising 404). - Support one-and-many JSON create via ContactStoreRequest and reuse ContactService.CreateMany so cache invalidation stays single-shot for Store and CSV upload alike. - Add DI getters ContactRepository, ContactService, ContactHandlerValidator, ContactHandler and RegisterContactRoutes; register the routes alongside RegisterMessageThreadRoutes. - Finalise Task 7 by injecting container.ContactService() into MessageThreadService, replacing the temporary nil dependency. - Cover all five routes with real Fiber requests plus a shared ContactRepository fake that verifies service/repository effects, and pin the DI wiring with a compile-time test that constructs MessageThreadService with the ContactService. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore(api): regenerate contacts swagger Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(api): mark contact fields optional Make emails/properties optional in contact request DTOs. Regenerate Swagger docs and add request JSON regression tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore(web): regenerate API models with Contact types Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(web): add contacts Pinia store Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(web): avoid false contact reload errors Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(web): add contacts management page with add/edit/delete/import dialogs Add the /contacts page grounded in the existing Vuetify theme. Header uses text-display-large; debounced search drives the API ?query= param. VDataTable columns: Name, Phone Numbers, Emails, Created, Updated, Actions. Rows show avatar initials, phone chips and relative timestamps via humanizeTime. Add/edit/delete/import-CSV dialogs use opacity 0.9 and warning-colored Close controls. Add/Edit has repeatable phone numbers, emails and free-form properties, preserved on edit. CSV import surfaces row-indexed API validation errors inline, not only via a toast. loadContacts forwards the trimmed search value as the query param, keeping Task 11's contract. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(web): guard stale contacts loads Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(web): display contact names on threads Preserve contact details across mark-read updates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(api): return accurate contacts total for server pagination Extend the contact repository/service/handler so GET /v1/contacts returns a top-level total count for the same user/query filter, independent of skip/limit, enabling true server-side pagination. - add ContactRepository.Count reusing a shared scopedContactQuery helper so Index and Count filters can never drift; Count ignores limit/offset - add ContactService.Count and handler responseOKWithTotal; Index returns total - add Total to responses.ContactsResponse and regenerate Swagger - sanitize parsed CSV rows before validation so CSV and JSON accept the same phone/email formats; drop the now-redundant re-sanitize on upload - assert Scan error behaviour instead of the unexported stacktrace type - tests for count filter parity, total propagation, and CSV sanitization Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(web): server-side pagination for the contacts page - store total now reflects the server count; loadContacts accepts skip and limit and remembers the current window so mutation refreshes stay in place - contacts page uses VDataTableServer with items-length bound to the server total; page/size changes fetch the correct skip/limit and a debounced query resets to page 1 without duplicate requests - delete bumps the load generation so an in-flight load cannot resurrect a deleted contact, without leaving loading stuck or hiding delete errors - remove the dead filteredContacts computed and add defensive null coalescing for emails/phone_numbers in the table display - regenerate API models with the new contacts total field Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(web): mark contacts headers unsortable Remove misleading sort affordances from the contacts table. Keep the subtitle aligned with the active search state. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: add contacts integration coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1f3addc9-71dd-4cb7-bfae-e6fdcc8511af * fix(web): prefix Vuetify composables Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(web): define contacts header styling Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(web): refine contacts table Improve the contacts table layout, actions, relative timestamps, and header emphasis. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(web): define contact phone input Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(web): improve contact dialog fields Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: display of buttons on contacts page * feat(api): limit contacts by plan Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: updated mcp.json to remove axiom and playwright * fix(web): update reactive page composables Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a93bfbb-739a-414c-8eb4-48b15a69fb9d * fix: align contacts sorting and caching Propagate contact table sorting through the API and repository while keeping contact lookups on the process-local cache. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dec094f9-5386-4607-998a-1701ac10b7cf * Update api/pkg/repositories/gorm_contact_repository.go Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(api): delete contacts with user account Subscribe contact cleanup to account deletion events so user contact data is removed from storage and invalidated from the contact-map cache. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dec094f9-5386-4607-998a-1701ac10b7cf * fix(api): restore contact repository build Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dec094f9-5386-4607-998a-1701ac10b7cf * perf(contacts): bound thread contact lookups Fetch and cache only phone numbers present in the current thread page. Keep cache entries consistent across mutations and include the staged contact form UX updates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ffe6b904-8f76-4e89-a786-d07a0cc9096d * fix(contacts): address review regressions Stabilize asynchronous integration flows. Keep contact pagination, resolution, and generated API contracts deterministic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 58beb14a-b8b6-4d9c-a27d-5e70118cef95 * feat(contacts): add MongoDB repository Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 47a18375-9f8b-4f08-9014-ef78dcb72780 * feat(contacts): manage contacts from threads Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 369472a4-40f8-4604-81c2-c4942b88f0b6 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Copilot-Session: 8dd82cae-8bc6-4eaa-9b90-95073720c577 Copilot-Session: 1f3addc9-71dd-4cb7-bfae-e6fdcc8511af Copilot-Session: 4a93bfbb-739a-414c-8eb4-48b15a69fb9d Copilot-Session: dec094f9-5386-4607-998a-1701ac10b7cf Copilot-Session: ffe6b904-8f76-4e89-a786-d07a0cc9096d Copilot-Session: 58beb14a-b8b6-4d9c-a27d-5e70118cef95 Copilot-Session: 47a18375-9f8b-4f08-9014-ef78dcb72780 Copilot-Session: 369472a4-40f8-4604-81c2-c4942b88f0b6
1 parent 1e7bda7 commit c2709f7

80 files changed

Lines changed: 11435 additions & 120 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.mcp.json‎

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,9 @@
11
{
22
"mcpServers": {
3-
"playwright": {
4-
"type": "stdio",
5-
"command": "npx",
6-
"args": [
7-
"-y",
8-
"@modelcontextprotocol/server-playwright",
9-
"--base-url",
10-
"http://localhost:3000"
11-
],
12-
"env": {
13-
"BROWSER": "chromium"
14-
}
15-
},
163
"context7": {
174
"type": "stdio",
185
"command": "npx",
196
"args": ["@upstash/context7-mcp@latest"]
20-
},
21-
"axiom": {
22-
"type": "stdio",
23-
"command": "npx",
24-
"args": ["-y", "mcp-remote", "https://mcp.axiom.co/mcp"]
257
}
268
}
279
}

0 commit comments

Comments
 (0)