kin: KIN-ARCH-006 Добавить autocommit_enabled и obsidian_vault_path в базовый SCHEMA

This commit is contained in:
Gros Frumos 2026-03-16 09:57:14 +02:00
parent 295a95bc7f
commit 7630736860
4 changed files with 58 additions and 5 deletions

View file

@ -117,6 +117,8 @@ def _slim_task(task: dict) -> dict:
} }
if task.get("revise_comment"): if task.get("revise_comment"):
result["revise_comment"] = task["revise_comment"] result["revise_comment"] = task["revise_comment"]
if task.get("acceptance_criteria"):
result["acceptance_criteria"] = task["acceptance_criteria"]
return result return result

View file

@ -29,6 +29,8 @@ CREATE TABLE IF NOT EXISTS projects (
ssh_key_path TEXT, ssh_key_path TEXT,
ssh_proxy_jump TEXT, ssh_proxy_jump TEXT,
description TEXT, description TEXT,
autocommit_enabled INTEGER DEFAULT 0,
obsidian_vault_path TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP created_at DATETIME DEFAULT CURRENT_TIMESTAMP
); );
@ -56,6 +58,7 @@ CREATE TABLE IF NOT EXISTS tasks (
revise_comment TEXT, revise_comment TEXT,
category TEXT DEFAULT NULL, category TEXT DEFAULT NULL,
telegram_sent BOOLEAN DEFAULT 0, telegram_sent BOOLEAN DEFAULT 0,
acceptance_criteria TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP, created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
); );
@ -290,6 +293,10 @@ def _migrate(conn: sqlite3.Connection):
conn.execute("ALTER TABLE tasks ADD COLUMN telegram_sent BOOLEAN DEFAULT 0") conn.execute("ALTER TABLE tasks ADD COLUMN telegram_sent BOOLEAN DEFAULT 0")
conn.commit() conn.commit()
if "acceptance_criteria" not in task_cols:
conn.execute("ALTER TABLE tasks ADD COLUMN acceptance_criteria TEXT")
conn.commit()
if "obsidian_vault_path" not in proj_cols: if "obsidian_vault_path" not in proj_cols:
conn.execute("ALTER TABLE projects ADD COLUMN obsidian_vault_path TEXT") conn.execute("ALTER TABLE projects ADD COLUMN obsidian_vault_path TEXT")
conn.commit() conn.commit()

View file

@ -197,16 +197,17 @@ def create_task(
forgejo_issue_id: int | None = None, forgejo_issue_id: int | None = None,
execution_mode: str | None = None, execution_mode: str | None = None,
category: str | None = None, category: str | None = None,
acceptance_criteria: str | None = None,
) -> dict: ) -> dict:
"""Create a task linked to a project.""" """Create a task linked to a project."""
conn.execute( conn.execute(
"""INSERT INTO tasks (id, project_id, title, status, priority, """INSERT INTO tasks (id, project_id, title, status, priority,
assigned_role, parent_task_id, brief, spec, forgejo_issue_id, assigned_role, parent_task_id, brief, spec, forgejo_issue_id,
execution_mode, category) execution_mode, category, acceptance_criteria)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(id, project_id, title, status, priority, assigned_role, (id, project_id, title, status, priority, assigned_role,
parent_task_id, _json_encode(brief), _json_encode(spec), parent_task_id, _json_encode(brief), _json_encode(spec),
forgejo_issue_id, execution_mode, category), forgejo_issue_id, execution_mode, category, acceptance_criteria),
) )
conn.commit() conn.commit()
return get_task(conn, id) return get_task(conn, id)

View file

@ -58,9 +58,9 @@ def test_update_project_tech_stack_json(conn):
# -- project_type and SSH fields (KIN-071) -- # -- project_type and SSH fields (KIN-071) --
def test_create_operations_project(conn): def test_create_operations_project(conn):
"""KIN-071: operations project stores SSH fields.""" """KIN-071: operations project stores SSH fields. KIN-ARCH-005: path не передаётся."""
p = models.create_project( p = models.create_project(
conn, "srv1", "My Server", "", conn, "srv1", "My Server",
project_type="operations", project_type="operations",
ssh_host="10.0.0.1", ssh_host="10.0.0.1",
ssh_user="root", ssh_user="root",
@ -72,6 +72,7 @@ def test_create_operations_project(conn):
assert p["ssh_user"] == "root" assert p["ssh_user"] == "root"
assert p["ssh_key_path"] == "~/.ssh/id_rsa" assert p["ssh_key_path"] == "~/.ssh/id_rsa"
assert p["ssh_proxy_jump"] == "jumpt" assert p["ssh_proxy_jump"] == "jumpt"
assert p["path"] is None
def test_create_development_project_defaults(conn): def test_create_development_project_defaults(conn):
@ -521,3 +522,45 @@ def test_update_task_category_preserves_status_and_priority(conn):
assert updated["category"] == "UI" assert updated["category"] == "UI"
assert updated["status"] == "in_progress" assert updated["status"] == "in_progress"
assert updated["priority"] == 3 assert updated["priority"] == 3
# -- KIN-ARCH-006: autocommit_enabled и obsidian_vault_path в SCHEMA --
def test_schema_project_has_autocommit_enabled_column(conn):
"""KIN-ARCH-006: таблица projects содержит колонку autocommit_enabled."""
cols = {r[1] for r in conn.execute("PRAGMA table_info(projects)").fetchall()}
assert "autocommit_enabled" in cols
def test_schema_project_has_obsidian_vault_path_column(conn):
"""KIN-ARCH-006: таблица projects содержит колонку obsidian_vault_path."""
cols = {r[1] for r in conn.execute("PRAGMA table_info(projects)").fetchall()}
assert "obsidian_vault_path" in cols
def test_autocommit_enabled_default_is_zero(conn):
"""KIN-ARCH-006: autocommit_enabled по умолчанию равен 0."""
models.create_project(conn, "p1", "P1", "/p1")
p = models.get_project(conn, "p1")
assert p["autocommit_enabled"] == 0
def test_obsidian_vault_path_default_is_none(conn):
"""KIN-ARCH-006: obsidian_vault_path по умолчанию равен NULL."""
models.create_project(conn, "p1", "P1", "/p1")
p = models.get_project(conn, "p1")
assert p["obsidian_vault_path"] is None
def test_autocommit_enabled_can_be_set_to_one(conn):
"""KIN-ARCH-006: autocommit_enabled можно установить в 1 через update_project."""
models.create_project(conn, "p1", "P1", "/p1")
updated = models.update_project(conn, "p1", autocommit_enabled=1)
assert updated["autocommit_enabled"] == 1
def test_obsidian_vault_path_can_be_set(conn):
"""KIN-ARCH-006: obsidian_vault_path можно установить через update_project."""
models.create_project(conn, "p1", "P1", "/p1")
updated = models.update_project(conn, "p1", obsidian_vault_path="/vault/my-notes")
assert updated["obsidian_vault_path"] == "/vault/my-notes"