rspace-online/modules/files/db/schema.sql

75 lines
3.2 KiB
SQL

-- rFiles schema — file sharing, memory cards
-- Inside rSpace shared DB, schema: rfiles
CREATE TABLE IF NOT EXISTS rfiles.media_files (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
original_filename VARCHAR(500) NOT NULL,
title VARCHAR(500),
description TEXT,
mime_type VARCHAR(200),
file_size BIGINT DEFAULT 0,
file_hash VARCHAR(64),
storage_path TEXT NOT NULL,
tags JSONB DEFAULT '[]',
is_processed BOOLEAN DEFAULT FALSE,
processing_error TEXT,
uploaded_by TEXT,
shared_space TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_files_hash ON rfiles.media_files (file_hash);
CREATE INDEX IF NOT EXISTS idx_files_mime ON rfiles.media_files (mime_type);
CREATE INDEX IF NOT EXISTS idx_files_space ON rfiles.media_files (shared_space);
CREATE INDEX IF NOT EXISTS idx_files_created ON rfiles.media_files (created_at DESC);
CREATE TABLE IF NOT EXISTS rfiles.public_shares (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
token VARCHAR(48) NOT NULL UNIQUE,
media_file_id UUID NOT NULL REFERENCES rfiles.media_files(id) ON DELETE CASCADE,
created_by TEXT,
expires_at TIMESTAMPTZ,
max_downloads INTEGER,
download_count INTEGER DEFAULT 0,
is_password_protected BOOLEAN DEFAULT FALSE,
password_hash TEXT,
note VARCHAR(500),
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_shares_token ON rfiles.public_shares (token);
CREATE INDEX IF NOT EXISTS idx_shares_active ON rfiles.public_shares (is_active) WHERE is_active = TRUE;
CREATE INDEX IF NOT EXISTS idx_shares_expires ON rfiles.public_shares (expires_at);
CREATE TABLE IF NOT EXISTS rfiles.memory_cards (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
shared_space TEXT NOT NULL,
title VARCHAR(500) NOT NULL,
body TEXT,
card_type VARCHAR(20) DEFAULT 'note' CHECK (card_type IN ('note', 'idea', 'task', 'reference', 'quote')),
tags JSONB DEFAULT '[]',
position INTEGER DEFAULT 0,
created_by TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_cards_space ON rfiles.memory_cards (shared_space);
CREATE INDEX IF NOT EXISTS idx_cards_type ON rfiles.memory_cards (card_type);
CREATE INDEX IF NOT EXISTS idx_cards_position ON rfiles.memory_cards (position);
CREATE TABLE IF NOT EXISTS rfiles.access_logs (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
media_file_id UUID REFERENCES rfiles.media_files(id) ON DELETE CASCADE,
share_id UUID REFERENCES rfiles.public_shares(id) ON DELETE SET NULL,
accessed_at TIMESTAMPTZ DEFAULT NOW(),
ip_address INET,
user_agent VARCHAR(500),
access_type VARCHAR(20) DEFAULT 'download' CHECK (access_type IN ('download', 'view', 'share_created', 'share_revoked'))
);
CREATE INDEX IF NOT EXISTS idx_logs_accessed ON rfiles.access_logs (accessed_at DESC);
CREATE INDEX IF NOT EXISTS idx_logs_type ON rfiles.access_logs (access_type);