# Úkol: Refactor scenar-creator CGI → FastAPI ## Kontext Aplikace `scenar-creator` je webový nástroj pro tvorbu časových harmonogramů (scénářů) z Excel souborů nebo inline formulářů. Výstupem je Excel timetable soubor ke stažení. Aktuálně běží jako CGI/Apache app. Úkol: přepsat na FastAPI architekturu. ## Schválená architektura ### Tech Stack - **Backend:** FastAPI (replaces CGI/Apache) - **UI:** Vanilla JS + interact.js z CDN (drag-and-drop timeline, NO build pipeline) - **PDF generování:** ReportLab (přidáme NOVÝ výstupní formát vedle Excel) - **Docs:** MkDocs Material - **Storage:** filesystem (JSON export/import), NO databáze - **Python:** 3.12, `python:3.12-slim` base image - **Server:** uvicorn na portu 8080 ### Nová struktura souborů ``` scenar-creator/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI app, router registrace, static files │ ├── config.py # Konfigurace (verze, limity, fonts) │ ├── models/ │ │ ├── __init__.py │ │ ├── event.py # Pydantic: EventInfo, ProgramType, Block, ScenarioDocument │ │ └── responses.py # API response modely │ ├── api/ │ │ ├── __init__.py │ │ ├── router.py # APIRouter │ │ ├── scenario.py # POST /api/validate, /api/import-excel, /api/export-json │ │ └── pdf.py # POST /api/generate-pdf │ ├── core/ │ │ ├── __init__.py │ │ ├── validator.py # z scenar/core.py - validate_inputs, validate_excel_template, overlap detection │ │ ├── timetable.py # z scenar/core.py - create_timetable (Excel output) │ │ ├── excel_reader.py # z scenar/core.py - read_excel, parse_inline_schedule │ │ └── pdf_generator.py # NOVÝ - ReportLab PDF rendering (A4 landscape timetable) │ └── static/ │ ├── index.html # Hlavní SPA │ ├── css/ │ │ └── app.css │ └── js/ │ ├── app.js # State management │ ├── canvas.js # interact.js timeline editor │ ├── api.js # fetch() wrapper │ └── export.js # JSON import/export ├── docs/ │ └── mkdocs.yml ├── tests/ │ ├── test_api.py # Přizpůsobit existující testy │ ├── test_core.py │ └── test_pdf.py ├── Dockerfile # Nový - FastAPI + uvicorn, NO Apache ├── requirements.txt # Nový ├── pytest.ini └── README.md ``` ## API Endpointy ``` GET / → static/index.html GET /api/health → {"status": "ok", "version": "2.0.0"} POST /api/validate → validuje scenario JSON (Pydantic) POST /api/import-excel → upload Excel → vrací ScenarioDocument JSON POST /api/generate-excel → ScenarioDocument → Excel file download POST /api/generate-pdf → ScenarioDocument → PDF file download GET /api/template → stáhnout scenar_template.xlsx GET /docs → Swagger UI (FastAPI built-in) ``` ## Datové modely (Pydantic v2) ```python class Block(BaseModel): datum: date zacatek: time konec: time program: str typ: str garant: Optional[str] = None poznamka: Optional[str] = None class ProgramType(BaseModel): code: str description: str color: str # hex #RRGGBB class EventInfo(BaseModel): title: str = Field(..., max_length=200) detail: str = Field(..., max_length=500) class ScenarioDocument(BaseModel): version: str = "1.0" event: EventInfo program_types: List[ProgramType] blocks: List[Block] ``` ## Zachovat beze změn - Veškerá business logika z `scenar/core.py` — jen přesunout/refactorovat do `app/core/` - Existující testy v `tests/` — přizpůsobit k FastAPI (TestClient místo CGI simulace) - `templates/scenar_template.xlsx` ## Smazat/nahradit - `cgi-bin/scenar.py` → nahradit FastAPI endpointy + static SPA - `Dockerfile` → nový bez Apache/CGI - `requirements.txt` → přidat: `fastapi>=0.115`, `uvicorn[standard]>=0.34`, `reportlab>=4.0`, `python-multipart>=0.0.20` ## Frontend SPA (index.html) - Zachovat existující UI flow: tabs (Import Excel | Vytvořit inline) - Import tab: upload Excel → volání `/api/import-excel` → zobrazit schedule editor - Builder tab: inline tvorba schedule + types → volání `/api/generate-excel` nebo `/api/generate-pdf` - **Nový prvek:** tlačítko "Stáhnout PDF" vedle "Stáhnout Excel" - Timeline canvas s interact.js: drag bloky na časové ose (volitelné, pokud nestihne) - API calls přes `api.js` fetch wrappers ## PDF výstup (ReportLab) - A4 landscape - Stejná struktura jako Excel output: název akce, detail, tabulka s časovými sloty po 15 min - Barevné bloky podle program_types - Legenda dole ## Dockerfile (nový) ```dockerfile FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=5s CMD curl -fsS http://localhost:8080/api/health || exit 1 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"] ``` ## CI/CD - `.gitea/workflows/build-and-push.yaml` existuje — zachovat, jen zkontrolovat jestli funguje s novou strukturou - Po dokončení: `git add -A && git commit -m "feat: refactor to FastAPI architecture v2.0" && git push` ## Výsledek - Plně funkční FastAPI app nahrazující CGI - Všechny testy procházejí (`pytest`) - Dockerfile builduje bez chyb (`docker build .`) - Git push do `main` branch