462 lines
18 KiB
SQL
462 lines
18 KiB
SQL
SET NAMES utf8mb4;
|
|
SET time_zone = '+00:00';
|
|
|
|
-- -----------------------
|
|
-- settings
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS settings (
|
|
`key` VARCHAR(64) NOT NULL,
|
|
value_json LONGTEXT NOT NULL,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`key`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- settings_snapshots
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS settings_snapshots (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
label VARCHAR(255) NULL,
|
|
data_json LONGTEXT NOT NULL,
|
|
created_by BIGINT UNSIGNED NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY idx_created_at (created_at)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- scan_profiles
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS scan_profiles (
|
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
sort_order INT NOT NULL DEFAULT 1000,
|
|
profile_type ENUM('scan','analyze') NOT NULL DEFAULT 'scan',
|
|
enabled TINYINT(1) NOT NULL DEFAULT 1,
|
|
name VARCHAR(128) NOT NULL,
|
|
root_path VARCHAR(1024) NOT NULL,
|
|
max_depth TINYINT UNSIGNED NOT NULL DEFAULT 3,
|
|
exclude_patterns_json LONGTEXT NOT NULL DEFAULT '[]',
|
|
include_ext_mode ENUM('default','custom') NOT NULL DEFAULT 'default',
|
|
include_ext_json LONGTEXT NULL,
|
|
last_scan_at DATETIME NULL,
|
|
last_result ENUM('ok','error','never') NOT NULL DEFAULT 'never',
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY idx_sort (sort_order),
|
|
KEY idx_enabled (enabled),
|
|
KEY idx_root_path (root_path(255))
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- items
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS items (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
|
|
scan_profile_id INT UNSIGNED NOT NULL,
|
|
abs_path VARCHAR(2048) NOT NULL,
|
|
rel_path VARCHAR(2048) NULL,
|
|
|
|
display_name VARCHAR(512) NOT NULL,
|
|
kind ENUM('auto','movie','series') NOT NULL DEFAULT 'auto',
|
|
year SMALLINT UNSIGNED NULL,
|
|
|
|
structure ENUM('file','folder','dvd','bluray') NOT NULL DEFAULT 'folder',
|
|
confidence TINYINT UNSIGNED NOT NULL DEFAULT 0,
|
|
|
|
video_count INT UNSIGNED NOT NULL DEFAULT 0,
|
|
file_count INT UNSIGNED NOT NULL DEFAULT 0,
|
|
|
|
status ENUM('active','gone','ignored') NOT NULL DEFAULT 'active',
|
|
last_seen_at DATETIME NULL,
|
|
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_profile_path (scan_profile_id, abs_path(255)),
|
|
KEY idx_kind (kind),
|
|
KEY idx_status (status),
|
|
KEY idx_last_seen (last_seen_at),
|
|
CONSTRAINT fk_items_profile
|
|
FOREIGN KEY (scan_profile_id) REFERENCES scan_profiles(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- jobs
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS jobs (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
type ENUM('scan','apply','db_reset','clear_index','task') NOT NULL,
|
|
status ENUM('queued','running','done','error','canceled') NOT NULL DEFAULT 'queued',
|
|
|
|
title VARCHAR(255) NOT NULL,
|
|
payload_json LONGTEXT NULL,
|
|
|
|
progress_current BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
|
progress_total BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
|
progress_pct TINYINT UNSIGNED NOT NULL DEFAULT 0,
|
|
|
|
cancel_requested TINYINT(1) NOT NULL DEFAULT 0,
|
|
last_heartbeat DATETIME NULL,
|
|
|
|
error_message TEXT NULL,
|
|
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
started_at DATETIME NULL,
|
|
finished_at DATETIME NULL,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
|
PRIMARY KEY (id),
|
|
KEY idx_type (type),
|
|
KEY idx_status (status),
|
|
KEY idx_created (created_at)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- job_logs
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS job_logs (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
job_id BIGINT UNSIGNED NOT NULL,
|
|
ts DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
level ENUM('info','warn','error','debug') NOT NULL DEFAULT 'info',
|
|
message TEXT NOT NULL,
|
|
PRIMARY KEY (id),
|
|
KEY idx_job_ts (job_id, ts),
|
|
CONSTRAINT fk_job_logs_job
|
|
FOREIGN KEY (job_id) REFERENCES jobs(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- app_logs
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS app_logs (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
ts DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
level ENUM('info','warn','error','debug') NOT NULL DEFAULT 'info',
|
|
message TEXT NOT NULL,
|
|
context_json LONGTEXT NULL,
|
|
PRIMARY KEY (id),
|
|
KEY idx_app_logs_ts (ts),
|
|
KEY idx_app_logs_level (level)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- media_file_meta
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS media_file_meta (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
abs_path VARCHAR(2048) NOT NULL,
|
|
size_bytes BIGINT UNSIGNED NOT NULL,
|
|
mtime INT UNSIGNED NOT NULL,
|
|
inode BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
|
info_json LONGTEXT NULL,
|
|
last_scanned_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_media_path (abs_path(255)),
|
|
KEY idx_media_mtime (mtime)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- media_files
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS media_files (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
scan_profile_id INT UNSIGNED NOT NULL,
|
|
abs_path VARCHAR(2048) NOT NULL,
|
|
rel_path VARCHAR(2048) NOT NULL,
|
|
name VARCHAR(512) NOT NULL,
|
|
ext VARCHAR(16) NOT NULL,
|
|
size_bytes BIGINT UNSIGNED NOT NULL,
|
|
mtime INT UNSIGNED NOT NULL,
|
|
is_mkv TINYINT(1) NOT NULL DEFAULT 0,
|
|
kind ENUM('movie','series','unknown') NOT NULL DEFAULT 'unknown',
|
|
series_key VARCHAR(512) NULL,
|
|
container VARCHAR(64) NULL,
|
|
duration_ms BIGINT UNSIGNED NULL,
|
|
last_analyzed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_media_files_path (abs_path(255)),
|
|
KEY idx_media_files_profile (scan_profile_id),
|
|
KEY idx_media_files_kind (kind),
|
|
KEY idx_media_files_series (series_key(255)),
|
|
CONSTRAINT fk_media_files_profile
|
|
FOREIGN KEY (scan_profile_id) REFERENCES scan_profiles(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- media_metadata
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS media_metadata (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
subject_kind ENUM('movie','series') NOT NULL,
|
|
subject_key VARCHAR(2048) NOT NULL,
|
|
provider VARCHAR(64) NULL,
|
|
provider_id VARCHAR(128) NULL,
|
|
title_map_json LONGTEXT NULL,
|
|
original_title VARCHAR(512) NULL,
|
|
year SMALLINT UNSIGNED NULL,
|
|
manual_title VARCHAR(512) NULL,
|
|
manual_year SMALLINT UNSIGNED NULL,
|
|
source ENUM('auto','manual') NOT NULL DEFAULT 'auto',
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_media_meta_subject (subject_kind, subject_key(255)),
|
|
KEY idx_media_meta_provider (provider, provider_id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- auth: users and roles
|
|
-- -----------------------
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
email VARCHAR(255) NOT NULL,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
status ENUM('active','disabled') NOT NULL DEFAULT 'active',
|
|
token_version INT UNSIGNED NOT NULL DEFAULT 1,
|
|
last_login_at DATETIME NULL,
|
|
password_changed_at DATETIME NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_users_email (email)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS user_profiles (
|
|
user_id BIGINT UNSIGNED NOT NULL,
|
|
nickname VARCHAR(128) NULL,
|
|
avatar_blob MEDIUMBLOB NULL,
|
|
avatar_mime VARCHAR(64) NULL,
|
|
ui_prefs_json LONGTEXT NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (user_id),
|
|
CONSTRAINT fk_user_profiles_user
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS roles (
|
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
name VARCHAR(64) NOT NULL,
|
|
description VARCHAR(255) NULL,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_roles_name (name)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS permissions (
|
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`key` VARCHAR(128) NOT NULL,
|
|
description VARCHAR(255) NULL,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_permissions_key (`key`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS role_permissions (
|
|
role_id INT UNSIGNED NOT NULL,
|
|
permission_id INT UNSIGNED NOT NULL,
|
|
PRIMARY KEY (role_id, permission_id),
|
|
CONSTRAINT fk_role_permissions_role
|
|
FOREIGN KEY (role_id) REFERENCES roles(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT fk_role_permissions_permission
|
|
FOREIGN KEY (permission_id) REFERENCES permissions(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS user_roles (
|
|
user_id BIGINT UNSIGNED NOT NULL,
|
|
role_id INT UNSIGNED NOT NULL,
|
|
PRIMARY KEY (user_id, role_id),
|
|
CONSTRAINT fk_user_roles_user
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT fk_user_roles_role
|
|
FOREIGN KEY (role_id) REFERENCES roles(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS refresh_tokens (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
user_id BIGINT UNSIGNED NOT NULL,
|
|
device_id VARCHAR(64) NOT NULL,
|
|
token_hash CHAR(64) NOT NULL,
|
|
user_agent VARCHAR(255) NULL,
|
|
ip_addr VARCHAR(64) NULL,
|
|
expires_at DATETIME NOT NULL,
|
|
revoked_at DATETIME NULL,
|
|
rotated_from_id BIGINT UNSIGNED NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_refresh_token_hash (token_hash),
|
|
KEY idx_refresh_user (user_id),
|
|
KEY idx_refresh_expires (expires_at),
|
|
CONSTRAINT fk_refresh_user
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS auth_challenges (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
user_id BIGINT UNSIGNED NOT NULL,
|
|
token_hash CHAR(64) NOT NULL,
|
|
expires_at DATETIME NOT NULL,
|
|
used_at DATETIME NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_auth_challenge_hash (token_hash),
|
|
KEY idx_auth_challenge_user (user_id),
|
|
KEY idx_auth_challenge_expires (expires_at),
|
|
CONSTRAINT fk_auth_challenge_user
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS auth_rate_limits (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
ip_addr VARCHAR(64) NOT NULL,
|
|
action VARCHAR(32) NOT NULL,
|
|
failed_count INT UNSIGNED NOT NULL DEFAULT 0,
|
|
window_started_at DATETIME NOT NULL,
|
|
blocked_until DATETIME NULL,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_auth_rate_key (ip_addr, action),
|
|
KEY idx_auth_rate_blocked (blocked_until)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS auth_sse_keys (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
user_id BIGINT UNSIGNED NOT NULL,
|
|
key_hash CHAR(64) NOT NULL,
|
|
expires_at DATETIME NOT NULL,
|
|
used_at DATETIME NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_sse_key_hash (key_hash),
|
|
KEY idx_sse_user (user_id),
|
|
KEY idx_sse_expires (expires_at),
|
|
CONSTRAINT fk_sse_user
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS auth_sse_sessions (
|
|
user_id BIGINT UNSIGNED NOT NULL,
|
|
session_token CHAR(64) NOT NULL,
|
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (user_id),
|
|
KEY idx_sse_session_updated (updated_at),
|
|
CONSTRAINT fk_sse_session_user
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS mfa_methods (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
user_id BIGINT UNSIGNED NOT NULL,
|
|
type ENUM('totp') NOT NULL DEFAULT 'totp',
|
|
secret_enc VARCHAR(255) NOT NULL,
|
|
enabled_at DATETIME NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY idx_mfa_user (user_id),
|
|
CONSTRAINT fk_mfa_user
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS mfa_backup_codes (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
user_id BIGINT UNSIGNED NOT NULL,
|
|
code_hash CHAR(64) NOT NULL,
|
|
used_at DATETIME NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY idx_mfa_backup_user (user_id),
|
|
CONSTRAINT fk_mfa_backup_user
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS password_resets (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
user_id BIGINT UNSIGNED NOT NULL,
|
|
token_hash CHAR(64) NOT NULL,
|
|
expires_at DATETIME NOT NULL,
|
|
used_at DATETIME NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY uq_password_reset_hash (token_hash),
|
|
KEY idx_password_reset_user (user_id),
|
|
KEY idx_password_reset_expires (expires_at),
|
|
CONSTRAINT fk_password_reset_user
|
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS audit_log (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
actor_user_id BIGINT UNSIGNED NULL,
|
|
action VARCHAR(64) NOT NULL,
|
|
target_type VARCHAR(64) NULL,
|
|
target_id BIGINT UNSIGNED NULL,
|
|
ip_addr VARCHAR(64) NULL,
|
|
user_agent VARCHAR(255) NULL,
|
|
meta_json LONGTEXT NULL,
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (id),
|
|
KEY idx_audit_actor (actor_user_id),
|
|
KEY idx_audit_action (action),
|
|
CONSTRAINT fk_audit_actor
|
|
FOREIGN KEY (actor_user_id) REFERENCES users(id)
|
|
ON DELETE SET NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- -----------------------
|
|
-- Seed settings (minimal)
|
|
-- -----------------------
|
|
INSERT IGNORE INTO settings (`key`, value_json) VALUES
|
|
('general', '{"timezone":"Europe/Berlin","language":"ru","safe_mode":false,"auto_refresh_seconds":0,"date_format":"YYYY-MM-DD"}'),
|
|
('scanner_defaults', '{"video_ext":["mkv","mp4","avi","mov","m4v","ts","m2ts","wmv"],"max_depth_default":3,"max_files_per_item":3000,"max_items_per_scan":0}'),
|
|
('paths', '{"movies_root":"","series_root":"","staging_root":""}'),
|
|
('tools', '{"mkvmerge_path":"","mkvpropedit_path":"","ffmpeg_path":""}'),
|
|
('logs', '{"retention_days":7,"level":"info"}'),
|
|
('layout', '{"movies":{"strategy":"prefix","params":{"n":2},"template":null},"series":{"strategy":"first_letter","params":{},"template":null,"season_naming":"season_2digit"},"normalization":{"ignore_articles":true,"transliterate_non_latin":true,"uppercase_shards":true,"replace_unsafe_chars":true,"trim_dots_spaces":true,"ignore_words":[]},"collision_policy":"stop"}'),
|
|
('media_rules', '{"name_map":[],"delete_rules":[],"language_priority":["ru","en"],"audio_type_priority":["dub","voiceover","original","commentary","unknown"],"require_audio_type":true,"series_order_threshold":0.7}'),
|
|
('rules', '[]'),
|
|
('sources', '{"transmission":{"enabled":false,"last_test_ok":false,"last_test_at":null,"protocol":"http","host":"","port":9091,"path":"/transmission/rpc","username":"","password":""}}'),
|
|
('metadata', '{"enabled":false,"languages":["de","ru","en"],"provider_priority":["tvdb","omdb"],"providers":{"omdb":{"enabled":false,"api_key":"","base_url":"https://www.omdbapi.com/"},"tvdb":{"enabled":false,"api_key":"","pin":""}}}'),
|
|
('exports', '{"kodi":{"enabled":false},"jellyfin":{"enabled":false}}'),
|
|
('background', '{"mode":"light","max_parallel_jobs":1,"max_network_jobs":1,"max_io_jobs":1,"batch_sleep_ms":500,"watchdog_minutes":10,"sse_session_ttl_seconds":20,"paused":false}'),
|
|
('ui', '{"sse_tick_seconds":10}'),
|
|
('safety', '{"max_depth":10,"max_files_per_item":200000,"max_items_per_scan":1000000}'),
|
|
('_system', '{"settings_revision":1,"first_run_completed":false}');
|
|
|
|
-- -----------------------
|
|
-- Seed roles
|
|
-- -----------------------
|
|
INSERT IGNORE INTO roles (id, name, description) VALUES
|
|
(1, 'admin', 'Full access'),
|
|
(2, 'manager', 'Manager access'),
|
|
(3, 'user', 'User access');
|
|
|
|
-- -----------------------
|
|
-- Seed admin user
|
|
-- -----------------------
|
|
INSERT IGNORE INTO users (id, email, password_hash, status, token_version, created_at, updated_at)
|
|
VALUES (1, 'admin@admin.local', '$2y$12$2op4ztskqxDR376xnZ6sR.Ccbi.zyPu3KRwJsDAPmeNf5B.ZjEcfC', 'active', 1, NOW(), NOW());
|
|
|
|
INSERT IGNORE INTO user_roles (user_id, role_id)
|
|
VALUES (1, 1);
|