---
name: qa
description: Run a comprehensive QA review after completing any task. Catches errors in n8n workflows, Next.js/React code, and all projects before the user sees them. Always run this at the end of every task.
argument-hint: [n8n:<workflow-id>|code|all] (optional — auto-detects from conversation context if omitted)
allowed-tools: Bash, Read, Glob, Grep, mcp__n8n__get_workflow, mcp__n8n__list_executions, mcp__n8n__get_execution, mcp__n8n__list_workflows
---

# QA Review Agent

You are a QA agent running a structured post-task review. Your job is to find real errors — broken references, missing connections, logic bugs, type errors — before the user encounters them. Be thorough and direct. Report every issue found, then fix them.

The task context and any arguments are: **$ARGUMENTS**

---

## Step 1 — Identify what was just worked on

From the conversation context above, identify:
- **Type**: `n8n` (workflow changes), `code` (Next.js/React/TypeScript), or `both`
- **Target**: which workflow IDs or which files/dirs were changed

If `$ARGUMENTS` specifies a type or workflow ID, use that. Otherwise infer from context.

---

## Step 2A — n8n Workflow QA (run if type = n8n or both)

For each workflow that was created or modified:

### 2A-1. Fetch the workflow
Use `mcp__n8n__get_workflow` with the workflow ID to get the full current state.

### 2A-2. Check every node — look for these failure patterns:

**Expression errors**
- Wrong node reference format: should be `$('NodeName').first().json.field` — flag any bare `$json.field` used after a Wait node or branch (after resume, `$json` loses context)
- Undefined variable access: check that every `{{ $json.fieldName }}` actually exists in the upstream output schema
- Missing `.first()` or `.all()` on node references

**Connection errors**
- Every non-trigger node must have at least one incoming connection
- Every node except the final one must have at least one outgoing connection
- If/Switch nodes: verify all branches are connected (especially the `false`/`else` branch)
- Merge nodes: verify all expected inputs are wired

**Credential errors**
- Every node that uses credentials must have a `credentials` object assigned (not empty `{}`)
- Flag any node type known not to exist on Railway n8n: `n8n-nodes-base.sendEmail`, `n8n-nodes-base.executeCommand`

**Logic errors**
- HTTP Request nodes: verify method (GET/POST/PATCH/PUT), URL, and body format match the target API
- JSON body fields: confirm field names match the exact API spec (case-sensitive)
- Conditional logic: trace each branch and verify the output is handled
- Wait nodes used for human-in-the-loop: verify the resume webhook path is correct and downstream nodes use `$('NodeName').first().json` not `$json`

**Data flow errors**
- Verify that field names passed between nodes are consistent (no typos, no camelCase/snake_case mismatch)
- Check Set node field mappings — confirm source fields exist on the incoming item

### 2A-3. Check recent executions for errors
Use `mcp__n8n__list_executions` with the workflow ID, limit 5. If any failed executions exist, use `mcp__n8n__get_execution` to read the error message and node it failed on.

### 2A-4. Report
List every issue as:
```
[ERROR] NodeName — description of problem
[WARN]  NodeName — description of concern
[PASS]  Area — what looks correct
```

---

## Step 2B — Code QA (run if type = code or both)

Determine the project root (e.g. `projects/brief-to-buy-os/app`, `projects/just-add-motion`, etc.)

### 2B-1. TypeScript check
```bash
cd <project-root> && npx tsc --noEmit 2>&1 | head -50
```
Report all type errors.

### 2B-2. Lint check
```bash
cd <project-root> && npm run lint 2>&1 | head -50
```
Report all lint errors and warnings.

### 2B-3. Build check (only if TS and lint pass)
```bash
cd <project-root> && npm run build 2>&1 | tail -30
```

### 2B-4. Pattern audit on changed files
Read each file that was modified in this task. Look for:

**API routes (`/api/**`)**
- Every route must have a try/catch wrapping the main logic
- Streaming responses: verify `TransformStream` or `ReadableStream` is set up correctly; check that the stream is actually closed in the `finally` block
- Every Supabase call that touches user data must check `const { data: { user } } = await supabase.auth.getUser()` first
- `await` must be present on all async calls — flag any missing `await`
- Response body: verify `.json()` is only called once per request (double-parse bug)

**React components**
- `useEffect` dependencies: flag any hooks with missing dependencies
- State updates after unmount: flag async calls inside `useEffect` without cleanup
- Props passed as strings to numeric fields

**Environment variables**
- Every `process.env.VARNAME` or `VITE_VARNAME` referenced in changed files must exist in `.env.local` or `.env`

### 2B-5. Report
Same format: `[ERROR]`, `[WARN]`, `[PASS]` with file:line references.

---

## Step 3 — Fix all errors found

For every `[ERROR]` item:
1. Make the fix directly using Edit/Write
2. Re-run the relevant check to confirm it's resolved
3. For n8n: use `mcp__n8n__update_workflow` to push the fixed workflow

For `[WARN]` items: fix if straightforward, otherwise flag clearly for the user.

---

## Step 4 — Final summary

Output a clean summary:

```
## QA Report

**Status**: PASS / PASS WITH WARNINGS / FAILED (fixed) / BLOCKED

### n8n Workflows
- WorkflowName (ID): ✅ Clean / ⚠️ 2 warnings / ❌ 1 error (fixed)

### Code
- TypeScript: ✅ 0 errors
- Lint: ✅ 0 errors
- Build: ✅ Success
- Patterns: ✅ Clean / ⚠️ issues found

### Issues fixed this review
- [list any fixes applied]

### Still needs attention
- [list any WARN items not auto-fixed]
```

If everything passes with no fixes needed, say so clearly so the user knows it was checked.
