--- phase: 01-core-generation-pipeline plan: 01 type: execute wave: 1 depends_on: [] files_modified: - backend/main.py - backend/config.py - backend/__init__.py - backend/routers/__init__.py - frontend/vite.config.ts - frontend/package.json - frontend/tsconfig.json - frontend/tsconfig.app.json - frontend/src/main.tsx - frontend/src/App.tsx - frontend/src/index.css - frontend/src/api/client.ts - frontend/index.html - Dockerfile - docker-compose.yml - requirements.txt - .env.example - .gitignore autonomous: true must_haves: truths: - "FastAPI app starts on port 8000 and responds to GET /api/health with 200" - "React SPA builds with Vite and base path /postgenerator/" - "Docker multi-stage build produces a working container that serves both API and SPA" - "SPA catch-all returns index.html for non-API routes without breaking /api/ routes" artifacts: - path: "backend/main.py" provides: "FastAPI app with SPAStaticFiles catch-all, health endpoint, CORS-free single origin" contains: "SPAStaticFiles" - path: "backend/config.py" provides: "Centralized path constants from env vars (DATA_PATH, PROMPTS_PATH, OUTPUTS_PATH)" contains: "DATA_PATH" - path: "frontend/vite.config.ts" provides: "Vite config with base /postgenerator/, Tailwind v4 plugin, dev proxy to :8000" contains: "base: '/postgenerator/'" - path: "frontend/src/api/client.ts" provides: "API client with base URL /postgenerator/api for production" contains: "/postgenerator/api" - path: "Dockerfile" provides: "Multi-stage build: Node builds React, Python serves everything" contains: "frontend-builder" - path: "docker-compose.yml" provides: "Single service with volume mount for data persistence" contains: "lab-postgenerator-app" - path: "requirements.txt" provides: "Python dependencies pinned" contains: "fastapi" key_links: - from: "frontend/vite.config.ts" to: "backend/main.py" via: "Vite dev proxy /api -> localhost:8000" pattern: "proxy.*api.*8000" - from: "Dockerfile" to: "backend/main.py" via: "CMD uvicorn with --root-path /postgenerator" pattern: "root-path" - from: "backend/main.py" to: "frontend/dist" via: "SPAStaticFiles mount" pattern: "SPAStaticFiles.*static" --- Creare lo scheletro infrastrutturale completo: FastAPI app con SPA catch-all, React + Vite + Tailwind v4 project, Docker multi-stage build, e tutte le configurazioni per il subpath /postgenerator/. Purpose: Stabilire il plumbing funzionante prima di qualsiasi business logic. Verificare che il container Docker serve API e SPA correttamente, evitando i pitfall 4 (root_path double-path) e 9 (React API URL subpath). Output: Container Docker buildabile che serve una pagina React vuota su / e risponde a /api/health, pronto per ricevere routers e servizi nei piani successivi. @C:\Users\miche\.claude/get-shit-done/workflows/execute-plan.md @C:\Users\miche\.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/research/STACK.md @.planning/research/ARCHITECTURE.md @.planning/research/PITFALLS.md @.planning/phases/01-core-generation-pipeline/01-CONTEXT.md Task 1: Backend FastAPI skeleton + config + Docker build backend/__init__.py backend/main.py backend/config.py backend/routers/__init__.py requirements.txt .env.example .gitignore Dockerfile docker-compose.yml 1. Aggiornare .gitignore con: __pycache__/, .venv/, *.pyc, node_modules/, frontend/dist/, .env, backend/data/outputs/ 2. Creare backend/__init__.py (vuoto). 3. Creare backend/config.py: - DATA_PATH = Path(os.getenv("DATA_PATH", "./data")) - PROMPTS_PATH = DATA_PATH / "prompts" - OUTPUTS_PATH = DATA_PATH / "outputs" - CAMPAIGNS_PATH = DATA_PATH / "campaigns" - CONFIG_PATH = DATA_PATH / "config" - Funzione get_settings() che legge ANTHROPIC_API_KEY e LLM_MODEL da env 4. Creare backend/routers/__init__.py (vuoto). 5. Creare backend/main.py: - FastAPI() senza root_path nel costruttore (CRITICO: root_path solo via Uvicorn --root-path) - Classe SPAStaticFiles che estende StaticFiles con fallback a index.html - Health endpoint: GET /api/health -> {"status": "ok"} - Mount SPAStaticFiles su "/" come ULTIMA operazione (dopo tutti i router) - Startup event che crea le directory data/ se non esistono (prompts, outputs, campaigns, config) 6. Creare requirements.txt: - fastapi[standard]==0.135.1 - anthropic==0.84.0 - httpx==0.28.1 - python-dotenv==1.2.2 - aiofiles 7. Creare .env.example: - ANTHROPIC_API_KEY=your-key-here - LLM_MODEL=claude-sonnet-4-5 - DATA_PATH=/app/data 8. Creare Dockerfile multi-stage: - Stage 1 (frontend-builder): FROM node:22-slim, WORKDIR /app/frontend, COPY package*.json, npm ci, COPY tutto, npm run build - Stage 2 (runtime): FROM python:3.12-slim, WORKDIR /app, COPY requirements.txt, pip install --no-cache-dir, COPY backend/ ./backend/, COPY --from=frontend-builder /app/frontend/dist ./static, CMD ["uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "8000", "--root-path", "/postgenerator"] 9. Creare docker-compose.yml: - service "app" con container_name "lab-postgenerator-app" - build context "." con dockerfile "Dockerfile" - env_file: .env - volumes: postgenerator-data:/app/data (named volume per persistenza) - networks: proxy_net (external: true) - deploy.resources.limits: memory 1024M, cpus '1.0' (Next.js-level per build React) - NO porte esposte pubblicamente - File backend/main.py contiene SPAStaticFiles e NON contiene root_path nel costruttore FastAPI() - File Dockerfile contiene --root-path /postgenerator nel CMD - File docker-compose.yml contiene proxy_net e container_name lab-postgenerator-app - requirements.txt contiene fastapi[standard]==0.135.1 e anthropic==0.84.0 Backend skeleton e Docker config pronti. FastAPI app definita senza root_path nel costruttore. Dockerfile multi-stage con --root-path solo in Uvicorn CMD. docker-compose.yml con volume per dati e rete proxy_net. Task 2: React + Vite + Tailwind v4 SPA scaffold con API client frontend/package.json frontend/vite.config.ts frontend/tsconfig.json frontend/tsconfig.app.json frontend/index.html frontend/src/main.tsx frontend/src/App.tsx frontend/src/index.css frontend/src/api/client.ts 1. Creare il progetto React + TypeScript con Vite: - PREREQUISITO: la directory frontend/ NON deve esistere. Se esiste, rimuoverla prima: rm -rf frontend - cd al progetto, eseguire: npm create vite@latest frontend -- --template react-ts --yes - Il flag --yes evita prompt interattivi che bloccherebbero l'esecuzione autonoma - Questo genera la struttura base 2. Installare dipendenze frontend: - cd frontend - npm install tailwindcss @tailwindcss/vite - npm install react-router-dom @tanstack/react-query - npm install lucide-react 3. Configurare vite.config.ts: - import react from '@vitejs/plugin-react' - import tailwindcss from '@tailwindcss/vite' - plugins: [react(), tailwindcss()] - base: '/postgenerator/' - server.proxy: { '/postgenerator/api': { target: 'http://localhost:8000', changeOrigin: true, rewrite: path => path.replace('/postgenerator', '') } } 4. Configurare frontend/src/index.css: - Rimuovere contenuto default Vite - Aggiungere: @import "tailwindcss"; 5. Creare frontend/src/api/client.ts: - const API_BASE = '/postgenerator/api' - Funzione generica apiFetch(endpoint: string, options?: RequestInit): Promise - Gestione errori con throw su status non-ok - Export API_BASE e apiFetch 6. Aggiornare frontend/src/App.tsx: - Import BrowserRouter con basename="/postgenerator" - Import QueryClientProvider da @tanstack/react-query - Struttura base con Routes placeholder - Pagina placeholder con titolo "PostGenerator" e messaggio "Setup completo" 7. Aggiornare frontend/src/main.tsx: - StrictMode + render App 8. Aggiornare frontend/index.html: - title: "PostGenerator" - Rimuovere favicon Vite default ATTENZIONE Pitfall 9: L'API client DEVE usare '/postgenerator/api' come base, NON '/api'. Questo e' l'absolute path che funziona dietro nginx lab-router. - cd frontend && npm run build completa senza errori - vite.config.ts contiene base: '/postgenerator/' - frontend/src/api/client.ts contiene '/postgenerator/api' - frontend/src/App.tsx contiene basename="/postgenerator" - index.css contiene @import "tailwindcss" React SPA scaffold completo con Tailwind v4, react-router con basename corretto, TanStack Query configurato, API client con path /postgenerator/api. Build Vite produce output in frontend/dist/ pronto per essere copiato nel container Docker. 1. `cd frontend && npm run build` produce output in dist/ senza errori 2. FastAPI main.py: SPAStaticFiles registrato DOPO health endpoint 3. Dockerfile: --root-path /postgenerator nel CMD, NON nel costruttore FastAPI() 4. Nessun hardcoded `/api/` senza prefisso /postgenerator/ nel frontend 5. docker-compose.yml: NO porte esposte, usa proxy_net - Backend FastAPI app definita con health endpoint e SPA catch-all - Frontend React builds con base path /postgenerator/ - Docker multi-stage build configurato - API client usa path corretto /postgenerator/api - Tutti i pitfall infrastrutturali (4, 9) indirizzati nella configurazione After completion, create `.planning/phases/01-core-generation-pipeline/01-01-SUMMARY.md`