For agentic workers: REQUIRED SUB-SKILL: Use superpowers:test-driven-development and superpowers:executing-plans to implement this plan task-by-task.
Goal: Map each governed DataFlow to multiple identifiable n8n Workflow versions while enforcing one active version per environment.
Architecture: Neo4j remains the DataFlow definition store; PostgreSQL owns immutable workflow version mappings and activation state. The backend coordinates n8n API calls through a state machine and outbox, with a partial unique index as the final concurrency guard.
Tech Stack: Flask, PostgreSQL, Neo4j, n8n REST API, pytest, Vue 2.
Files:
migrations/versions/20260716_20_workflow_versions.pyapp/core/data_flow/workflow_models.pyCreate: tests/test_workflow_version_schema.py
[ ] Test version uniqueness and concurrent attempts to create two active rows for one (dataflow_uid, environment).
[ ] Create dataflow_workflow_versions with UUID ID, stable dataflow_uid, environment enum, monotonically increasing version number, n8n ID, immutable definition hash, status and audit fields.
[ ] Add UNIQUE(dataflow_uid, environment, version_no) and the partial unique active index.
[ ] Seed no production mappings automatically; provide an import report command for existing n8n workflows.
Files:
app/core/data_flow/workflow_repository.pyapp/core/data_factory/n8n_client.pytests/test_workflow_repository.pyModify: tests/test_n8n_client_config.py
[ ] Test creating a version from an n8n workflow, canonical JSON hashing, missing workflow, duplicate hash and redaction of credentials.
[ ] Add n8n client methods for read/export/activate/deactivate with explicit timeouts and typed errors.
[ ] Persist only a safe definition snapshot or hash; never store n8n credential secrets in PostgreSQL.
[ ] Use stable DataFlow UID and reject numeric Neo4j IDs for new mappings.
Files:
app/core/data_flow/workflow_activation.pyCreate: tests/test_workflow_activation.py
[ ] Test draft-to-validating-to-active, old active-to-superseded, n8n failure, retry, duplicate request and two concurrent activation requests.
[ ] Lock the environment mapping, mark the target validating, invoke n8n, then atomically switch PostgreSQL active status and append outbox events.
[ ] If n8n succeeds but PostgreSQL finalization fails, reconcile from n8n state and correlation ID instead of blindly reactivating.
[ ] Expose activation_failed with actionable error metadata that excludes API keys.
Files:
app/api/data_flow/routes.pyapp/api/data_flow/schemas.pyCreate: tests/test_workflow_version_api.py
[ ] Add list/create/detail/activate endpoints under /api/dataflow/{dataflow_uid}/workflow-versions.
[ ] Require editor permission to create versions and administrator/editor-with-activation permission to activate.
[ ] Return both DataFlow identity and n8n Workflow identity, version, environment, status and timestamps.
[ ] Keep /api/datafactory/workflows/* for n8n-native diagnostics; do not rename Workflow globally.
Files:
frontend/src/views/dataGovernance/dataProcess/index.vuefrontend/src/views/dataGovernance/dataProcess/components/workflowVersions.vuefrontend/src/api/dataGovernance.jsCreate: tests/e2e/workflow-versions.spec.js
[ ] Display DataFlow details separately from n8n Workflow versions and show the active version per environment.
[ ] Require confirmation before activation and disable actions while a request is in flight.
[ ] Show validation/activation errors and n8n execution links without exposing credentials.
[ ] Verify viewer read-only, editor version creation and authorized activation in browser tests.
Files:
app/commands/reconcile_workflow_versions.pytests/integration/test_n8n_reconciliation.pyModify: deploy/docker/README.md
[ ] Compare PostgreSQL active mappings with local n8n activation state and emit a report before making repairs.
[ ] Test n8n downtime, request timeout, backend restart and out-of-band n8n deactivation.
[ ] Run full local-stack acceptance and prove one active version per environment under concurrency.
[ ] Regenerate OpenAPI and publish operator recovery commands.