-- ============================================================================
-- Inou Database Schema (inou.db)
-- ============================================================================
-- Three core tables + two reference tables.
-- Tables are NOT auto-created from Go. Run this manually.
-- OAuth tables are in separate auth.db (see schema-auth.sql).
-- ============================================================================

-- Everything: dossier profiles (cat 0), imaging, labs, genome, docs, ...
-- String fields are BLOB (compress→encrypt via Pack/Unpack).
-- Integer/bool fields are plain INTEGER.
-- IDs are plain TEXT (not packed).
CREATE TABLE IF NOT EXISTS entries (
    EntryID      TEXT PRIMARY KEY,
    DossierID    TEXT NOT NULL,
    ParentID     TEXT DEFAULT '',
    Category     INTEGER DEFAULT 0,
    Type         BLOB,
    Value        BLOB,
    Summary      BLOB,
    Ordinal      INTEGER DEFAULT 0,
    Timestamp    INTEGER DEFAULT 0,
    TimestampEnd INTEGER DEFAULT 0,
    Status       INTEGER DEFAULT 0,
    Tags         BLOB,
    Data         BLOB,
    SearchKey    BLOB
);

CREATE INDEX IF NOT EXISTS idx_entries_dossier ON entries(DossierID);
CREATE INDEX IF NOT EXISTS idx_entries_parent ON entries(DossierID, ParentID);
CREATE INDEX IF NOT EXISTS idx_entries_category ON entries(DossierID, Category);
CREATE INDEX IF NOT EXISTS idx_entries_searchkey ON entries(SearchKey);

-- RBAC grants: who (GranteeID) can access whose (DossierID) data.
-- All columns plain text/int — no packing.
CREATE TABLE IF NOT EXISTS access (
    AccessID   TEXT PRIMARY KEY,
    DossierID  TEXT NOT NULL,
    GranteeID  TEXT NOT NULL,
    EntryID    TEXT DEFAULT '',
    Relation   INTEGER DEFAULT 0,
    Ops        INTEGER DEFAULT 0,
    CreatedAt  INTEGER DEFAULT 0
);

CREATE INDEX IF NOT EXISTS idx_access_grantee ON access(GranteeID);
CREATE INDEX IF NOT EXISTS idx_access_dossier ON access(DossierID);

-- Immutable audit log. String fields are packed.
CREATE TABLE IF NOT EXISTS audit (
    AuditID    TEXT PRIMARY KEY,
    Actor1ID   TEXT,
    Actor2ID   TEXT,
    TargetID   TEXT,
    Action     BLOB,
    Details    BLOB,
    RelationID INTEGER DEFAULT 0,
    Timestamp  INTEGER DEFAULT 0
);

CREATE INDEX IF NOT EXISTS idx_audit_actor ON audit(Actor1ID);
CREATE INDEX IF NOT EXISTS idx_audit_target ON audit(TargetID);

-- Lab test properties (per LOINC code)
-- Public reference data (not PII). Plain text.
-- Values stored as int64 with x1,000,000 scaling for float precision.
CREATE TABLE IF NOT EXISTS lab_test (
    loinc_id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    si_unit TEXT NOT NULL,
    direction TEXT NOT NULL DEFAULT 'range',
    si_factor INTEGER NOT NULL DEFAULT 1000000
);

-- Lab reference ranges (always in SI units)
CREATE TABLE IF NOT EXISTS lab_reference (
    ref_id TEXT PRIMARY KEY,
    loinc_id TEXT NOT NULL,
    source TEXT NOT NULL,
    sex TEXT NOT NULL DEFAULT '',
    age_days INTEGER NOT NULL DEFAULT 0,
    age_end INTEGER NOT NULL,
    ref_low INTEGER NOT NULL DEFAULT -1,
    ref_high INTEGER NOT NULL DEFAULT -1,
    unit TEXT NOT NULL
);

CREATE INDEX IF NOT EXISTS idx_lab_reference_loinc ON lab_reference(loinc_id);
