kin: KIN-089 При попытке добавить креды прод сервера для проекта corelock вылетает 500 Internal Server Error

This commit is contained in:
Gros Frumos 2026-03-16 20:39:17 +02:00
parent e80e50ba0c
commit 4a65d90218
13 changed files with 1215 additions and 4 deletions

View file

@ -41,6 +41,11 @@ def build_context(
"role": role,
}
# Attachments — all roles get them so debugger sees screenshots, UX sees mockups, etc.
attachments = models.list_attachments(conn, task_id)
if attachments:
ctx["attachments"] = attachments
# If task has a revise comment, fetch the last agent output for context
if task and task.get("revise_comment"):
row = conn.execute(
@ -269,6 +274,14 @@ def format_prompt(context: dict, role: str, prompt_template: str | None = None)
sections.append(last_output)
sections.append("")
# Attachments
attachments = context.get("attachments")
if attachments:
sections.append(f"## Attachments ({len(attachments)}):")
for a in attachments:
sections.append(f"- {a['filename']}: {a['path']}")
sections.append("")
# Previous step output (pipeline chaining)
prev = context.get("previous_output")
if prev:

View file

@ -397,6 +397,37 @@ def _migrate(conn: sqlite3.Connection):
""")
conn.commit()
# Migrate project_environments: old schema used label/login/credential,
# new schema uses name/username/auth_value (KIN-087 column rename).
env_cols = {r[1] for r in conn.execute("PRAGMA table_info(project_environments)").fetchall()}
if "name" not in env_cols and "label" in env_cols:
conn.executescript("""
PRAGMA foreign_keys=OFF;
CREATE TABLE project_environments_new (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id TEXT NOT NULL REFERENCES projects(id),
name TEXT NOT NULL,
host TEXT NOT NULL,
port INTEGER DEFAULT 22,
username TEXT NOT NULL,
auth_type TEXT NOT NULL DEFAULT 'password',
auth_value TEXT,
is_installed INTEGER NOT NULL DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(project_id, name)
);
INSERT INTO project_environments_new
SELECT id, project_id, label, host, port, login, auth_type,
credential, is_installed, created_at, updated_at
FROM project_environments;
DROP TABLE project_environments;
ALTER TABLE project_environments_new RENAME TO project_environments;
CREATE INDEX IF NOT EXISTS idx_environments_project ON project_environments(project_id);
PRAGMA foreign_keys=ON;
""")
conn.commit()
if "project_phases" not in existing_tables:
conn.executescript("""
CREATE TABLE IF NOT EXISTS project_phases (
@ -520,6 +551,21 @@ def _migrate(conn: sqlite3.Connection):
""")
conn.commit()
if "task_attachments" not in existing_tables:
conn.executescript("""
CREATE TABLE IF NOT EXISTS task_attachments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
filename TEXT NOT NULL,
path TEXT NOT NULL,
mime_type TEXT NOT NULL,
size INTEGER NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_task_attachments_task ON task_attachments(task_id);
""")
conn.commit()
# Rename legacy 'auto' → 'auto_complete' (KIN-063)
conn.execute(
"UPDATE projects SET execution_mode = 'auto_complete' WHERE execution_mode = 'auto'"

View file

@ -869,6 +869,55 @@ def add_chat_message(
return _row_to_dict(row)
# ---------------------------------------------------------------------------
# Task Attachments (KIN-090)
# ---------------------------------------------------------------------------
def create_attachment(
conn: sqlite3.Connection,
task_id: str,
filename: str,
path: str,
mime_type: str,
size: int,
) -> dict:
"""Create a task attachment record. path must be absolute."""
cur = conn.execute(
"""INSERT INTO task_attachments (task_id, filename, path, mime_type, size)
VALUES (?, ?, ?, ?, ?)""",
(task_id, filename, path, mime_type, size),
)
conn.commit()
row = conn.execute(
"SELECT * FROM task_attachments WHERE id = ?", (cur.lastrowid,)
).fetchone()
return _row_to_dict(row)
def list_attachments(conn: sqlite3.Connection, task_id: str) -> list[dict]:
"""List all attachments for a task ordered by creation time."""
rows = conn.execute(
"SELECT * FROM task_attachments WHERE task_id = ? ORDER BY created_at",
(task_id,),
).fetchall()
return _rows_to_list(rows)
def get_attachment(conn: sqlite3.Connection, attachment_id: int) -> dict | None:
"""Get a single attachment by id."""
row = conn.execute(
"SELECT * FROM task_attachments WHERE id = ?", (attachment_id,)
).fetchone()
return _row_to_dict(row)
def delete_attachment(conn: sqlite3.Connection, attachment_id: int) -> bool:
"""Delete attachment record. Returns True if deleted, False if not found."""
cur = conn.execute("DELETE FROM task_attachments WHERE id = ?", (attachment_id,))
conn.commit()
return cur.rowcount > 0
def get_chat_messages(
conn: sqlite3.Connection,
project_id: str,