Skip to content

fix(web): point passport proxy at entity-shape backend route#340

Open
ctol3r wants to merge 1 commit into
mainfrom
wave/passport-proxy-shape-fix
Open

fix(web): point passport proxy at entity-shape backend route#340
ctol3r wants to merge 1 commit into
mainfrom
wave/passport-proxy-shape-fix

Conversation

@ctol3r
Copy link
Copy Markdown
Owner

@ctol3r ctol3r commented May 12, 2026

Summary

The web proxy at apps/web/app/api/passport/[npi]/route.ts was fetching the wrong backend endpoint. The backend has two passport routes with divergent contracts:

Backend route Contract Function
GET /api/passport/:npi NPI-shape{npi, accessMode, public, credentials, sanctions, privileges, decisions, meta} loadPassportData() in routes/passport.ts (public/wallet/selective modes)
GET /api/passport/npi/:npi Entity-shape{entityId, identity, authority, training, standing, readiness, sources, sourceCoverage, lastCheckedAt, trustPosture, ...} buildPassportDataByNpi() via routes/passportEntity.ts

The web proxy's validator assertPassportData (in apps/web/lib/trust/passport-contract.ts) is built for the entity-shape, but the proxy was calling the NPI-shape route. Every seeded NPI returned 502 invalid_upstream_payload.

Fix

One-line URL change in the proxy: /api/passport/${npi}/api/passport/npi/${npi}.

Adds a guard test (passport-proxy-routes.test.ts: new case) that asserts the upstream URL contains /api/passport/npi/ so this can't regress.

Validation against live runtime

GET http://localhost:3030/api/passport/1346053246
→ 200, 15075 bytes
→ keys: authority, credentials, decisionPosture, entityId, identity,
        lastCheckedAt, monitoring, npi, readiness, sourceCoverage,
        sources, standing, training, trustPosture, truth

Truth rules

  • No banned phrases in changed surfaces.
  • No new claims about verification status — the fix only routes the proxy at the correct backend endpoint.

Validation

  • Targeted tests: 4/4 passing (__tests__/passport-proxy-routes.test.ts)
  • Build: pnpm turbo run build --filter @vitalcv/web13/13 tasks, 39s

Scope

  • apps/web/app/api/passport/[npi]/route.ts (1-line URL change + comment)
  • apps/web/__tests__/passport-proxy-routes.test.ts (1 guard test added)

The web proxy at /api/passport/[npi] was calling the backend's
/api/passport/:npi (loadPassportData / public-or-wallet NPI-shape) but
its validator (assertPassportData) expects the entity-shape — top-level
entityId, identity, authority, training, standing, readiness, sources,
sourceCoverage, lastCheckedAt, trustPosture — that the backend's
/api/passport/npi/:npi (buildPassportDataByNpi) returns.

Result against a seeded NPI:
  before: 502 {"error":"invalid_upstream_payload","detail":"…"}
  after:  200 with all 14 top-level keys present and valid

Adds a guard test pinning the upstream URL so a regression that
re-routes back to the NPI-shape endpoint can't silently reintroduce
the 502.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vcv-web Ready Ready Preview, Comment May 12, 2026 5:40am
vitalcv Ready Ready Preview, Comment May 12, 2026 5:40am

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants