arch-design-agent-skill-das.../backend/app/modules/editor/interfaces/http/router.py
2026-03-23 17:02:04 +00:00

85 lines
2.8 KiB
Python

"""Editor HTTP router — file read/write and impact analysis endpoints."""
from __future__ import annotations
from dataclasses import asdict
from fastapi import APIRouter
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from app.modules.project.application.services import ProjectService
from app.modules.scanner.application.services import ScanService
from app.modules.editor.application.services import EditorService
router = APIRouter(prefix="/projects/{project_id}/files", tags=["editor"])
_project_service: ProjectService | None = None
_scan_service: ScanService | None = None
_editor_service: EditorService | None = None
def init_router(
project_service: ProjectService,
scan_service: ScanService,
editor_service: EditorService,
) -> None:
global _project_service, _scan_service, _editor_service
_project_service = project_service
_scan_service = scan_service
_editor_service = editor_service
class SaveFileRequest(BaseModel):
content: str
def _get_or_trigger_scan(project_id: str):
"""Get cached scan or trigger a new one."""
result = _scan_service.get_latest_scan(project_id)
if result is None:
project = _project_service.get_project(project_id)
result = _scan_service.scan(project)
return result
@router.get("/{path:path}/impact")
def get_impact(project_id: str, path: str):
"""Return impact analysis for a given file."""
project = _project_service.get_project(project_id)
scan_result = _get_or_trigger_scan(project_id)
impact = _editor_service.get_impact(project, path, scan_result)
return asdict(impact)
@router.get("/{path:path}")
def get_file(project_id: str, path: str):
"""Read a design file and return its content."""
project = _project_service.get_project(project_id)
editable = _editor_service.get_file(project, path)
return {
"path": editable.path,
"format": editable.format,
"content": editable.content,
"last_modified": editable.last_modified.isoformat(),
}
@router.put("/{path:path}")
def save_file(project_id: str, path: str, body: SaveFileRequest):
"""Write content to a design file and re-scan."""
project = _project_service.get_project(project_id)
scan_result = _editor_service.save_file(project, path, body.content)
return {
"project_id": scan_result.project_id,
"scanned_at": scan_result.scanned_at.isoformat(),
"summary": {
"total_files": scan_result.summary.total_files,
"ok": scan_result.summary.ok,
"sparse": scan_result.summary.sparse,
"missing": scan_result.summary.missing,
"placeholder_heavy": scan_result.summary.placeholder_heavy,
"template_residue": scan_result.summary.template_residue,
},
}