2026-07-16-workbench-persistence.md 4.1 KB

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.