4.5 KiB
4.5 KiB
08 — Требования к схеме БД — ORCH-087
Все изменения аддитивны и идемпотентны, безопасны на живой ОБЩЕЙ прод-БД (enduro-trails + orchestrator из одного инстанса). Существующие колонки/данные не трогаются. Решение — ADR-001.
1. Новая таблица tracker_messages (G1 — anti-orphan, Подход Б)
Реестр ВСЕХ Telegram message_id, созданных трекером для задачи, и их состояние. Позволяет
подчищать осиротевшие карточки, ссылку на которые потерял одиночный tasks.tracker_message_id.
CREATE TABLE IF NOT EXISTS tracker_messages (
task_id INTEGER NOT NULL, -- логический FK tasks.id (без REFERENCES, как jobs.task_id)
message_id INTEGER NOT NULL, -- Telegram message_id отправленной карточки
created_at TEXT DEFAULT (datetime('now')),
deleted INTEGER NOT NULL DEFAULT 0, -- 0 = живая (надо подчистить), 1 = удалена/исчерпана
PRIMARY KEY (task_id, message_id)
);
CREATE INDEX IF NOT EXISTS idx_tracker_messages_live
ON tracker_messages(task_id) WHERE deleted = 0;
- Миграция:
conn.executescript(...)сCREATE TABLE/INDEX IF NOT EXISTSвinit_db()(рядом с блокомjob_deps). Повторныйinit_db— no-op. PRIMARY KEY(task_id, message_id)→INSERT OR IGNOREидемпотентен (дубль mid не падает).- Частичный индекс
WHERE deleted=0ускоряет sweep (выборка только живых). - Логический FK (без
REFERENCES tasks(id)) — миграция не падает на pre-existing БД, какjob_deps. deleted=1присваивается при: успешномdelete, «уже нет» (message to delete not found), «нельзя удалить» (48ч,message can't be deleted—_DELETE_GONE_MARKERS). Transient-fail (False) → запись остаётсяdeleted=0, повтор на следующем апдейте.
Helper'ы доступа (src/db.py, never-raise)
| Функция | Назначение |
|---|---|
record_tracker_message(task_id, message_id) |
INSERT OR IGNORE свежий mid (deleted=0) |
mark_tracker_message_deleted(task_id, message_id) |
UPDATE … SET deleted=1 |
list_live_tracker_messages(task_id) -> list[int] |
все deleted=0 mid задачи (для sweep) |
get_tracker_message_id / set_tracker_message_id — без изменений (обратная совместимость).
2. Новая колонка agent_runs.effort (G4 — эффорт в строке стадии)
-- идемпотентная миграция в init_db(), рядом с _ensure_column(... "agent_runs", "model" ...)
ALTER TABLE agent_runs ADD COLUMN effort TEXT; -- через _ensure_column (no-op если есть)
- Миграция:
_ensure_column(conn, "agent_runs", "effort", "TEXT"). - Хранит ФАКТИЧЕСКИ применённый
--effortзапуска (то, что ушло в CLI), стампится вlauncher._spawnпослеeffort = resolve_agent_effort(...). Не пересчитывается на рендере. NULL/""для старых строк и для запусков с опущенным флагом (effort=="") → рендер опускает эффорт-суффикс (деградация без падения, AC-9).- Значения: подмножество
VALID_EFFORTS(low|medium|high|xhigh|max) либоNULL.
3. Гарантии совместимости (общая прод-БД)
- Никаких
ALTER/DROPсуществующих колонок; только новая таблица + новая колонка. CREATE TABLE IF NOT EXISTS/_ensure_column→ повторный запуск инертен (AC-10).- Данные enduro-trails не читаются и не пишутся этими миграциями (таблицы изолированы по
task_id, колонкаeffortзаполняется только новыми запусками). - Restart-safe: всё состояние в БД; рестарт орка не теряет реестр и не плодит сирот по новой схеме.