| name | auditing-parity |
| description | Compares a modernized Next.js application against its legacy Express counterpart using runtime side-by-side verification. Use when ensuring functional and business logic parity between two systems. |
Side-by-Side Parity Audit
Verify the modernization by performing a side-by-side architectural and interaction audit between the legacy and modern applications.
Objective
Ensure 1:1 functional parity by systematically comparing the live behavior and internal logic of both applications. The goal is to prove the new code is a perfect functional replacement.
Prerequisites
- Legacy App: Running on
http://localhost:3000.
- Modern App: Running on
http://localhost:3001.
- Unified State (MongoDB): Both applications must target the same database instance to ensure data consistency during side-by-side testing.
Pre-Audit Environment Setup
Before performing the audit, you MUST ensure a stable MongoDB environment:
- Detect Port Conflicts: Run
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" and look for any container binding to 0.0.0.0:27017.
- Stop Conflicting Instances: If a container is binding to
27017 but is not the intended database for this audit session, stop it immediately (docker stop <ID>).
- Fresh Lifecycle: To ensure a clean state, run
docker compose down in both modern-app/ and legacy-app/ before starting the "Unified" database instance (docker compose up -d mongodb in modern-app/).
- Verify Unified Port: Ensure only one MongoDB container is reporting a bound host port in
docker ps.
- Connectivity Check: Verify both applications connect to
localhost:27017 (or the unified instance) without error.
Instructions for the Audit Subagent
Copy this checklist and track your progress:
Task Progress:
- [ ] Step 0: Validate Database & Container State
- [ ] Step 1: Execute Side-by-Side Interactions
- [ ] Step 2: Compare Network Payloads
- [ ] Step 3: Verify Complex Authorization
- [ ] Step 4: Validate Edge Cases & Error Responses
- [ ] Step 5: Final Parity Report
- [ ] Step 6: Rinse and Repeat
Step 1. Execute Side-by-Side Interactions
You MUST invoke the browser_subagent tool to interactively test both applications. Formulate a specific subagent task to perform the following actions in tandem:
- Navigation: Click through all primary and sub-resource routes. Do the URL structures match or have a clear mapping?
- Data Entry: Submit the same data into both legacy and modern forms. Ensure both succeed or fail in the same way.
- Empty States: Compare views when no data is present.
Step 2. Compare Network Payloads (Terminal / CLI)
You MUST use the run_command tool with curl to directly query and intercept API requests, avoiding browser caching or rendering delays:
- Request Bodies: Ensure the new frontend API routes accept the exact same field names and types expected by the legacy API contract.
- Response Envelopes: Verify that the JSON response structure is identical (Check for wrapped vs. unwrapped payloads using
curl | jq .).
- Status Codes: Confirm that success (200/201) and failure (400/404/422/500) HTTP codes match exactly.
Step 3. Verify Complex Authorization (Terminal / CLI)
Use curl (via run_command) to construct authenticated and unauthenticated network requests to test "Owner-Only" and "Role-Only" logic:
- Unauthorized Access: If the legacy app redirects to
/login for a specific route, does the modern app do the same or return a 401?
- Horizontal Privilege Checks: Attempt a
DELETE request for another user's resource. Confirm the same failure/guard occurs in the modern app.
Step 4. Validate Edge Cases & Error Responses (Terminal / CLI)
Use curl (via run_command) to inject malformed data via POST/PUT payloads (empty JSON {}, invalid IDs, excessively long strings) and strictly compare the errors array structures returned. While the UI can be modern, the API logic must remain functionally equivalent to prevent breaking downstream consumers.
Step 5. Final Parity Report
Compile findings into a docs/verification/Functional_Parity_Report.md. Categorize every finding as Confirmed Parity, Functional Gap (missing logic), or Intentional Drift (modernized logic with a documented reason).
Step 6: Rinse and Repeat
If there are any gaps or errors during testing, go back to the modern app and fix them. Then, repeat these steps from the beginning until the modern app is a perfect functional replacement for the legacy app.