# 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.
