first commit

This commit is contained in:
2026-03-28 15:43:18 +08:00
commit e5611df24e
54 changed files with 11065 additions and 0 deletions

111
backend/sql/init.sql Normal file
View File

@@ -0,0 +1,111 @@
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE TABLE IF NOT EXISTS devices (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
device_code VARCHAR(64) NOT NULL UNIQUE,
name VARCHAR(128) NOT NULL,
type VARCHAR(64) NOT NULL,
user_agent TEXT,
network_group_key VARCHAR(128),
public_ip_hash VARCHAR(128),
is_online BOOLEAN NOT NULL DEFAULT FALSE,
last_seen_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS rooms (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(4) NOT NULL UNIQUE,
creator_device_id UUID NOT NULL REFERENCES devices(id),
joiner_device_id UUID REFERENCES devices(id),
status VARCHAR(32) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
initiator_device_id UUID NOT NULL REFERENCES devices(id),
target_device_id UUID NOT NULL REFERENCES devices(id),
room_id UUID REFERENCES rooms(id),
connect_mode VARCHAR(32) NOT NULL DEFAULT 'p2p',
status VARCHAR(32) NOT NULL DEFAULT 'connecting',
fail_reason TEXT,
connected_at TIMESTAMPTZ,
closed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS transfers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID REFERENCES sessions(id),
kind VARCHAR(16) NOT NULL,
name VARCHAR(255) NOT NULL,
content TEXT,
size_bytes BIGINT NOT NULL DEFAULT 0,
sender_device_id UUID NOT NULL REFERENCES devices(id),
receiver_device_id UUID NOT NULL REFERENCES devices(id),
transfer_strategy VARCHAR(32) NOT NULL,
current_channel VARCHAR(32) NOT NULL DEFAULT 'p2p',
fallback_allowed BOOLEAN NOT NULL DEFAULT FALSE,
final_status VARCHAR(32) NOT NULL DEFAULT 'pending',
fallback_reason TEXT,
object_key TEXT,
expires_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS fallback_objects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
transfer_id UUID NOT NULL UNIQUE REFERENCES transfers(id) ON DELETE CASCADE,
bucket VARCHAR(128) NOT NULL,
object_key TEXT NOT NULL UNIQUE,
size_bytes BIGINT NOT NULL DEFAULT 0,
cleanup_state VARCHAR(32) NOT NULL DEFAULT 'pending',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ NOT NULL,
cleaned_at TIMESTAMPTZ
);
CREATE TABLE IF NOT EXISTS admin_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(64) NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS system_configs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
config_key VARCHAR(128) NOT NULL UNIQUE,
config_value JSONB NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS audit_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
operator_type VARCHAR(32) NOT NULL,
operator_id UUID,
action VARCHAR(128) NOT NULL,
payload JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_devices_online ON devices (is_online, last_seen_at DESC);
CREATE INDEX IF NOT EXISTS idx_devices_network_group ON devices (network_group_key);
CREATE INDEX IF NOT EXISTS idx_rooms_status_expires ON rooms (status, expires_at DESC);
CREATE INDEX IF NOT EXISTS idx_sessions_status_created ON sessions (status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_transfers_status_created ON transfers (final_status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_transfers_sender_receiver ON transfers (sender_device_id, receiver_device_id);
CREATE INDEX IF NOT EXISTS idx_fallback_objects_expires ON fallback_objects (cleanup_state, expires_at ASC);
CREATE INDEX IF NOT EXISTS idx_audit_logs_created ON audit_logs (created_at DESC);
INSERT INTO system_configs (config_key, config_value)
VALUES
('transfer_policy', '{"max_minio_fallback_size_bytes":10737418240,"minio_capacity_bytes":128849018880,"minio_retention_hours":2,"p2p_connect_timeout_sec":15,"turn_connect_timeout_sec":20,"minio_usage_alert_percent":85,"minio_fallback_enabled":true,"turn_urls":[],"turn_username":"","turn_password":""}'::jsonb)
ON CONFLICT (config_key) DO NOTHING;

108
backend/sql/init_sqlite.sql Normal file
View File

@@ -0,0 +1,108 @@
CREATE TABLE IF NOT EXISTS devices (
id TEXT PRIMARY KEY,
device_code TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
type TEXT NOT NULL,
user_agent TEXT,
network_group_key TEXT,
public_ip_hash TEXT,
is_online INTEGER NOT NULL DEFAULT 0,
last_seen_at TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS rooms (
code TEXT PRIMARY KEY,
creator_device_id TEXT NOT NULL REFERENCES devices(id),
joiner_device_id TEXT REFERENCES devices(id),
status TEXT NOT NULL,
created_at TEXT NOT NULL,
expires_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS sessions (
id TEXT PRIMARY KEY,
initiator_device_id TEXT NOT NULL REFERENCES devices(id),
target_device_id TEXT NOT NULL REFERENCES devices(id),
room_code TEXT REFERENCES rooms(code),
connect_mode TEXT NOT NULL DEFAULT 'p2p',
status TEXT NOT NULL DEFAULT 'connecting',
fail_reason TEXT,
connected_at TEXT,
closed_at TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS transfers (
id TEXT PRIMARY KEY,
session_id TEXT REFERENCES sessions(id),
kind TEXT NOT NULL,
name TEXT NOT NULL,
content TEXT,
size_bytes INTEGER NOT NULL DEFAULT 0,
sender_device_id TEXT NOT NULL REFERENCES devices(id),
receiver_device_id TEXT NOT NULL REFERENCES devices(id),
transfer_strategy TEXT NOT NULL,
current_channel TEXT NOT NULL DEFAULT 'p2p',
fallback_allowed INTEGER NOT NULL DEFAULT 0,
final_status TEXT NOT NULL DEFAULT 'pending',
fallback_reason TEXT,
object_key TEXT,
expires_at TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS fallback_objects (
transfer_id TEXT PRIMARY KEY REFERENCES transfers(id) ON DELETE CASCADE,
bucket TEXT NOT NULL,
object_key TEXT NOT NULL UNIQUE,
size_bytes INTEGER NOT NULL DEFAULT 0,
cleanup_state TEXT NOT NULL DEFAULT 'pending',
created_at TEXT NOT NULL,
expires_at TEXT NOT NULL,
cleaned_at TEXT
);
CREATE TABLE IF NOT EXISTS admin_users (
username TEXT PRIMARY KEY,
password_hash TEXT NOT NULL,
is_active INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS system_configs (
config_key TEXT PRIMARY KEY,
config_value TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS audit_logs (
id TEXT PRIMARY KEY,
operator_type TEXT NOT NULL,
operator_id TEXT,
action TEXT NOT NULL,
payload TEXT,
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_devices_online ON devices (is_online, last_seen_at DESC);
CREATE INDEX IF NOT EXISTS idx_devices_network_group ON devices (network_group_key);
CREATE INDEX IF NOT EXISTS idx_rooms_status_expires ON rooms (status, expires_at DESC);
CREATE INDEX IF NOT EXISTS idx_sessions_status_created ON sessions (status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_transfers_status_created ON transfers (final_status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_transfers_sender_receiver ON transfers (sender_device_id, receiver_device_id);
CREATE INDEX IF NOT EXISTS idx_fallback_objects_expires ON fallback_objects (cleanup_state, expires_at ASC);
CREATE INDEX IF NOT EXISTS idx_audit_logs_created ON audit_logs (created_at DESC);
INSERT INTO system_configs (config_key, config_value, updated_at)
VALUES (
'transfer_policy',
'{"max_minio_fallback_size_bytes":10737418240,"minio_capacity_bytes":128849018880,"minio_retention_hours":2,"p2p_connect_timeout_sec":15,"turn_connect_timeout_sec":20,"minio_usage_alert_percent":85,"minio_fallback_enabled":true,"turn_urls":[],"turn_username":"","turn_password":""}',
STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')
)
ON CONFLICT(config_key) DO NOTHING;