docs(02-01): complete prompt CRUD + prompt editor plan

Tasks completed: 2/2
- Backend prompts router with 4 CRUD endpoints
- Frontend Prompt Editor page with types, hooks, route, sidebar

SUMMARY: .planning/phases/02-prompt-control-output-review/02-01-SUMMARY.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michele
2026-03-08 20:58:24 +01:00
parent ca3dd59072
commit 36fa50173f
2 changed files with 118 additions and 17 deletions

View File

@@ -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).