

-- 1) Users
CREATE TABLE users (
  user_id       BIGSERIAL PRIMARY KEY,
  email         VARCHAR(255) UNIQUE NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  display_name  VARCHAR(120),
  avatar_url    VARCHAR(500),
  bio           TEXT,
  created_at    TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- 2) Audio Posts
CREATE TABLE audio_posts (
  post_id        BIGSERIAL PRIMARY KEY,
  user_id        BIGINT NOT NULL,

  title          VARCHAR(255) NOT NULL,
  description    TEXT,

  visibility     VARCHAR(20) NOT NULL DEFAULT 'private',
  status         VARCHAR(20) NOT NULL DEFAULT 'uploaded',

  recorded_date  DATE,
  language       VARCHAR(20) DEFAULT 'en',

  storage_prefix VARCHAR(500) NOT NULL,

  manifest_sha256 CHAR(64),
  bundle_sha256   CHAR(64),

  published_at   TIMESTAMP,
  created_at     TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at     TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

  CONSTRAINT fk_audio_posts_user
    FOREIGN KEY (user_id) REFERENCES users(user_id)
      ON DELETE CASCADE,

  CONSTRAINT chk_audio_visibility
    CHECK (visibility IN ('private','public')),

  CONSTRAINT chk_audio_status
    CHECK (status IN ('uploaded','processing','ready','failed'))
);

CREATE INDEX idx_audio_posts_user ON audio_posts(user_id);
CREATE INDEX idx_audio_posts_visibility ON audio_posts(visibility);

-- 3) Archive Files (integrity ledger)
CREATE TABLE archive_files (
  file_id      BIGSERIAL PRIMARY KEY,
  post_id      BIGINT NOT NULL,

  role         VARCHAR(30) NOT NULL,
  path         VARCHAR(500) NOT NULL,
  content_type VARCHAR(120),
  size_bytes   BIGINT,
  sha256       CHAR(64) NOT NULL,

  created_at   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

  CONSTRAINT fk_archive_files_post
    FOREIGN KEY (post_id) REFERENCES audio_posts(post_id)
      ON DELETE CASCADE,

  CONSTRAINT uq_archive_post_role UNIQUE (post_id, role),
  CONSTRAINT uq_archive_post_path UNIQUE (post_id, path),

  CONSTRAINT chk_archive_role CHECK (role IN (
    'original_audio',
    'normalized_audio',
    'transcript_json',
    'transcript_txt',
    'metadata',
    'rights',
    'manifest',
    'bundle'
  ))
);

CREATE INDEX idx_archive_files_post ON archive_files(post_id);

-- 4) Archive Metadata (store JSON as TEXT to keep it "plain")
CREATE TABLE archive_metadata (
  post_id     BIGINT PRIMARY KEY,
  metadata    TEXT NOT NULL,  -- JSON string

  created_at  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

  CONSTRAINT fk_archive_metadata_post
    FOREIGN KEY (post_id) REFERENCES audio_posts(post_id)
      ON DELETE CASCADE
);

-- 5) Archive Rights / Consent (store arrays as TEXT to keep it "plain")
CREATE TABLE archive_rights (
  post_id             BIGINT PRIMARY KEY,

  has_speaker_consent BOOLEAN NOT NULL DEFAULT FALSE,
  license             VARCHAR(50),
  consent_notes       TEXT,

  allowed_use         TEXT,  -- JSON string like ["education","research"]
  restrictions        TEXT,  -- JSON string like ["no_doxxing"]

  updated_at          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

  CONSTRAINT fk_archive_rights_post
    FOREIGN KEY (post_id) REFERENCES audio_posts(post_id)
      ON DELETE CASCADE
);

-- 6) RAG Chunks (store embeddings as TEXT to keep it "plain")
CREATE TABLE rag_chunks (
  chunk_id    BIGSERIAL PRIMARY KEY,
  post_id     BIGINT NOT NULL,

  start_sec   DOUBLE PRECISION NOT NULL,
  end_sec     DOUBLE PRECISION NOT NULL,
  text        TEXT NOT NULL,
  confidence  DOUBLE PRECISION,

  embedding   vector(1536), 

  created_at  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

  CONSTRAINT fk_rag_chunks_post
    FOREIGN KEY (post_id) REFERENCES audio_posts(post_id)
      ON DELETE CASCADE
);

CREATE INDEX idx_rag_chunks_post ON rag_chunks(post_id);

-- 7) Audit Log
CREATE TABLE audit_log (
  log_id     BIGSERIAL PRIMARY KEY,
  post_id    BIGINT,
  user_id    BIGINT,
  action     VARCHAR(50) NOT NULL,
  details    TEXT, -- JSON string
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

  CONSTRAINT fk_audit_post
    FOREIGN KEY (post_id) REFERENCES audio_posts(post_id)
      ON DELETE SET NULL,

  CONSTRAINT fk_audit_user
    FOREIGN KEY (user_id) REFERENCES users(user_id)
      ON DELETE SET NULL
);

CREATE INDEX idx_audit_post ON audit_log(post_id);
