Some checks failed
Build & Push Docker / build (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
146 lines
5.8 KiB
Markdown
146 lines
5.8 KiB
Markdown
# Ú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
|