Skip to main content

DB Schema

Key tables in the okt_repository and okt_system schemas. Migrations live in backend/db/migrations/.

okt_repository.sources

The source row: URL, status, parsed content, sentence offsets, DOI, storage info.

ColumnTypeDescription
idUUID PK
repository_idUUID FK
urlTEXT
kindTEXTtext / pdf / etc
statusTEXTpending / fetching / fetched / failed / processed
contentTEXTPreview
parsed_titleTEXT
parsed_textTEXT
parsed_markdownTEXTPreferred by decomposition
parsed_htmlTEXT
parsed_authorTEXT
parsed_sitenameTEXT
parsed_languageTEXT
published_atDATE
doiTEXT
oa_statusTEXT
sentence_offsetsINT[]Flat [start0,end0,start1,end1,...] rune offsets of the global sentence array
storage_keyTEXT
content_typeTEXT
local_pathTEXT
stored_atTIMESTAMPTZ
fetch_attemptsINT
fetched_atTIMESTAMPTZ
errorTEXT
created_atTIMESTAMPTZ
updated_atTIMESTAMPTZ
processed_atTIMESTAMPTZ

okt_repository.source_images

Inline images + PDF page renders.

ColumnTypeDescription
idUUID PK
source_idUUID FK CASCADE
kindTEXTinline / page
page_numberINT(for PDF pages)
positionINT
urlTEXT
width / height / bytesINT
local_pathTEXT
storage_keyTEXT
content_typeTEXT
mirrored_atTIMESTAMPTZ
alt_textTEXT

okt_repository.facts

Atomic, self-contained facts.

ColumnTypeDescription
idUUID PK
textTEXTThe self-contained fact text
statusTEXTnew / stable / to_delete
fact_kindTEXTtext / image (default text)
image_urlTEXT(for image facts)
embedded_atTIMESTAMPTZWhen the vector was upserted to Qdrant
embedded_modelTEXT
created_atTIMESTAMPTZ

No source_id column — all source links live in the junction.

okt_repository.fact_sources

Junction: fact <-> source.

ColumnType
fact_idUUID FK CASCADE
source_idUUID FK CASCADE
chunk_indexINT
first_seen_atTIMESTAMPTZ

PK: (fact_id, source_id) (ON CONFLICT idempotent).

okt_repository.fact_references

Sentence-level provenance.

ColumnType
fact_idUUID FK
source_idUUID FK
sentence_indexINT
chunk_indexINT
first_seen_atTIMESTAMPTZ

PK: (fact_id, source_id, sentence_index). Keys into sources.sentence_offsets.

okt_repository.concepts

Concept nodes.

ColumnTypeDescription
idUUID PK
repository_idUUID FK
canonical_nameTEXTDisplay name
contextTEXTOntology label (DBpedia L3 or custom)
descriptionTEXT
summarizing_atTIMESTAMPTZPer-concept summarization lock
embedded_atTIMESTAMPTZ
embedded_modelTEXT
created_atTIMESTAMPTZ

Unique: (repository_id, lower(canonical_name), lower(context)).

okt_repository.concept_aliases

Aliases for each concept.

ColumnType
idUUID PK
concept_idUUID FK CASCADE
alias_textTEXT
created_atTIMESTAMPTZ

Index on lower(alias_text) (lookup); unique (concept_id, lower(alias_text)).

okt_repository.fact_concepts

Junction: fact <-> concept.

ColumnType
fact_idUUID FK
concept_idUUID FK
first_seen_atTIMESTAMPTZ

PK: (fact_id, concept_id).

okt_repository.concept_summaries

Per-concept summary slices.

ColumnTypeDescription
idUUID PK
concept_idUUID FK
repository_idUUID FK
contextTEXT
sequence_numINT1-based slice index
is_completeBOOLEANFALSE=open/accumulating, TRUE=frozen
fact_countINT
contentTEXTMarkdown with [text](<fact:fact_id>) citations
covered_fact_idsUUID[]
modelTEXT
created_atTIMESTAMPTZ
updated_atTIMESTAMPTZ

Unique partial index uq_concept_summaries_concept_open on (concept_id) WHERE is_complete = FALSE.

okt_repository.concept_syntheses

One authoritative synthesis per concept group.

ColumnTypeDescription
idUUID PK
repository_idUUID FK
canonical_nameTEXT
contentTEXTMarkdown synthesis
covered_summary_idsUUID[]
covered_concept_idsUUID[]
embedded_image_idsUUID[]
modelTEXT
created_atTIMESTAMPTZ
updated_atTIMESTAMPTZ

Unique: (repository_id, lower(canonical_name)).

okt_repository.concept_relations

Materialized view — weighted edges between concepts.

ColumnType
repository_idUUID
name_aTEXT (lower(canonical_name))
name_bTEXT
shared_fact_countINT

Pairs ordered name_a < name_b, self-pairs excluded. Unique for REFRESH CONCURRENTLY.

okt_system.ai_usage

Every LLM call is logged.

ColumnType
idUUID PK
task_idTEXT
modelTEXT
providerTEXT
prompt_tokensINT
completion_tokensINT
total_tokensINT
created_atTIMESTAMPTZ