Self-hosted multi-platform broadcast newsroom for activist collectives: publishing pipeline with group approval and DST-proof scheduling, TweetDeck-style column wall with hostile-content-safe rendering, live control room with Auto Director, bridged chat governance with polls and quorum, distributed sandboxed transcode workers, encrypted content-addressed archive, monthly analytics. MIT licensed. See README.md and docs/.
52 lines
2.2 KiB
SQL
52 lines
2.2 KiB
SQL
-- 009: first-class video assets and their processing lifecycle
|
|
CREATE TABLE video_assets (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
workspace_id uuid NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
storage_key text NOT NULL,
|
|
mime_type text NOT NULL,
|
|
size_bytes bigint NOT NULL,
|
|
width int,
|
|
height int,
|
|
duration_ms int,
|
|
frame_rate numeric,
|
|
codec text,
|
|
audio_codec text,
|
|
thumbnail_key text,
|
|
created_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE video_processing_jobs (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
workspace_id uuid NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
video_asset_id uuid NOT NULL REFERENCES video_assets(id) ON DELETE CASCADE,
|
|
state text NOT NULL CHECK (state IN ('queued', 'probing', 'transcoding', 'complete', 'failed')),
|
|
progress_percent int NOT NULL DEFAULT 0,
|
|
output_key text,
|
|
error text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX video_assets_workspace_created
|
|
ON video_assets (workspace_id, created_at DESC, id DESC);
|
|
CREATE INDEX video_processing_jobs_asset_created
|
|
ON video_processing_jobs (video_asset_id, created_at DESC);
|
|
|
|
CREATE TRIGGER trg_video_asset_ws_immutable BEFORE UPDATE ON video_assets
|
|
FOR EACH ROW EXECUTE FUNCTION reject_workspace_change();
|
|
CREATE TRIGGER trg_video_job_ws_immutable BEFORE UPDATE ON video_processing_jobs
|
|
FOR EACH ROW EXECUTE FUNCTION reject_workspace_change();
|
|
|
|
ALTER TABLE video_assets ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE video_processing_jobs ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE video_assets FORCE ROW LEVEL SECURITY;
|
|
ALTER TABLE video_processing_jobs FORCE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY tenant_isolation ON video_assets
|
|
USING (workspace_id = NULLIF(current_setting('app.workspace_id', true), '')::uuid)
|
|
WITH CHECK (workspace_id = NULLIF(current_setting('app.workspace_id', true), '')::uuid);
|
|
CREATE POLICY tenant_isolation ON video_processing_jobs
|
|
USING (workspace_id = NULLIF(current_setting('app.workspace_id', true), '')::uuid)
|
|
WITH CHECK (workspace_id = NULLIF(current_setting('app.workspace_id', true), '')::uuid);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON video_assets, video_processing_jobs TO sp_app;
|