Commit Graph

7 Commits

Author SHA1 Message Date
Michele
05972fa8f1 feat(02-01): backend prompts router with 4 CRUD endpoints
- GET /api/prompts — list all prompts with modified/default flag
- GET /api/prompts/{name} — read prompt content + required variables
- PUT /api/prompts/{name} — save modified prompt with validation
- POST /api/prompts/{name}/reset — restore prompt to default
- Lazy PromptService init to handle lifespan directory creation
- Router registered in main.py before SPA catch-all

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:54:30 +01:00
Michele
d8e3eb9415 fix(01): calendar slot merge in OutputReview for PN/Schwartz badges
GenerateResponse now includes calendar field from backend.
OutputReview merges CalendarSlot into PostResult via slot_index,
enabling BadgePN, BadgeSchwartz rendering and Retry button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 03:14:07 +01:00
Michele
e06edde4ef 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
2026-03-08 02:14:17 +01:00
Michele
083621afd3 feat(01-03): LLMService, CSVBuilder, GenerationPipeline
- LLMService: retry 3x, RateLimitError legge retry-after header, 5xx backoff esponenziale, ValidationError riprova con istruzione correttiva, inter_request_delay 2s
- LLMService.generate_topic(): usa TopicResult come response_schema (passa per loop retry/validation)
- CSVBuilder: encoding utf-8-sig, header CANVA_FIELDS locked, mappa GeneratedPost+CalendarSlot -> 33 colonne
- GenerationPipeline: background task asyncio.create_task, _jobs dict progresso real-time, per-item try/except individuale, persistenza JSON su disco
2026-03-08 02:10:28 +01:00
Michele
ef9b9471fc feat(01-02): CalendarService, PromptService, 7 prompt .txt in italiano
- backend/services/calendar_service.py: genera 13 slot con distribuzione PN (4v+2s+2n+3r+1c+1p) e Schwartz (L5=3,L4=3,L3=4,L2=2,L1=1), ordina per funnel, ruota nicchie, calcola date
- backend/services/prompt_service.py: carica/compila/elenca prompt {{variabile}}, ValueError per variabili mancanti
- backend/data/prompts/system_prompt.txt: sistema prompt esperto content marketing B2B italiano
- backend/data/prompts/topic_generator.txt: generazione topic per slot calendario
- backend/data/prompts/pas_valore.txt: formato PAS per post valore educativo
- backend/data/prompts/listicle_valore.txt: formato Listicle per post valore
- backend/data/prompts/bab_storytelling.txt: formato BAB per post storytelling
- backend/data/prompts/aida_promozione.txt: formato AIDA per post promozionale
- backend/data/prompts/dato_news.txt: formato Dato+Implicazione per post news
2026-03-08 02:00:00 +01:00
Michele
209d8962f7 feat(01-02): costanti dominio, schemas Pydantic, FormatSelector
- backend/constants.py: CANVA_FIELDS (33 col locked), PERSUASION_DISTRIBUTION (13), SCHWARTZ_DISTRIBUTION (13)
- backend/schemas/calendar.py: CalendarSlot, CalendarRequest, CalendarResponse
- backend/schemas/generate.py: SlideContent, GeneratedPost, TopicResult, GenerateRequest, PostResult, GenerateResponse
- backend/data/format_mapping.json: matrice 6 tipi x 5 livelli (30 combinazioni)
- backend/services/format_selector.py: FormatSelector con select_format e fallback PAS
- fix .gitignore: backend/data/prompts/ e format_mapping.json non erano ignorabili
2026-03-08 01:54:58 +01:00
Michele
50d5708016 feat(01-01): Backend FastAPI skeleton + Docker build config
- FastAPI app with SPAStaticFiles catch-all (root_path NOT in constructor)
- config.py with DATA_PATH, PROMPTS_PATH, OUTPUTS_PATH, CAMPAIGNS_PATH, CONFIG_PATH
- Startup lifespan creates data directories automatically
- Health endpoint: GET /api/health -> {"status": "ok"}
- Dockerfile multi-stage: node:22-slim builds React, python:3.12-slim serves API+SPA
- --root-path /postgenerator set in Uvicorn CMD only (avoids Pitfall #4)
- docker-compose.yml: lab-postgenerator-app, proxy_net, named volume for data persistence
- requirements.txt with pinned versions: fastapi[standard]==0.135.1, anthropic==0.84.0
2026-03-08 01:51:41 +01:00