Files
postgenerator/.planning/phases/04-enrichment/04-02-PLAN.md
Michele 6078c75c22 docs(04): create phase plan
Phase 04: Enrichment
- 2 plan(s) in 2 wave(s)
- Wave 1: backend UnsplashService + Settings + pipeline/CSV integration
- Wave 2: frontend Settings UI + PostCard thumbnail + OutputReview hint
- Ready for execution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 01:52:13 +01:00

225 lines
9.7 KiB
Markdown

---
phase: 04-enrichment
plan: 02
type: execute
wave: 2
depends_on: ["04-01"]
files_modified:
- frontend/src/types.ts
- frontend/src/pages/Settings.tsx
- frontend/src/pages/OutputReview.tsx
- frontend/src/components/PostCard.tsx
- frontend/src/api/hooks.ts
autonomous: true
must_haves:
truths:
- "La pagina Settings mostra un campo per l'API key Unsplash nella sezione appropriata"
- "Se Unsplash non e' configurato, OutputReview mostra un avviso discreto che suggerisce di configurarlo"
- "Se Unsplash e' configurato e le keyword sono state risolte in URL, la PostCard mostra un thumbnail della cover image"
- "Il thumbnail e' visibile solo per post con URL immagine reali (non per keyword testuali)"
- "SettingsStatus include unsplash_api_key_configured per controllo frontend"
artifacts:
- path: "frontend/src/types.ts"
provides: "Tipo Settings con unsplash_api_key, SettingsStatus con unsplash_api_key_configured"
contains: "unsplash_api_key"
- path: "frontend/src/pages/Settings.tsx"
provides: "Campo input per Unsplash API key"
contains: "unsplash"
- path: "frontend/src/components/PostCard.tsx"
provides: "Thumbnail cover image quando URL disponibile"
contains: "img"
key_links:
- from: "frontend/src/pages/Settings.tsx"
to: "Settings type"
via: "Campo unsplash_api_key nel form state"
pattern: "unsplash_api_key"
- from: "frontend/src/pages/OutputReview.tsx"
to: "useSettingsStatus"
via: "Controlla unsplash_api_key_configured per avviso"
pattern: "unsplash"
- from: "frontend/src/components/PostCard.tsx"
to: "cover_image_keyword"
via: "Controlla se inizia con http per decidere se mostrare thumbnail"
pattern: "http|img|thumbnail"
---
<objective>
Aggiornare il frontend per supportare la configurazione Unsplash e mostrare thumbnail delle immagini nell'anteprima.
Purpose: L'utente puo' configurare la propria API key Unsplash dalla pagina Impostazioni. Nell'Output Review, se le immagini sono state risolte in URL reali, ogni PostCard mostra un piccolo thumbnail della cover image. Se Unsplash non e' configurato, un avviso discreto suggerisce di configurarlo per ottenere immagini reali nel CSV.
Output: Frontend aggiornato con campo Unsplash in Settings, thumbnail preview in PostCard, hint discreto in OutputReview.
</objective>
<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>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/04-enrichment/04-CONTEXT.md
@.planning/phases/04-enrichment/04-01-SUMMARY.md
# File da modificare — leggi PRIMA di implementare
@frontend/src/types.ts
@frontend/src/pages/Settings.tsx
@frontend/src/pages/OutputReview.tsx
@frontend/src/components/PostCard.tsx
@frontend/src/api/hooks.ts
</context>
<tasks>
<task type="auto">
<name>Task 1: Types + Settings page + hooks per Unsplash</name>
<files>
frontend/src/types.ts
frontend/src/pages/Settings.tsx
frontend/src/api/hooks.ts
</files>
<action>
**1. Aggiorna `frontend/src/types.ts`:**
Aggiungi a `Settings`:
```typescript
unsplash_api_key?: string | null
```
Aggiungi a `SettingsStatus`:
```typescript
unsplash_api_key_configured: boolean
```
**2. Aggiorna `frontend/src/pages/Settings.tsx`:**
Aggiungi una nuova sezione "Immagini" DOPO la sezione "Anthropic" e PRIMA di "Brand". La sezione contiene:
- Titolo sezione: `<h2>` con stile `text-xs font-semibold text-stone-500 uppercase tracking-wider` e testo "Immagini"
- Campo API Key Unsplash: input password con toggle visibilita' (stessa struttura dell'API Key Claude). Placeholder: se gia' configurata mostra `"••••••••••••••••"`, se non configurata mostra `"Incolla la tua Access Key Unsplash"`.
- Testo helper sotto: se configurata `"API key Unsplash configurata. Le keyword verranno risolte in URL immagini reali nel CSV."`, se non configurata `"Opzionale. Registrati su unsplash.com/developers per ottenere una Access Key gratuita (50 req/h)."`.
Aggiorna `useEffect` di inizializzazione form per includere `unsplash_api_key: ''` (come per api_key, non pre-popolare).
Nel `handleSubmit`, applica la stessa logica di api_key: se `unsplash_api_key` e' vuota, non inviarla (evita sovrascrittura). Reset dopo salvataggio.
Gestione stato visibilita': aggiungi `showUnsplashKey` state separato (non condividere con `showApiKey`).
**3. Hooks — nessuna modifica necessaria:**
`useSettings()`, `useUpdateSettings()` e `useSettingsStatus()` gia' funzionano genericamente con i tipi Settings/SettingsStatus. L'aggiunta di nuovi campi ai tipi TypeScript e' sufficiente.
</action>
<verify>
- `cd frontend && npx tsc --noEmit` compila senza errori TypeScript
- Verifica visivamente che Settings.tsx abbia la sezione Immagini con input Unsplash
</verify>
<done>
Types aggiornati con unsplash_api_key. Settings page ha sezione "Immagini" con campo API Key Unsplash, toggle visibilita', helper text condizionale, e logica di submit identica a API Key Claude.
</done>
</task>
<task type="auto">
<name>Task 2: Thumbnail PostCard + hint OutputReview</name>
<files>
frontend/src/components/PostCard.tsx
frontend/src/pages/OutputReview.tsx
</files>
<action>
**1. Aggiorna `frontend/src/components/PostCard.tsx`:**
Nel rendering della sezione SUCCESS, DOPO il cover_title e PRIMA dei metadati secondari (formato/nicchia/data), aggiungi un thumbnail condizionale.
Logica di rilevamento URL: `const coverIsUrl = post.cover_image_keyword.startsWith('http')`. Se `coverIsUrl` e' true, mostra un thumbnail `<img>`:
```tsx
{coverIsUrl && (
<div className="mt-2 mb-1">
<img
src={post.cover_image_keyword}
alt="Cover preview"
loading="lazy"
className="w-20 h-14 object-cover rounded-md border border-stone-700"
onError={(e) => { (e.target as HTMLImageElement).style.display = 'none' }}
/>
</div>
)}
```
Il thumbnail e':
- Piccolo: `w-20 h-14` (80x56px) — sufficiente per anteprima senza appesantire la pagina
- `object-cover` per riempire senza distorsione
- `loading="lazy"` per performance (13 immagini nella pagina)
- `onError` nasconde l'immagine se il caricamento fallisce (URL scaduto o invalido)
- `rounded-md border border-stone-700` per coerenza con il design stone/amber
**2. Aggiorna `frontend/src/pages/OutputReview.tsx`:**
Aggiungi un hint discreto DOPO il box "Info edit inline" e PRIMA della griglia post. L'hint appare SOLO quando Unsplash NON e' configurato.
Usa `useSettingsStatus()` per controllare `unsplash_api_key_configured`:
```tsx
import { useSettingsStatus } from '../api/hooks'
// Nel componente, dopo le altre hook calls
const { data: settingsStatus } = useSettingsStatus()
// Nel JSX, DOPO il box "Info edit inline"
{settingsStatus && !settingsStatus.unsplash_api_key_configured && (
<div className="px-4 py-2 rounded-lg bg-stone-800/30 border border-stone-700/50 text-xs text-stone-600 flex items-center gap-2">
<span>Le colonne immagine contengono keyword testuali.</span>
<a
href="#"
onClick={(e) => { e.preventDefault(); navigate('/settings') }}
className="text-amber-500/70 hover:text-amber-400 underline underline-offset-2"
>
Configura Unsplash
</a>
<span>per URL immagini reali.</span>
</div>
)}
```
Importa `useNavigate` da `react-router-dom` (verificare se gia' importato) e `useSettingsStatus` da hooks.
Stile dell'hint: volutamente discreto (`text-stone-600`, bordo sottile) — non intrusivo, non un warning aggressivo. Scompare quando Unsplash e' configurato.
**NOTA IMPORTANTE**: Se il progetto usa `<Link>` di react-router invece di `navigate()`, usa `<Link to="/settings">` per coerenza. Verificare il pattern usato nel codebase.
</action>
<verify>
- `cd frontend && npx tsc --noEmit` compila senza errori TypeScript
- Verifica che PostCard mostri thumbnail quando cover_image_keyword e' un URL
- Verifica che OutputReview mostri hint quando Unsplash non e' configurato
</verify>
<done>
PostCard mostra thumbnail 80x56px della cover image quando la keyword e' un URL Unsplash. OutputReview mostra hint discreto con link a Settings quando Unsplash non e' configurato. L'hint scompare quando l'API key e' presente.
</done>
</task>
</tasks>
<verification>
Verifica complessiva frontend Phase 4 Plan 02:
1. **TypeScript build**: `cd frontend && npx tsc --noEmit` — zero errori
2. **Settings Unsplash**: La sezione "Immagini" appare nella pagina Settings con campo API key, toggle visibilita', helper text
3. **PostCard thumbnail**: Se cover_image_keyword inizia con "http", il thumbnail e' visibile; se e' una keyword testuale, nessun thumbnail
4. **OutputReview hint**: Senza Unsplash configurato, l'hint suggerisce di configurarlo; con Unsplash configurato, l'hint non appare
5. **Nessuna regressione**: Tutte le funzionalita' esistenti (edit inline, rigenerazione, download CSV, badge PN/Schwartz) funzionano come prima
</verification>
<success_criteria>
- Types TypeScript aggiornati con unsplash_api_key in Settings e unsplash_api_key_configured in SettingsStatus
- Settings page ha sezione "Immagini" funzionante con campo Unsplash API key
- PostCard mostra thumbnail condizionale per URL immagini
- OutputReview mostra hint discreto quando Unsplash non configurato
- TypeScript compila senza errori
- Nessuna regressione sulle funzionalita' esistenti
</success_criteria>
<output>
After completion, create `.planning/phases/04-enrichment/04-02-SUMMARY.md`
</output>