kin: KIN-071 Добавить тип проекта: development / operations / research. Для operations: вместо path к локальной папке — ssh-доступ (host, user, key, proxy or jump). При создании operations-проекта запускается sysadmin-агент который подключается по SSH, обходит сервер, составляет карту: какие сервисы запущены (docker ps, systemctl), какие конфиги где лежат, какие порты открыты, какие версии. Результат сохраняется в decisions и modules как база знаний по серверу. Код не хранится локально — агенты работают через SSH. PM для operations вызывает sysadmin/debugger, не architect/frontend_dev.

This commit is contained in:
Gros Frumos 2026-03-16 09:17:42 +02:00
parent d9172fc17c
commit 75fee86110
4 changed files with 371 additions and 0 deletions

View file

@ -1265,3 +1265,71 @@ def test_kin016_pipeline_blocked_agent_stops_next_steps_integration(client):
assert items[0]["task_id"] == "P1-001"
assert items[0]["reason"] == "no repo access"
assert items[0]["agent_role"] == "debugger"
# ---------------------------------------------------------------------------
# KIN-071: project_type и SSH-поля в API
# ---------------------------------------------------------------------------
def test_create_operations_project_with_ssh_fields(client):
"""KIN-071: POST /api/projects с project_type=operations и SSH-полями возвращает 200."""
r = client.post("/api/projects", json={
"id": "srv1",
"name": "My Server",
"path": "",
"project_type": "operations",
"ssh_host": "10.0.0.1",
"ssh_user": "root",
"ssh_key_path": "~/.ssh/id_rsa",
"ssh_proxy_jump": "jumpt",
})
assert r.status_code == 200
data = r.json()
assert data["project_type"] == "operations"
assert data["ssh_host"] == "10.0.0.1"
assert data["ssh_user"] == "root"
assert data["ssh_key_path"] == "~/.ssh/id_rsa"
assert data["ssh_proxy_jump"] == "jumpt"
def test_create_project_invalid_type_returns_400(client):
"""KIN-071: POST /api/projects с недопустимым project_type → 400."""
r = client.post("/api/projects", json={
"id": "bad",
"name": "Bad",
"path": "/bad",
"project_type": "legacy",
})
assert r.status_code == 400
def test_patch_project_invalid_type_returns_400(client):
"""KIN-071: PATCH /api/projects/{id} с недопустимым project_type → 400."""
r = client.patch("/api/projects/p1", json={"project_type": "invalid_type"})
assert r.status_code == 400
def test_create_operations_project_without_ssh_host_allowed(client):
"""KIN-071: API не валидирует ssh_host на стороне бэкенда — проект создаётся без него."""
r = client.post("/api/projects", json={
"id": "srv2",
"name": "Server No SSH",
"path": "",
"project_type": "operations",
})
assert r.status_code == 200
assert r.json()["project_type"] == "operations"
assert r.json()["ssh_host"] is None
def test_create_research_project_type_accepted(client):
"""KIN-071: project_type=research принимается API."""
r = client.post("/api/projects", json={
"id": "res1",
"name": "Research Project",
"path": "/research",
"project_type": "research",
})
assert r.status_code == 200
assert r.json()["project_type"] == "research"