@marinoscar/kvox-eval 0.0.0-bootstrap → 0.1.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE +21 -0
  3. package/README.md +166 -0
  4. package/dist/ask/index.d.ts +6 -0
  5. package/dist/ask/index.js +28 -0
  6. package/dist/ask/question-schema.d.ts +121 -0
  7. package/dist/ask/question-schema.js +167 -0
  8. package/dist/ask/report.d.ts +88 -0
  9. package/dist/ask/report.js +170 -0
  10. package/dist/ask/scorer.d.ts +104 -0
  11. package/dist/ask/scorer.js +164 -0
  12. package/dist/ask-run/ask-command.d.ts +62 -0
  13. package/dist/ask-run/ask-command.js +254 -0
  14. package/dist/ask-run/host/app.d.ts +65 -0
  15. package/dist/ask-run/host/app.js +146 -0
  16. package/dist/ask-run/host/db.d.ts +38 -0
  17. package/dist/ask-run/host/db.js +126 -0
  18. package/dist/ask-run/host/ports.d.ts +35 -0
  19. package/dist/ask-run/host/ports.js +113 -0
  20. package/dist/ask-run/index.d.ts +13 -0
  21. package/dist/ask-run/index.js +35 -0
  22. package/dist/ask-run/replay.d.ts +128 -0
  23. package/dist/ask-run/replay.js +212 -0
  24. package/dist/ask-run/run-ask-eval.d.ts +125 -0
  25. package/dist/ask-run/run-ask-eval.js +193 -0
  26. package/dist/ask-run/seed-golden-graph.d.ts +64 -0
  27. package/dist/ask-run/seed-golden-graph.js +495 -0
  28. package/dist/cli/index.d.ts +3 -0
  29. package/dist/cli/index.js +12 -0
  30. package/dist/cli/kg-command.d.ts +66 -0
  31. package/dist/cli/kg-command.js +238 -0
  32. package/dist/cli/main.d.ts +18 -0
  33. package/dist/cli/main.js +69 -0
  34. package/dist/fixtures/domains.d.ts +16 -0
  35. package/dist/fixtures/domains.js +33 -0
  36. package/dist/fixtures/fixture-schema.d.ts +323 -0
  37. package/dist/fixtures/fixture-schema.js +199 -0
  38. package/dist/fixtures/index.d.ts +16 -0
  39. package/dist/fixtures/index.js +40 -0
  40. package/dist/fixtures/load.d.ts +73 -0
  41. package/dist/fixtures/load.js +137 -0
  42. package/dist/fixtures/questions.d.ts +15 -0
  43. package/dist/fixtures/questions.js +26 -0
  44. package/dist/index.d.ts +20 -0
  45. package/dist/index.js +36 -0
  46. package/dist/kg/gold-runner.d.ts +13 -0
  47. package/dist/kg/gold-runner.js +57 -0
  48. package/dist/kg/index.d.ts +17 -0
  49. package/dist/kg/index.js +65 -0
  50. package/dist/kg/internals.d.ts +7 -0
  51. package/dist/kg/internals.js +17 -0
  52. package/dist/kg/prediction-schema.d.ts +245 -0
  53. package/dist/kg/prediction-schema.js +102 -0
  54. package/dist/kg/predictions.d.ts +11 -0
  55. package/dist/kg/predictions.js +49 -0
  56. package/dist/kg/report.d.ts +84 -0
  57. package/dist/kg/report.js +125 -0
  58. package/dist/kg/run-kg-eval.d.ts +77 -0
  59. package/dist/kg/run-kg-eval.js +137 -0
  60. package/dist/kg/runner.d.ts +72 -0
  61. package/dist/kg/runner.js +51 -0
  62. package/dist/kg/runners/extract-resolve-runner.d.ts +40 -0
  63. package/dist/kg/runners/extract-resolve-runner.js +199 -0
  64. package/dist/kg/runners/extract-runner.d.ts +65 -0
  65. package/dist/kg/runners/extract-runner.js +243 -0
  66. package/dist/kg/scorer.d.ts +226 -0
  67. package/dist/kg/scorer.js +463 -0
  68. package/dist/kg/targets.d.ts +17 -0
  69. package/dist/kg/targets.js +16 -0
  70. package/dist/kg/text.d.ts +45 -0
  71. package/dist/kg/text.js +100 -0
  72. package/dist/live/adapters.d.ts +16 -0
  73. package/dist/live/adapters.js +58 -0
  74. package/dist/live/env.d.ts +39 -0
  75. package/dist/live/env.js +56 -0
  76. package/dist/live/index.d.ts +6 -0
  77. package/dist/live/index.js +16 -0
  78. package/dist/live/live-ai.d.ts +104 -0
  79. package/dist/live/live-ai.js +157 -0
  80. package/dist/parity/constants.d.ts +79 -0
  81. package/dist/parity/constants.js +104 -0
  82. package/dist/parity/index.d.ts +20 -0
  83. package/dist/parity/index.js +38 -0
  84. package/dist/parity/internals.d.ts +8 -0
  85. package/dist/parity/internals.js +16 -0
  86. package/dist/parity/scenario.d.ts +45 -0
  87. package/dist/parity/scenario.js +245 -0
  88. package/dist/parity/script.d.ts +44 -0
  89. package/dist/parity/script.js +136 -0
  90. package/dist/parity/snapshot.d.ts +43 -0
  91. package/dist/parity/snapshot.js +71 -0
  92. package/dist/real-data/index.d.ts +2 -0
  93. package/dist/real-data/index.js +12 -0
  94. package/dist/real-data/real-data.d.ts +76 -0
  95. package/dist/real-data/real-data.js +156 -0
  96. package/fixtures/kg-golden/README.md +136 -0
  97. package/fixtures/kg-golden/ask-questions.json +458 -0
  98. package/fixtures/kg-golden/meetings/m01-northwind-pilot-kickoff.json +792 -0
  99. package/fixtures/kg-golden/meetings/m02-halden-migration-planning.json +814 -0
  100. package/fixtures/kg-golden/meetings/m03-larkspur-weekly-sync.json +601 -0
  101. package/fixtures/kg-golden/meetings/m04-corvid-intake-discovery.json +690 -0
  102. package/fixtures/kg-golden/meetings/m05-hosting-vendor-selection.json +631 -0
  103. package/fixtures/kg-golden/meetings/m06-northwind-floor-data-review.json +649 -0
  104. package/fixtures/kg-golden/meetings/m07-gullwing-intro-notes.json +428 -0
  105. package/fixtures/kg-golden/meetings/m08-halden-migration-checkpoint.json +672 -0
  106. package/fixtures/kg-golden/meetings/m09-northwind-platform-org-update.json +711 -0
  107. package/fixtures/kg-golden/meetings/m10-corvid-prototype-review.json +623 -0
  108. package/fixtures/kg-golden/meetings/m11-solvane-grid-dashboard-scoping.json +689 -0
  109. package/fixtures/kg-golden/meetings/m12-northwind-pilot-replan.json +681 -0
  110. package/fixtures/kg-golden/meetings/m13-halden-cutover-go-no-go.json +721 -0
  111. package/fixtures/kg-golden/meetings/m14-gullwing-discovery-readout.json +719 -0
  112. package/fixtures/kg-golden/meetings/m15-halden-handover-ravi-leaving.json +716 -0
  113. package/fixtures/kg-golden/meetings/m16-varden-claims-portal-intro.json +704 -0
  114. package/fixtures/kg-golden/meetings/m17-corvid-usability-debrief.json +572 -0
  115. package/fixtures/kg-golden/meetings/m18-hosting-decision-revisited.json +655 -0
  116. package/fixtures/kg-golden/meetings/m19-solvane-integration-kickoff.json +726 -0
  117. package/fixtures/kg-golden/meetings/m20-northwind-go-live-retro.json +673 -0
  118. package/fixtures/kg-golden/meetings/m21-quarterly-account-review.json +449 -0
  119. package/fixtures/kg-golden/meetings/m22-halden-intro-call-2020.json +558 -0
  120. package/fixtures/kg-golden/meetings/m23-gullwing-model-review.json +702 -0
  121. package/fixtures/kg-golden/meetings/m24-varden-discovery-midpoint.json +643 -0
  122. package/fixtures/kg-golden/meetings/m25-corvid-rollout-planning.json +642 -0
  123. package/fixtures/kg-golden/meetings/m26-larkspur-engineering-prep.json +695 -0
  124. package/fixtures/kg-golden/meetings/m27-solvane-phase-one-demo.json +649 -0
  125. package/fixtures/kg-golden/meetings/m28-northwind-building-5-scoping.json +715 -0
  126. package/fixtures/kg-golden/meetings/m29-halden-southern-cutover-review.json +752 -0
  127. package/fixtures/kg-golden/meetings/m30-varden-portal-build-kickoff.json +697 -0
  128. package/fixtures/kg-golden/meetings/m31-gullwing-rollout-renewal.json +681 -0
  129. package/fixtures/kg-golden/meetings/m32-brambleway-weekly-sync.json +472 -0
  130. package/fixtures/kg-golden/meetings/m33-nina-oliver-one-on-one.json +342 -0
  131. package/fixtures/kg-golden/meetings/m34-coffee-with-dana.json +249 -0
  132. package/fixtures/kg-golden/meetings/m35-brambleway-june-sync.json +553 -0
  133. package/fixtures/kg-golden/meetings/m36-copenhagen-conference-planning.json +296 -0
  134. package/host/generated/client.d.ts +1 -0
  135. package/host/generated/client.js +5 -0
  136. package/host/generated/default.d.ts +1 -0
  137. package/host/generated/default.js +5 -0
  138. package/host/generated/edge.d.ts +1 -0
  139. package/host/generated/edge.js +1658 -0
  140. package/host/generated/index-browser.js +1684 -0
  141. package/host/generated/index.d.ts +192335 -0
  142. package/host/generated/index.js +1658 -0
  143. package/host/generated/package.json +139 -0
  144. package/host/generated/query_compiler_fast_bg.js +2 -0
  145. package/host/generated/query_compiler_fast_bg.wasm +0 -0
  146. package/host/generated/query_compiler_fast_bg.wasm-base64.js +2 -0
  147. package/host/generated/runtime/client.d.ts +3433 -0
  148. package/host/generated/runtime/client.js +110 -0
  149. package/host/generated/runtime/index-browser.d.ts +90 -0
  150. package/host/generated/runtime/index-browser.js +6 -0
  151. package/host/generated/runtime/wasm-compiler-edge.js +100 -0
  152. package/host/generated/schema.prisma +6312 -0
  153. package/host/generated/wasm-edge-light-loader.mjs +5 -0
  154. package/host/generated/wasm-worker-loader.mjs +5 -0
  155. package/host/prisma/fragments/kvox.ask.prisma +126 -0
  156. package/host/prisma/fragments/kvox.graph.prisma +1073 -0
  157. package/host/prisma/fragments/kvox.notes.prisma +787 -0
  158. package/host/prisma/fragments/kvox.search.prisma +211 -0
  159. package/host/prisma/fragments/kvox.transcripts.prisma +790 -0
  160. package/host/prisma/kvox.lock +101 -0
  161. package/host/prisma/migrations/20240101000000_initial/migration.sql +297 -0
  162. package/host/prisma/migrations/20240101000001_add_personal_access_tokens/migration.sql +31 -0
  163. package/host/prisma/migrations/20240101000002_add_credentials/migration.sql +20 -0
  164. package/host/prisma/migrations/20240101000003_add_notification_deliveries/migration.sql +27 -0
  165. package/host/prisma/migrations/20240101000004_drop_stale_uuid_defaults/migration.sql +35 -0
  166. package/host/prisma/migrations/20240101000005_add_notifications/migration.sql +22 -0
  167. package/host/prisma/migrations/20240101000006_add_push_subscriptions/migration.sql +25 -0
  168. package/host/prisma/migrations/20240101000007_add_jobs/migration.sql +110 -0
  169. package/host/prisma/migrations/20240101000008_add_worker_nodes/migration.sql +90 -0
  170. package/host/prisma/migrations/20240101000009_add_database_backup_runs/migration.sql +104 -0
  171. package/host/prisma/migrations/20240101000010_add_notification_broadcasts/migration.sql +57 -0
  172. package/host/prisma/migrations/20240101000011_add_backup_run_job_link/migration.sql +87 -0
  173. package/host/prisma/migrations/20240101000012_add_job_node_secrets/migration.sql +61 -0
  174. package/host/prisma/migrations/20240101000013_add_backup_run_pg_dump_version/migration.sql +26 -0
  175. package/host/prisma/migrations/20240101000014_add_job_claim_token/migration.sql +92 -0
  176. package/host/prisma/migrations/20240101000015_add_ai_platform/migration.sql +108 -0
  177. package/host/prisma/migrations/20240101000016_revoke_viewer_ai_use/migration.sql +32 -0
  178. package/host/prisma/migrations/20240101000017_add_user_credentials/migration.sql +29 -0
  179. package/host/prisma/migrations/20240101000018_add_device_session_credential_link/migration.sql +52 -0
  180. package/host/prisma/migrations/20240101000019_add_worker_node_vitals/migration.sql +3 -0
  181. package/host/prisma/migrations/20240101000020_add_job_trace_context/migration.sql +6 -0
  182. package/host/prisma/migrations/20240101000021_add_retention_created_at_indexes/migration.sql +13 -0
  183. package/host/prisma/migrations/20240101000022_add_organizations/migration.sql +142 -0
  184. package/host/prisma/migrations/20240101000023_split_system_org_roles/migration.sql +131 -0
  185. package/host/prisma/migrations/20240101000024_org_scoped_rls/migration.sql +215 -0
  186. package/host/prisma/migrations/20240101000025_add_groups/migration.sql +165 -0
  187. package/host/prisma/migrations/20240101000026_add_grants/migration.sql +117 -0
  188. package/host/prisma/migrations/20240101000027_add_org_settings/migration.sql +49 -0
  189. package/host/prisma/migrations/20240101000028_add_org_credentials/migration.sql +54 -0
  190. package/host/prisma/migrations/20240101000029_add_jobs_org_id/migration.sql +18 -0
  191. package/host/prisma/migrations/20240101000030_add_jobs_org_id_status_index/migration.sql +6 -0
  192. package/host/prisma/migrations/20240101000031_add_broadcast_target_org/migration.sql +21 -0
  193. package/host/prisma/migrations/20240101000032_add_android_app/migration.sql +60 -0
  194. package/host/prisma/migrations/20240101000033_open_job_reason/migration.sql +16 -0
  195. package/host/prisma/migrations/20240101000034_ai_usage_feature/migration.sql +37 -0
  196. package/host/prisma/migrations/20240101000035_add_app_metadata/migration.sql +49 -0
  197. package/host/prisma/migrations/20240101000036_open_sharing_vocabularies/migration.sql +97 -0
  198. package/host/prisma/migrations/20260914130000_kvox_add_transcripts/migration.sql +322 -0
  199. package/host/prisma/migrations/20260914140000_kvox_add_notes/migration.sql +311 -0
  200. package/host/prisma/migrations/20260915120000_kvox_add_search_vectors/migration.sql +150 -0
  201. package/host/prisma/migrations/20260915130000_kvox_add_search_embeddings/migration.sql +362 -0
  202. package/host/prisma/migrations/20260915210000_kvox_add_note_title_source/migration.sql +30 -0
  203. package/host/prisma/migrations/20260923120000_kvox_add_note_generation_context_snapshot/migration.sql +24 -0
  204. package/host/prisma/migrations/20260923130000_kvox_add_user_hidden_note_templates/migration.sql +35 -0
  205. package/host/prisma/migrations/20260923140000_kvox_add_transcript_speaker_identities/migration.sql +6 -0
  206. package/host/prisma/migrations/20260923150000_kvox_transcript_name_checks/migration.sql +95 -0
  207. package/host/prisma/migrations/20260923160000_kvox_add_note_body_format/migration.sql +27 -0
  208. package/host/prisma/migrations/20260923170000_kvox_add_note_version_body_format/migration.sql +23 -0
  209. package/host/prisma/migrations/20260926012548_kvox_add_knowledge_graph/migration.sql +680 -0
  210. package/host/prisma/migrations/20260926030000_kvox_fix_kg_relations_valid_precision_chk/migration.sql +29 -0
  211. package/host/prisma/migrations/20260926030100_kvox_add_transcript_recorded_at/migration.sql +9 -0
  212. package/host/prisma/migrations/20260926030200_kvox_kg_evidence_invariant/migration.sql +60 -0
  213. package/host/prisma/migrations/20260926040000_kvox_add_kg_graph_layouts/migration.sql +30 -0
  214. package/host/prisma/migrations/20260926050000_kvox_add_ask_conversations/migration.sql +99 -0
  215. package/host/prisma/migrations/20260926231512_kvox_add_kg_exports/migration.sql +52 -0
  216. package/host/prisma/migrations/20261016120000_kvox_transcripts_org_id/migration.sql +49 -0
  217. package/host/prisma/platform.lock +319 -0
  218. package/host/prisma/schema/app.kvox.ask.prisma +110 -0
  219. package/host/prisma/schema/app.kvox.graph.prisma +1030 -0
  220. package/host/prisma/schema/app.kvox.notes.prisma +746 -0
  221. package/host/prisma/schema/app.kvox.search.prisma +208 -0
  222. package/host/prisma/schema/app.kvox.transcripts.prisma +726 -0
  223. package/host/prisma/schema/platform.ai.prisma +419 -0
  224. package/host/prisma/schema/platform.android-app.prisma +46 -0
  225. package/host/prisma/schema/platform.base.prisma +15 -0
  226. package/host/prisma/schema/platform.credentials.prisma +156 -0
  227. package/host/prisma/schema/platform.db-backup.prisma +359 -0
  228. package/host/prisma/schema/platform.identity.prisma +638 -0
  229. package/host/prisma/schema/platform.jobs.prisma +824 -0
  230. package/host/prisma/schema/platform.notifications.prisma +641 -0
  231. package/host/prisma/schema/platform.settings.prisma +53 -0
  232. package/host/prisma/schema/platform.sharing.prisma +208 -0
  233. package/host/prisma/schema/platform.storage.prisma +118 -0
  234. package/package.json +112 -1
  235. package/parity/requests.ask.json +2681 -0
  236. package/parity/requests.m01.json +1554 -0
  237. package/parity/requests.m02.json +1554 -0
  238. package/parity/requests.m03.json +1554 -0
  239. package/parity/requests.m04.json +1554 -0
  240. package/parity/requests.m05.json +1554 -0
  241. package/parity/requests.m06.json +1554 -0
  242. package/parity/requests.m07.json +1554 -0
  243. package/parity/requests.m08.json +1554 -0
  244. package/parity/requests.m09.json +1554 -0
  245. package/parity/requests.m10.json +1554 -0
@@ -0,0 +1,208 @@
1
+ // GENERATED by platform db compose — do not edit
2
+ // source: app:kvox.search.prisma
3
+
4
+ // GENERATED by kvox-db sync — do not edit
5
+ // source: @marinoscar/kvox-db:schema/kvox.search.prisma
6
+
7
+ // =============================================================================
8
+ // Semantic search: pgvector storage (issue #181, epic #165)
9
+ // =============================================================================
10
+ //
11
+ // Layer 2 of search, sitting beside layer 1's generated `tsvector` columns
12
+ // (`20260915120000_add_search_vectors`): MEANING-based retrieval over the
13
+ // same transcript/note content, via vectors an AI embedding model produces.
14
+ // This is storage only — no embedding call, no chunking pipeline, lives in
15
+ // this schema; that is later issues in epic #165. The full argument for
16
+ // every decision below (the `vector(1536)` width contract, why
17
+ // `document_id` carries no foreign key, HNSW vs. IVFFlat, the
18
+ // `vector_cosine_ops` opclass, why embeddings are not a column on the
19
+ // document row, content addressing via `content_hash`, and why `status` is
20
+ // a Prisma enum while `document_type`/`reason` stay plain text) is in the
21
+ // header of `20260915130000_add_search_embeddings/migration.sql` — read that
22
+ // first; this comment only orients the three models against each other.
23
+ // =============================================================================
24
+
25
+ enum SearchIndexStatus {
26
+ pending
27
+ indexing
28
+ indexed
29
+ failed
30
+ skipped
31
+ }
32
+
33
+ // One row per chunk of a document's text (issue #181). `documentType` +
34
+ // `documentId` is a polymorphic reference with NO foreign key in either
35
+ // direction — the same precedent `Job.subjectType`/`subjectId` sets (see the
36
+ // block comment above `model Job`) and for the identical reason: the set of
37
+ // searchable document types is open-ended and code-owned. See the migration
38
+ // header's point 2 for the cost of that choice (an orphan row is possible)
39
+ // and who owes the sweep (the deleting document's own `transcript.purge` /
40
+ // `note.purge` handler, wired by a later issue).
41
+ model SearchChunk {
42
+ id String @id @default(uuid()) @db.Uuid
43
+
44
+ documentType String @map("document_type")
45
+ documentId String @map("document_id") @db.Uuid
46
+
47
+ // Position among this document's chunks. Together with
48
+ // (documentType, documentId) this is the natural key — see the unique
49
+ // index below.
50
+ ordinal Int
51
+
52
+ text String
53
+
54
+ // sha256 of this chunk's FINAL text — the content-addressing key. See the
55
+ // migration header's point 6: re-indexing an edited document only needs to
56
+ // re-embed the chunks whose hash actually changed, and the bill for that
57
+ // is the document owner's own vendor account.
58
+ contentHash String @map("content_hash")
59
+
60
+ // Character offsets into the document's source text, so a search result's
61
+ // snippet can be built directly from this row without re-locating the
62
+ // chunk inside the document. See the migration header's point 5 for why
63
+ // this lives on its own row rather than as a column on the document.
64
+ charStart Int @map("char_start")
65
+ charEnd Int @map("char_end")
66
+
67
+ createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
68
+
69
+ embeddings SearchEmbedding[]
70
+
71
+ // One chunk per position per document — the natural key a re-chunk
72
+ // upserts against.
73
+ @@unique([documentType, documentId, ordinal])
74
+ // The lookup every read of "this document's chunks" uses.
75
+ @@index([documentType, documentId])
76
+ // The content-addressing lookup the migration header's point 6 argues for.
77
+ @@index([contentHash])
78
+ @@map("search_chunks")
79
+ }
80
+
81
+ // One (chunk, model) embedding vector (issue #181). `chunkId` IS a real
82
+ // foreign key — unlike `SearchChunk.documentId` above, it points INSIDE this
83
+ // same module's own table, not sideways into another module's — and
84
+ // CASCADES: an embedding with no chunk left to belong to means nothing.
85
+ //
86
+ // ⚠ `embedding` is `Unsupported("vector(1536)")`, and it is REQUIRED, not
87
+ // optional — unlike the FTS `tsvector` columns in the sibling migration,
88
+ // which are database-GENERATED and so Prisma must never attempt to write
89
+ // them. This column is the opposite: application code writes it, on every
90
+ // insert, with no database-side generation at all. A REQUIRED `Unsupported`
91
+ // field makes `prisma.searchEmbedding.create(...)` (and every other
92
+ // generated-client write) UNCREATABLE for this model — the generated client
93
+ // has no way to construct a value for an unsupported type, so every write to
94
+ // this table MUST go through raw SQL (`$queryRaw`/`$executeRaw`, building the
95
+ // vector literal by hand). That is correct and intended, not a limitation to
96
+ // route around: a `vector` literal has to be assembled as raw SQL regardless
97
+ // of what the client layer offers, because there is no TypeScript
98
+ // representation of a pgvector value the generated client could accept in
99
+ // the first place. See the migration header's points 1, 3, 4 and 6 for the
100
+ // width contract, the HNSW index choice, the `vector_cosine_ops` opclass,
101
+ // and why `UNIQUE (chunkId, model)` is what makes a repeat embed cheap.
102
+ model SearchEmbedding {
103
+ id String @id @default(uuid()) @db.Uuid
104
+
105
+ chunkId String @map("chunk_id") @db.Uuid
106
+
107
+ // Which embedding model produced this vector — a plain string, open-ended,
108
+ // exactly like `Job.type` and `Transcript.provider` elsewhere in this
109
+ // schema, so a new or changed model costs this table zero migrations.
110
+ model String
111
+
112
+ // Recorded fact about the row, kept even though the column type already
113
+ // enforces the real width constraint. See the migration header's point 1
114
+ // for why this is not redundant: it is what lets a future width migration
115
+ // tell old rows from new ones without re-deriving the width from the
116
+ // vector itself.
117
+ dimensions Int
118
+
119
+ // `vector(1536)` — see the block comment above the model for the whole
120
+ // "why Unsupported, why required, why raw SQL" argument, and the migration
121
+ // header's point 1 for why 1536 specifically is a CONTRACT with
122
+ // `AiProvider`'s `EMBEDDING_DIMENSIONS`, not a default.
123
+ // Written as `Unsupported("vector(1536)")` with the parentheses as \u0028/\u0029: the
124
+ // composer's field reader (platform-db 0.1.0-next.5) stops a type at the first `)`.
125
+ // Prisma decodes the escapes, so the column type is still vector(1536).
126
+ embedding Unsupported("vector\u00281536\u0029")
127
+
128
+ createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
129
+
130
+ // ⚠ Cascade — this row has no meaning once its chunk is gone. See the
131
+ // header above the model.
132
+ chunk SearchChunk @relation(fields: [chunkId], references: [id], onDelete: Cascade)
133
+
134
+ // One vector per chunk per model — the natural key a re-embed upserts
135
+ // against, and the index the migration header's point 6 argues makes a
136
+ // repeat-embed check a single indexed lookup rather than a scan.
137
+ @@unique([chunkId, model])
138
+ // HAND-WRITTEN in migration.sql only — Prisma has no DSL for `USING hnsw`
139
+ // or for an index's operator class. See the migration header's
140
+ // "INTENTIONAL SCHEMA DRIFT" section (occurrence 5 of 5: `jobs`,
141
+ // `database_backup_runs`, `transcript_speakers`, this migration's own
142
+ // sibling's generated tsvector columns, and this). Do not "fix" this by
143
+ // inventing a Prisma-expressible substitute — there isn't one, and
144
+ // `prisma migrate dev`/`diff` must never be asked to reconcile this index
145
+ // away.
146
+ @@map("search_embeddings")
147
+ }
148
+
149
+ // One row per DOCUMENT (not chunk) — the legibility surface an owner or
150
+ // admin reads to answer "is this document semantically searchable, and if
151
+ // not, why not" (issue #181). `documentType`/`documentId` mirror
152
+ // `SearchChunk`'s polymorphic reference exactly, and for the identical
153
+ // reason (no foreign key, open-ended document types). `ownerId` IS a real
154
+ // foreign key into `users` and CASCADES: an index-state row for a document
155
+ // whose owner no longer exists means nothing, the same reasoning
156
+ // `Transcript.ownerId`/`Note.ownerId` already establish in this schema.
157
+ model SearchIndexState {
158
+ id String @id @default(uuid()) @db.Uuid
159
+
160
+ documentType String @map("document_type")
161
+ documentId String @map("document_id") @db.Uuid
162
+
163
+ ownerId String @map("owner_id") @db.Uuid
164
+
165
+ // A CLOSED set this application owns end to end — every value is written
166
+ // by code inside this repository, nothing external ever proposes a new
167
+ // one — so, unlike documentType/reason beside it, this IS a Prisma enum.
168
+ // See the migration header's "STATUS" section for the full three-way
169
+ // argument.
170
+ status SearchIndexStatus @default(pending)
171
+
172
+ // WHY this document is not (yet, or ever) semantically searchable —
173
+ // `ai_key_missing`, `ai_not_configured`, `dimension_mismatch`, … Plain
174
+ // TEXT and deliberately not an enum: it is a diagnostic string for a human
175
+ // debugging a stuck document, and it will grow new values as new failure
176
+ // modes are discovered. NULL outside of `failed`/`skipped` is itself
177
+ // informative.
178
+ reason String?
179
+
180
+ chunkCount Int @default(0) @map("chunk_count")
181
+
182
+ // Which embedding model produced the current chunk set, so a later change
183
+ // to the deployment's active model can be detected against rows indexed
184
+ // under an earlier one.
185
+ model String?
186
+
187
+ // The per-document hash "has this document's content changed since it was
188
+ // last indexed" is checked against — one comparison, not a full re-chunk,
189
+ // to decide whether a re-index has anything to do at all.
190
+ contentFingerprint String? @map("content_fingerprint")
191
+
192
+ lastError String? @map("last_error")
193
+
194
+ indexedAt DateTime? @map("indexed_at") @db.Timestamptz
195
+ createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
196
+ updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
197
+
198
+ // ⚠ Cascade. See the block comment above the model.
199
+ owner User @relation("SearchIndexStateOwner", fields: [ownerId], references: [id], onDelete: Cascade)
200
+
201
+ // One state row per document — the address every read/write of "this
202
+ // document's indexing status" uses.
203
+ @@unique([documentType, documentId])
204
+ // The `unindexedCount` query: "how many of this owner's documents are in
205
+ // state X".
206
+ @@index([ownerId, status])
207
+ @@map("search_index_state")
208
+ }