# Drop — Test Coverage Report 2026-07-16 (MC #105817)

# Drop — Test Coverage Report (MC #105817, Proveo audit)

Agent ID: proveo-105817
Verdict: CONDITIONS-FOUND

Date: 2026-07-16
Scope: /Users/makinja/ALAI/products/Drop (symlink → ~/business/ALAI-Holding-AS/products/Drop)
Method: static file-mapping + live test execution (vitest, drop-api and drop-app), CI config read, git history read. No coverage numbers fabricated — see "Not verified" section for what could not be executed.

## 1. Executive summary

Drop has FOUR distinct, unequally-tested surfaces:

| Surface | Test framework | Local run result | Verdict |
|---|---|---|---|
| `apps/drop-api` (Hono/TS, "legacy") | Vitest | **0/259 tests ran** — every suite fails at `beforeAll` (no Postgres) | BLOCKED locally |
| `apps/drop-app` (Next.js) | Vitest + Playwright + Stryker | 1155 passed / 361 failed / 252 skipped (96 files) — all 34 failing files are `tests/integration/*` (Postgres auth), unit tests pass | PARTIAL — integration layer blocked, unit layer healthy |
| `backend/` (Kotlin/Ktor, "migration target") | Kotest (assumed) | Not run (Gradle) | **4 test files vs 71 source files** — ~5% file coverage, and **not in git** |
| `apps/drop-mobile` (Expo/RN) | Jest + Detox + Playwright smoke | Not run this session | Only a Playwright smoke report from 2026-02-22 exists (no unit coverage evidence found) |

**Biggest finding is not a coverage number — it's a false "done."** MC #5124 ("Drop backend migration: Hono/TS → Kotlin/Ktor", H priority, CEO-mandated stack per ALAI CLAUDE.md 2026-03-17) is marked **Status: done** (completed 2026-03-29), but its `blocked_reason` field still reads *"autowork: 5 failed attempts, needs human review"*, and the actual output — `backend/` — is:
- untracked in git (`git ls-files backend/` = 0 files; `git status` shows `?? backend/`)
- has zero mention in `BUILD-BLUEPRINT.md` or `DEPLOY-MAP.md`
- covers only 4 of 71 Kotlin source files with tests (`ApplicationTest`, `PiiEncryptionTest`, `JwtServiceTest`, `AmlServiceTest` — auth/compliance modules only; banking, cards, complaints, consents, cron, dataaccess, disputes, merchants, notifications, rates, recipients, reports, settings, transactions, user, webhooks, withdrawal have **no Kotlin tests at all**)
- production (per Drop's own CLAUDE.md "Production Infrastructure" section) still runs `drop-app + drop-api` (the old TS stack) on the Azure VM — the Kotlin backend is not deployed anywhere

This means the CEO-mandated migration is being reported as complete while sitting as uncommitted, ~95%-untested code nobody can build on CI (it isn't even in the repo). Recommend John re-open #5124 or open a new MC task scoped to "commit + test-cover backend/ OR formally shelve it," not silently leave it "done."

## 2. drop-api (apps/drop-api) — Hono/TypeScript

- 71 non-test `.ts` files under `src/`, 16 test files (all under `src/__tests__/`, one per route/middleware area: reports, transactions, user, cards, merchants, admin, recipients, complaints, settings, consents, notifications, auth, withdrawal, cron, rates, health + `middleware/{auth,validation,rate-limit,error-handler}`).
- **Untested modules (no corresponding test file found):** `admin-auth.ts`, `alerts.ts`, `audit.ts`, `bankid.ts`, `circuit-breaker.ts`, `constants.ts`, `db.ts`, `email.ts`, `feature-flags.ts`, `idempotency.ts`, `logger.ts`, `metrics.ts`, `migrate.ts`, `notification-service.ts`, `push.ts`, `redis.ts`, `sentry.ts`, `transaction-monitor.ts`, `utils-server.ts`, all `services/*.ts` (fx-rates, mock-bank, mock-exchange, mode, payments, settlement, sms), and routes `disputes.ts`, `ob-consents.ts`, `openapi.ts`, `webhooks.ts`, `metrics.ts`, `server.ts`, `app.ts`. That's ~35 files (roughly half the app) with **no unit test file at all** — some logic may be exercised indirectly through route tests, but idempotency, webhooks, and settlement/payments services (the money-movement critical path) having zero direct tests is a red flag for a fintech product.
- **Local execution result: 100% blocked.** `npx vitest run --coverage` → all 20 suites fail in `src/__tests__/setup.ts` → `initDb()` → `Cannot connect to PostgreSQL... DATABASE_URL is required` (259 tests skipped, 0 executed). Root cause: no local Postgres listening on the port the test env resolves to; `.env` says port 5433, but nothing in this repo's `docker-compose.yml` was running (verified via `docker ps` — a `bilko-postgres-test` container occupies host port 5433, which would also collide with Drop's own compose file if started).
- **CI gap:** `.github/workflows/ci.yml` job `drop-api-test` (lines ~329-355) runs only `npx tsc --noEmit` + `npm run test` with `NODE_ENV: test` — **no `services: postgres` block, no DB startup step, no coverage step, no coverage-threshold gate, no `npm audit`** (unlike the sibling `drop-app-test` job which has all of these). This job can only be passing in CI today if the self-hosted `[anvil, drop]` runner happens to have a long-lived Postgres container matching these exact credentials already up — an undeclared, unreproducible dependency. Recommend: add an explicit Postgres service/step to `drop-api-test`, mirroring `drop-app-test`, and add the same 80/70/80/80 coverage gate.

## 3. drop-app (apps/drop-app) — Next.js

- 96 test files under `tests/{unit,integration,security,regression,performance}`, CI enforces 80/70/80/80 statement/branch/function/line thresholds + a coverage ratchet (never decrease vs. main) + Stryker mutation testing (60% kill-score gate on changed files) + Playwright E2E — **this is the most mature test setup in the repo.**
- Live run this session: `npx vitest run --coverage` → **1155 passed, 361 failed, 252 skipped** across 96 files, 174s. No coverage-summary.json was written because the run did not complete cleanly (see below) — coverage percentages could not be verified this session; rely on CI's own gate history for real numbers.
- **All 34 failing test files are exactly `tests/integration/api/*.test.ts`** (recipients, remittance-submit, settings, transactions, transfers, user, withdrawal, and others) — every failure is the same root cause: `error: password authentication failed for user "drop"` inside `tests/helpers/pg-test-db.ts::cleanupTestData`. Unit tests (mocked, no DB) all pass. This confirms the integration layer is fully dependent on a correctly-seeded local Postgres that isn't currently reachable/credentialed on this machine — same class of problem as drop-api, but only affecting the integration subset here, not the whole suite.
- Because the coverage summary file was never written on a failed run, **the CI "Enforce coverage thresholds" step would itself hard-fail with a missing-file error** in this exact scenario (`fs.readFileSync('coverage/coverage-summary.json')`), not just a threshold miss — worth confirming this doesn't happen on a real CI run (it likely doesn't fail this way in CI because CI's Postgres is provisioned correctly there; flagging as a fragility point, not a confirmed CI failure).

## 4. backend/ — Kotlin/Ktor ("migration target", MC #5124)

- 71 `.kt` files under `src/main/kotlin`, 4 under `src/test/kotlin`: `ApplicationTest`, `PiiEncryptionTest`, `auth/JwtServiceTest`, `modules/compliance/AmlServiceTest`.
- 20 business modules exist (admin, auth, banking, cards, complaints, compliance, consents, cron, dataaccess, disputes, health, merchants, metrics, notifications, openapi, rates, recipients, reports, settings, transactions, user, webhooks, withdrawal) — **16 of them have zero test coverage** (only auth, compliance/AML, and one root smoke test are covered).
- Entire `backend/` tree is **untracked** — not a single commit touches it (`git log -- backend/` empty, `git ls-files backend/` = 0). It exists only on this local machine's working directory. If this machine's disk is lost, this "completed" migration is gone with it.
- See §1 for the MC #5124 status contradiction.

## 5. drop-mobile (apps/drop-mobile) — Expo/React Native

- Has `jest` unit test config (`test:coverage` script exists) plus 16 Detox e2e specs (`e2e-detox/01-auth.test.js` … `16-error-recovery.test.js`) plus a Playwright web-smoke spec (`test-screens.spec.js`).
- Only artifact found: `TEST_REPORT.md`, dated **2026-02-22**, a one-off Playwright smoke run (not unit coverage) — 17/18 screens passed, **Onboarding screen flagged FAILED with JS console errors** (`ERR_CONNECTION_REFUSED` resource-load errors on every screen, one screen with an actual runtime error) and Receipt screen flagged as suspiciously low content (69 chars). No evidence this was re-verified after 2026-02-22, and no jest/coverage run was executed this session (out of scope for time — flagging as **not verified**, not as "passing").
- Recommend a follow-up Proveo task specifically for drop-mobile: run `npm run test:coverage` (Jest) live and re-run the Playwright smoke to confirm Onboarding is still broken or was fixed.

## 6. Flaky / environment-dependent tests (not "logic" flaky, but real)

No evidence of nondeterministic (intermittently-failing-on-identical-input) tests was found. All failures observed this session are **deterministic environment failures** (missing/misconfigured Postgres), not flakiness — every failing suite fails the same way, every time, for the same reason. This is actually the more important finding: the "flaky" symptom a dev would see (tests fail sometimes, pass other times) is fully explained by whether a correctly-seeded local Postgres happens to be running — which is a setup/CI hygiene issue, not flaky test logic.

## 7. Not verified this session (be explicit, no fabrication)

- Actual numeric coverage % for drop-api and backend/ (never produced a coverage-summary.json — blocked by missing DB / not run for Kotlin).
- Real coverage % for drop-app (run did not complete cleanly enough to emit `coverage/coverage-summary.json`; historical CI runs would have this — not fetched this session, out of scope/budget).
- Whether `drop-api-test` CI job is actually green right now on GitHub Actions (no `gh run list` check performed this session).
- drop-mobile Jest coverage (not executed).

## 8. Recommendations (priority order)

1. **[H]** Resolve MC #5124 status contradiction — either commit `backend/` to git with a real test suite covering the 16 untested modules, or formally mark the Kotlin migration shelved/paused and correct the MC record. Route: John + CodeCraft.
2. **[H]** Fix `drop-api-test` CI job: add explicit Postgres service, coverage step, and 80/70/80/80 gate to match `drop-app-test`. Route: FlowForge.
3. **[M]** Add unit tests for drop-api's untested money-movement modules: `idempotency.ts`, `services/payments.ts`, `services/settlement.ts`, `webhooks.ts`, `ob-consents.ts`. Route: CodeCraft.
4. **[M]** Re-run drop-mobile Jest coverage + re-verify Onboarding screen JS error from TEST_REPORT.md (2026-02-22, never re-confirmed). Route: Proveo follow-up task.
5. **[L]** Document local dev Postgres setup so `npm test` works out-of-the-box without manual `docker compose up` + port conflicts (port 5433 currently contested with an unrelated `bilko-postgres-test` container on this host).