# DataFlow n8n Workflow Versioning 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:** 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.

---

### Task 1: Create workflow version schema

**Files:**
- Create: `migrations/versions/20260716_20_workflow_versions.py`
- Create: `app/core/data_flow/workflow_models.py`
- Create: `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.

### Task 2: Add repository and n8n definition snapshotting

**Files:**
- Create: `app/core/data_flow/workflow_repository.py`
- Modify: `app/core/data_factory/n8n_client.py`
- Create: `tests/test_workflow_repository.py`
- Modify: `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.

### Task 3: Implement activation state machine

**Files:**
- Create: `app/core/data_flow/workflow_activation.py`
- Create: `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.

### Task 4: Add governed version APIs

**Files:**
- Modify: `app/api/data_flow/routes.py`
- Create: `app/api/data_flow/schemas.py`
- Create: `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.

### Task 5: Build the version management UI

**Files:**
- Modify: `frontend/src/views/dataGovernance/dataProcess/index.vue`
- Create: `frontend/src/views/dataGovernance/dataProcess/components/workflowVersions.vue`
- Modify: `frontend/src/api/dataGovernance.js`
- Create: `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.

### Task 6: Add reconciliation and operational acceptance

**Files:**
- Create: `app/commands/reconcile_workflow_versions.py`
- Create: `tests/integration/test_n8n_reconciliation.py`
- Modify: `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.
