diff --git a/.planning/STATE.md b/.planning/STATE.md index 84125f0..af99d2c 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -5,33 +5,34 @@ See: .planning/PROJECT.md (updated 2026-03-07) **Core value:** Generare un calendario di 13 caroselli Instagram strategicamente orchestrati, pronti per Canva Bulk Create, con un click dalla Web UI. -**Current focus:** Phase 1 completata e verificata — pronta per deploy e Phase 2 +**Current focus:** Phase 2 in corso — Prompt Control + Output Review ## Current Position -Phase: 1 of 4 (Core Generation Pipeline) — COMPLETE -Plan: 4 of 4 in current phase -Status: Phase 1 COMPLETATA e VERIFICATA — gap fix applicato per calendar slot merge -Last activity: 2026-03-08 — Phase 1 completata, verificata, gap corretto +Phase: 2 of 4 (Prompt Control + Output Review) +Plan: 1 of 2 in current phase +Status: In progress — 02-01 completato, 02-02 da eseguire +Last activity: 2026-03-08 — Completed 02-01-PLAN.md (Prompt CRUD + Prompt Editor UI) -Progress: [████░░░░░░] 25% (4/9 piani totali) +Progress: [█████░░░░░] 55% (5/9 piani totali) ## Performance Metrics **Velocity:** -- Total plans completed: 4 -- Average duration: ~8 min -- Total execution time: 33 min +- Total plans completed: 5 +- Average duration: ~7 min +- Total execution time: 38 min **By Phase:** | Phase | Plans | Total | Avg/Plan | |-------|-------|-------|----------| | 01-core-generation-pipeline | 4/4 COMPLETA | 33 min | 8 min | +| 02-prompt-control-output-review | 1/2 | 5 min | 5 min | **Recent Trend:** -- Last 4 plans: 6 min, 9 min, 8 min, 10 min -- Trend: baseline stabile ~8 min/piano +- Last 5 plans: 6 min, 9 min, 8 min, 10 min, 5 min +- Trend: velocita' in aumento *Updated after each plan completion* @@ -58,6 +59,7 @@ Recent decisions affecting current work: - [01-04]: Download CSV sempre via POST con edits inline (non GET originale) - [01-04]: localResults separato in OutputReview per edit inline senza mutare cache TanStack Query - [verification-fix]: GenerateResponse include calendar per badge PN/Schwartz nel frontend +- [02-01]: PromptService init lazy via _get_prompt_service() per sincronizzazione con lifespan directory ### Blockers/Concerns @@ -68,13 +70,11 @@ Recent decisions affecting current work: ## Session Continuity Last session: 2026-03-08 -Stopped at: Phase 1 completata e verificata — pronta per deploy +Stopped at: Completed 02-01-PLAN.md (Prompt CRUD + Prompt Editor UI) Resume file: None ## Next Actions -Phase 1 completata. Prossimi passi: -1. `vps-lab-deploy` per deployare su VPS e testare end-to-end -2. Configurare API key in Impostazioni UI -3. Generare primo calendario reale per validare qualita' prompt e token usage -4. Poi procedere con Phase 2 (Prompt Control + Output Review) +1. Eseguire 02-02-PLAN.md (Output Review enhancements) +2. Completare Phase 2 +3. `vps-lab-deploy` per deployare su VPS e testare end-to-end diff --git a/.planning/phases/02-prompt-control-output-review/02-01-SUMMARY.md b/.planning/phases/02-prompt-control-output-review/02-01-SUMMARY.md new file mode 100644 index 0000000..84f8206 --- /dev/null +++ b/.planning/phases/02-prompt-control-output-review/02-01-SUMMARY.md @@ -0,0 +1,101 @@ +--- +phase: 02-prompt-control-output-review +plan: 01 +subsystem: prompt-management +tags: [fastapi, react, crud, prompt-editor, tanstack-query] + +dependency_graph: + requires: + - 01-02 (PromptService with load/save/list/variables/exists methods) + - 01-04 (Web UI with stone/amber palette, Sidebar, Layout, routing) + provides: + - Prompt CRUD API (4 endpoints: list, read, write, reset) + - Prompt Editor UI page with live variable extraction + affects: + - 02-02 (Output Review enhancement may reference prompt editing) + - Future phases that add new prompt types + +tech_stack: + added: [] + patterns: + - Lazy PromptService init for directory lifecycle sync + - Default vs modified comparison for prompt versioning + - Client-side regex for live variable extraction + +key_files: + created: + - backend/routers/prompts.py + - frontend/src/pages/PromptEditor.tsx + modified: + - backend/main.py + - frontend/src/types.ts + - frontend/src/api/hooks.ts + - frontend/src/App.tsx + - frontend/src/components/Sidebar.tsx + +decisions: + - id: prompt-lazy-init + decision: "PromptService initialized lazily via _get_prompt_service() instead of module-level" + reason: "PROMPTS_PATH directory is created during FastAPI lifespan, not at import time. Module-level init would fail with FileNotFoundError during import." + date: 2026-03-08 + +metrics: + duration: ~5 min + completed: 2026-03-08 +--- + +# Phase 02 Plan 01: Prompt CRUD + Prompt Editor UI Summary + +**PromptService CRUD completo con 4 endpoint FastAPI e pagina React Prompt Editor con lista, textarea monospace, variabili live, salva e reset al default.** + +## What Was Done + +### Task 1: Backend prompts router (4 CRUD endpoints) +Created `backend/routers/prompts.py` with `APIRouter(prefix="/api/prompts", tags=["prompts"])`: + +- **GET /api/prompts** — Lists all `.txt` prompts with `modified` flag (compares runtime vs default in `backend/data/prompts/`) +- **GET /api/prompts/{name}** — Returns content, required variables, and modified flag +- **PUT /api/prompts/{name}** — Saves modified content with min_length=10 validation, returns updated variables +- **POST /api/prompts/{name}/reset** — Restores default content from `backend/data/prompts/`, returns 404 if no default exists + +Key implementation detail: PromptService is lazily initialized via `_get_prompt_service()` because `PROMPTS_PATH` is created during FastAPI's lifespan event, not at module import time. + +Router registered in `main.py` before the SPA catch-all mount. + +### Task 2: Frontend Prompt Editor (page, hooks, types, route, sidebar) +- **Types**: Added `PromptInfo`, `PromptListResponse`, `PromptDetail` to `types.ts` +- **Hooks**: Added `usePromptList`, `usePrompt`, `useSavePrompt`, `useResetPrompt` to `hooks.ts` with TanStack Query cache invalidation +- **Page**: Created `PromptEditor.tsx` with two-column layout (1/3 list, 2/3 editor on lg, stacked on mobile) + - Prompt list with amber "Modificato" / stone "Default" badges + - Monospace textarea (min-height 400px, stone-900 bg) + - Live client-side variable extraction via regex `{{nome}}` + - Save button (amber, disabled when not dirty) + - Reset to Default with inline confirmation dialog + - Success/error feedback inline +- **Route**: `/prompt-editor` added in `App.tsx` +- **Sidebar**: "Prompt Editor" nav item with `Pencil` icon, positioned after "Genera Singolo Post" and before "Impostazioni" + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 3 - Blocking] Lazy PromptService initialization** +- **Found during:** Task 1 +- **Issue:** Module-level `PromptService(PROMPTS_PATH)` raised `FileNotFoundError` because `PROMPTS_PATH` directory doesn't exist at import time — it's created in the FastAPI lifespan event. +- **Fix:** Changed to lazy initialization via `_get_prompt_service()` function with `PROMPTS_PATH.mkdir(parents=True, exist_ok=True)` on first access. +- **Files modified:** `backend/routers/prompts.py` +- **Commit:** 05972fa + +## Verification + +- [x] Backend imports without errors: `from backend.routers.prompts import router` OK +- [x] 4 routes registered: `/api/prompts/`, `/api/prompts/{name}`, `/api/prompts/{name}`, `/api/prompts/{name}/reset` +- [x] `main.py` includes `app.include_router(prompts.router)` before SPA catch-all +- [x] TypeScript compiles with `npx tsc --noEmit` — zero errors +- [x] Route `/prompt-editor` in App.tsx +- [x] Sidebar contains "Prompt Editor" nav link +- [x] Types and hooks exported correctly + +## Next Phase Readiness + +Plan 02-01 is complete. The Prompt Editor is functional for CRUD operations on prompt files. Plan 02-02 can proceed independently (Output Review enhancements).