# Workflow mapping

Trace every major workflow in a codebase from trigger to terminal effect, and write one markdown file of mermaid sequence diagrams.

## Modes

| Request | Mode | Runs |
| --- | --- | --- |
| "Map all workflows" | Full discovery (default) | Phases 1–5 |
| "Map workflow for {feature}" | Targeted discovery | Phases 2–5, from the feature's own entry points instead of the Phase 1 broad scan |
| "Update workflow map" | Incremental | Re-traces only workflows whose files changed against the existing map |
| "How does X work end-to-end" | Single workflow trace | Phases 2–4 only |

Dispatch and per-mode procedure are § Execution strategy. Load [`workflow-patterns.md`](workflow-patterns.md) at the start of Phase 1 (or of a targeted search) — it carries framework detection and the full grep/glob patterns per stack; the patterns below are the summary.

## Phase 1: Entry point discovery

Find every place a multi-step process begins, one sub-agent per technique. Adapt each pattern to the framework detected.

### Technique 1: Route harvesting

API route definitions are the primary backend entry points.

```
Express:    router.(get|post|put|patch|delete)\(
Fastify:    fastify.(get|post|put|patch|delete)\(
Next.js:    export (async )?function (GET|POST|PUT|PATCH|DELETE)
Hono:       app.(get|post|put|patch|delete)\(
tRPC:       .query\(|.mutation\(
```

Record each route as `{ method, path, handler_function, file }`. Drop trivial CRUD (one DB call plus a response); keep a route that:

- calls `startWorkflow`, `addJob`, `enqueue`, `emit` or `publish` (async dispatch)
- calls two or more service functions in sequence
- opens a transaction (`$transaction`, `BEGIN`, `withTransaction`)
- returns a job or workflow ID for polling
- triggers WebSocket or SSE events

### Technique 2: Background job discovery

Find every registered background job, workflow and queue.

```
Temporal:     export async function .*Workflow|workflowModules|startChild\(
BullMQ:       new Queue\(|new Worker\(|.add\(|.process\(
Celery:       @app.task|@shared_task
Inngest:      createFunction\(|inngest.send\(
Cron:         cron.schedule\(|@Cron\(|node-cron
EventEmitter: .on\(|.emit\(|EventEmitter
```

For Temporal, also read `temporal/config/workflowModules.js` (the workflow registry, with queues and dependencies) and `temporal/config/activityModules.js` (activity aggregation).

### Technique 3: Frontend action tracing

Find UI-initiated multi-step flows.

```
Redux thunks:  createAsyncThunk\(|dispatch\(
API calls:     api\.(post|put|patch|delete)\(|axios\.(post|put|patch|delete)\(|fetch\(
Form submits:  onSubmit|handleSubmit
Custom hooks:  use[A-Z].*\(\) that contain API calls
```

Keep actions that:

- POST, PUT, PATCH or DELETE to the backend — **never** a GET alone
- dispatch several Redux actions in sequence
- start a polling loop (`setInterval`, recursive `setTimeout`, retry patterns)
- open a WebSocket connection or listen for server-sent events

### Technique 4: Event and message tracing

Find event-driven workflows (WebSocket, pub/sub, SSE).

```
WebSocket:  socket.on\(|io.on\(|ws.on\(
SSE:        EventSource|text/event-stream
Redis pub:  .publish\(|.subscribe\(
Message:    .sendMessage\(|.postMessage\(
```

### Technique 5: Scheduled and lifecycle workflows

```
App startup:    app.listen|bootstrap|onModuleInit|main\(\)
Shutdown:       SIGTERM|SIGINT|gracefulShutdown|onModuleDestroy
Migrations:     migrate|seed|up\(\)|down\(\)
Health checks:  /health|/ping|/ready|/live
```

## Phase 2: Call chain tracing

Trace each entry point's full execution path, one sub-agent per workflow.

### Tracing algorithm

1. Start at the entry point function and read its body.
2. Classify each function call or `await`:
   1. DB operation → a `Database` action.
   2. External API call → a `{ServiceName}` action.
   3. Queue or workflow dispatch → a `{QueueSystem}` action, then recurse into the dispatched handler.
   4. Redux dispatch → a `Redux` action.
   5. Internal function in the same service → recurse, up to depth 4 unless the user sets another cap.
   6. WebSocket emit → a `WebSocket` action.
3. Record branching (`if`/`else`, `try`/`catch`, `switch`) as `alt` or `opt` blocks.
4. Record loops (polling, retry, pagination) as `loop` blocks.
5. Stop at a return to the caller, a terminal DB write, or an external system's response.
6. When a trace hits the depth cap, stop and mark the overflow point — `→ [continues deeper, capped at depth N]`. **Never** truncate silently.

### Participant identification

| Code pattern | Participant |
| --- | --- |
| React component, hook, event handler | `User` + `Frontend` |
| Express/API route handler | `API` |
| Temporal workflow | `Temporal` |
| BullMQ worker/processor | `Queue` |
| Prisma/Sequelize/Knex call | `Database` |
| External HTTP call (axios, fetch to external URL) | `{ServiceName}` (derive from URL or config) |
| Redis operation | `Cache` |
| WebSocket emit/broadcast | `WebSocket` |
| File system / S3 / storage | `Storage` |
| Git API calls | `Git` |
| Email/SMS send | `Notifications` |
| Auth provider (Keycloak, Better Auth, Auth0) | `Auth` |

### Branching detection

Draw a block only for conditional logic that forks the workflow:

| Condition | Block |
| --- | --- |
| Version conflict (optimistic locking) | `alt` |
| Error handling whose outcomes differ | `alt` |
| Permission or auth check | `opt` |
| Feature flag | `opt` |
| Retry with backoff | `loop` |
| Polling for completion | `loop` |
| Batch processing | `loop` |

## Phase 3: Classification and filtering

Not every route is a workflow.

### Workflow categories

| Category | Criteria | Include? |
| --- | --- | --- |
| **Orchestration** | Multi-step, multi-service, async handoffs (save, publish, deploy) | Always |
| **Auth & Session** | Login, logout, token refresh, SSO flows | Always |
| **Real-time** | WebSocket connections, live updates, presence | Always |
| **Event-driven** | Pub/sub chains, webhook handlers, event sourcing | Always |
| **Scheduled** | Cron jobs, recurring workflows, cleanup tasks | Always |
| **Data Pipeline** | ETL, import/export, migration, sync between systems | Always |
| **Simple CRUD** | Single DB call + response, no branching | Skip |
| **Static Serving** | File serving, asset delivery | Skip |
| **Health/Config** | Health checks, config endpoints | Skip |

### Complexity scoring

The score sets the diagram's detail: a simple workflow gets a compact diagram, a complex one full detail with `alt`/`opt`/`loop` blocks.

| Axis | Simple | Moderate | Complex |
| --- | --- | --- | --- |
| Steps — distinct operations (DB calls, API calls, dispatches) | 1–2 | 3–5 | 6+ |
| Participants — distinct systems | 2 | 3–4 | 5+ |
| Branching — `alt`/`opt` blocks | 0 (linear) | 1–2 | 3+ |

Async behaviour — polling, callbacks, child workflows — raises the score one level.

## Phase 4: Mermaid diagram generation

### Diagram template

````markdown
### {Workflow Name}

**Trigger:** {What initiates this — button click, API call, cron schedule, event} **Participants:** {List of systems involved} **Key files:** {3-5 most important files in the chain}

```mermaid
sequenceDiagram
    participant User
    participant Frontend
    participant API
    participant Database

    User->>Frontend: {User action}
    Frontend->>API: {HTTP method} {path}
    API->>Database: {Operation}
    Database-->>API: {Result}
    API-->>Frontend: {Response}
    Frontend-->>User: {UI update}
```

**Notes:**

- {Important implementation detail not visible in diagram}
- {Performance consideration, timeout, retry policy}
- {Known edge cases or failure modes}
````

### Diagram rules

1. **Arrow types:** solid (`->>`) for calls and requests, dashed (`-->>`) for returns and responses.
2. **Activation bars:** `activate`/`deactivate` **only** for long-running operations (Temporal workflows, polling loops).
3. **Alt blocks:** for a real workflow branch whose outcomes differ (conflict vs success) — **never** for generic error handling such as a catch that rethrows.
4. **Loop blocks:** for polling, retry and batch processing, with the condition in the label.
5. **Opt blocks:** for conditional steps (feature flags, optional integrations).
6. **Notes:** `Note over` for context that does not fit an arrow label.
7. **Participant order:** left to right along the data flow — `User`, `Frontend`, `API`, backend, `Database`.
8. **Label brevity:** arrow labels of 8 words or fewer, naming the action rather than the implementation detail.
9. **Max participants:** 7 per diagram. Past that, split into sub-diagrams or collapse internal services.
10. **Max steps:** 15 visible interactions per diagram. Past that, group related steps or use `rect` blocks.

### Grouping related steps

Collapse a run of same-type sequential operations into one `rect`:

```mermaid
sequenceDiagram
    rect rgb(240, 240, 240)
        Note over Temporal,Database: Save all entities (10 types)
        Temporal->>Database: Upsert objects, attributes, pages...
        Database-->>Temporal: Saved
    end
```

## Phase 5: Output assembly

### Output file structure

Write to the user-specified path, defaulting to `docs/architecture/workflows.md`; create the target directory if it is missing.

```markdown
---
generated: { YYYY-MM-DD }
scope: { full | feature-name }
workflows_found: { count }
---

# Codebase Workflows

Auto-generated workflow map. Traces execution paths from user action to terminal effect.

## Table of Contents

| Workflow | Category | Trigger | Participants | Complexity |
| --- | --- | --- | --- | --- |
| [{Name}](#{anchor}) | {Category} | {Trigger} | {Count} | {Simple/Moderate/Complex} |

---

## Orchestration Workflows

### {Workflow Name}

{Diagram + metadata as defined in Phase 4}

---

## Authentication & Session Workflows

### {Workflow Name}

{...}

---

## Real-time Workflows

### {Workflow Name}

{...}

---

## Event-driven Workflows

### {Workflow Name}

{...}

---

## Scheduled Workflows

### {Workflow Name}

{...}

---

## Data Pipeline Workflows

### {Workflow Name}

{...}
```

### Section ordering

Sections follow the template's order — Orchestration, Authentication & Session, Real-time, Event-driven, Scheduled, Data Pipeline. Skip an empty section.

## Execution strategy

### Full discovery (default)

1. Launch 5 parallel sub-agents for Phase 1, one per technique.
2. Collect their results and deduplicate the entry points.
3. Launch parallel sub-agents for Phase 2, one per workflow, at most 8 concurrent.
4. Run Phases 3–5 sequentially in the main agent.

### Targeted discovery

The user names a feature; skip the Phase 1 broad scan.

1. Find the feature's directories and files — grep for the feature name in routes, components and workflows.
2. Trace from those entry points only.
3. Write a single-feature workflow document.

### Incremental update

1. Read the existing workflow map.
2. For each workflow it lists, check whether its key files changed (`git diff`).
3. Re-trace only the changed workflows; keep unchanged sections as they are.

## Advanced techniques

### Payload storage detection

A large payload stored separately and referenced by ID:

```
storePayload|savePayload|workflow_payload|jobData
→ then: retrievePayload|fetchPayload|getPayload (in the worker/activity)
```

Mark it in the diagram as a "Store payload → reference by ID" pattern.

### Optimistic locking detection

Version comparisons:

```
version.*!==|version.*conflict|StaleObjectError|OptimisticLock
if.*serverVersion.*localVersion|if.*version.*mismatch
```

Each is a conflict branch — an `alt` block.

### Polling loop detection

The frontend waiting on async completion:

```
setInterval|setTimeout.*recursive|poll|retry.*status
GET.*status\?.*workflowId|GET.*status\?.*jobId
```

Put the polling interval and timeout in the diagram.

### Child workflow / sub-job detection

Spawned sub-processes:

```
startChild\(|spawnChild|fork\(|.add\(.*queue
Promise\.all.*map.*startWorkflow
```

Draw them as nested sequences or separate linked diagrams.

### Transaction boundary detection

Explicit transaction markers:

```
\$transaction|\$executeRaw|BEGIN|COMMIT|ROLLBACK
withTransaction|runInTransaction|atomic
```

Group the operations inside a transaction in a `rect` block.

### Rate limiting and middleware detection

Middleware applied to route groups:

```
rateLimit|rateLimiter|throttle
authenticate|authorize|requireAuth|requireRole
validate|validateBody|validateParams
```

Show each as a guard — an `opt` block or a note.

## Quality checks

Before writing the output, verify:

- [ ] Every diagram has at least 3 participants — fewer is too simple to document
- [ ] Every diagram has both request and response arrows (no dangling calls)
- [ ] Participant names match across all diagrams (the same DB carries the same name everywhere)
- [ ] Every `alt`/`opt`/`loop` block states its condition in the block label
- [ ] Every listed key file exists in the codebase (verify with glob)
- [ ] No workflow appears twice under different names
- [ ] Mermaid syntax is valid (no unclosed blocks, balanced `activate`/`deactivate`)
- [ ] Table of contents anchors match the actual heading anchors
