-- Inou Database Schema
-- Created: 2025-12-29
-- All IDs are 64-bit integers (hash of UUID)
-- All timestamps are Unix epoch (INTEGER)
-- String fields are encrypted unless noted

--------------------------------------------------------------------------------
-- ENUMS (defined in code, documented here)
--------------------------------------------------------------------------------
-- sex (ISO 5218): 0=unknown, 1=male, 2=female, 9=not_applicable
-- relation: 0=self, 1=parent, 2=child, 3=spouse, 4=sibling, 5=caregiver, 6=medical_professional, 7=other
-- status: 0=active, 1=deleted, 2=pending, 3=revoked, 4=processed, 5=in_review, ...

--------------------------------------------------------------------------------
-- DOSSIERS
--------------------------------------------------------------------------------
CREATE TABLE dossiers (
  dossier_id INTEGER PRIMARY KEY,
  email_hash TEXT UNIQUE,              -- plaintext, for lookup
  email TEXT,                          -- encrypted
  name TEXT,                           -- encrypted
  date_of_birth DATE,                  -- plaintext
  sex INTEGER DEFAULT 0,               -- enum
  phone TEXT,                          -- encrypted
  language TEXT DEFAULT 'en',        -- plaintext
  timezone TEXT,                       -- plaintext
  auth_code INTEGER,                   -- 6-digit code
  auth_code_expires_at INTEGER,        -- epoch
  last_login INTEGER,                  -- epoch
  invited_by_dossier_id INTEGER,       -- FK
  created_at INTEGER                   -- epoch
);
CREATE UNIQUE INDEX idx_dossiers_email_hash ON dossiers(email_hash);

--------------------------------------------------------------------------------
-- DOSSIER ACCESS (sharing permissions)
--------------------------------------------------------------------------------
CREATE TABLE dossier_access (
  accessor_dossier_id INTEGER,         -- who has access
  target_dossier_id INTEGER,           -- whose dossier
  relation INTEGER DEFAULT 0,          -- enum
  is_care_receiver INTEGER DEFAULT 0,  -- boolean
  can_edit INTEGER DEFAULT 0,          -- boolean
  status INTEGER DEFAULT 0,            -- enum
  created_at INTEGER,                  -- epoch
  accessed_at INTEGER,                 -- epoch
  PRIMARY KEY (accessor_dossier_id, target_dossier_id)
);
CREATE INDEX idx_access_accessor ON dossier_access(accessor_dossier_id);
CREATE INDEX idx_access_target ON dossier_access(target_dossier_id);

--------------------------------------------------------------------------------
-- ENTRIES (all data: imaging, labs, vitals, genome, uploads, etc.)
--------------------------------------------------------------------------------
CREATE TABLE entries (
  entry_id INTEGER PRIMARY KEY,
  dossier_id INTEGER NOT NULL,         -- FK
  parent_id INTEGER,                   -- FK self-ref (hierarchy)
  product_id INTEGER,                  -- FK to products (optional)
  category TEXT NOT NULL,              -- encrypted, deterministic
  type TEXT NOT NULL,                  -- encrypted, deterministic
  value TEXT,                          -- encrypted
  ordinal INTEGER DEFAULT 0,           -- sort order within parent
  timestamp INTEGER NOT NULL,          -- epoch
  timestamp_end INTEGER,               -- epoch (for ranges)
  status INTEGER DEFAULT 0,            -- enum
  tags TEXT,                           -- encrypted
  data TEXT                            -- encrypted JSON
);
CREATE INDEX idx_entries_dossier_category_type ON entries(dossier_id, category, type);
CREATE INDEX idx_entries_dossier_timestamp ON entries(dossier_id, timestamp);
CREATE INDEX idx_entries_parent ON entries(parent_id, ordinal);

--------------------------------------------------------------------------------
-- AUDIT
--------------------------------------------------------------------------------
CREATE TABLE audit (
  audit_id INTEGER PRIMARY KEY,
  dossier_id INTEGER,                  -- who performed action
  action TEXT,                         -- encrypted
  target_dossier_id INTEGER,           -- affected dossier (if applicable)
  details TEXT,                        -- encrypted JSON
  timestamp INTEGER                    -- epoch
);
CREATE INDEX idx_audit_dossier_timestamp ON audit(dossier_id, timestamp);
CREATE INDEX idx_audit_target_timestamp ON audit(target_dossier_id, timestamp);

--------------------------------------------------------------------------------
-- OBJECTS (binary files)
-- Stored on disk at: /objects/{dossier_id}/{aa}/{bb}/{entry_id}
-- where aa/bb are first 4 chars of entry_id for sharding
--------------------------------------------------------------------------------
