Files
ipwatch/backend/app/routers/architecture.py
2026-02-07 16:57:37 +01:00

133 lines
3.6 KiB
Python

"""
Endpoints API pour l'éditeur d'architecture
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import List, Optional, Dict, Any
from uuid import uuid4
from datetime import datetime
import json
from pathlib import Path
from backend.app.core.database import get_arch_db
from backend.app.models.architecture import ArchitectureNode
router = APIRouter(prefix="/api/architecture", tags=["Architecture"])
DATA_DIR = Path(__file__).resolve().parents[3] / "data"
WORLD_FILE = DATA_DIR / "architecture.json"
class ArchitectureNodeCreate(BaseModel):
id: Optional[str] = None
type: str
x: int
y: int
width: int
height: int
rotation: int = 0
payload: Dict[str, Any]
class ArchitectureNodeResponse(BaseModel):
id: str
type: str
x: int
y: int
width: int
height: int
rotation: int
payload: Dict[str, Any]
created_at: datetime
class Config:
from_attributes = True
class ArchitectureWorldPayload(BaseModel):
items: List[Dict[str, Any]]
splines: Optional[List[Dict[str, Any]]] = None
@router.get("/nodes", response_model=List[ArchitectureNodeResponse])
async def list_nodes(db: Session = Depends(get_arch_db)):
"""Liste tous les noeuds d'architecture"""
nodes = db.query(ArchitectureNode).order_by(ArchitectureNode.created_at.asc()).all()
results = []
for node in nodes:
try:
payload = json.loads(node.payload or "{}")
except json.JSONDecodeError:
payload = {}
results.append(ArchitectureNodeResponse(
id=node.id,
type=node.type,
x=node.x,
y=node.y,
width=node.width,
height=node.height,
rotation=node.rotation,
payload=payload,
created_at=node.created_at
))
return results
@router.post("/nodes", response_model=ArchitectureNodeResponse)
async def create_node(payload: ArchitectureNodeCreate, db: Session = Depends(get_arch_db)):
"""Créer un noeud d'architecture"""
node_id = payload.id or str(uuid4())
node = ArchitectureNode(
id=node_id,
type=payload.type,
x=payload.x,
y=payload.y,
width=payload.width,
height=payload.height,
rotation=payload.rotation,
payload=json.dumps(payload.payload)
)
db.add(node)
db.commit()
db.refresh(node)
return ArchitectureNodeResponse(
id=node.id,
type=node.type,
x=node.x,
y=node.y,
width=node.width,
height=node.height,
rotation=node.rotation,
payload=payload.payload,
created_at=node.created_at
)
def ensure_world_file() -> None:
DATA_DIR.mkdir(parents=True, exist_ok=True)
if not WORLD_FILE.exists():
WORLD_FILE.write_text(json.dumps({"items": [], "splines": []}, indent=2), encoding="utf-8")
@router.get("/world")
async def get_world():
"""Charge le fichier architecture.json, le crée si absent."""
ensure_world_file()
try:
data = json.loads(WORLD_FILE.read_text(encoding="utf-8"))
except json.JSONDecodeError:
data = {"items": [], "splines": []}
return data
@router.post("/world")
async def save_world(payload: ArchitectureWorldPayload):
"""Sauvegarde les éléments du world dans architecture.json."""
ensure_world_file()
splines = payload.splines or []
WORLD_FILE.write_text(
json.dumps({"items": payload.items, "splines": splines}, indent=2),
encoding="utf-8"
)
return {"status": "ok", "count": len(payload.items), "splines": len(splines)}