scMedia/sql/schema.sql
2026-01-16 22:53:04 +01:00

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);