Skip to content

feat(db): add quick-chat history tables and tRPC - #5536

Merged
iscekic merged 3 commits into
mainfrom
quick-chat-spectator-5c48
Aug 27, 2026
Merged

feat(db): add quick-chat history tables and tRPC#5536
iscekic merged 3 commits into
mainfrom
quick-chat-spectator-5c48

Conversation

@iscekic

@iscekic iscekic commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

No new behavior — this level adds only the backend storage and API for quick-chat history; the visible Quick Chat experience ships in later levels.


Two new tables, quick_chat_threads and quick_chat_messages, store quick-chat history. Partial unique indexes enforce one thread per user in the personal scope and one per user plus organization in the organization scope. Messages cascade-delete with their thread, and the thread's user key is restrict, so account deletion removes the threads and messages explicitly in the cleanup step.

Files
  • packages/db/src/schema.ts — adds the two Drizzle table definitions with their select and insert types; declares the unique indexes quick_chat_threads_user_personal_uidx and quick_chat_threads_user_org_uidx, and the lookup index IDX_quick_chat_messages_thread_created_at.
  • packages/db/src/migrations/0233_big_abomination.sql — generated DDL (23 lines) that creates both tables, the user, organization, and message foreign keys, the cascade and restrict actions, the two partial unique indexes, and the message lookup index.

The quickChat namespace adds the getOrCreateThread, listMessages, and appendMessages procedures with Zod-validated inputs, and getOrCreateThread re-selects the raced thread on a concurrent unique violation. listMessages pages from newest to oldest through an opaque base64url keyset cursor that carries (created_at, id), so rows that share a timestamp are never skipped. appendMessages gives each row a strictly-increasing created_at, so a batch keeps its append order under the id tie-break.

Files
  • apps/web/src/routers/quick-chat-router.ts — new router (215 lines); resolves the thread scope and checks organization membership for the organization scope; encodes and decodes the composite keyset cursor; serializes timestamps to ISO; implements the three procedures.
  • apps/web/src/routers/root-router.ts — registers quickChat on the root router.
  • packages/trpc/src/mobile.ts — registers quickChat on the mobile-scoped router, extending the mobile client type surface.

The accepted usage feature values now include quick-chat, so a caller can send that header and the gateway attributes usage to it. No rate-limit set changes.

Files
  • apps/web/src/lib/feature-detection.ts — adds 'quick-chat' to FEATURE_VALUES.

Account soft deletion now hard-deletes a user's quick-chat threads and messages. Messages go first, selected through the user's threads, so the thread delete cannot race the message cascade and leave rows behind.

Files
  • apps/web/src/lib/user/index.ts — imports both tables; in the anonymization step, deletes the user's messages through a thread subquery, then deletes the user's threads.

Tests: 3 files changed — quick-chat-router.test.ts, feature-detection.test.ts, and user/index.test.ts.
Generated: 2 files — 0233_snapshot.json and _journal.json.


Verification

No E2E report: none attached — this is a lower stacked level; the tip PR carries the E2E report and screenshots. No manual test paths were run; this level changes no UI and its behavior is covered by automated tests.

Visual Changes

Visual Changes: N/A

Reviewer Notes

Human steps: none known for this level alone.
Notes: none.

Stacked PRs — merge bottom to top. Each level shows only its own diff.

Runtime verification (E2E, user advocacy, simplify) runs on the tip PR over every level.
Every level keeps its own checks, its own bot review, and its own threads; each one is answered on its own PR.
Each level is its own deliverable: it builds and passes its own checks alone.
A finding on a level is repaired on that level, then carried upward with stack.sh forward.

  1. quick-chat-spectator-5c48feat(db): add quick-chat history tables and tRPC #5536 ← this PR
  2. quick-chat-spectator-5c48-s2feat(mobile): add flagged Chat tab for gateway chats #5541
  3. quick-chat-spectator-5c48-s3feat(mobile): add read-only review spectator transcript #5566 (tip)

@iscekic iscekic self-assigned this Aug 27, 2026
Comment thread apps/web/src/routers/quick-chat-router.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • apps/web/src/routers/quick-chat-router.ts
  • apps/web/src/routers/quick-chat-router.test.ts
Previous Review Summaries (2 snapshots, latest commit f56779c)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit f56779c)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • apps/web/src/routers/quick-chat-router.ts
  • apps/web/src/routers/quick-chat-router.test.ts

Previous review (commit 355c1ae)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

listMessages pages on created_at alone while sorting by (created_at, id), so equal timestamps skip messages.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/web/src/routers/quick-chat-router.ts 136 Keyset pagination can skip messages that share a created_at
Files Reviewed (12 files)
  • apps/web/src/lib/feature-detection.test.ts
  • apps/web/src/lib/feature-detection.ts
  • apps/web/src/lib/user/index.test.ts
  • apps/web/src/lib/user/index.ts
  • apps/web/src/routers/quick-chat-router.test.ts
  • apps/web/src/routers/quick-chat-router.ts - 1 issue
  • apps/web/src/routers/root-router.ts
  • packages/db/src/migrations/0233_big_abomination.sql
  • packages/db/src/migrations/meta/0233_snapshot.json
  • packages/db/src/migrations/meta/_journal.json
  • packages/db/src/schema.ts
  • packages/trpc/src/mobile.ts

Fix these issues in Kilo Cloud


Reviewed by grok-4.6 · Input: 53.2K · Output: 5.4K · Cached: 208.8K

Review guidance: REVIEW.md from base branch main

The listMessages query orders by (created_at DESC, id DESC) but paged
with a created_at-only cursor, so rows sharing a timestamp could be
skipped at the page boundary. Encode the last row's (created_at, id)
into an opaque keyset cursor and filter with a tie-break-aware
comparison.
@iscekic iscekic added the human-ready The PR is ready for human review. label Aug 27, 2026
@iscekic
iscekic requested a review from eshurakov August 27, 2026 16:59
@iscekic
iscekic merged commit d3b9ab4 into main Aug 27, 2026
53 checks passed
@iscekic
iscekic deleted the quick-chat-spectator-5c48 branch August 27, 2026 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants