Files
VoiceVault/database/schema.sql

156 lines
4.2 KiB
MySQL
Raw Normal View History

2026-02-14 16:13:03 -07:00
2026-02-14 21:39:08 -07:00
-- 1) Users
2026-02-14 16:13:03 -07:00
CREATE TABLE users (
2026-02-14 21:39:08 -07:00
user_id BIGSERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
2026-02-14 16:29:15 -07:00
password_hash VARCHAR(255) NOT NULL,
2026-02-14 21:39:08 -07:00
display_name VARCHAR(120),
avatar_url VARCHAR(500),
bio TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
2026-02-14 16:13:03 -07:00
);
2026-02-14 21:39:08 -07:00
-- 2) Audio Posts
CREATE TABLE audio_posts (
post_id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
2026-02-14 16:13:03 -07:00
2026-02-14 21:39:08 -07:00
title VARCHAR(255) NOT NULL,
description TEXT,
2026-02-14 16:13:03 -07:00
2026-02-14 21:39:08 -07:00
visibility VARCHAR(20) NOT NULL DEFAULT 'private',
status VARCHAR(20) NOT NULL DEFAULT 'uploaded',
2026-02-14 16:13:03 -07:00
2026-02-14 21:39:08 -07:00
recorded_date DATE,
language VARCHAR(20) DEFAULT 'en',
storage_prefix VARCHAR(500) NOT NULL,
2026-02-14 16:13:03 -07:00
2026-02-14 21:39:08 -07:00
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'))
2026-02-14 16:13:03 -07:00
);
2026-02-14 21:39:08 -07:00
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'
))
2026-02-14 16:13:03 -07:00
);
2026-02-14 21:39:08 -07:00
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
2026-02-14 16:13:03 -07:00
);
2026-02-14 21:39:08 -07:00
-- 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
2026-02-14 16:13:03 -07:00
);
2026-02-14 21:39:08 -07:00
-- 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,
2026-02-14 22:46:27 -07:00
embedding vector(1536),
2026-02-14 21:39:08 -07:00
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
2026-02-14 16:13:03 -07:00
);
2026-02-14 21:39:08 -07:00
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
2026-02-14 16:13:03 -07:00
);
2026-02-14 21:39:08 -07:00
CREATE INDEX idx_audit_post ON audit_log(post_id);