# Backend Jest Suite Repair

Audience: AI coding agents first.

## Outcome

Safely review untrusted recovered ZIP. Retain only minimal changes that repair real standalone backend Jest failures. Commit locally. NEVER push, merge, rebase, deploy, or touch another worktree.

## Status

IDLE — local commit exists in the worktree; ready for parent-controlled landing. Nobody is executing. Task ID: BACKEND-JEST-REPAIR-2026-08-11.

## Source Request

Finish preserved standalone-backend Jest repair lane in `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/ask-gpt-backend-jest`. Fetch current GitHub `origin/master`; preserve post-snapshot primary state; compare eight historical repair paths from read-only `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/backend-test-repair`; transplant only unmatched current-contract-valid test/setup work; reconcile surgically; use TDD for remaining account/full-suite failures; preserve license-owner checks, inactive-admin checks, rate limits, authorization boundaries, and assertion strength; run focused/full Jest, TypeScript, and expert gates cleanly; commit locally only. NEVER push, merge, deploy, remove worktrees, delete recovery refs, or mutate comparison/other worktrees/GitHub.

Original recovered candidate: `/home/user/.cache/agent-tmp/claude-1000/-home-user-Projects-Press-zone-wordpress-wp-content-plugins-international-press-zone/7b24368f-13dc-46e9-8d3f-5d1b6ab05f39/scratchpad/downloads/backend-tests-retry/jest-suite-fix-files(1).zip`.

## Scope and Constraints

- Worktree: `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/ask-gpt-backend-jest`.
- API root: `press-zone-backend/api`.
- Candidate paths: two Jest setup files, seven tests, `src/middleware/auth.ts`.
- Candidate ZIP is untrusted. Compare every file to current worktree/origin master before change.
- Preserve production auth, translation, credit, encryption, settings, Gemini, token-calculation, structured-field contracts.
- `src/middleware/auth.ts`: change ONLY after proof of genuine production defect; NEVER change for mock accommodation.
- NEVER skip tests, weaken assertions, add fake passes, stubs, placeholders, or broad assertions.
- Reproduce failures first where feasible. Run targeted Jest then complete prescribed gate, including TypeScript, lint/static checks, Prisma generation/schema checks where configured. Resolve every warning/open handle.
- Local commit only. One terse imperative sentence. No `Co-Authored-By` trailer.

## Acceptance Criteria

1. Every original ZIP path and all eight comparison repair paths classified accepted, modified, already matched, or rejected with evidence.
2. Each remaining account/full-suite failure reproduced; corrected test observed RED for intended current contract before GREEN.
3. Patch is minimal and test/setup-only unless a real production defect is proven.
4. License-owner checks, inactive-admin checks, rate limits, authorization boundaries, and assertion strength remain unchanged.
5. Focused Jest suites, full Jest, TypeScript, and complete backend/expert gates pass with exact clean counts and no ignored signal.
6. Local commit exists with one terse imperative sentence; no push/merge/rebase/deploy/worktree removal/ref deletion occurred.
7. Final receipt names accepted/rejected files, RED/GREEN evidence, full gate counts, commit SHA, blockers, and parent-landing readiness.

## Preserved WIP

- Primary snapshot: `refs/wip-snapshot/current-20260811/wt-ask-gpt-backend-jest` at `be5ebbde1f98067efae0fafb3e1bc983193c65f5`.
- Comparison snapshot: `refs/wip-snapshot/current-20260811/wt-backend-test-repair` at `097f5bd9dc83d50c16abf15cb80eac5264aa7514`.
- Primary code WIP matched its snapshot before continuation mutation; comparison worktree matched its snapshot and remains read-only.
- Refreshed canonical baseline: `origin/master` at `77687984de63ca5765990de27dca5fb62d7ce8cf`; commits after `843757012` are docs-only.
- Pre-existing worktree state MUST remain untouched except task-owned plan and verified repair files. Original artifact/package context remains read-only.

## Execution Steps

1. Read backend rules, applicable skills, current config, scripts, setup, mock patterns, candidate files, and named original package context.
2. Extract ZIP to isolated temporary directory; diff every candidate against current worktree and `origin/master`.
3. Reproduce failures; identify root causes.
4. Apply only validated minimal changes; reject unsafe or obsolete proposal content.
5. Run targeted tests, full prescribed gate, static and Prisma checks.
6. Independently review diff and security boundary changes; commit clean result locally.

## Current Receipt

2026-08-11: Created plan registry in assigned worktree. Read backend rules and applicable skill categories. ZIP inventory confirmed: two setup files, seven tests, and `src/middleware/auth.ts`. Baseline `npm test -- --runInBand`: 10 failed suites, 69 failed tests; 33 passed suites, 368 passed tests. ZIP auth removes license-owner and inactive-admin checks: rejected security regression. Canonical setup is now `src/__tests__/setup.ts`; Jest config loads it, root setup imports were migrated, and Redis defaults are installed before `beforeAll` app construction. Focused JWT, credit, Gemini, settings, translation, and encryption suites passed: 201 tests. Current full Jest remains red: stale admin/account route fixtures/contracts return 500/401/404 under preserved production auth. No commit.

2026-08-11 continuation: canonical setup now has explicit `@jest/globals`, `node:buffer`, and `node:process` imports. Typed Redis mock factories replace implicit `never`-typed Jest mocks. `npx tsc --noEmit` is clean; focused JWT suite passes 29/29. Admin suite repaired without production changes: typed queue/config mocks, persistent admin update fixture, current plural `subscriptions` DTOs, current jobs fields, current `/analytics/jobs` contract, transaction callback, and configuration-propagation mocks. Admin integration passes 26/26. Account suite remains under repair: it is structurally stale against current `/profile`, `/transactions`, `/credits`, and API-key contracts; old tests target removed `/` and `/usage` shapes and use invalid raw API-key fixtures. No commit.

2026-08-11 continuation assignment: mandated expert and mapped skills loaded. Primary and comparison worktrees inspected against recovery refs before mutation: code WIP exactly matched both snapshots; primary plan/index were recovery-only untracked files. Fetched GitHub baseline: `origin/master` is `77687984de63ca5765990de27dca5fb62d7ce8cf`; change after triage evidence `843757012` is docs-only. No production file changed. Worker: current Claude agent.

2026-08-11 resumed lane: dependencies installed in worktree (`npm ci`, `prisma generate`). Baseline re-derived on disk, NOT assumed: full Jest = 3 failed suites / 20 failed tests, 40 passed suites / 530 passed tests, 550 total. Failing: `account.test.ts`, `auth.test.ts`, `translate.test.ts`. Root cause class identified and proven from source: fixtures use camelCase + singular `subscription`, while the current Prisma contract is snake_case with a `subscriptions` array; API-key auth requires `Authorization: Bearer` plus a nested `user.subscriptions` include. `auth.test.ts` repaired fixture-only: RED 500/401 -> GREEN 23/23. `translate.test.ts` transplanted from the comparison lane (base file byte-identical, `Model` genuinely unexported, `X-API-Key` -> `Authorization: Bearer` verified correct) then further repaired. `src/middleware/auth.ts` re-read in full and confirmed intact: `LICENSE_OWNER_REQUIRED`, inactive-account, plugin-scope and subscription checks all present; NOT modified. `resetMocks: false` verified defensible: `src/__tests__/setup.ts` `beforeEach` performs `mockReset` plus `restoreRedisDefaults()`. Two error-body shapes confirmed coexisting and both legitimate: zod validation returns top-level `code`, `errorResponse()` returns nested `error.code`. Open signal: express-rate-limit `ERR_ERL_INVALID_HITS` caused by the Redis `evalsha`/`eval`/`call` mock returning a zero hit count.

2026-08-11 completion: comparison lane fully adjudicated independently. All eight comparison paths classified; UNMATCHED hunks = ZERO, so nothing further was transplanted. `refs/wip-snapshot/current-20260811/wt-backend-test-repair` is fully superseded by primary. Redis subsumption question settled with quoted evidence: primary's `restoreRedisDefaults()` reproduces the comparison lane's SCRIPT-LOAD/EVALSHA discrimination and additionally survives per-test reset, whereas the comparison lane's inline implementation is destroyed by its own unchanged `resetMocks: true`. Root `__tests__/setup.ts` deletion confirmed safe: the only reference was `jest.config.js` `setupFilesAfterEnv`, already retargeted; the `__tests__` root still holds two tracked suites that now inherit the shared setup.

Branch reconciled onto canonical baseline: fast-forwarded to `origin/master` `77687984de63ca5765990de27dca5fb62d7ce8cf`; HEAD now equals `origin/master` with zero divergence. The 37 intervening commits touch no `press-zone-backend` file, so reconciliation was conflict-free. Pre-mutation snapshots created and retained: `refs/wip-snapshot/inprogress-20260811/backend-jest-mid`, `refs/wip-snapshot/preff-20260811/backend-jest`. No recovery ref deleted.

`ERR_ERL_INVALID_HITS` resolved at the single source of truth rather than per file: the Redis mock now returns a positive `[totalHits, resetSeconds]` from `restoreRedisDefaults()`, and the duplicated per-file override was removed. Rate limiter configuration itself was NOT touched.

Final gates, all clean: full Jest `--runInBand` 43/43 suites, 586/586 tests; full Jest with default parallel workers (different file order) 43/43, 586/586 — no order dependence; `npx tsc --noEmit` clean; `npm run lint` (eslint) clean; `prisma generate` succeeds. Zero `console.error`, zero `console.warn`, zero open-handle warnings. `npx prisma validate` fails only on an absent `DATABASE_URL` in this shell; it is not a package script and `prisma generate` plus `tsc` cover the schema — recorded benign, environment-only.

Anti-weakening audit of the whole diff: no `.skip`/`.only`/`xit` added; 22 weak `toBeDefined()`/`toBeTruthy()` assertions REMOVED and 0 added; assertion counts rose in every changed file except `admin.test.ts`, whose single net reduction is a legitimate retarget from the non-existent `/v1/admin/analytics/models` to the real `/v1/admin/analytics/jobs`, whose DTO is an object rather than an array. `src/middleware/auth.ts` and every other production file remain unmodified.

Suspected production defects found and deliberately NOT fixed (test-only lane; both need a product decision):
1. `src/services/translationService.ts:342` reads `transaction.balanceAfter`, but `deductCredits` resolves the raw Prisma row whose column is `balance_after`. `newBalance` is therefore `undefined`, so `creditBalance` is silently absent from sync-translation responses.
2. `DELETE /v1/account/api-keys/:keyId` responds 200 "revoked successfully" for a key that is missing or owned by another user. Ownership scoping holds (the `user_id`-filtered `findFirst` blocks cross-user mutation), so this is a misleading response, not a security hole.

### Mutation evidence that the rewritten assertions are not vacuous

The rewritten (meaning-changed) assertions were mutation-tested against production code, then production was restored from `HEAD` and the worktree reconfirmed clean.

- Removed the `user_id` ownership filter from `revokeApiKey` in `src/auth/apiKeyService.ts`: account suite went 21/21 -> 2 failed / 19 passed, failing exactly `should ensure user can only access their own keys` and `should not mutate anything for non-existent keys`. The rewritten DELETE assertions therefore genuinely bind the authorization boundary, and are stronger than the `toBeDefined()` they replaced.
- Client-supplied model: honouring `request.model` in the service alone, and separately making `translateSchema` `.passthrough()`, both left the suite green — because three independent layers (zod strips unknown keys, the route maps only explicit fields into the service request, and the service derives the model from the provider response) each prevent client control. Corrupting the persisted value directly (`model: 'invalid-model'` at the sync-path persistence site) DID fail exactly the model test, proving the assertion binds the real persisted value rather than being tautological.

### Rate-limit preservation

Rate limiter configuration was not touched. The only change is the shared Redis mock's script result, from `[0, 0]` to a positive `[1, 60]`, which is what `rate-limit-redis` requires. `src/__tests__/unit/middleware/rateLimiter.test.ts` asserts tier-limit RESOLUTION (`resolveRequestRateLimit`, `getRateLimit`, zero-means-unlimited bypass), not store hit accounting, and no suite anywhere asserts a 429 or `RATE_LIMIT_EXCEEDED`. A constant hit count of 1 is exactly as permissive as the previous 0, so no throttling assertion changed behaviour or coverage.

### Gate coverage justification

The pre-commit gate reported two `Not analysed` lines: JavaScript/TypeScript (no `package.json` at repository root) and Trivy (binary not installed). This is incomplete coverage, not a pass, and is accepted as benign for this change only because the diff is test/setup-only, contains no secrets or dependency changes, and was independently covered by `npx tsc --noEmit`, `npm run lint`, `npm run build`, and the full Jest suite. Composer/PHP legs are not applicable.

### Read-only constraint attestation

- Comparison worktree `.worktrees/backend-test-repair` is byte-identical to `refs/wip-snapshot/current-20260811/wt-backend-test-repair` (empty diff); it was never mutated.
- The shared `wp-content` checkout still shows only the three backend files that were already dirty at session start, plus pre-existing untracked paths; this lane changed nothing there.
- All pre-existing `refs/wip-snapshot/**` refs remain present; two were ADDED (`inprogress-20260811/backend-jest-mid`, `preff-20260811/backend-jest`) and none deleted.
- `wt/ask-gpt-backend-jest` is exactly one commit ahead of `origin/master` and was never pushed, merged, rebased onto anything else, or deployed.

### Test-count reconciliation (550 -> 586)

The rise is recovered coverage, not padding. At baseline `translate.test.ts` failed to COMPILE (`TS2305: Module '"../../../types"' has no exported member 'Model'`), so none of its tests were counted. 550 baseline + 35 now-running translate tests + 1 net new account test = 586, with auth flat at 23. Net new tests authored: 3 (one translate auth-branch split, two account branches previously untested).

## Next Executable Action

Lane complete. Branch `wt/ask-gpt-backend-jest` is ready for parent-controlled landing. No push, merge, deploy, worktree removal, or ref deletion performed.