Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
84 lines
7.5 KiB
Markdown
84 lines
7.5 KiB
Markdown
# Scratchpad — AI Chat History Search
|
|
|
|
- Plan slug: `2026-04-07-ai-chat-history-search`
|
|
- Created: `2026-04-07`
|
|
|
|
## What This Is
|
|
|
|
Working memory for adding searchable AI chat history to the existing enterprise chat sidebar.
|
|
|
|
## Decisions
|
|
|
|
- (2026-04-07) Search scope is chat-level only. Results should return matching chats, not individual matching messages or snippets.
|
|
- (2026-04-07) A match should come from either chat titles or persisted message body content.
|
|
- (2026-04-07) Use Postgres full-text search over the existing `chats` and `messages` tables rather than vector search or a denormalized search document.
|
|
- (2026-04-07) Keep the feature inside the existing history card in `RightSidebarContent.tsx`; do not add a separate page or modal.
|
|
- (2026-04-07) Keep `preview_text` behavior unchanged: show the latest persisted message preview, not the matched text excerpt.
|
|
- (2026-04-07) Minimum query length is assumed to be 2 characters unless product scope changes during review.
|
|
|
|
## Discoveries / Constraints
|
|
|
|
- (2026-04-07) Current persistence lives in `ee/server/src/lib/chat-actions/chatActions.tsx`, with `Chat.getRecentByUser(...)` in `ee/server/src/models/chat.ts` and `Message.getByChatId(...)` in `ee/server/src/models/message.ts`.
|
|
- (2026-04-07) The history sidebar already uses one server-action seam for recent history and one for full-chat load, so search can slot into that pattern with a new action instead of a new API route.
|
|
- (2026-04-07) The existing AI schema migration already creates `process_large_lexemes(...)` and uses generated `tsvector` columns elsewhere, so chat search can reuse that pattern.
|
|
- (2026-04-07) `Chat.tsx` persists chats/messages during the existing SSE flow; search should avoid changing that write path.
|
|
- (2026-04-07) The current history list is capped at 20 rows and uses latest persisted message content as `preview_text`; search should preserve both unless scope changes.
|
|
- (2026-04-07) Existing sidebar tests live in `server/src/test/unit/RightSidebar.historyToggle.test.tsx`; DB-backed persistence tests already exist in `server/src/test/integration/chatPersistenceExecution.integration.test.ts`.
|
|
|
|
## Commands / Runbooks
|
|
|
|
- (2026-04-07) Locate relevant chat history flow: `rg -n "RightSidebarContent|listCurrentUserChatsAction|getChatMessagesAction|createNewChatAction|addMessageToChatAction" .`
|
|
- (2026-04-07) Inspect current chat actions: `sed -n '1,280p' ee/server/src/lib/chat-actions/chatActions.tsx`
|
|
- (2026-04-07) Inspect chat persistence query shape: `sed -n '1,260p' ee/server/src/models/chat.ts`
|
|
- (2026-04-07) Inspect current history sidebar behavior: `sed -n '1,760p' ee/server/src/components/layout/RightSidebarContent.tsx`
|
|
- (2026-04-07) Inspect AI schema migration: `sed -n '1,180p' ee/server/migrations/202410291100_create_ai_schema.cjs`
|
|
- (2026-04-07) Validate the plan artifacts: `python3 /Users/roberisaacs/.codex/skills/alga-plan/scripts/validate_plan.py ee/docs/plans/2026-04-07-ai-chat-history-search`
|
|
|
|
## Links / References
|
|
|
|
- `ee/server/src/components/layout/RightSidebarContent.tsx`
|
|
- `ee/server/src/components/chat/Chat.tsx`
|
|
- `ee/server/src/lib/chat-actions/chatActions.tsx`
|
|
- `ee/server/src/models/chat.ts`
|
|
- `ee/server/src/models/message.ts`
|
|
- `ee/server/migrations/202410291100_create_ai_schema.cjs`
|
|
- `server/src/test/unit/RightSidebar.historyToggle.test.tsx`
|
|
- `server/src/test/integration/chatPersistenceExecution.integration.test.ts`
|
|
|
|
## Open Questions
|
|
|
|
- No blocking product questions remain after confirming:
|
|
- chat-level results only
|
|
- match on titles and message content
|
|
- Postgres full-text search path
|
|
|
|
## Implementation Log
|
|
|
|
- (2026-04-07) Completed F001: Added migration `ee/server/migrations/20260407163000_add_chat_history_search_indexes.cjs` to create `chats.title_index` as a stored generated `tsvector` from `coalesce(title_text, '')`.
|
|
- (2026-04-07) Completed F002: Added `chats_title_index_idx` GIN index on `chats.title_index` in the same migration.
|
|
- (2026-04-07) Completed F003: Added `messages.content_index` as a stored generated `tsvector` using `process_large_lexemes(coalesce(content, ''))` in the same migration.
|
|
- (2026-04-07) Completed F004: Added `messages_content_index_idx` GIN index on `messages.content_index` in the same migration.
|
|
- (2026-04-07) Completed F005: Added `Chat.searchByUser(userId, query, limit)` in `ee/server/src/models/chat.ts` returning `ChatHistoryItem[]`.
|
|
- (2026-04-07) Completed F006: `Chat.searchByUser` matches chats by `chats.title_index` OR related `messages.content_index` using `websearch_to_tsquery`.
|
|
- (2026-04-07) Completed F007: `Chat.searchByUser` keeps one row per chat (chat-driven query with `exists`) and orders by relevance rank then recency (`coalesce(updated_at, created_at) desc`).
|
|
- (2026-04-07) Completed F008: `Chat.searchByUser` preserves `preview_text` from the latest persisted message (`message_order desc`, fallback `id desc`).
|
|
- (2026-04-07) Completed F009: Added `searchCurrentUserChatsAction(query, limit)` in `ee/server/src/lib/chat-actions/chatActions.tsx` with trim + minimum length (2) guard.
|
|
- (2026-04-07) Completed F010: Search action fails closed for unavailable persistence and rollout schema gaps (`42P01`, `42703`) by returning `[]` and not breaking sidebar behavior.
|
|
- (2026-04-07) Completed F011: Added chat-history search input and local query state in `ee/server/src/components/layout/RightSidebarContent.tsx`.
|
|
- (2026-04-07) Completed F012: Empty search query path now explicitly loads recent chats via `listCurrentUserChatsAction(HISTORY_LIMIT)` and keeps “Recent Chats” mode.
|
|
- (2026-04-07) Completed F013: Added debounced search (`250ms`) for trimmed queries with length >= 2 and “Search Results” labeling.
|
|
- (2026-04-07) Completed F014: One-character queries show helper state and skip server search calls.
|
|
- (2026-04-07) Completed F015: Search result rows continue to reuse existing row rendering (title, timestamp, preview, rename/delete).
|
|
- (2026-04-07) Completed F016: Selecting search result row reuses existing `getChatMessagesAction(chatId)` load flow.
|
|
- (2026-04-07) Completed F017: Added explicit search states for loading, query-too-short, no-results (and preserved no-saved-chats state for recent mode).
|
|
- (2026-04-07) Completed F018: Rename/delete now refresh the currently active dataset (`recent` or current search query) via `refreshActiveHistoryDataset`.
|
|
- (2026-04-07) Completed F019: Clearing query immediately restores recent dataset (no sidebar close/reopen required).
|
|
- (2026-04-07) Completed T001/T002: Added DB-backed integration coverage in `server/src/test/integration/chatHistorySearch.integration.test.ts` for title+message matching, dedupe, preview behavior, relevance+recency ordering, user scoping, and non-match guard.
|
|
- (2026-04-07) Completed T003/T004/T005/T006: Added sidebar unit coverage in `server/src/test/unit/RightSidebar.historySearch.test.tsx` for empty-query recent mode, debounced threshold switching, query-too-short helper, clear-to-recent behavior, no-results state, result selection load, and rename/delete re-search behavior.
|
|
- (2026-04-07) Completed T007: Added `searchCurrentUserChatsAction` fail-closed unit coverage in `server/src/test/unit/chatActions.searchCurrentUserChatsAction.test.ts` for unavailable persistence and missing-column rollout scenarios.
|
|
|
|
## Additional Gotchas
|
|
|
|
- Chat search uses cached persistence checks in `chatActions.tsx`; unit tests that validate fallback behavior should reset modules or isolate imports to avoid cross-test cache effects.
|
|
- Search refresh after mutations is tied to current trimmed query state to keep mode consistency between recent/search datasets.
|