90 lines
3.1 KiB
SQL
90 lines
3.1 KiB
SQL
-- ============================================================================
|
|
-- 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);
|