Skip to content

Data Model Reference

This page covers the full relational schema, the Neo4j property graph, the Weaviate vector schema, and the trend path tables. Use the entity-relationship diagrams as the authoritative reference for table structure and foreign-key relationships.


1. Core Pipeline — PostgreSQL Schema

The six tables below form the backbone of the ingestion and governance pipeline.

erDiagram
    source_artifacts {
        string artifact_id PK
        string source_system
        string source_type
        string source_ref UK
        datetime received_at
        string legal_basis
        string customer_scope
        string processing_run_id
    }

    transcript_segments {
        string segment_id PK
        string artifact_id FK
        int sequence
        text text
        string start_offset
        string end_offset
        string speaker
        string privacy_class
    }

    candidate_questions {
        string candidate_id PK
        text question_text
        float confidence
        string flow_type
        string source_segment_id
        string artifact_id FK
        string processing_run_id
    }

    candidate_answers {
        string candidate_id PK
        text answer_text
        string source_segment_id
        string question_candidate_id FK
        string artifact_id FK
        float confidence
        string processing_run_id
    }

    classification_records {
        string record_id PK
        string candidate_id FK
        text answer_text
        string primary_horn_type
        float primary_confidence
        json alternative_types
        string assertion_subtype
        json assertion_grammar
        boolean requires_review
        string model_version
        string processing_run_id
        datetime classified_at
    }

    approved_answers {
        string answer_id PK
        string candidate_id
        string horn_type
        string assertion_subtype
        text answer_text
        json assertion_grammar
        string status
        int version
        string owner_role
        string validation_record_id
        datetime created_at
        date review_due
        string supersedes_id
        string customer_scope
        json conflict_record_ids
    }

    source_artifacts ||--o{ transcript_segments : "artifact_id"
    source_artifacts ||--o{ candidate_questions : "artifact_id"
    source_artifacts ||--o{ candidate_answers : "artifact_id"
    candidate_questions ||--o{ candidate_answers : "question_candidate_id"
    candidate_questions ||--o{ classification_records : "candidate_id"

2. Validation and Registry Tables

erDiagram
    validation_assignments {
        string assignment_id PK
        string candidate_id
        string horn_type
        string current_state
        string assigned_to
        datetime created_at
        datetime updated_at
        json record_ids
        json conflict_flag_ids
    }

    validation_records {
        string record_id PK
        string assignment_id FK
        string candidate_id
        string decision
        string actor
        datetime timestamp
        text rationale
        text revised_text
        string prior_record_id
        json conflict_flags
    }

    conflict_flags {
        string flag_id PK
        string assignment_id_a FK
        string assignment_id_b
        string conflict_type
        text description
        datetime detected_at
    }

    evidence_links {
        string link_id PK
        string answer_id FK
        text source_ref
        datetime created_at
    }

    version_chains {
        string chain_id PK
        string answer_id FK
        string supersedes_id
        datetime created_at
    }

    registry_conflict_records {
        string conflict_id PK
        string answer_id_a FK
        string answer_id_b
        string conflict_type
        text description
        datetime detected_at
    }

    validation_assignments ||--o{ validation_records : "assignment_id"
    validation_assignments ||--o{ conflict_flags : "assignment_id_a"
    approved_answers ||--o{ evidence_links : "answer_id"
    approved_answers ||--o{ version_chains : "answer_id"
    approved_answers ||--o{ registry_conflict_records : "answer_id_a"

3. Generation Tables (Flow B)

erDiagram
    work_items {
        string work_item_id PK
        string candidate_id FK
        text question_text
        string source_segment_id
        string processing_run_id
        string state
        string jira_issue_key
        datetime created_at
        datetime updated_at
        text escalation_reason
        string generated_candidate_id
    }

    generated_candidates {
        string generated_id PK
        string work_item_id FK
        string question_candidate_id
        string answer_candidate_id
        text generated_text
        json citations
        string model_version
        int prompt_tokens
        int completion_tokens
        datetime generated_at
        string origin
    }

    candidate_questions ||--o{ work_items : "candidate_id"
    work_items ||--o{ generated_candidates : "work_item_id"

4. Trend Path Tables

The eight trend path tables extend the core schema. They are populated during intake and are query-ready immediately — no validation or registry step is required.

erDiagram
    transcript_lines {
        string line_id PK
        string artifact_id FK
        string segment_id FK
        int sequence
        int source_index
        string start_offset
        string end_offset
        string speaker
        text text
    }

    raw_mentions {
        string mention_id PK
        string line_id FK
        string artifact_id FK
        string segment_id
        text mention_text
        text normalized_text
        int start_char
        int end_char
        string mention_type
        string privacy_class
        string extractor_version
        string processing_run_id
    }

    line_sentiments {
        string line_id PK_FK
        float compound
        float pos
        float neu
        float neg
        string sentiment_label
        string scorer_version
        string processing_run_id
    }

    question_mention_links {
        string link_id PK
        string question_candidate_id FK
        string mention_id FK
        string link_basis
        int distance_lines
        string processing_run_id
    }

    canonical_entities {
        string canonical_entity_id PK
        text label
        text normalized_label
        string status
        string created_by
        datetime created_at
        string resolution_mode
    }

    mention_resolutions {
        string resolution_id PK
        string mention_id FK
        string canonical_entity_id FK
        float match_score
        string resolution_mode
        string review_state
        string actor
        datetime resolved_at
    }

    mention_clusters {
        string cluster_id PK
        text cluster_key
        int frequency
        datetime first_seen_at
        datetime last_seen_at
        string status
        string suggested_entity_id
    }

    canonical_entity_taxonomies {
        string assignment_id PK
        string canonical_entity_id FK
        string taxonomy_type
        string taxonomy_value
        string assigned_by
        datetime assigned_at
    }

    transcript_segments ||--o{ transcript_lines : "segment_id"
    source_artifacts ||--o{ transcript_lines : "artifact_id"
    transcript_lines ||--o{ raw_mentions : "line_id"
    transcript_lines ||--|| line_sentiments : "line_id"
    candidate_questions ||--o{ question_mention_links : "question_candidate_id"
    raw_mentions ||--o{ question_mention_links : "mention_id"
    raw_mentions ||--o{ mention_resolutions : "mention_id"
    canonical_entities ||--o{ mention_resolutions : "canonical_entity_id"
    canonical_entities ||--o{ canonical_entity_taxonomies : "canonical_entity_id"

5. Neo4j Property Graph

The graph is a derived projection updated by the raw_to_knowledge_graph Celery worker. It supports contradiction traversal, supersession chains, and trend analytics via Cypher.

graph LR
    subgraph knowledge_grp["Knowledge Graph (Milestone 7)"]
        ANS[Answer\nanswer_id\nhorn_type · status\nsubject · predicate\nobject_value · scope]
        QST[Question\nquestion_id\nquestion_text]
        EVI[Evidence\nevidence_id\nsource_ref]
        CON[Concept\nlabel]
    end

    subgraph trend_grp["Trend Graph (Trend Path)"]
        ART[Artifact\nartifact_id]
        SEG2[TranscriptSegment\nsegment_id]
        LNE[TranscriptLine\nline_id · text\nspeaker · sequence]
        MNT[RawMention\nmention_id\nnormalized_text\nmention_type]
        ENT[CanonicalEntity\ncanonical_entity_id\nlabel · status]
        TAX[TaxonomyTerm\ntype · value]
        SPK[Speaker\nname]
        CSC[CustomerScope\nname]
        TBK[TimeBucket\nweek: YYYY-Www]
    end

    QST -->|ANSWERED_BY| ANS
    ANS -->|SUPPORTED_BY| EVI
    ANS -->|ABOUT| CON
    ANS -->|SUPERSEDES| ANS
    ANS ---|CONFLICTS_WITH| ANS

    ART -->|IN_SCOPE| CSC
    SEG2 -->|HAS_LINE| LNE
    LNE -->|HAS_MENTION| MNT
    MNT -->|RESOLVES_TO| ENT
    ENT -->|IN_TAXONOMY| TAX
    LNE -->|SPOKEN_BY| SPK
    LNE -->|IN_WEEK| TBK
    QST -->|MENTIONS| ENT

Node properties:

Node Key properties
Answer answer_id, horn_type, subject, predicate, object_value, scope, status, version
Question question_id, question_text, source_session_id
Evidence evidence_id, source_ref, last_verified
Concept label (unique key)
TranscriptLine line_id, artifact_id, segment_id, sequence, speaker, text
RawMention mention_id, normalized_text, mention_type
CanonicalEntity canonical_entity_id, label, normalized_label, status
TaxonomyTerm type + value (composite key)
Speaker name
CustomerScope name
TimeBucket week (ISO 8601 week string, e.g. 2026-W23)

6. Migration Sequence

Alembic migrations are applied in order. Each revision builds on the previous.

graph LR
    M0([None]) --> M1["001\ninitial_schema\nsource_artifacts\ntranscript_segments\ncandidate_questions\ncandidate_answers"]
    M1 --> M2["002\nclassification_schema\nclassification_records"]
    M2 --> M3["003\nvalidation_schema\nvalidation_assignments\nvalidation_records\nconflict_flags"]
    M3 --> M4["004\nregistry_schema\napproved_answers\nevidence_links\nversion_chains\nregistry_conflict_records"]
    M4 --> M5["005\ngeneration_schema\nwork_items\ngenerated_candidates"]
    M5 --> M6["006\ntrend_schema\ntranscript_lines\nraw_mentions\nline_sentiments\nquestion_mention_links\ncanonical_entities\nmention_resolutions\nmention_clusters\ncanonical_entity_taxonomies"]

7. Weaviate Schema

Weaviate holds vector embeddings of approved answers for semantic retrieval and known-answer detection.

Collection: ApprovedAnswer
  Properties:
    answer_id     (text, tokenize: field)
    answer_text   (text, tokenize: word)    ← vectorized
    horn_type     (text, tokenize: field)
    status        (text, tokenize: field)
    customer_scope (text, tokenize: field)
    version       (int)
  Vectorizer: text2vec-openai (or text2vec-transformers)
  Distance metric: cosine
  Known-answer threshold: ≥ 0.92

Weaviate is write-only from the raw_to_knowledge_graph worker; the API reads it for search queries. It is never the source of truth — always verify against PostgreSQL approved_answers.