Show AI structure path errors in HTML5
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-05-21 23:31:01 +03:00
parent dafb552ad3
commit 9ea2ff5518
3 changed files with 47 additions and 7 deletions
@@ -25,6 +25,7 @@ def render_html5_ai_structure_page(*, project_id: str, projects: Iterable[object
<section class="panel setup-main"> <section class="panel setup-main">
<div class="panel-title">Подготовка структуры</div> <div class="panel-title">Подготовка структуры</div>
{render_html5_ai_structure_form(project_id)} {render_html5_ai_structure_form(project_id)}
<p class="object-summary">Пути должны быть доступны серверу SFERA/API. Для docker-test используйте папку, смонтированную или доступную внутри контейнера; локальные диски Windows и закрытые SMB-папки без учетных данных сервер не увидит.</p>
<div data-html5-ai-structure-result>{render_html5_ai_structure_result(result)}</div> <div data-html5-ai-structure-result>{render_html5_ai_structure_result(result)}</div>
</section> </section>
</section> </section>
@@ -43,11 +44,11 @@ def render_html5_ai_structure_form(project_id: str) -> str:
> >
<label> <label>
<span>Папка с cf/cfe или выгрузкой</span> <span>Папка с cf/cfe или выгрузкой</span>
<input name="input_path" placeholder="D:\\1c\\source" /> <input name="input_path" value="\\\\192.168.220.200\\mst\\1c\\MARKA\\CODEX\\CF" />
</label> </label>
<label> <label>
<span>Папка результата</span> <span>Папка результата</span>
<input name="output_path" placeholder="D:\\sfera-ai\\result" /> <input name="output_path" value="\\\\192.168.220.200\\mst\\1c\\MARKA\\CODEX\\CODEX" />
</label> </label>
<label> <label>
<span>Project id</span> <span>Project id</span>
@@ -85,6 +86,21 @@ def render_html5_ai_structure_result(result: dict | None) -> str:
""" """
def render_html5_ai_structure_error(message: str) -> str:
return f"""
<section class="ai-structure-result" data-html5-ai-structure-status="error">
<div class="access-plan-head">
<span class="status-pill">ошибка</span>
<strong>Подготовка не выполнена</strong>
</div>
<ul class="access-warnings">
<li>{escape(message)}</li>
</ul>
<p class="muted padded">Проверьте, что входная и выходная папки доступны именно серверу SFERA/API. Если файлы лежат на рабочем ПК, сначала положите их в общую папку или выполните экспорт через агент.</p>
</section>
"""
def _diagnostics(items: list[object]) -> str: def _diagnostics(items: list[object]) -> str:
if not items: if not items:
return "" return ""
@@ -6,7 +6,11 @@ from typing import Any
from fastapi import HTTPException from fastapi import HTTPException
from api_server.html5_ai_structure import render_html5_ai_structure_page, render_html5_ai_structure_result from api_server.html5_ai_structure import (
render_html5_ai_structure_error,
render_html5_ai_structure_page,
render_html5_ai_structure_result,
)
from api_server.html5_forms import form_value from api_server.html5_forms import form_value
@@ -28,8 +32,15 @@ def html5_ai_structure_run(
input_path = form_value(form, "input_path") input_path = form_value(form, "input_path")
output_path = form_value(form, "output_path") output_path = form_value(form, "output_path")
if not input_path: if not input_path:
raise HTTPException(status_code=400, detail="input_path is required") return render_html5_ai_structure_error("Заполните входную папку с .cf/.cfe или выгрузкой 1С.")
if not output_path: if not output_path:
raise HTTPException(status_code=400, detail="output_path is required") return render_html5_ai_structure_error("Заполните папку результата.")
result = prepare(project_id=effective_project_id, input_path=Path(input_path), output_path=Path(output_path)) try:
result = prepare(project_id=effective_project_id, input_path=Path(input_path), output_path=Path(output_path))
except FileNotFoundError as error:
return render_html5_ai_structure_error(str(error))
except PermissionError as error:
return render_html5_ai_structure_error(f"Нет доступа к папке: {error}")
except OSError as error:
return render_html5_ai_structure_error(f"Ошибка файловой системы: {error}")
return render_html5_ai_structure_result(result) return render_html5_ai_structure_result(result)
+14 -1
View File
@@ -1727,7 +1727,14 @@ def test_ai_structure_prepare_writes_ai_ready_package(tmp_path: Path):
assert "Treat modules/forms/commands as parts" in (output / "ai_context.md").read_text(encoding="utf-8") assert "Treat modules/forms/commands as parts" in (output / "ai_context.md").read_text(encoding="utf-8")
page = client.get("/html5/projects/ai-demo/ai-structure") page = client.get("/html5/projects/ai-demo/ai-structure")
assert_html5_response_contract(page, 'data-html5-page="ai-structure"', "Структура для ИИ", full_page=True) assert_html5_response_contract(
page,
'data-html5-page="ai-structure"',
"Структура для ИИ",
"192.168.220.200",
"Пути должны быть доступны серверу",
full_page=True,
)
html5_run = client.post( html5_run = client.post(
"/html5/projects/ai-demo/ai-structure/run", "/html5/projects/ai-demo/ai-structure/run",
@@ -1735,6 +1742,12 @@ def test_ai_structure_prepare_writes_ai_ready_package(tmp_path: Path):
) )
assert_html5_response_contract(html5_run, "ready", "codex-1c-context-ai-demo-html5", "sir_snapshot.json", "normalized_project.json") assert_html5_response_contract(html5_run, "ready", "codex-1c-context-ai-demo-html5", "sir_snapshot.json", "normalized_project.json")
html5_missing = client.post(
"/html5/projects/ai-demo/ai-structure/run",
data={"project_id": "ai-demo-html5", "input_path": str(tmp_path / "missing"), "output_path": str(tmp_path / "html5-out")},
)
assert_html5_response_contract(html5_missing, "ошибка", "Input path not found")
def test_ai_structure_prepare_reports_cf_cfe_export_required(tmp_path: Path): def test_ai_structure_prepare_reports_cf_cfe_export_required(tmp_path: Path):
source = tmp_path / "cf-source" source = tmp_path / "cf-source"