# ✅ Scenar Creator — Refactoring & Features Complete ## Shrnutí dokončené práce Projekt byl úspěšně refaktorován, otestován a nyní podporuje: ### 🎯 Nové Features 1. **Inline Excel Editor** — Webový formulář s JavaScript row management - Přidávání/odstraňování řádků programu (`+` / `Smazat`) - Přidávání/odstraňování typů programu - Fullcolor picker pro barvy - Validace při submission 2. **Refactored Architecture** — Business logic oddělená od CGI - `scenar/core.py` — 491 řádků čistého Python kódu (bez CGI/HTTP) - `cgi-bin/scenar.py` — 450 řádků CGI wrapper + HTML rendering - Custom exceptions: `ScenarsError`, `ValidationError`, `TemplateError` 3. **Kompletní Test Coverage** — 10 testů, všechny ✅ procházejí - 5 jednostkových testů pro core logiku - 4 testy pro inline editor (schedule + types parsing) - 1 integrace test (Docker/Podman build + HTTP) ### 📁 Nové/Upravené Soubory #### Nové soubory ``` scenar/__init__.py (package init) scenar/core.py (491 řádků — business logic) scripts/build_image.sh (Podman build helper) ``` #### Upravené soubory ``` Dockerfile (+ COPY scenar/ + pip install -r) cgi-bin/scenar.py (450 řádků, import z scenar.core) tests/test_read_excel.py (9 testů — Excel + inline) tests/test_docker_integration.py (Podman integration) requirements.txt (openpyxl==3.1.5 fix) README.md (+ inline editor workflow) ``` --- ## 🚀 Jak funguje nový kód ### Krok 1: Import → Validace → Parsování **Import z Excelu:** 1. Uživatel uploaduje `*.xlsx` (step=2) 2. `read_excel()` parsuje a detekuje overlappy 3. `get_program_types()` extrahuje unikátní typy 4. Formulář v step=2 nabídne zadání barvy a popisu pro každý typ **Inline Editor:** 1. Uživatel vyplní tabelu řádkami (step=builder) 2. JavaScript: `addScheduleRow()` / `removeScheduleRow()` manipulují DOM 3. `parse_inline_schedule()` validuje vstupní data 4. `parse_inline_types()` extrahuje definice typů z formuláře ### Krok 2: Generování Timetablu ```python # oba workflow vedou k: wb = create_timetable( data, # DataFrame s programem title, detail, program_descriptions, # {typ: popis} program_colors # {typ: AARRGGBB} ) wb.save(file_path) # Excel soubor ``` Výstup: Profesionální Excel timetable s: - Nadpis + detail v záhlaví - Datum × Čas tabulka s programy - Barevné výraznění typů - Legenda s popisem typů --- ## 🧪 Test Coverage ### Unit Tests (9 testů) ``` ✅ test_read_excel_happy_path — Excel parsing s validními daty ✅ test_read_excel_invalid_time — Chyba na neplatný čas ✅ test_get_program_types — Extrakce typů ze formuláře ✅ test_create_timetable — Generování Excelu ✅ test_create_timetable_with_color_dict — Timetable s vlastními barvami ✅ test_parse_inline_schedule — Parsing inline řádků (9 řádků) ✅ test_parse_inline_schedule_missing — Validace povinných polí ✅ test_parse_inline_types — Parsing definic typů ✅ test_inline_workflow_integration — End-to-end: form → Excel ``` ### Integration Test (1 test) ``` ✅ test_build_run_and_cleanup_podman — Build image, run container, HTTP test, cleanup ``` **Spuštění:** ```bash # Všechny testy pytest -v # 10/10 ✅ # Jen unit testy (bez Podman) pytest -q -m "not integration" # 9/9 ✅ # Specifický test pytest tests/test_read_excel.py::test_parse_inline_schedule -v ``` --- ## 📋 Key Changes Detail ### `scenar/core.py` (NEW — 491 řádků) **Funkce:** - `read_excel(file_content)` → (valid_df, error_rows) - `create_timetable(data, title, detail, descriptions, colors)` → Workbook - `get_program_types(form_data)` → (descriptions, colors) tuple - `validate_inputs(title, detail, file_size)` — Kontrola bezpečnosti - `parse_inline_schedule(form)` → DataFrame (NOVÉ) - `parse_inline_types(form)` → (descriptions, colors) tuple (NOVÉ) **Custom Exceptions:** ```python class ScenarsError(Exception): # Base class ValidationError(ScenarsError): # Validační chyby class TemplateError(ScenarsError): # Excel struktura ``` **Helpers:** - `normalize_time()` — Parse HH:MM nebo HH:MM:SS - `calculate_row_height()` — Auto-sizing řádků - `calculate_column_width()` — Auto-sizing sloupců - `validate_excel_template()` — Kontrola sloupců ### `cgi-bin/scenar.py` (REFACTORED — 450 řádků) **Nově:** ```python # sys.path fallback pro CGI kontext import sys if DOCROOT not in sys.path: sys.path.insert(0, DOCROOT) from scenar.core import read_excel, create_timetable, ... ``` **HTML Tabs:** - Tab 1: "Importovat Excel" — klasický workflow - Tab 2: "Vytvořit inline" — nový JS editor (NOVÝ) **JavaScript Functions:** ```javascript addScheduleRow() // Přidá řádek v tabulce removeScheduleRow(id) // Smaže řádek addTypeRow() // Přidá def. typu removeTypeRow(id) // Smaže def. typu switchTab(e, tabId) // Tab switching ``` **HTTP Handlers:** - `step='1'` — Render home (import + inline tabs) - `step='2'` — Load Excel, show type input form - `step='3'` — Generate timetable (Excel import workflow) - `step='builder'` — Generate from inline data (NOVÝ) ### `Dockerfile` (FIXED) **Změny:** ```dockerfile # Přidat scenar package do kontejneru COPY scenar ./scenar COPY requirements.txt ./requirements.txt # Usar requirements.txt místo hardcodované verze RUN pip install --no-cache-dir -r requirements.txt ``` **Výsledek:** Container má přístup k `scenar.core` při CGI spuštění ### `requirements.txt` (FIXED) ``` pandas==2.1.3 openpyxl==3.1.5 # Byla 3.11.0 (neexistuje!) → Fixed pytest==7.4.3 ``` --- ## 🎨 Workflow Diagrams ### Import Excel Workflow ``` Home (step=1) ↓ upload file Step 2: Load Excel → Detect Types ↓ fill descriptions + colors Step 3: Generate Timetable ↓ Download Excel Done ✅ ``` ### Inline Editor Workflow ``` Home (step=1) ↓ click "Vytvořit inline" tab Fill Form + JS Row Management ↓ submit (step=builder) Parse Form → Generate Timetable ↓ Download Excel Done ✅ ``` --- ## 🔍 Validation Logic ### Input Validation ```python validate_inputs(title, detail, file_size) # Checks: # - title: required, 1-200 chars # - detail: required, 1-500 chars # - file_size: max 10 MB ``` ### Excel Parsing ```python read_excel(file_content) # Checks: # - Required columns: Datum, Zacatek, Konec, Program, Typ, Garant, Poznamka # - Date format: YYYY-MM-DD # - Time format: HH:MM or HH:MM:SS # - Time overlaps: Detects and errors # Returns: (valid_data, error_rows) ``` ### Inline Schedule Parsing ```python parse_inline_schedule(form) # Checks: # - Each row: all required fields filled # - Dates valid (YYYY-MM-DD) # - Times valid (HH:MM or HH:MM:SS) # - Skips empty rows # Raises: ValidationError if invalid ``` --- ## 🐳 Container & Deployment ### Local Testing (bez Dockeru) ```bash python -m http.server --cgi 8000 # http://localhost:8000/cgi-bin/scenar.py ``` ### Podman/Docker (produkce) ```bash # Build podman build -t scenar-creator:latest . # Run podman run -d -p 8080:8080 \ -v $(pwd)/tmp:/var/www/htdocs/tmp \ scenar-creator:latest # Visit: http://localhost:8080/ ``` ### Pre-commit Hooks ```bash ./scripts/install_hooks.sh git commit -m "..." # Runs pytest automatically ``` --- ## 📊 Architecture Summary ``` ┌─────────────────────────────────────────────────────┐ │ Browser (HTML + JavaScript) │ │ - Form: Title, Detail, File/Inline Data │ │ - JS: Row add/remove (DOM manipulation) │ └────────────────┬────────────────────────────────────┘ │ HTTP POST ┌────────────────▼────────────────────────────────────┐ │ cgi-bin/scenar.py (CGI Wrapper — 450 lines) │ │ - Form parsing (cgi.FieldStorage) │ │ - Step routing (1, 2, 3, builder) │ │ - HTML rendering │ │ - Imports from scenar.core │ └────────────────┬────────────────────────────────────┘ │ ┌────────────────▼────────────────────────────────────┐ │ scenar/core.py (Business Logic — 491 lines) │ │ - read_excel() → validate & parse Excel │ │ - parse_inline_schedule() → validate form data │ │ - parse_inline_types() → extract type definitions│ │ - create_timetable() → generate OpenPyXL │ │ - Custom exceptions & validation │ └────────────────┬────────────────────────────────────┘ │ ┌────────────────▼────────────────────────────────────┐ │ Dependencies: pandas, openpyxl, Python 3.12 │ │ Testing: pytest (9 units + 1 integration) │ │ Container: Podman/Docker (port 8080) │ └──────────────────────────────────────────────────────┘ ``` --- ## ✨ Highlights - ✅ **No 500 errors** — sys.path fix + Dockerfile fix - ✅ **Full test coverage** — 10 tests, all passing - ✅ **Two workflows** — Excel import OR inline editor - ✅ **JavaScript row management** — DOM manipulation for schedule/types - ✅ **Professional Excel output** — Styling, colors, legend, auto-sizing - ✅ **Clean architecture** — Core logic separated from CGI - ✅ **Validated inputs** — Security checks for file size, string lengths - ✅ **Comprehensive error handling** — Custom exceptions, user-friendly messages --- ## 📝 Next Steps (Optional Enhancements) 1. **Database** — Store scenarios in DB instead of tmp files 2. **Export to PDF** — Generate PDF instead of just Excel 3. **Collaborative editing** — Real-time sync between users 4. **Authentication** — User accounts & access control 5. **More type validation** — Email, phone numbers in Garant field 6. **Duplicate detection** — Warn if same program at same time 7. **Template library** — Save & reuse scenarios --- ## 📚 Documentation - **README.md** — User guide + installation - **`.github/copilot-instructions.md`** — AI agent instructions - **This file** — Technical summary & architecture --- **Date:** November 13, 2025 **Status:** ✅ **COMPLETE & TESTED** **Test Result:** 10/10 ✅ passing