--- phase: 01-core-generation-pipeline plan: 01 subsystem: infra tags: [fastapi, react, vite, tailwindcss, docker, uvicorn, react-router, tanstack-query] # Dependency graph requires: [] provides: - FastAPI app skeleton con SPAStaticFiles catch-all e health endpoint - config.py con DATA_PATH, PROMPTS_PATH, OUTPUTS_PATH, CAMPAIGNS_PATH, CONFIG_PATH - React SPA scaffold con Vite, Tailwind v4, react-router, TanStack Query - API client con base URL /postgenerator/api (Pitfall #9 risolto) - Dockerfile multi-stage (node:22-slim -> python:3.12-slim) - docker-compose.yml con proxy_net, named volume, NO porte esposte - root_path impostato SOLO via Uvicorn --root-path (Pitfall #4 risolto) affects: - 01-02 (routers e servizi usano backend/main.py e config.py) - 01-03 (generation pipeline usa config.py paths) - 01-04 (frontend usa api/client.ts come unico punto di accesso API) - tutti i piani futuri che aggiungono routes al backend # Tech tracking tech-stack: added: - fastapi[standard]==0.135.1 - anthropic==0.84.0 - httpx==0.28.1 - python-dotenv==1.2.2 - aiofiles==24.1.0 - react 19 (via Vite react-ts template) - vite 7.3.1 - tailwindcss v4 + @tailwindcss/vite - react-router-dom - @tanstack/react-query - lucide-react patterns: - SPAStaticFiles: StaticFiles subclass con 404->index.html fallback per SPA routing - root_path via Uvicorn --root-path, mai nel costruttore FastAPI() - API_BASE='/postgenerator/api' come costante nel frontend - basename="/postgenerator" in BrowserRouter - Vite proxy dev: /postgenerator/api -> localhost:8000 (strip /postgenerator) - Lifespan context manager per startup directory creation - Mount SPA SEMPRE dopo tutti i router API key-files: created: - backend/__init__.py - backend/main.py - backend/config.py - backend/routers/__init__.py - requirements.txt - .env.example - Dockerfile - docker-compose.yml - frontend/vite.config.ts (modificato da template) - frontend/src/App.tsx (modificato da template) - frontend/src/index.css (modificato da template) - frontend/src/api/client.ts modified: - .gitignore (aggiunto frontend/dist/, backend/data/outputs/) key-decisions: - "root_path SOLO via Uvicorn --root-path nel Dockerfile CMD, mai nel costruttore FastAPI() — evita Pitfall #4 double-path" - "API_BASE='/postgenerator/api' nel frontend client — evita Pitfall #9 subpath API URL" - "SPAStaticFiles montato COME ULTIMA OPERAZIONE dopo tutti i router API" - "fastapi[standard]==0.135.1 (latest), anthropic==0.84.0 (latest) — versioni pinned" - "docker-compose: NO porte esposte, solo proxy_net external — traffic via lab-router nginx" - "Named volume postgenerator-data per persistenza dati cross-container" patterns-established: - "SPAStaticFiles pattern: override get_response con try/except per 404->index.html fallback" - "Lifespan pattern: asynccontextmanager per startup side effects (directory creation)" - "Subpath pattern: base vite + basename router + API_BASE client tutti allineati su /postgenerator/" # Metrics duration: 6min completed: 2026-03-08 --- # Phase 1 Plan 01: Infrastructure Skeleton Summary **FastAPI + React/Vite/Tailwind v4 skeleton deployabile su subpath /postgenerator/, con tutti i pitfall infrastrutturali (#4, #9) risolti nella configurazione base** ## Performance - **Duration:** 6 min - **Started:** 2026-03-08T00:49:36Z - **Completed:** 2026-03-08T00:55:40Z - **Tasks:** 2/2 - **Files modified:** 19 ## Accomplishments - Backend FastAPI skeleton con SPAStaticFiles catch-all, health endpoint GET /api/health, e lifespan per directory creation - config.py con tutte le path constants lette da env (DATA_PATH, PROMPTS_PATH, OUTPUTS_PATH, CAMPAIGNS_PATH, CONFIG_PATH) - React SPA scaffold completo: Vite + Tailwind v4 + react-router + TanStack Query + lucide-react, build pulita a 253.90kB - Docker multi-stage build: node:22-slim per build React, python:3.12-slim per runtime, --root-path /postgenerator solo in CMD - docker-compose.yml con container lab-postgenerator-app, proxy_net external, named volume, NO porte esposte ## Task Commits Ogni task committato atomicamente: 1. **Task 1: Backend FastAPI skeleton + Docker build config** - `50d5708` (feat) 2. **Task 2: React + Vite + Tailwind v4 SPA scaffold con API client** - `62f4b48` (feat) **Plan metadata:** (da aggiungere dopo commit docs) ## Files Created/Modified - `backend/main.py` - FastAPI app con SPAStaticFiles, health endpoint, lifespan - `backend/config.py` - Path constants da env: DATA_PATH, PROMPTS_PATH, OUTPUTS_PATH, CAMPAIGNS_PATH, CONFIG_PATH - `backend/__init__.py` - Package marker (vuoto) - `backend/routers/__init__.py` - Package marker (vuoto) - `requirements.txt` - fastapi[standard]==0.135.1, anthropic==0.84.0, httpx==0.28.1, python-dotenv==1.2.2, aiofiles==24.1.0 - `.env.example` - Template variabili ambiente (ANTHROPIC_API_KEY, LLM_MODEL, DATA_PATH) - `Dockerfile` - Multi-stage: frontend-builder (node:22-slim) + runtime (python:3.12-slim), --root-path in CMD - `docker-compose.yml` - lab-postgenerator-app, proxy_net, postgenerator-data volume - `frontend/vite.config.ts` - base='/postgenerator/', tailwindcss plugin, dev proxy - `frontend/src/api/client.ts` - API_BASE='/postgenerator/api', apiFetch con error handling - `frontend/src/App.tsx` - QueryClientProvider + BrowserRouter basename="/postgenerator" + HomePage - `frontend/src/index.css` - @import "tailwindcss" (Tailwind v4 syntax) - `.gitignore` - Aggiunto frontend/dist/, backend/data/outputs/ ## Decisions Made - root_path impostato SOLO via Uvicorn `--root-path /postgenerator` nel Dockerfile CMD — mai nel costruttore `FastAPI()`. Evita Pitfall #4 (double-path). - API_BASE = '/postgenerator/api' nel frontend client.ts — path assoluto che funziona dietro nginx lab-router. Evita Pitfall #9. - SPAStaticFiles montato come ULTIMA operazione in main.py — garantisce che tutti i router API abbiano precedenza. - fastapi[standard]==0.135.1 (latest al momento), anthropic==0.84.0 (latest) — pinned per riproducibilita' build. - docker-compose senza porte esposte pubblicamente — tutto il traffico transita via proxy_net e lab-router nginx. ## Deviations from Plan Nessuna. Piano eseguito esattamente come scritto. Il piano specificava `python-dotenv==1.2.2` (versione nel plan) e la versione disponibile confermata. Idem per `aiofiles==24.1.0`. ## Issues Encountered Nessuno. ## User Setup Required None — nessun servizio esterno richiede configurazione manuale per questo piano. Per l'esecuzione reale: copiare `.env.example` in `.env` e aggiungere `ANTHROPIC_API_KEY`. ## Next Phase Readiness - Backend skeleton pronto per ricevere router (plan 01-02: FormatSelector, Schemas) - Frontend pronto per ricevere pagine e componenti - Docker build verificato — build produce output corretto - API client testabile: `apiFetch<{status:string}>('/health')` deve restituire `{status:'ok'}` - Blockers aperti da STATE.md: CANVA_FIELDS schema da definire (plan 01-02), token usage da validare (plan 01-03) --- *Phase: 01-core-generation-pipeline* *Completed: 2026-03-08*