|
5 | 5 | import type { EngineConfig } from "./config.ts"; |
6 | 6 | import { log } from "./log.ts"; |
7 | 7 | import { createDb, type Db, type RawSql } from "./db/client.ts"; |
| 8 | +import { createFtsVerification } from "./core/fts-language.ts"; |
8 | 9 | import type { VisibilitySpec } from "./core/schemas/document.ts"; |
9 | 10 | import { captureDocument } from "./services/capture.ts"; |
10 | 11 | import { |
@@ -57,9 +58,26 @@ export function createKnowledgePlane(config: KnowledgeConfig): KnowledgePlane { |
57 | 58 | const { db, sql }: { db: Db; sql: RawSql } = createDb(engineConfig); |
58 | 59 | const deps = { db, sql, config: engineConfig }; |
59 | 60 |
|
| 61 | + // Serving-path schema validation, industry-standard fail-fast shape |
| 62 | + // (Hibernate validate / Rails check_all_pending!): the mount is |
| 63 | + // synchronous, so "before accepting traffic" becomes a memoized check |
| 64 | + // awaited by the first query. Read-only; migration stays a deploy step. |
| 65 | + // Hosts with a real readiness probe can call verifyFtsLanguage there |
| 66 | + // instead — this memo then resolves against an already-verified schema. |
| 67 | + const ensureVerified = createFtsVerification( |
| 68 | + { |
| 69 | + query: async (text, params) => |
| 70 | + (await sql.unsafe(text, [...params] as never[])) as unknown as Array< |
| 71 | + Record<string, unknown> |
| 72 | + >, |
| 73 | + }, |
| 74 | + engineConfig.ftsLanguage, |
| 75 | + ); |
| 76 | + |
60 | 77 | return { |
61 | 78 | async search(params) { |
62 | 79 | try { |
| 80 | + await ensureVerified(); |
63 | 81 | const result = await hybridSearch(deps, { |
64 | 82 | tenantId: params.tenantId, |
65 | 83 | principalId: params.principalId, |
@@ -114,6 +132,7 @@ export function createKnowledgePlane(config: KnowledgeConfig): KnowledgePlane { |
114 | 132 | }, |
115 | 133 |
|
116 | 134 | async capture(params) { |
| 135 | + await ensureVerified(); |
117 | 136 | const adapter = params.adapter ?? "mcp"; |
118 | 137 | const externalRef = |
119 | 138 | params.externalRef ?? |
|
0 commit comments