feat(api): rename + delete conversation endpoints (#364) #366

Merged
james merged 1 commit from 364-chat-conversation-mgmt into main 2026-06-29 13:51:18 +00:00
Owner

The data layer for chat conversation management (#364). The switcher needs to rename and delete conversations, but only GET existed. This adds the endpoints + hooks; the chat switcher UI is a follow-up — deliberately sequenced after the in-flight chat.tsx changes (#352 markdown, #363 diffs) settle, to avoid a three-way merge pileup on that file.

What's in it

  • ConversationsRepository.updateTitle(id, title) and delete(id). delete clears messages then the conversation as two plain statements — FK enforcement isn't on for the SQLite leg, and a transaction would run against libsql's per-connection :memory: test DB (schemaless); messages-first self-heals on a mid-failure.
  • PATCH /api/conversations/{id} (rename, zUpdateConversationRequest; empty title clears it) and DELETE /api/conversations/{id} (200 { ok }). Per-user 404; a cross-user rename/delete can't touch another user's conversation.
  • @carol/api-client: useUpdateConversation + useDeleteConversation.
  • zod/openapi + api-client types regenerated (coverage 119 → 121).

Verification (local)

  • typecheck ✓ · lint
  • test against both engines (ephemeral Postgres): 1238 passed, 0 skipped (+ dual-engine repo tests: rename, delete-cascades-messages; route tests: rename/clear, delete→404, cross-user 404, 401)
  • @carol/api-client: check ✓ · test ✓ 42 · openapi:check ✓ · coverage 121
  • semgrep ✓ 0 findings on the new files

Follow-up (the rest of #364)

  • The chat switcher UI: rename (inline edit) + delete (confirm) + search/filter + auto-scroll-to-latest. Will land on top of the settled chat.tsx once #352/#363 merge.

Part of #364.

🤖 Generated with Claude Code

The data layer for chat conversation management (#364). The switcher needs to rename and delete conversations, but only GET existed. This adds the endpoints + hooks; **the chat switcher UI is a follow-up** — deliberately sequenced after the in-flight `chat.tsx` changes (#352 markdown, #363 diffs) settle, to avoid a three-way merge pileup on that file. ## What's in it - **`ConversationsRepository.updateTitle(id, title)`** and **`delete(id)`**. `delete` clears messages then the conversation as two plain statements — FK enforcement isn't on for the SQLite leg, and a transaction would run against libsql's per-connection `:memory:` test DB (schemaless); messages-first self-heals on a mid-failure. - **`PATCH /api/conversations/{id}`** (rename, `zUpdateConversationRequest`; empty title clears it) and **`DELETE /api/conversations/{id}`** (`200 { ok }`). Per-user 404; a cross-user rename/delete can't touch another user's conversation. - **`@carol/api-client`**: `useUpdateConversation` + `useDeleteConversation`. - zod/openapi + api-client types regenerated (coverage 119 → 121). ## Verification (local) - `typecheck` ✓ · `lint` ✓ - `test` against **both engines** (ephemeral Postgres): **1238 passed, 0 skipped** (+ dual-engine repo tests: rename, delete-cascades-messages; route tests: rename/clear, delete→404, cross-user 404, 401) - `@carol/api-client`: `check` ✓ · test ✓ 42 · `openapi:check` ✓ · coverage 121 - semgrep ✓ 0 findings on the new files ## Follow-up (the rest of #364) - The chat switcher UI: rename (inline edit) + delete (confirm) + search/filter + auto-scroll-to-latest. Will land on top of the settled `chat.tsx` once #352/#363 merge. Part of #364. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(api): rename + delete conversation endpoints (#364)
All checks were successful
Commits / Conventional Commits (pull_request) Successful in 6s
PR / OpenAPI (pull_request) Successful in 2m14s
PR / Static analysis (pull_request) Successful in 2m23s
PR / pnpm audit (pull_request) Successful in 2m44s
PR / Lint (pull_request) Successful in 3m21s
PR / OSV-Scanner (pull_request) Successful in 1m20s
PR / Client (web export smoke) (pull_request) Successful in 3m43s
PR / Build (pull_request) Successful in 3m58s
PR / Typecheck (pull_request) Successful in 4m8s
PR / Package age policy (soft) (pull_request) Successful in 47s
PR / Test (sqlite) (pull_request) Successful in 4m20s
PR / Test (postgres) (pull_request) Successful in 4m24s
Secrets / gitleaks (pull_request) Successful in 51s
PR / Coverage (soft) (pull_request) Successful in 3m30s
PR / E2E (Playwright) (pull_request) Successful in 7m43s
PR / Trivy (image) (pull_request) Successful in 5m18s
24778900d3
The chat conversation switcher needs to rename and delete conversations;
only GET existed. Add the data layer + hooks (the chat UI is a follow-up,
sequenced after the in-flight chat.tsx changes settle).

- ConversationsRepository.updateTitle(id, title) and delete(id). delete
  clears messages then the conversation as two plain statements — FK
  enforcement isn't on for the SQLite leg, and a transaction would run
  against libsql's per-connection :memory: DB; messages-first self-heals.
- PATCH /api/conversations/{id} (rename, zUpdateConversationRequest) and
  DELETE /api/conversations/{id} (200 {ok}). Per-user 404; cross-user
  rename/delete can't touch another user's conversation.
- @carol/api-client: useUpdateConversation + useDeleteConversation.
- zod/openapi + api-client types regenerated (coverage 119 → 121).

Dual-engine repo tests (rename, delete-cascades-messages) + route tests
(rename/clear, delete→404, cross-user 404, 401).

Part of #364.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

📊 Test coverage

Patch coverage: no testable lines changed.

Overall (app/, lib/, db/, excluding UI per ADR-0019):

Metric Value Soft target
Lines 79.4% ≥ 50%
Branches 71.2% ⚠️ ≥ 75%
Functions 80.5% informational

Soft thresholds per ADR-0019. Coverage is informational and does not block merge.

<!-- coverage-comment --> ## 📊 Test coverage **Patch coverage:** no testable lines changed. **Overall** (`app/`, `lib/`, `db/`, excluding UI per ADR-0019): | Metric | Value | Soft target | |---|---|---| | Lines | 79.4% ✅ | ≥ 50% | | Branches | 71.2% ⚠️ | ≥ 75% | | Functions | 80.5% | informational | Soft thresholds per [ADR-0019](docs/adr/0019-coverage-soft-targets.md). Coverage is informational and does not block merge.
james merged commit f1bd3542e0 into main 2026-06-29 13:51:18 +00:00
james deleted branch 364-chat-conversation-mgmt 2026-06-29 13:51:18 +00:00
Sign in to join this conversation.
No description provided.