mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-02 13:39:41 +02:00
Bounded federated search over in-memory stores (sessions/cases, run-summary events, file paths). Zod-validated query (q 1-200 chars, types csv, limit 1-60), grouped session->event->file with exact-match-first + recency tiebreak, total cap 60 + per-group cap 25, snippet cap 200, path-safety (relativePath only). Frontend search box (history panel) deferred to next cycle; resume/history-prompt text matching deferred to v1.1 (lives in large on-disk files, out of v1 bounded scope). New: src/search-service.ts (pure core), src/types/search.ts, src/web/routes/search-routes.ts. Tests: test/search-service.test.ts (14), test/routes/search-routes.test.ts (10).
78 lines
3.1 KiB
TypeScript
78 lines
3.1 KiB
TypeScript
/**
|
|
* @fileoverview Cross-session federated search types (COD-9).
|
|
*
|
|
* Defines the typed shapes for `GET /api/search` — a bounded, in-memory
|
|
* federated search across three v1 sources: live sessions/cases, run-summary
|
|
* timeline events, and per-session attachment file paths. Terminal-buffer scans
|
|
* and any persisted index are explicitly out of scope for v1.
|
|
*
|
|
* Key exports:
|
|
* - SearchSourceType — the federated source kinds, also the group order key.
|
|
* - SearchResult — a single typed result card (source, session id/name,
|
|
* timestamp, snippet, jump-to action target).
|
|
* - SearchJumpTarget — where the frontend should navigate when a card is opened.
|
|
* - SearchResponseData — grouped result payload returned in the ApiResponse envelope.
|
|
*
|
|
* No I/O, no dependencies on other domain modules. The pure search core lives
|
|
* in `src/search-service.ts`; the route wrapper in `src/web/routes/search-routes.ts`.
|
|
*/
|
|
|
|
/** Federated source kinds. Group/render order is sessions → events → files. */
|
|
export type SearchSourceType = 'session' | 'event' | 'file';
|
|
|
|
/** Where the frontend should jump when a result card is activated. */
|
|
export interface SearchJumpTarget {
|
|
/** Kind of navigation target. */
|
|
kind: 'session' | 'run-summary' | 'file-preview';
|
|
/** Owning Codeman session id (always present — every result is session-scoped). */
|
|
sessionId: string;
|
|
/**
|
|
* Secondary identifier for the target:
|
|
* - kind 'run-summary': the run-summary event id
|
|
* - kind 'file-preview': the attachment history item id
|
|
* - kind 'session': undefined (the sessionId is sufficient)
|
|
*/
|
|
targetId?: string;
|
|
/**
|
|
* Workspace-relative path for file-preview targets. Never an absolute path —
|
|
* server-private external paths are intentionally omitted to avoid leakage.
|
|
*/
|
|
relativePath?: string;
|
|
}
|
|
|
|
/** A single typed search result card. */
|
|
export interface SearchResult {
|
|
/** Which federated source produced this result. */
|
|
type: SearchSourceType;
|
|
/** Owning Codeman session id. */
|
|
sessionId: string;
|
|
/** Display name of the owning session / case. */
|
|
sessionName: string;
|
|
/** Millisecond timestamp used for recency ranking and display. */
|
|
timestamp: number;
|
|
/** Short, already-truncated snippet describing the match. */
|
|
snippet: string;
|
|
/** True when the query matched the primary name/path exactly (case-insensitive). */
|
|
exactMatch: boolean;
|
|
/** Navigation target for the jump-to action. */
|
|
jumpTo: SearchJumpTarget;
|
|
}
|
|
|
|
/** A group of results for one source type, in render order. */
|
|
export interface SearchResultGroup {
|
|
type: SearchSourceType;
|
|
results: SearchResult[];
|
|
}
|
|
|
|
/** Payload returned as `data` inside the standard ApiResponse envelope. */
|
|
export interface SearchResponseData {
|
|
/** The normalized query that was executed. */
|
|
query: string;
|
|
/** Results grouped by source type, ordered sessions → events → files. */
|
|
groups: SearchResultGroup[];
|
|
/** Total number of results across all groups (after caps applied). */
|
|
totalResults: number;
|
|
/** True if any group or the total was capped (more matches existed). */
|
|
truncated: boolean;
|
|
}
|