refactor(phase-2d-t11): unify DB types, delete src/types/database.ts (-83 LoC)

Collapse duplicated Record/Row pairs in src/services/sqlite/types.ts:
ObservationRecord, SessionSummaryRecord, SdkSessionRecord are now type
aliases over their *Row counterparts. ObservationWithContext (unused)
deleted. UserPromptRecord + LatestPromptResult kept as JOIN projection
shapes distinct from raw-table Row selects.

All 9 remaining importers of src/types/database.ts migrated to
src/services/sqlite/types.ts; the old file is deleted. Typecheck errors
drop by 12 (stale Record shape was masking type drift). Test baseline
unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-04-21 13:23:41 -07:00
parent db7048e75c
commit f52ac36f4b
10 changed files with 66 additions and 149 deletions

View File

@@ -1,5 +1,5 @@
import { Database } from 'bun:sqlite';
import { TableNameRow } from '../../types/database.js';
import { TableNameRow } from './types.js';
import { DATA_DIR, DB_PATH, ensureDir } from '../../shared/paths.js';
import { logger } from '../../utils/logger.js';
import { isDirectChild } from '../../shared/path-utils.js';

View File

@@ -7,7 +7,7 @@ import {
SessionSummaryRecord,
UserPromptRecord,
LatestPromptResult
} from '../../types/database.js';
} from './types.js';
import type { PendingMessageStore } from './PendingMessageStore.js';
import { computeObservationContentHash, findDuplicateObservation } from './observations/store.js';
import { parseFileList } from './observations/files.js';

View File

@@ -5,7 +5,7 @@ import {
IndexInfo,
TableNameRow,
SchemaVersion
} from '../../../types/database.js';
} from '../types.js';
import { DEFAULT_PLATFORM_SOURCE } from '../../../shared/platform-source.js';
/**

View File

@@ -5,7 +5,7 @@
import { Database } from 'bun:sqlite';
import { logger } from '../../../utils/logger.js';
import type { ObservationRecord } from '../../../types/database.js';
import type { ObservationRecord } from '../types.js';
import type { GetObservationsByIdsOptions, ObservationSessionRow } from './types.js';
/**

View File

@@ -4,7 +4,7 @@
import type { Database } from 'bun:sqlite';
import { logger } from '../../../utils/logger.js';
import type { UserPromptRecord, LatestPromptResult } from '../../../types/database.js';
import type { UserPromptRecord, LatestPromptResult } from '../types.js';
import type { RecentUserPromptResult, PromptWithProject, GetPromptsByIdsOptions } from './types.js';
/**

View File

@@ -3,7 +3,7 @@
*/
import type { Database } from 'bun:sqlite';
import { logger } from '../../../utils/logger.js';
import type { SessionSummaryRecord } from '../../../types/database.js';
import type { SessionSummaryRecord } from '../types.js';
import type { SessionSummary, GetByIdsOptions } from './types.js';
/**

View File

@@ -6,7 +6,7 @@
*/
import type { Database } from 'bun:sqlite';
import type { ObservationRecord, SessionSummaryRecord, UserPromptRecord } from '../../../types/database.js';
import type { ObservationRecord, SessionSummaryRecord, UserPromptRecord } from '../types.js';
import { logger } from '../../../utils/logger.js';
import { OBSERVER_SESSIONS_PROJECT } from '../../../shared/paths.js';

View File

@@ -285,3 +285,61 @@ export interface UserPromptSearchResult extends UserPromptRow {
rank?: number; // FTS5 relevance score (lower is better)
score?: number; // Normalized score (higher is better, 0-1)
}
// Schema introspection types (PRAGMA results)
export interface TableColumnInfo {
cid: number;
name: string;
type: string;
notnull: number;
dflt_value: string | null;
pk: number;
}
export interface IndexInfo {
seq: number;
name: string;
unique: number;
origin: string;
partial: number;
}
export interface TableNameRow {
name: string;
}
export interface SchemaVersion {
version: number;
}
// Legacy *Record aliases. Historically these were separate (under-specified)
// views of the same rows represented by the *Row types above. Unified here
// to eliminate drift — callers using `*Record` get the full row shape.
export type SdkSessionRecord = SDKSessionRow;
export type ObservationRecord = ObservationRow;
export type SessionSummaryRecord = SessionSummaryRow;
// JOIN-projected prompt shapes (not a single-table SELECT *). Kept distinct
// from UserPromptRow which reflects the raw user_prompts table.
export interface UserPromptRecord {
id: number;
content_session_id: string;
prompt_number: number;
prompt_text: string;
project?: string; // From JOIN with sdk_sessions
platform_source?: string;
created_at: string;
created_at_epoch: number;
}
export interface LatestPromptResult {
id: number;
content_session_id: string;
memory_session_id: string;
project: string;
platform_source: string;
prompt_number: number;
prompt_text: string;
created_at_epoch: number;
}

View File

@@ -6,7 +6,7 @@
*/
import { logger } from '../../../utils/logger.js';
import type { ObservationRecord } from '../../../types/database.js';
import type { ObservationRecord } from '../../sqlite/types.js';
import type { SessionStore } from '../../sqlite/SessionStore.js';
import type { SearchManager } from '../SearchManager.js';
import { CorpusRenderer } from './CorpusRenderer.js';

View File

@@ -1,141 +0,0 @@
/**
* TypeScript types for database query results
* Provides type safety for bun:sqlite query results
*/
/**
* Schema information from sqlite3 PRAGMA table_info
*/
export interface TableColumnInfo {
cid: number;
name: string;
type: string;
notnull: number;
dflt_value: string | null;
pk: number;
}
/**
* Index information from sqlite3 PRAGMA index_list
*/
export interface IndexInfo {
seq: number;
name: string;
unique: number;
origin: string;
partial: number;
}
/**
* Table name from sqlite_master
*/
export interface TableNameRow {
name: string;
}
/**
* Schema version record
*/
export interface SchemaVersion {
version: number;
}
/**
* SDK Session database record
*/
export interface SdkSessionRecord {
id: number;
content_session_id: string;
memory_session_id: string | null;
project: string;
user_prompt: string | null;
started_at: string;
started_at_epoch: number;
completed_at: string | null;
completed_at_epoch: number | null;
status: 'active' | 'completed' | 'failed';
worker_port?: number;
prompt_counter?: number;
}
/**
* Observation database record
*/
export interface ObservationRecord {
id: number;
memory_session_id: string;
project: string;
text: string | null;
type: 'decision' | 'bugfix' | 'feature' | 'refactor' | 'discovery' | 'change';
created_at: string;
created_at_epoch: number;
title?: string;
concept?: string;
source_files?: string;
prompt_number?: number;
discovery_tokens?: number;
}
/**
* Session Summary database record
*/
export interface SessionSummaryRecord {
id: number;
memory_session_id: string;
project: string;
request: string | null;
investigated: string | null;
learned: string | null;
completed: string | null;
next_steps: string | null;
created_at: string;
created_at_epoch: number;
prompt_number?: number;
discovery_tokens?: number;
}
/**
* User Prompt database record
*/
export interface UserPromptRecord {
id: number;
content_session_id: string;
prompt_number: number;
prompt_text: string;
project?: string; // From JOIN with sdk_sessions
platform_source?: string;
created_at: string;
created_at_epoch: number;
}
/**
* Latest user prompt with session join
*/
export interface LatestPromptResult {
id: number;
content_session_id: string;
memory_session_id: string;
project: string;
platform_source: string;
prompt_number: number;
prompt_text: string;
created_at_epoch: number;
}
/**
* Observation with context (for time-based queries)
*/
export interface ObservationWithContext {
id: number;
memory_session_id: string;
project: string;
text: string | null;
type: string;
created_at: string;
created_at_epoch: number;
title?: string;
concept?: string;
source_files?: string;
prompt_number?: number;
discovery_tokens?: number;
}