-- maestro · SQLite schema v0.1（设计见 DESIGN.md §6/§9）
PRAGMA journal_mode = WAL;
PRAGMA foreign_keys = ON;

CREATE TABLE IF NOT EXISTS projects (
  id             TEXT PRIMARY KEY,
  name           TEXT NOT NULL,
  repo_path      TEXT NOT NULL UNIQUE,
  default_branch TEXT NOT NULL DEFAULT 'main',
  verify_cmd     TEXT,
  autonomy       TEXT NOT NULL DEFAULT 'manual',     -- manual | auto-easy | auto-approved
  model          TEXT,
  concurrency    INTEGER NOT NULL DEFAULT 1,
  max_retries    INTEGER NOT NULL DEFAULT 2,          -- 失败后最大自动重试次数
  timeout_ms     INTEGER NOT NULL DEFAULT 1800000,    -- 单次执行超时毫秒（默认 30min）
  status         TEXT NOT NULL DEFAULT 'active',      -- active | paused
  created_at     TEXT NOT NULL,
  last_sync_at   TEXT,                                 -- 最近一次 todo.json 同步时间
  logo           TEXT,                                 -- 自定义 logo（URL / 仓库内相对路径；null=自动）
  sort_order     INTEGER NOT NULL DEFAULT 0,           -- 侧栏排序（小在前）
  checks             TEXT,                                -- 分项检查命令 JSON（如 {"lint":"npm run lint"}）
  auto_approve_plan  INTEGER NOT NULL DEFAULT 0,         -- 全 easy 子任务时跳过 plan_review（0=关）
  auto_approve_exec  INTEGER NOT NULL DEFAULT 0,         -- 双复审 approve 后跳过 exec_review（0=关）
  budget_usd         REAL,                                -- 项目当期预算上限 USD（null=不限）
  budget_period      TEXT NOT NULL DEFAULT 'month',       -- 预算周期 day | month
  agent_rules        TEXT,                                -- L2 项目级 agent 执行规范（注入 worker prompt）
  models             TEXT                                 -- 项目级可配置模型 JSON（按角色/复杂度覆盖默认 opus-4.8）
);

CREATE TABLE IF NOT EXISTS tasks (
  id          TEXT PRIMARY KEY,
  project_id  TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
  parent_id   TEXT REFERENCES tasks(id) ON DELETE CASCADE,
  depth       INTEGER NOT NULL DEFAULT 1,            -- 1..4
  title       TEXT NOT NULL,
  complexity  TEXT NOT NULL,                          -- hard | medium | easy
  status      TEXT NOT NULL DEFAULT 'init',
  priority    INTEGER NOT NULL DEFAULT 1,            -- P0 最高 / P1 中 / P2 最低
  deps        TEXT NOT NULL DEFAULT '[]',             -- JSON array of task ids
  plan        TEXT,                                   -- Hard：分析 + 拆解
  spec        TEXT,                                   -- Medium：改动 + 理由
  operations  TEXT,                                   -- Easy：将执行的操作
  result          TEXT,                               -- JSON TaskResult
  assignee        TEXT,                               -- agent | human
  retry_baseline  INTEGER NOT NULL DEFAULT 0,         -- 上次手动重投时已有的失败 run 数（重置重试计数用）
  next_eligible_at TEXT,                              -- 持久化退避：早于此时间不被领取（null=即刻可领）
  created_at  TEXT NOT NULL,
  updated_at  TEXT NOT NULL,
  source_ref  TEXT,                                   -- 旧 todo 来源标识（todo:17 / todo:17/1A），项目内唯一
  attachments TEXT,                                   -- 附件 JSON [{name,type,path}]（图片/文件随任务提交）
  scope_files TEXT                                    -- 声明的改动文件范围 JSON（glob/路径）；diff 越界=硬闸
);
CREATE INDEX IF NOT EXISTS idx_tasks_project ON tasks(project_id, status);
CREATE INDEX IF NOT EXISTS idx_tasks_parent  ON tasks(parent_id);
CREATE INDEX IF NOT EXISTS idx_tasks_source  ON tasks(project_id, source_ref);

CREATE TABLE IF NOT EXISTS approvals (
  id      TEXT PRIMARY KEY,
  task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
  gate    TEXT NOT NULL,                              -- plan | spec | exec
  action  TEXT NOT NULL,                              -- accept | reject
  actor   TEXT NOT NULL,
  reason  TEXT,                                       -- reject 必填
  at      TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_approvals_task ON approvals(task_id, at);

CREATE TABLE IF NOT EXISTS runs (
  id                TEXT PRIMARY KEY,
  task_id           TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
  kind              TEXT NOT NULL,                    -- planner | executor | reviewer | security
  worktree          TEXT,
  branch            TEXT,
  status            TEXT NOT NULL,                    -- started | succeeded | failed | cancelled
  started_at        TEXT NOT NULL,
  ended_at          TEXT,
  transcript_ref    TEXT,
  claude_session_id TEXT,
  error             TEXT,
  worker_pid        INTEGER,                          -- 多进程执行：worker 进程 pid（daemon 写，判活用）
  last_seq          INTEGER NOT NULL DEFAULT 0,        -- 已 ingest 的 outbox 最大 seq（幂等游标）
  usage             TEXT,                             -- token 用量 JSON {input,output,cacheRead,cacheWrite}
  cost_usd          REAL                              -- 该 run 折算成本 USD（按模型×token，见 model/pricing.ts）
);
CREATE INDEX IF NOT EXISTS idx_runs_task ON runs(task_id, started_at);

-- 追加型事件日志：审计 + 实时看板推送源
CREATE TABLE IF NOT EXISTS events (
  id         TEXT PRIMARY KEY,
  project_id TEXT NOT NULL,
  task_id    TEXT,
  type       TEXT NOT NULL,
  payload    TEXT NOT NULL DEFAULT '{}',
  at         TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_events_project ON events(project_id, at);

-- 用户级配置（per-user）：新建项目默认值的单一来源。单本地用户 'local'，多用户前向兼容。
CREATE TABLE IF NOT EXISTS settings (
  user_id    TEXT PRIMARY KEY,
  data       TEXT NOT NULL DEFAULT '{}',   -- 核心策略子集 JSON（autonomy/concurrency/max_retries/timeout_ms/auto_approve_*/budget_*/model）
  updated_at TEXT NOT NULL
);
