feat(01-03): API routers (calendar, generate, export, settings) e wiring main.py
- schemas/settings.py: Settings pydantic model con api_key, llm_model, nicchie_attive, tono
- routers/calendar.py: POST /api/calendar/generate, GET /api/calendar/formats
- routers/generate.py: POST /api/generate/bulk (202 + job_id), GET /job/{job_id}/status (polling), GET /job/{job_id}, POST /single
- routers/export.py: GET /api/export/{job_id}/csv (originale), POST /api/export/{job_id}/csv (modifiche inline)
- routers/settings.py: GET /api/settings/status (api_key_configured), GET /api/settings, PUT /api/settings
- main.py: include_router x4 PRIMA di SPAStaticFiles, copia prompt default al primo avvio
This commit is contained in:
59
backend/routers/calendar.py
Normal file
59
backend/routers/calendar.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""Router per la gestione del calendario editoriale.
|
||||
|
||||
Endpoint:
|
||||
- POST /api/calendar/generate — genera un calendario di 13 slot
|
||||
- GET /api/calendar/formats — ritorna il mapping formati disponibili
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
from backend.schemas.calendar import CalendarRequest, CalendarResponse
|
||||
from backend.services.calendar_service import CalendarService
|
||||
from backend.services.format_selector import FormatSelector
|
||||
|
||||
|
||||
router = APIRouter(prefix="/api/calendar", tags=["calendar"])
|
||||
|
||||
# Istanze dei servizi (create una volta alla startup del router)
|
||||
_format_selector = FormatSelector()
|
||||
_calendar_service = CalendarService(format_selector=_format_selector)
|
||||
|
||||
|
||||
@router.post("/generate", response_model=CalendarResponse)
|
||||
async def generate_calendar(request: CalendarRequest) -> CalendarResponse:
|
||||
"""Genera un calendario editoriale di 13 slot.
|
||||
|
||||
Produce un piano di pubblicazione con:
|
||||
- Distribuzione PN (valore, storytelling, news, riprova_sociale, coinvolgimento, promozione)
|
||||
- Livelli Schwartz L1-L5 corretti per ogni tipo di contenuto
|
||||
- Formato narrativo selezionato automaticamente
|
||||
- Date di pubblicazione suggerite
|
||||
- Rotazione nicchie (50% generico, 50% verticali)
|
||||
|
||||
Args:
|
||||
request: Parametri del calendario (obiettivo, settimane, nicchie, frequenza, data_inizio).
|
||||
|
||||
Returns:
|
||||
CalendarResponse con 13 slot ordinati per fase funnel.
|
||||
"""
|
||||
return _calendar_service.generate_calendar(request)
|
||||
|
||||
|
||||
@router.get("/formats")
|
||||
async def get_formats() -> dict:
|
||||
"""Ritorna il mapping completo dei formati narrativi disponibili.
|
||||
|
||||
Utile per il frontend per visualizzare quale formato viene usato
|
||||
per ogni combinazione tipo_contenuto x livello_schwartz.
|
||||
|
||||
Returns:
|
||||
Dict con le 30 combinazioni tipo x livello -> formato narrativo.
|
||||
"""
|
||||
return {
|
||||
"mapping": _format_selector.get_mapping(),
|
||||
"formati_disponibili": list(
|
||||
set(_format_selector.get_mapping().values())
|
||||
),
|
||||
}
|
||||
Reference in New Issue
Block a user