# Workbench Persistence Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:test-driven-development and superpowers:executing-plans to implement this plan task-by-task. **Goal:** Deliver a user-specific workbench using only five approved standard widgets and persist layout across sessions. **Architecture:** A backend widget registry defines IDs, permissions, size limits and data providers. PostgreSQL stores validated layout JSON per user. The Vue 2 frontend renders registry-backed widgets and cannot submit arbitrary component names, scripts or SQL. **Tech Stack:** Flask, PostgreSQL JSONB, Vue 2, ECharts where already available, pytest, browser tests. --- ### Task 1: Add layout persistence schema **Files:** - Create: `migrations/versions/20260716_30_workbench_layouts.py` - Create: `app/core/workbench/models.py` - Create: `tests/test_workbench_schema.py` - [ ] Create `workbench_layouts(user_id, layout_version, widgets JSONB, updated_at)` with one current layout per user. - [ ] Test user isolation, optimistic version conflicts and deletion when a user is removed. - [ ] Store only widget ID, position, size and allowlisted settings. - [ ] Seed no universal layout row; use a code-defined default for first access. ### Task 2: Implement the standard widget registry **Files:** - Create: `app/core/workbench/registry.py` - Create: `app/core/workbench/providers.py` - Create: `tests/test_workbench_registry.py` - [ ] Register exactly `pending_reviews`, `order_status`, `product_stats`, `datasource_health`, `n8n_executions`. - [ ] Define min/max dimensions, supported settings, permission and data provider for every widget. - [ ] Test rejection of unknown IDs, duplicate instances beyond allowed count, invalid sizes and unauthorized widgets. - [ ] Make provider failures local to one widget and return a typed degraded state. ### Task 3: Add workbench APIs **Files:** - Create: `app/api/system/workbench.py` - Modify: `app/api/system/__init__.py` - Create: `tests/test_workbench_api.py` - [ ] Implement `GET /api/system/workbench/registry`, `GET /layout`, `PUT /layout` and `GET /data`. - [ ] Derive `user_id` from the token, never from request body/query. - [ ] Validate the full layout server-side and use `If-Match`/layout version to prevent silent overwrite. - [ ] Batch widget data providers with timeouts and expose per-widget freshness timestamps. ### Task 4: Replace the acceptance mock with real widgets **Files:** - Modify: `frontend/src/views/home/index.vue` - Modify: `frontend/src/views/home/edit.vue` - Modify: `frontend/src/views/home/workbench.js` - Create: `frontend/src/api/workbench.js` - Create: `frontend/src/views/home/components/standardWidgets/` - [ ] Map registry IDs to five statically imported Vue components. - [ ] Load saved layout, fall back to the default, and persist drag/resize changes with conflict handling. - [ ] Provide loading, empty, degraded and permission-denied states for each widget. - [ ] Keep the current static workbench as an acceptance fixture until the persisted path passes browser tests. ### Task 5: Verify accessibility, resilience and role behavior **Files:** - Create: `tests/e2e/workbench.spec.js` - Modify: `tests/test_cleanup_contract.py` - [ ] Verify keyboard access to edit/save/reset, readable labels and non-color-only status indicators. - [ ] Verify two users retain independent layouts across logout/login and browser restart. - [ ] Verify n8n downtime degrades only the execution widget and does not block the page. - [ ] Verify viewers can arrange allowed widgets but cannot trigger edit/approval operations embedded in summaries. ### Task 6: Contract and performance acceptance **Files:** - Modify: `docs/architecture/OPENAPI.yaml` - Modify: `docs/architecture/DATA_MODEL.md` - Modify: `deploy/docker/README.md` - [ ] Set a local acceptance target of first widget data under 2 seconds and all providers under 5 seconds. - [ ] Add query indexes based on measured plans for review/order/product summaries. - [ ] Regenerate OpenAPI and document widget freshness and degraded semantics. - [ ] Run Python, frontend build, browser and Docker smoke suites.