feat: refactor to FastAPI architecture v2.0
Some checks failed
Build & Push Docker / build (push) Has been cancelled

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-20 16:28:21 +01:00
parent 87f1fc2c7a
commit e2bdadd0ce
32 changed files with 2896 additions and 55 deletions

69
app/core/validator.py Normal file
View File

@@ -0,0 +1,69 @@
"""
Validation logic for Scenar Creator.
Extracted from scenar/core.py — validate_inputs, validate_excel_template, overlap detection.
"""
import pandas as pd
from datetime import datetime
import logging
logger = logging.getLogger(__name__)
DEFAULT_COLOR = "#ffffff"
MAX_FILE_SIZE_MB = 10
REQUIRED_COLUMNS = ["Datum", "Zacatek", "Konec", "Program", "Typ", "Garant", "Poznamka"]
class ScenarsError(Exception):
"""Base exception for Scenar Creator."""
pass
class ValidationError(ScenarsError):
"""Raised when input validation fails."""
pass
class TemplateError(ScenarsError):
"""Raised when Excel template is invalid."""
pass
def validate_inputs(title: str, detail: str, file_size: int) -> None:
"""Validate user inputs for security and sanity."""
if not title or not isinstance(title, str):
raise ValidationError("Title is required and must be a string")
if len(title.strip()) == 0:
raise ValidationError("Title cannot be empty")
if len(title) > 200:
raise ValidationError("Title is too long (max 200 characters)")
if not detail or not isinstance(detail, str):
raise ValidationError("Detail is required and must be a string")
if len(detail.strip()) == 0:
raise ValidationError("Detail cannot be empty")
if len(detail) > 500:
raise ValidationError("Detail is too long (max 500 characters)")
if file_size > MAX_FILE_SIZE_MB * 1024 * 1024:
raise ValidationError(f"File size exceeds {MAX_FILE_SIZE_MB} MB limit")
def normalize_time(time_str: str):
"""Parse time string in formats %H:%M or %H:%M:%S."""
for fmt in ('%H:%M', '%H:%M:%S'):
try:
return datetime.strptime(time_str, fmt).time()
except ValueError:
continue
return None
def validate_excel_template(df: pd.DataFrame) -> None:
"""Validate that Excel has required columns."""
missing_cols = set(REQUIRED_COLUMNS) - set(df.columns)
if missing_cols:
raise TemplateError(
f"Excel template missing required columns: {', '.join(missing_cols)}. "
f"Expected: {', '.join(REQUIRED_COLUMNS)}"
)