docs(01): create phase plan
Phase 01: Core Generation Pipeline - 4 plan(s) in 3 wave(s) - Wave 1: 01-01 (infra) + 01-02 (core services) parallel - Wave 2: 01-03 (LLM pipeline + API routers) - Wave 3: 01-04 (Web UI) with human-verify checkpoint - Ready for execution
This commit is contained in:
255
.planning/phases/01-core-generation-pipeline/01-01-PLAN.md
Normal file
255
.planning/phases/01-core-generation-pipeline/01-01-PLAN.md
Normal file
@@ -0,0 +1,255 @@
|
||||
---
|
||||
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"
|
||||
---
|
||||
|
||||
<objective>
|
||||
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.
|
||||
</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/research/STACK.md
|
||||
@.planning/research/ARCHITECTURE.md
|
||||
@.planning/research/PITFALLS.md
|
||||
@.planning/phases/01-core-generation-pipeline/01-CONTEXT.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Backend FastAPI skeleton + config + Docker build</name>
|
||||
<files>
|
||||
backend/__init__.py
|
||||
backend/main.py
|
||||
backend/config.py
|
||||
backend/routers/__init__.py
|
||||
requirements.txt
|
||||
.env.example
|
||||
.gitignore
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
</files>
|
||||
<action>
|
||||
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
|
||||
</action>
|
||||
<verify>
|
||||
- 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
|
||||
</verify>
|
||||
<done>
|
||||
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.
|
||||
</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: React + Vite + Tailwind v4 SPA scaffold con API client</name>
|
||||
<files>
|
||||
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
|
||||
</files>
|
||||
<action>
|
||||
1. Creare il progetto React + TypeScript con Vite:
|
||||
- cd al progetto, eseguire: npm create vite@latest frontend -- --template react-ts
|
||||
- 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<T>(endpoint: string, options?: RequestInit): Promise<T>
|
||||
- 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.
|
||||
</action>
|
||||
<verify>
|
||||
- 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"
|
||||
</verify>
|
||||
<done>
|
||||
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.
|
||||
</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
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
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- 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
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-core-generation-pipeline/01-01-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user