J4 / UPGRADES
← All practice results

p2-03-express

Public GitHub evidence ↗

# P2-03 — Express RealWorld: GREEN (measured practice scope)

Target: `gothinkster/node-express-realworld-example-app` @ `30b68e1e881462b2f4164ea09ab4c4f5699c7b0b`.
Express **4.18.2 → 5.2.1**, exact version committed in package.json and package-lock.json. Owned fork: `j4groupfounders/node-express-realworld-example-app`, branch `j4/p2-upgrade`, verified SHA `e151567f0a008351f6c9492be8357d0e7c698af7`.
Pre-registration: `5df3a66322ff3e20f79098b08c340682535525a2`.

## Acceptance evidence

- Primary project suite: **26 runnable tests pass baseline and upgrade**, five suites. One pre-existing TODO remains unchanged; no tests deleted, newly skipped, or made nonblocking. `npm test` targets the app Jest suite; we invoke its Jest config directly without Nx daemon orchestration. The separately generated `e2e/` placeholder expecting `{message: 'Hello API'}` is outside that default target and is **not claimed as tested** (declared in baseline notes before upgrade). This is a scope limitation.
- TypeScript application compile check passes.
- Real HTTP process backed by a migrated empty PostgreSQL database boots. Six frozen snapshots match status, content-type and normalized body hash: `/` 200; `/api/tags` 200; `/api/articles` 200; `/api/user` 401; `/j4-missing` 404; malformed `POST /api/users/login` 422.
- Five independent route faults: project tests detect **0/5**, project tests + harness detect **5/5**. Miss rate falls 100% → 0%, meeting both seeded-fault gates for this deliberately narrow fault set. Every mutation is restored; no live mutated branch or upstream PR exists.
- **Zero human edits**. All changes made by this bounded coding worker.

## CI ledger

| Run | Outcome | Job minutes |
|---|---|---:|
| [37533006053](https://github.com/j4groupfounders/node-express-realworld-example-app/actions/runs/37533006053) | Baseline: 4 tests fail because mock loaded after service import | 0.667 |
| [37533252361](https://github.com/j4groupfounders/node-express-realworld-example-app/actions/runs/37533252361) | Baseline: 26 pass; malformed login produces 500 | 0.750 |
| [37533460011](https://github.com/j4groupfounders/node-express-realworld-example-app/actions/runs/37533460011) | Baseline: tests + compile + six HTTP snapshots pass | 0.817 |
| [37533655943](https://github.com/j4groupfounders/node-express-realworld-example-app/actions/runs/37533655943) | First framework upgrade: tests + compile + differential pass | 0.833 |
| [37533953442](https://github.com/j4groupfounders/node-express-realworld-example-app/actions/runs/37533953442) | Committed lockfile verification + five seeded faults pass | 0.917 |

Total: **5 CI runs, 3.984 actual job minutes**. Preregistration-to-terminal wall time: approximately **10.07 min** (21:17:48–21:27:53 UTC); includes scheduling/parallel waiting. Public standard Linux runners; no paid service or model calls launched by scripts.

## Baseline repairs / owner decision

1. Initialize the existing Prisma mock via Jest `setupFilesAfterEnv`, before importing services. No assertion changes.
2. Existing malformed login `{}` formerly returns 500 due to undefined user. Supply an empty object to the existing login validator; now returns 422 with the existing email-validation error. **Intentional baseline bug fix, owner-review behavior change**; documented before freezing snapshots, not silently attributed to the framework upgrade.

The framework upgrade itself needs only Express pin/lock changes; no new compatibility shim.

## Limits

Empty-database unauthenticated HTTP surface only; no authenticated HTTP replay, frozen-clock fixture scenario, route-enumeration coverage percentage, line-coverage percentage, password-boundary mutation, or token-expiry mutation is claimed. The five HTTP-output faults show a gap in service-unit tests, not representative whole-app defect detection. This result is not a full production-readiness claim. No measured token/spend telemetry is available to this worker; no token-cost estimate is presented as measurement.