Files
Michele d320bf04f5 docs(04-01): complete Unsplash image resolution plan
Tasks completed: 2/2
- Task 1: UnsplashService + Settings unsplash_api_key
- Task 2: Integrazione pipeline + CSV con risoluzione Unsplash

SUMMARY: .planning/phases/04-enrichment/04-01-SUMMARY.md
2026-03-09 08:12:12 +01:00

6.5 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established duration completed
04-enrichment 01 api
unsplash
httpx
image-resolution
cache
csv
settings
phase provides
01-core-generation-pipeline CSVBuilder con colonne _image_keyword, Settings schema, GenerationPipeline con JobStatus
phase provides
02-prompt-control-output-review Export router con download CSV con edits
UnsplashService con search, cache disco, traduzione IT->EN, retry, rate limit awareness
Campo unsplash_api_key in Settings schema e router (mascherato, None-preserving)
CSVBuilder con image_url_map opzionale per risoluzione keyword -> URL Unsplash
GenerationPipeline integra UnsplashService dopo batch LLM e salva image_url_map nel job JSON
Export router riutilizza image_url_map dal job originale per CSV con edits
04-enrichment
added patterns
httpx (async HTTP client per Unsplash API)
Fallback trasparente
keyword non risolvibili restano testuali senza bloccare l'export
Cache in-memory + disco con persistenza tra riavvii (unsplash_cache.json)
Risoluzione batch post-LLM
Unsplash chiamato UNA SOLA VOLTA dopo il batch completo
image_url_map salvato nel job JSON per riuso in export con edits (no re-chiamata Unsplash)
None-preserving merge per nuovi campi API key (stesso pattern di api_key esistente)
created modified
backend/services/unsplash_service.py
backend/schemas/settings.py
backend/routers/settings.py
backend/services/csv_builder.py
backend/services/generation_pipeline.py
backend/routers/export.py
Risoluzione Unsplash avviene UNA SOLA VOLTA dopo il batch LLM, non ad ogni download CSV
image_url_map salvato nel job JSON: riusato da export con edits senza re-chiamare Unsplash
generate_single NON risolve Unsplash: velocita' e riuso map del job originale
Dizionario statico IT->EN con ~30 keyword B2B per traduzione (no API translation)
Fallback trasparente: keyword non risolte restano testuali, nessun errore bloccante
Rate limit: se X-Ratelimit-Remaining < 5, stop batch corrente con keyword restanti non risolte
No retry su 401/403 (API key invalida), 1 retry su errori di rete
UnsplashService chiuso con close() nel finally block dopo ogni risoluzione batch
_resolve_image() come metodo privato CSVBuilder per separare logica di risoluzione
Optional[dict[str, str]] come tipo per image_url_map in tutto il sistema
5min 2026-03-09

Phase 4 Plan 01: Unsplash Integration Summary

UnsplashService con cache disco e traduzione IT->EN integrato nella pipeline: keyword immagine CSV diventano URL Unsplash reali (~1080px landscape) quando API key configurata, con fallback trasparente a keyword testuali

Performance

  • Duration: 5 min
  • Started: 2026-03-09T07:05:03Z
  • Completed: 2026-03-09T07:10:25Z
  • Tasks: 2
  • Files modified: 6

Accomplishments

  • UnsplashService con search async, cache in-memory + disco, dizionario traduzione IT->EN (~30 keyword B2B), retry su errori rete, rate limit awareness via header
  • Settings schema e router aggiornati con unsplash_api_key (mascherata, None-preserving merge nel PUT)
  • CSVBuilder aggiornato con image_url_map opzionale: _resolve_image() applica URL Unsplash su cover, slides s2-s7 e CTA, con fallback a keyword testuale
  • GenerationPipeline integra _resolve_unsplash_keywords() dopo il batch LLM: carica settings, crea UnsplashService, risolve keyword uniche, salva image_url_map nel job JSON
  • Export router recupera image_url_map dal job JSON e la passa a build_csv_content() per CSV con edits

Task Commits

  1. Task 1: UnsplashService + Settings unsplash_api_key - afba4c5 (feat)
  2. Task 2: Integrazione pipeline + CSV con risoluzione Unsplash - 9e7205e (feat)

Files Created/Modified

  • backend/services/unsplash_service.py - UnsplashService con search, cache, traduzione IT->EN, retry, rate limit
  • backend/schemas/settings.py - Campo unsplash_api_key Optional[str] aggiunto a Settings
  • backend/routers/settings.py - unsplash_api_key_masked in SettingsResponse, unsplash_api_key_configured in SettingsStatusResponse, merge None-preserving nel PUT
  • backend/services/csv_builder.py - image_url_map opzionale in build_csv/build_csv_content/_build_rows, metodo _resolve_image()
  • backend/services/generation_pipeline.py - image_url_map in JobStatus (dataclass + serializzazione JSON), metodo _resolve_unsplash_keywords(), import UnsplashService
  • backend/routers/export.py - Recupera image_url_map dal job JSON e passa a build_csv_content()

Decisions Made

  • Risoluzione UNA SOLA VOLTA: Unsplash chiamato dopo il batch LLM completo, image_url_map salvata nel job JSON per riuso in export con edits senza re-chiamata API
  • generate_single non risolve Unsplash: La rigenerazione singola e' veloce e deve restare tale; le keyword nuove useranno il fallback testuale nel CSV
  • Dizionario statico IT->EN: ~30 keyword B2B comuni tradotte; parole non trovate restano invariate (molte keyword di contesto sono gia' in inglese per Unsplash)
  • Fallback trasparente: keyword non risolvibili (errori, rate limit, nessun risultato) non compaiono nel dizionario; il caller usa la keyword originale senza eccezioni
  • Rate limit awareness: se X-Ratelimit-Remaining < 5, flag self._rate_limited = True e stop per il batch corrente

Deviations from Plan

None - piano eseguito esattamente come scritto.

Issues Encountered

None.

User Setup Required

Per usare l'integrazione Unsplash:

  1. Creare un account sviluppatore su https://unsplash.com/developers
  2. Creare un'applicazione e copiare il Client-ID (Access Key)
  3. Inserire il Client-ID nel campo "Chiave API Unsplash" nelle Impostazioni del backend

Nessuna configurazione del server richiesta — la funzionalita' e' opt-in e il sistema funziona normalmente senza la chiave.

Next Phase Readiness

  • Integrazione Unsplash backend completa e pronta per deploy su VPS
  • Il frontend non e' ancora aggiornato: le Impostazioni non mostrano il campo Unsplash API key (necessario per Phase 4 Plan 02 o aggiornamento standalone)
  • Il CSV con URL Unsplash funziona end-to-end: generazione batch → risoluzione keyword → CSV con URL → export con edits riutilizza gli URL
  • Cache disco (unsplash_cache.json) pronta: il volume Docker nel VPS deve includere DATA_PATH per persistenza

Phase: 04-enrichment Completed: 2026-03-09