-- 1.软件应用表：管理所有接入自动更新系统的软件
CREATE TABLE IF NOT EXISTS apps (
    id INTEGER PRIMARY KEY AUTOINCREMENT, -- 自增主键ID
    app_id TEXT NOT NULL UNIQUE, -- 软件唯一标识（客户端用来区分不同软件）
    app_name TEXT NOT NULL -- 软件展示名称
);

-- 2.软件版本表：存储每个软件各个渠道下的所有版本号
CREATE TABLE IF NOT EXISTS versions (
    id INTEGER PRIMARY KEY AUTOINCREMENT, -- 版本自增主键version_id，关联文件表
    app_id TEXT NOT NULL, -- 关联apps表的软件唯一标识
    channel TEXT DEFAULT 'stable', -- 更新渠道：stable正式稳定版 / beta测试版
    version TEXT NOT NULL, -- 版本号，如1.0.0、1.0.2
    latest INTEGER DEFAULT 0, -- 是否为当前渠道最新版本：1=是最新，0=历史旧版
    client_protocol INTEGER NOT NULL DEFAULT 1, -- 该版本客户端支持的更新/策略协议版本
    create_time TEXT DEFAULT (datetime('now')), -- 新增：版本创建时间
    UNIQUE(app_id, channel, version) -- 联合唯一约束：同一个软件+渠道不能重复存在相同版本
);

-- 3.版本关联文件表：记录每个版本需要更新的全部文件信息（exe、dll、资源文件）
CREATE TABLE IF NOT EXISTS version_files (
    id INTEGER PRIMARY KEY AUTOINCREMENT, -- 文件记录自增ID
    version_id INTEGER NOT NULL, -- 关联versions表的版本主键id
    path TEXT NOT NULL, -- 文件在MinIO存储桶内的完整路径
    sha256 TEXT NOT NULL, -- 文件哈希值，客户端下载后做完整性/防篡改校验
    size INTEGER -- 文件字节大小，用于计算下载进度、校验磁盘空间
);

-- 4.升级日志记录表：存储所有客户端上报的升级结果，用于后台统计排查问题
CREATE TABLE IF NOT EXISTS upgrade_logs (
    id INTEGER PRIMARY KEY AUTOINCREMENT, -- 日志自增主键
    device_id TEXT, -- 用户设备唯一标识，区分不同电脑客户端
    from_ver TEXT, -- 升级前本地旧版本号
    to_ver TEXT, -- 升级目标新版本号
    result TEXT, -- 升级结果：success成功 / fail失败
    create_time TEXT -- 升级上报时间
);

--5.日志数据表
CREATE TABLE IF NOT EXISTS update_report (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    device_id TEXT NOT NULL,
    app_id TEXT NOT NULL,
    from_version TEXT NOT NULL,
    to_version TEXT NOT NULL,
    result TEXT NOT NULL,
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 6. 每个应用/渠道的运行与升级策略；每次保存必须递增 policy_seq
CREATE TABLE IF NOT EXISTS version_policies (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    app_id TEXT NOT NULL,
    channel TEXT NOT NULL DEFAULT 'stable',
    policy_seq INTEGER NOT NULL DEFAULT 1,
    force_update INTEGER NOT NULL DEFAULT 0,
    allow_rollback INTEGER NOT NULL DEFAULT 0,
    offline_allowed INTEGER NOT NULL DEFAULT 1,
    valid_until TEXT NOT NULL,
    min_supported_version TEXT NOT NULL DEFAULT '',
    disabled_versions TEXT NOT NULL DEFAULT '[]',
    message TEXT NOT NULL DEFAULT '',
    created_at TEXT DEFAULT (datetime('now')),
    updated_at TEXT DEFAULT (datetime('now')),
    UNIQUE(app_id, channel)
);


-- 7. RSA 签发的客户端设备身份
CREATE TABLE IF NOT EXISTS devices (
 id INTEGER PRIMARY KEY AUTOINCREMENT, device_id TEXT NOT NULL UNIQUE, app_id TEXT NOT NULL,
 installation_id TEXT NOT NULL, machine_hash TEXT NOT NULL DEFAULT '', credential_seq INTEGER NOT NULL DEFAULT 1,
 disabled INTEGER NOT NULL DEFAULT 0, disabled_reason TEXT NOT NULL DEFAULT '',
 first_seen_at TEXT DEFAULT (datetime('now')), last_seen_at TEXT DEFAULT (datetime('now')), last_ip TEXT NOT NULL DEFAULT '',
 UNIQUE(app_id, installation_id)
);


-- 8. 软件授权及其设备占用关系
CREATE TABLE IF NOT EXISTS licenses (
 id INTEGER PRIMARY KEY AUTOINCREMENT, license_id TEXT NOT NULL UNIQUE, license_key_hash TEXT NOT NULL UNIQUE,
 customer_name TEXT NOT NULL, app_id TEXT NOT NULL, channel_code TEXT NOT NULL DEFAULT 'stable',
 max_devices INTEGER NOT NULL DEFAULT 1, valid_until TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'active',
 created_at TEXT DEFAULT (datetime('now')), updated_at TEXT DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS license_devices (
 license_id TEXT NOT NULL, device_id TEXT NOT NULL UNIQUE, bound_at TEXT DEFAULT (datetime('now')),
 PRIMARY KEY(license_id,device_id)
);


-- 9. 每个应用独立维护的动态发布渠道
CREATE TABLE IF NOT EXISTS channels (
 id INTEGER PRIMARY KEY AUTOINCREMENT, app_id TEXT NOT NULL, channel_code TEXT NOT NULL,
 display_name TEXT NOT NULL, enabled INTEGER NOT NULL DEFAULT 1, sort_order INTEGER NOT NULL DEFAULT 100,
 created_at TEXT DEFAULT (datetime('now')), updated_at TEXT DEFAULT (datetime('now')),
 UNIQUE(app_id, channel_code)
);


-- 10. 文件下载授权与客户端完成结果
CREATE TABLE IF NOT EXISTS download_logs (
 id INTEGER PRIMARY KEY AUTOINCREMENT, device_id TEXT NOT NULL, license_id TEXT NOT NULL,
 app_id TEXT NOT NULL, version TEXT NOT NULL, channel_code TEXT NOT NULL, file_path TEXT NOT NULL,
 file_size INTEGER NOT NULL DEFAULT 0, result TEXT NOT NULL, ip TEXT NOT NULL DEFAULT '',
 user_agent TEXT NOT NULL DEFAULT '', created_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_download_logs_created ON download_logs(created_at);
CREATE INDEX IF NOT EXISTS idx_download_logs_device ON download_logs(device_id,created_at);

-- 11. 管理后台写操作审计
CREATE TABLE IF NOT EXISTS admin_audit_logs (
 id INTEGER PRIMARY KEY AUTOINCREMENT, actor_hash TEXT NOT NULL, action TEXT NOT NULL,
 method TEXT NOT NULL, path TEXT NOT NULL, target TEXT NOT NULL DEFAULT '', result TEXT NOT NULL,
 status_code INTEGER NOT NULL, ip TEXT NOT NULL DEFAULT '', user_agent TEXT NOT NULL DEFAULT '',
 created_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_admin_audit_created ON admin_audit_logs(created_at);


-- 12. SimCAE 崩溃报告原始数据索引
CREATE TABLE IF NOT EXISTS crash_reports (
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 report_id TEXT NOT NULL UNIQUE,
 client_report_id TEXT NOT NULL UNIQUE,
 content_hash TEXT NOT NULL,
 status TEXT NOT NULL DEFAULT 'stored',
 symbolication_status TEXT NOT NULL DEFAULT 'not_started',
 product TEXT NOT NULL,
 app_version TEXT NOT NULL,
 git_commit TEXT NOT NULL,
 build_type TEXT NOT NULL,
 channel TEXT NOT NULL,
 exception_code TEXT NOT NULL DEFAULT '',
 crash_time_utc TEXT NOT NULL,
 received_at_utc TEXT NOT NULL,
 remote_address TEXT NOT NULL DEFAULT '',
 content_length INTEGER NOT NULL DEFAULT 0,
 metadata_sha256 TEXT NOT NULL,
 metadata_size INTEGER NOT NULL DEFAULT 0,
 minidump_sha256 TEXT NOT NULL,
 minidump_size INTEGER NOT NULL DEFAULT 0,
 attachments_sha256 TEXT NOT NULL DEFAULT '',
 attachments_size INTEGER NOT NULL DEFAULT 0,
 storage_path TEXT NOT NULL,
 metadata_json TEXT NOT NULL,
 server_json TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_crash_reports_build ON crash_reports(product,app_version,git_commit);
CREATE INDEX IF NOT EXISTS idx_crash_reports_exception ON crash_reports(exception_code);
CREATE INDEX IF NOT EXISTS idx_crash_reports_received ON crash_reports(received_at_utc);

-- 13. SimCAE 符号包上传索引
CREATE TABLE IF NOT EXISTS crash_symbol_uploads (
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 symbol_upload_id TEXT NOT NULL UNIQUE,
 identity_hash TEXT NOT NULL UNIQUE,
 status TEXT NOT NULL DEFAULT 'stored',
 product TEXT NOT NULL,
 app_version TEXT NOT NULL,
 git_commit TEXT NOT NULL,
 build_type TEXT NOT NULL,
 platform TEXT NOT NULL,
 toolchain TEXT NOT NULL,
 created_at_utc TEXT NOT NULL,
 received_at_utc TEXT NOT NULL,
 metadata_sha256 TEXT NOT NULL,
 metadata_size INTEGER NOT NULL DEFAULT 0,
 symbols_sha256 TEXT NOT NULL,
 symbols_size INTEGER NOT NULL DEFAULT 0,
 storage_path TEXT NOT NULL,
 metadata_json TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_crash_symbols_build ON crash_symbol_uploads(product,app_version,git_commit,build_type,platform);
CREATE INDEX IF NOT EXISTS idx_crash_symbols_received ON crash_symbol_uploads(received_at_utc);

-- 14. 崩溃原始文件访问审计
CREATE TABLE IF NOT EXISTS crash_file_access_logs (
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 report_id TEXT NOT NULL,
 file_name TEXT NOT NULL,
 actor_hash TEXT NOT NULL,
 ip TEXT NOT NULL DEFAULT '',
 user_agent TEXT NOT NULL DEFAULT '',
 created_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_crash_file_access_report ON crash_file_access_logs(report_id,created_at);
