---
name: step-05-report
description: Generate final report from prd.json structured data (v3 unified or v2 legacy)
next_step: null
---

# Step 5: Generate Report

## YOUR TASK:

Generate a comprehensive feature report using structured data from prd.json.

---

## 1. Load Data

```javascript
const prd = readJSON('.ralph/prd.json');
const stats = {
  feature: prd.feature, status: prd.status,
  iterations_used: prd.config.current_iteration - 1,
  tasks: {
    total: prd.tasks.length,
    completed: prd.tasks.filter(t => t.status === 'completed').length,
    failed: prd.tasks.filter(t => t.status === 'failed').length,
    blocked: prd.tasks.filter(t => t.status === 'blocked').length
  }
};

// Aggregate files from all tasks
const filesCreated = [...new Set(prd.tasks.flatMap(t => t.files_changed?.created || []))];
const filesModified = [...new Set(prd.tasks.flatMap(t => t.files_changed?.modified || []))];
const totalDuration = prd.history.reduce((sum, h) => sum + (h.duration_seconds || 0), 0);
```

### 1b. Multi-Module Aggregation

```javascript
const queuePath = '.ralph/modules-queue.json';
let moduleStats = null;
if (fileExists(queuePath)) {
  const queue = readJSON(queuePath);
  moduleStats = { totalModules: queue.totalModules, completedModules: queue.completedModules, modules: [] };
  for (const mod of queue.modules) {
    const modPrd = readJSON(mod.prdFile);
    moduleStats.modules.push({
      code: mod.code, status: mod.status,
      tasks: { total: modPrd.tasks.length, completed: modPrd.tasks.filter(t => t.status === 'completed').length, failed: modPrd.tasks.filter(t => t.status === 'failed').length },
      filesCreated: [...new Set(modPrd.tasks.flatMap(t => t.files_changed?.created || []))].length,
      commits: [...new Set(modPrd.tasks.filter(t => t.commit_hash).map(t => t.commit_hash))].length
    });
  }
}
```

### 1c. Team Results Aggregation

```javascript
// If Agent Teams were used, results are already in per-module PRDs
// Aggregate from moduleStats (same as 1b)
```

### 1d. Test Metrics

```bash
TEST_PROJECT="tests/$(basename $(pwd)).Tests.Unit"
if [ -d "$TEST_PROJECT" ]; then
  dotnet test "$TEST_PROJECT" --no-build --verbosity minimal
  # Parse total/passed/failed/skipped from output
fi
```

### 1e. Final DB Validation (if infrastructure/migration tasks were executed)

```bash
INFRA_PROJECT=$(ls src/*Infrastructure*/*.csproj 2>/dev/null | head -1)
API_PROJECT=$(ls src/*Api*/*.csproj 2>/dev/null | head -1)

if [ -n "$INFRA_PROJECT" ] && [ -n "$API_PROJECT" ]; then
  echo "FINAL DB VALIDATION: Applying all migrations on fresh SQL Server LocalDB..."

  # 1. Check no pending model changes
  dotnet ef migrations has-pending-model-changes \
    --project "$INFRA_PROJECT" \
    --startup-project "$API_PROJECT"
  PENDING_RESULT=$?

  # 2. Apply all migrations on temp database
  DB_NAME="SmartStack_FinalCheck_$(date +%s)"
  CONN_STRING="Server=(localdb)\\MSSQLLocalDB;Database=$DB_NAME;Integrated Security=true;TrustServerCertificate=true;Connect Timeout=120;"
  dotnet ef database update \
    --connection "$CONN_STRING" \
    --project "$INFRA_PROJECT" \
    --startup-project "$API_PROJECT"
  MIGRATION_RESULT=$?

  # 3. Run integration tests against real SQL Server
  INT_TEST_PROJECT=$(ls tests/*Tests.Integration*/*.csproj 2>/dev/null | head -1)
  INT_TEST_RESULT=0
  if [ -n "$INT_TEST_PROJECT" ]; then
    dotnet test "$INT_TEST_PROJECT" --no-build --verbosity minimal
    INT_TEST_RESULT=$?
  fi

  # 4. Cleanup
  sqlcmd -S "(localdb)\MSSQLLocalDB" -Q "IF DB_ID('$DB_NAME') IS NOT NULL BEGIN ALTER DATABASE [$DB_NAME] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [$DB_NAME]; END" 2>/dev/null

  # Record results
  DB_VALIDATION="PASS"
  [ $PENDING_RESULT -ne 0 ] && DB_VALIDATION="FAIL (pending model changes)"
  [ $MIGRATION_RESULT -ne 0 ] && DB_VALIDATION="FAIL (migration apply failed)"
  [ $INT_TEST_RESULT -ne 0 ] && DB_VALIDATION="FAIL (integration tests failed on SQL Server)"
fi
```

Include DB validation results in report section:
```markdown
## DB Validation (SQL Server LocalDB)
| Check | Result |
|-------|--------|
| Pending model changes | {PENDING_RESULT == 0 ? "PASS" : "FAIL"} |
| Migrations apply cleanly | {MIGRATION_RESULT == 0 ? "PASS" : "FAIL"} |
| Integration tests (real SQL Server) | {INT_TEST_RESULT == 0 ? "PASS" : "N/A"} |
| Overall | {DB_VALIDATION} |
```

## 2. Generate Report

Write to `.ralph/reports/{feature-slug}.md`:

```markdown
# Feature Report: {feature}

## Summary
| Field | Value |
|-------|-------|
| Status | {status} |
| Iterations | {iterations_used} / {max} |
| Branch | {branch} |
| Duration | {totalDuration}s ({min} min) |

## Tasks
| # | Task | Category | Status | Commit |
|---|------|----------|--------|--------|
{for each task:}
| {id} | {description} | {category} | {status_emoji} | {commit_hash} |

**{completed}/{total} completed, {failed} failed, {blocked} blocked**

{if moduleStats:}
## Modules
| Module | Status | Tasks | Completed | Failed | Files | Commits |
|--------|--------|-------|-----------|--------|-------|---------|
{for each mod:}
| {code} | {status} | {total} | {completed} | {failed} | {filesCreated} | {commits} |

**{completedModules}/{totalModules} modules completed**
{end if}

## Test Metrics
| Metric | Value |
|--------|-------|
| Tests Executed | {yes/no} |
| Status | {passed/failed} |
| Total | {n} | Passed | {n} | Failed | {n} |
| Coverage | {n}% |

## Failed Tasks
{table of failed tasks with error messages, or "None"}

## Files
- Created: {filesCreated.length}
- Modified: {filesModified.length}

## Commits
{unique commits list}

---
*Auto-generated by Ralph Loop — SmartStack CLI*
```

## 3. Finalize

```javascript
prd.updated_at = new Date().toISOString();
writeJSON('.ralph/prd.json', prd);
```

## 4. Display Summary

```
RALPH LOOP COMPLETE
Feature: {feature} | Status: {status}
Iterations: {n} | Tasks: {completed}/{total}
{moduleStats ? `Modules: ${completedModules}/${totalModules}` : ""}
Files: {created} created, {modified} modified
Report: .ralph/reports/{slug}.md
```

## 5. Completion Promise (if applicable)

```
<promise>{completion_promise}</promise>
```

## 6. Next Steps

```
1. Review report: .ralph/reports/{slug}.md
2. Run full test suite: dotnet test
3. Create PR: /gitflow pr
4. Clean up: rm -rf .ralph/ (optional)
```

---

Ralph loop complete. No more steps.
