Files
Michele 696b265e4d fix(01): revise plans based on checker feedback
- Fix CSV-01 column count: 32 -> 33 (8 meta + 24 slide + 1 caption)
- Add TopicResult Pydantic model + topic_generator.txt prompt
- Make bulk generation async with background task + polling endpoint
- Add POST /api/export/{job_id}/csv for inline edit CSV download
- Split Plan 01-04 Task 2 into 2a/2b/2c (badges, slideviewer, pages)
- Update ProgressIndicator to use polling on /status endpoint
- Add --yes flag and frontend/ prerequisite note to Plan 01-01

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 01:40:30 +01:00

20 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
phase plan type wave depends_on files_modified autonomous must_haves
01-core-generation-pipeline 04 execute 3
01-01
01-02
01-03
frontend/src/App.tsx
frontend/src/pages/Dashboard.tsx
frontend/src/pages/GenerateCalendar.tsx
frontend/src/pages/GenerateSingle.tsx
frontend/src/pages/OutputReview.tsx
frontend/src/pages/Settings.tsx
frontend/src/components/Layout.tsx
frontend/src/components/Sidebar.tsx
frontend/src/components/PostCard.tsx
frontend/src/components/SlideViewer.tsx
frontend/src/components/ProgressIndicator.tsx
frontend/src/components/BadgePN.tsx
frontend/src/components/BadgeSchwartz.tsx
frontend/src/api/client.ts
frontend/src/api/hooks.ts
frontend/src/types.ts
false
truths artifacts key_links
L'utente vede una Dashboard con link a Genera Calendario, Genera Singolo Post, e Impostazioni
L'utente compila il form Genera Calendario (obiettivo + settimane) e clicca Genera — vede progress indicator che si aggiorna in tempo reale tramite polling ogni 2s su /api/generate/job/{job_id}/status
L'utente vede i 13 post generati come griglia di card con badge colorati PN e Schwartz
L'utente clicca su una card e vede le slide con navigazione frecce laterali + caption Instagram
L'utente puo' modificare il testo di una slide inline (click to edit) e le modifiche si riflettono nel CSV scaricato tramite POST /api/export/{job_id}/csv
L'utente scarica il CSV cliccando un pulsante Download CSV
Post falliti appaiono come card errore con pulsante Riprova
Il pulsante Genera e' disabilitato se API key non configurata, con messaggio che rimanda a Impostazioni
La pagina Impostazioni permette di configurare API key, modello LLM, nicchie, frequenza
path provides min_lines
frontend/src/pages/Dashboard.tsx Dashboard con stato e navigazione 30
path provides min_lines
frontend/src/pages/GenerateCalendar.tsx Form generazione calendario con progress indicator 80
path provides min_lines
frontend/src/pages/OutputReview.tsx Griglia card post con espansione slide, edit inline, download CSV 100
path provides min_lines
frontend/src/pages/Settings.tsx Form configurazione con API key, modello, nicchie 50
path provides min_lines
frontend/src/components/PostCard.tsx Card singolo post con badge PN e Schwartz 40
path provides min_lines
frontend/src/components/SlideViewer.tsx Navigazione slide con frecce laterali 50
path provides contains
frontend/src/api/hooks.ts TanStack Query hooks per tutte le API calls useQuery
from to via pattern
frontend/src/api/hooks.ts /postgenerator/api apiFetch con endpoint completo apiFetch
from to via pattern
frontend/src/pages/GenerateCalendar.tsx frontend/src/api/hooks.ts useMutation per POST /api/generate/bulk (async, ritorna job_id) useGenerateCalendar
from to via pattern
frontend/src/components/ProgressIndicator.tsx frontend/src/api/hooks.ts useJobStatus(jobId) polling ogni 2s su GET /api/generate/job/{job_id}/status useJobStatus
from to via pattern
frontend/src/pages/OutputReview.tsx frontend/src/api/hooks.ts useDownloadEditedCsv per POST /api/export/{job_id}/csv con edits inline useDownloadEditedCsv
from to via pattern
frontend/src/pages/OutputReview.tsx frontend/src/components/PostCard.tsx Render griglia di PostCard PostCard
from to via pattern
frontend/src/components/PostCard.tsx frontend/src/components/SlideViewer.tsx Espansione card mostra SlideViewer SlideViewer
Creare l'intera Web UI: Dashboard, form Genera Calendario con progress indicator, Output Review con griglia card + navigazione slide + edit inline + download CSV, form Genera Singolo Post, e pagina Impostazioni.

Purpose: Dare all'utente l'interfaccia per interagire con la pipeline di generazione. Questa e' l'unica via di accesso al sistema — senza UI il backend non e' utilizzabile.

Output: SPA React completa con tutte le pagine e componenti per il workflow: configura -> genera -> rivedi -> scarica.

<execution_context> @C:\Users\miche.claude/get-shit-done/workflows/execute-plan.md @C:\Users\miche.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/01-core-generation-pipeline/01-CONTEXT.md @.planning/phases/01-core-generation-pipeline/01-01-SUMMARY.md @.planning/phases/01-core-generation-pipeline/01-02-SUMMARY.md @.planning/phases/01-core-generation-pipeline/01-03-SUMMARY.md Task 1: Layout, routing, API hooks, tipi TypeScript, pagine Settings e Dashboard frontend/src/types.ts frontend/src/api/client.ts frontend/src/api/hooks.ts frontend/src/components/Layout.tsx frontend/src/components/Sidebar.tsx frontend/src/App.tsx frontend/src/pages/Dashboard.tsx frontend/src/pages/Settings.tsx 1. Creare frontend/src/types.ts con i tipi TypeScript che rispecchiano gli schemas Pydantic del backend: - CalendarSlot, CalendarRequest, CalendarResponse - SlideContent, GeneratedPost, PostResult, GenerateResponse - JobStatus (job_id: string, status: "running" | "completed" | "failed", total: number, completed: number, current_post: number, results: PostResult[]) - Settings (api_key, llm_model, nicchie_attive, lingua, frequenza_post, brand_name, tono) - SettingsStatus (api_key_configured: boolean, llm_model: string)
2. Aggiornare frontend/src/api/client.ts (gia' creato in Plan 01):
   - Aggiungere metodi specifici: apiGet<T>, apiPost<T>, apiPut<T>
   - Gestione download file: apiDownload(endpoint) -> Blob

3. Creare frontend/src/api/hooks.ts con TanStack Query hooks:
   - useSettings(): useQuery per GET /api/settings
   - useSettingsStatus(): useQuery per GET /api/settings/status
   - useUpdateSettings(): useMutation per PUT /api/settings
   - useGenerateCalendar(): useMutation per POST /api/generate/bulk — ritorna {job_id} (async, NON GenerateResponse)
   - useGenerateSingle(): useMutation per POST /api/generate/single
   - useJobStatus(jobId): useQuery per GET /api/generate/job/{jobId}/status con refetchInterval condizionale (2000ms quando running, disabilitato quando completed/failed)
   - useJobResults(jobId): useQuery per GET /api/generate/job/{jobId}
   - useDownloadCsv(): funzione che chiama GET /api/export/{jobId}/csv e triggera download browser (CSV originale)
   - useDownloadEditedCsv(): funzione che chiama POST /api/export/{jobId}/csv con results modificati e triggera download browser (CSV con edits)
   - useFormats(): useQuery per GET /api/calendar/formats

4. Creare frontend/src/components/Layout.tsx:
   - Layout wrapper con Sidebar a sinistra e contenuto a destra
   - Responsive: sidebar collassabile su mobile
   - Tailwind CSS per styling

5. Creare frontend/src/components/Sidebar.tsx:
   - Logo/titolo "PostGenerator" in alto
   - Navigazione con link: Dashboard, Genera Calendario, Genera Singolo Post, Impostazioni
   - Usa react-router-dom NavLink con activeClassName
   - Icone da lucide-react

6. Aggiornare frontend/src/App.tsx:
   - BrowserRouter con basename="/postgenerator"
   - QueryClientProvider con QueryClient
   - Layout wrapping
   - Routes: / -> Dashboard, /genera -> GenerateCalendar, /genera-singolo -> GenerateSingle, /risultati/:jobId -> OutputReview, /impostazioni -> Settings

7. Creare frontend/src/pages/Dashboard.tsx:
   - Card di benvenuto con nome progetto e descrizione breve
   - Quick actions: "Genera Calendario" (link), "Impostazioni" (link)
   - Se API key non configurata: banner prominente "Configura la tua API key Claude nelle Impostazioni"
   - Se ci sono job recenti (check /api/generate/job/latest): mostra ultimo job con link a risultati
   - Usa useSettingsStatus() per verificare API key

8. Creare frontend/src/pages/Settings.tsx:
   - Form con campi:
     - API Key Claude (input password con toggle visibilita', mostra solo ultimi 4 char se gia' configurata)
     - Modello LLM (select: claude-sonnet-4-5, claude-haiku-3-5)
     - Brand Name (input text, opzionale)
     - Tono di voce (input text, default "diretto e concreto")
     - Nicchie attive (lista checkbox con le nicchie default + possibilita' di aggiungerne)
     - Frequenza post settimanale (number input, 1-7, default 3)
   - Pulsante Salva con feedback (successo/errore)
   - Usa useSettings() e useUpdateSettings()

NOTA DESIGN: Claude ha discrezione sul design UI. Scegliere uno stile pulito e professionale, NON il solito template generico con gradienti viola. Colori suggeriti: palette terrosa o industriale adatta a B2B.
- frontend/src/App.tsx ha BrowserRouter con basename="/postgenerator" - frontend/src/api/hooks.ts ha almeno 10 hooks/functions (settings, settingsStatus, updateSettings, generateCalendar, generateSingle, jobStatus, jobResults, downloadCsv, downloadEditedCsv, formats) - frontend/src/types.ts ha CalendarSlot, GeneratedPost, PostResult, JobStatus, Settings - Sidebar ha 4 link di navigazione - Settings ha campo API key con tipo password - Dashboard mostra banner se API key non configurata - npm run build completa senza errori TypeScript Layout con sidebar, routing completo, API hooks TanStack Query per tutti gli endpoint, tipi TypeScript, Dashboard con stato API key, Settings form funzionale. Task 2a: Badge components e PostCard frontend/src/components/BadgePN.tsx frontend/src/components/BadgeSchwartz.tsx frontend/src/components/PostCard.tsx 1. Creare frontend/src/components/BadgePN.tsx: - Badge colorato per tipo Persuasion Nurturing - Colori distinti per ogni tipo: valore (blu), storytelling (viola), news (verde), riprova_sociale (arancione), coinvolgimento (giallo), promozione (rosso) - Mostra label (es. "Valore", "Storytelling")
2. Creare frontend/src/components/BadgeSchwartz.tsx:
   - Badge per livello Schwartz (L1-L5)
   - Colori progressivi (L5 chiaro -> L1 scuro) per indicare vicinanza all'acquisto
   - Tooltip con descrizione livello

3. Creare frontend/src/components/PostCard.tsx:
   - Card per singolo post nel risultato
   - Mostra: indice, tipo PN (badge), livello Schwartz (badge), formato narrativo, nicchia, data
   - Se status=success: mostra cover_title come titolo card, click per espandere
   - Se status=failed: card con sfondo rosso chiaro, icona errore, messaggio errore, pulsante "Riprova"
   - Pulsante Riprova chiama useGenerateSingle() per rigenerare quel slot
   - Click su card success -> espande per mostrare SlideViewer (SlideViewer placeholder prop per ora)
- BadgePN.tsx ha 6 colori distinti per i tipi PN - BadgeSchwartz.tsx ha 5 livelli con tooltip - PostCard.tsx ha stati distinti per success e failed, con pulsante Riprova - npm run build completa senza errori TypeScript Badge PN e Schwartz con colori distinti. PostCard con stati success/failed, badge, e placeholder per SlideViewer expansion. Task 2b: SlideViewer con inline edit e ProgressIndicator con polling frontend/src/components/SlideViewer.tsx frontend/src/components/ProgressIndicator.tsx frontend/src/api/hooks.ts 1. Creare frontend/src/components/SlideViewer.tsx: - Visualizzazione slide-by-slide con navigazione frecce laterali (stile Instagram stories) - Mostra: slide corrente N/8, headline, body, image_keyword - Freccia sinistra/destra per navigare - Ogni campo testo e' EDITABILE inline: click per trasformare in input/textarea - Le modifiche aggiornano lo stato locale (PostResult) tramite callback onEdit prop - Sotto le slide: caption Instagram in textarea editabile - Keyboard navigation: frecce sinistra/destra per cambiare slide
2. Creare frontend/src/components/ProgressIndicator.tsx:
   - Riceve job_id come prop
   - USA POLLING: chiama GET /api/generate/job/{job_id}/status ogni 2 secondi via useJobStatus(jobId) hook
   - Mostra progresso generazione bulk: "Post {completed}/{total} in generazione..."
   - Barra di progresso visuale basata su completed/total dal polling response
   - Lista dei post con stato: pending (grigio), processing (spinner — il current_post), success (verde check), failed (rosso X)
   - Animazione per il post attualmente in generazione (current_post dal polling)
   - Quando status diventa "completed": smette di pollare, chiama callback onComplete(jobId)

3. Aggiornare frontend/src/api/hooks.ts:
   - Aggiungere useJobStatus(jobId): useQuery per GET /api/generate/job/{jobId}/status con refetchInterval di 2000ms quando status e' "running", disabilitato quando "completed" o "failed"
   - Aggiungere useDownloadEditedCsv(): funzione che chiama POST /api/export/{jobId}/csv con i results modificati e triggera download browser
   - Aggiornare useGenerateCalendar(): mutation che chiama POST /api/generate/bulk e ritorna {job_id} (non GenerateResponse, dato che ora e' async)
- SlideViewer.tsx ha navigazione frecce e campi editabili inline con callback onEdit - ProgressIndicator.tsx usa useJobStatus() hook con polling ogni 2 secondi - ProgressIndicator.tsx smette di pollare quando status != "running" - hooks.ts ha useJobStatus con refetchInterval condizionale - hooks.ts ha useDownloadEditedCsv che chiama POST endpoint - npm run build completa senza errori TypeScript SlideViewer con navigazione slide e edit inline via callback. ProgressIndicator usa polling real-time su /status endpoint per mostrare progresso per-item. API hooks aggiornati per async generation pattern (job_id + polling + POST CSV con edits). Task 2c: Pagine GenerateCalendar, OutputReview, GenerateSingle frontend/src/pages/GenerateCalendar.tsx frontend/src/pages/GenerateSingle.tsx frontend/src/pages/OutputReview.tsx 1. Creare frontend/src/pages/GenerateCalendar.tsx: - Form con campi: - Obiettivo campagna (textarea, obbligatorio, placeholder "Es: Aumentare awareness sull'AI per PMI italiane") - Settimane (number, default 2, range 1-4) - Brand name (input, opzionale — prende default da Settings) - Tono di voce (input, opzionale — prende default da Settings) - Nicchie (multi-select o checkbox, prende default da Settings) - Pulsante "Genera Calendario" con stati: - Se API key non configurata: disabilitato, messaggio "Configura API key nelle Impostazioni" - Se configurata: abilitato, al click chiama useGenerateCalendar() mutation - FLUSSO ASYNC: al click, mutation ritorna {job_id}. La pagina mostra ProgressIndicator con job_id. ProgressIndicator polla /status e quando status="completed" chiama onComplete che fa redirect a OutputReview con jobId. - Usa useSettingsStatus() per controllare API key
2. Creare frontend/src/pages/OutputReview.tsx:
   - Riceve jobId da route params
   - Carica risultati con useJobResults(jobId)
   - Header con: nome campagna, conteggio successi/falliti, pulsante "Download CSV"
   - Griglia di PostCard (3 colonne desktop, 2 tablet, 1 mobile)
   - PostCard espandibile con SlideViewer
   - GESTIONE STATO EDIT INLINE:
     - Mantiene stato locale dei post (copia di GenerateResponse)
     - Quando utente edita una slide in SlideViewer, aggiorna lo stato locale via callback
     - Il pulsante "Download CSV" invia lo stato locale modificato al backend via POST /api/export/{jobId}/csv (useDownloadEditedCsv hook)
     - Questo garantisce che il CSV rifletta le modifiche inline dell'utente
   - Se ci sono post falliti: mostra nota "Il CSV contiene solo i N post generati con successo"
   - Se tutti i post sono falliti: messaggio "Nessun post generato con successo. Riprova."

3. Creare frontend/src/pages/GenerateSingle.tsx:
   - Form per generare un singolo post manualmente:
     - Topic (textarea, obbligatorio)
     - Tipo contenuto (select: valore, storytelling, news, riprova_sociale, coinvolgimento, promozione)
     - Livello Schwartz (select: L1-L5)
     - Nicchia (select dalla lista)
     - Formato narrativo (select, auto-compilato in base a tipo+livello ma override possibile)
   - Al submit: chiama useGenerateSingle()
   - Mostra risultato con SlideViewer direttamente nella pagina
   - Pulsante download CSV per singolo post
- GenerateCalendar.tsx ha form con obiettivo e settimane, pulsante disabilitato senza API key - GenerateCalendar.tsx mostra ProgressIndicator con job_id dopo submit (non attende risposta sincrona) - OutputReview.tsx mostra griglia di PostCard con badge PN e Schwartz - OutputReview.tsx usa useDownloadEditedCsv per inviare edits al backend prima del download - GenerateSingle.tsx ha form con select per tipo, livello, nicchia, formato - npm run build completa senza errori TypeScript Pagine complete: GenerateCalendar con form + ProgressIndicator async polling. OutputReview con griglia card, SlideViewer expansion, edit inline che si riflettono nel CSV via POST endpoint. GenerateSingle con form e anteprima. Web UI completa con tutte le pagine: Dashboard, Genera Calendario, Output Review, Genera Singolo Post, Impostazioni. Inclusi progress indicator con polling real-time, griglia card con badge, navigazione slide, edit inline con CSV export tramite POST. 1. Verificare che `cd frontend && npm run build` completa senza errori 2. Verificare che la struttura delle pagine e componenti sia coerente 3. Controllare che il routing in App.tsx abbia tutte le 5 route 4. Verificare che l'API client usi /postgenerator/api come base 5. Opzionale: se deployato, navigare su https://lab.mlhub.it/postgenerator/ e verificare che la UI si carichi Digita "approved" se la UI e' accettabile, oppure descrivi i problemi da correggere 1. `cd frontend && npm run build` produce dist/ senza errori 2. App.tsx ha 5 route definite con BrowserRouter basename="/postgenerator" 3. Tutti i componenti importano tipi da types.ts (non definiscono tipi inline) 4. API hooks usano /postgenerator/api come base URL 5. PostCard ha due varianti visive: success (espandibile) e failed (errore + riprova) 6. SlideViewer supporta edit inline e navigazione frecce, con callback onEdit 7. GenerateCalendar disabilita pulsante se API key non configurata 8. GenerateCalendar mostra ProgressIndicator con job_id (non attende risposta sincrona) 9. ProgressIndicator polla /api/generate/job/{job_id}/status ogni 2s e smette quando completato 10. OutputReview usa useDownloadEditedCsv (POST) per scaricare CSV con modifiche inline

<success_criteria>

  • Dashboard mostra stato API key e quick actions
  • Settings permette configurazione API key, modello, nicchie, frequenza
  • Genera Calendario ha form, async submit con job_id, ProgressIndicator con polling real-time
  • ProgressIndicator polla /status e mostra progresso per-item (pending/processing/success/failed)
  • Output Review mostra griglia card con badge, slide viewer con edit inline
  • Download CSV invia edits al backend via POST e riceve CSV aggiornato
  • Post falliti mostrano errore e pulsante Riprova
  • Genera Singolo Post ha form completo con anteprima risultato
  • Build frontend completa senza errori </success_criteria>
After completion, create `.planning/phases/01-core-generation-pipeline/01-04-SUMMARY.md`