Files

128 lines
4.9 KiB
SQL

-- ==============================================================================
-- OnEver Drive — PostgreSQL Production Schema
-- ==============================================================================
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
hashed_password VARCHAR(255) NOT NULL,
full_name VARCHAR(255),
role VARCHAR(50) DEFAULT 'ADMIN' NOT NULL,
is_active BOOLEAN DEFAULT TRUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS clients (
id SERIAL PRIMARY KEY,
client_code VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
hostname VARCHAR(255),
os_info VARCHAR(255),
ip_address VARCHAR(100),
agent_version VARCHAR(50) DEFAULT '1.0.0' NOT NULL,
status VARCHAR(50) DEFAULT 'OFFLINE' NOT NULL,
storage_used_bytes BIGINT DEFAULT 0 NOT NULL,
storage_quota_bytes BIGINT DEFAULT 107374182400 NOT NULL,
last_seen_at TIMESTAMP WITH TIME ZONE,
last_backup_at TIMESTAMP WITH TIME ZONE,
is_active BOOLEAN DEFAULT TRUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS client_credentials (
id SERIAL PRIMARY KEY,
client_id INTEGER REFERENCES clients(id) ON DELETE CASCADE NOT NULL,
device_id VARCHAR(100) UNIQUE NOT NULL,
token_hash VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) DEFAULT 'Primary Windows Agent' NOT NULL,
is_revoked BOOLEAN DEFAULT FALSE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
last_used_at TIMESTAMP WITH TIME ZONE
);
CREATE TABLE IF NOT EXISTS registration_codes (
id SERIAL PRIMARY KEY,
code VARCHAR(50) UNIQUE NOT NULL,
is_used BOOLEAN DEFAULT FALSE NOT NULL,
client_name_hint VARCHAR(255),
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS backup_jobs (
id SERIAL PRIMARY KEY,
job_code VARCHAR(50) UNIQUE NOT NULL,
client_id INTEGER REFERENCES clients(id) ON DELETE CASCADE NOT NULL,
name VARCHAR(255) NOT NULL,
source_path VARCHAR(1024) NOT NULL,
file_patterns VARCHAR(255) DEFAULT '*.bak,*.mdf' NOT NULL,
schedule_cron VARCHAR(100) DEFAULT '0 2 * * *' NOT NULL,
keep_daily INTEGER DEFAULT 7 NOT NULL,
keep_weekly INTEGER DEFAULT 4 NOT NULL,
keep_monthly INTEGER DEFAULT 12 NOT NULL,
min_stable_time_seconds INTEGER DEFAULT 60 NOT NULL,
status VARCHAR(50) DEFAULT 'IDLE' NOT NULL,
last_run_at TIMESTAMP WITH TIME ZONE,
next_run_at TIMESTAMP WITH TIME ZONE,
is_active BOOLEAN DEFAULT TRUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS backup_sessions (
id SERIAL PRIMARY KEY,
session_code VARCHAR(100) UNIQUE NOT NULL,
client_id INTEGER REFERENCES clients(id) ON DELETE CASCADE NOT NULL,
job_id INTEGER REFERENCES backup_jobs(id) ON DELETE CASCADE,
filename VARCHAR(512) NOT NULL,
file_size BIGINT NOT NULL,
chunk_size INTEGER DEFAULT 4194304 NOT NULL,
total_chunks INTEGER NOT NULL,
received_chunks_count INTEGER DEFAULT 0 NOT NULL,
sha256_full VARCHAR(64) NOT NULL,
status VARCHAR(50) DEFAULT 'PENDING' NOT NULL,
error_message TEXT,
started_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
completed_at TIMESTAMP WITH TIME ZONE
);
CREATE TABLE IF NOT EXISTS backup_chunks (
id SERIAL PRIMARY KEY,
session_id INTEGER REFERENCES backup_sessions(id) ON DELETE CASCADE NOT NULL,
chunk_index INTEGER NOT NULL,
chunk_size INTEGER NOT NULL,
sha256 VARCHAR(64) NOT NULL,
is_received BOOLEAN DEFAULT FALSE NOT NULL,
received_at TIMESTAMP WITH TIME ZONE,
UNIQUE(session_id, chunk_index)
);
CREATE TABLE IF NOT EXISTS backup_files (
id SERIAL PRIMARY KEY,
client_id INTEGER REFERENCES clients(id) ON DELETE CASCADE NOT NULL,
job_id INTEGER REFERENCES backup_jobs(id) ON DELETE CASCADE,
session_id INTEGER REFERENCES backup_sessions(id) ON DELETE SET NULL,
filename VARCHAR(512) NOT NULL,
relative_path VARCHAR(1024) NOT NULL,
file_size BIGINT NOT NULL,
sha256 VARCHAR(64) NOT NULL,
retention_tag VARCHAR(50) DEFAULT 'DAILY' NOT NULL,
is_active BOOLEAN DEFAULT TRUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS event_logs (
id SERIAL PRIMARY KEY,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
event_type VARCHAR(100) NOT NULL,
severity VARCHAR(50) DEFAULT 'INFO' NOT NULL,
client_id INTEGER,
job_id INTEGER,
user_email VARCHAR(255),
ip_address VARCHAR(100),
message TEXT NOT NULL,
details_json TEXT
);
CREATE INDEX IF NOT EXISTS idx_sessions_client_status ON backup_sessions(client_id, status);
CREATE INDEX IF NOT EXISTS idx_event_logs_timestamp ON event_logs(timestamp);