feat(crewing): EPFO/UAN assisted verification (GstService pattern, flagged) #89

Merged
shad0w merged 1 commit from feat/crewing-epfo into feat/crewing-followups 2026-06-22 18:54:50 +00:00
Owner

Crewing — EPFO / UAN assisted verification (GstService pattern)

Builds EPFO/UAN verification the same way GST works (per spec A3"EPFO proxy microservice, GstService pattern"). Stacks on #88 (follow-ups); base feat/crewing-followups. Behind NEXT_PUBLIC_CREWING_ENABLED.

What's in

  • EpfoService/ — new standalone microservice mirroring GstService (Express + Playwright). EPFO is OTP-gated (no anonymous captcha lookup like GST), so the handshake is two steps: POST /otp {uan} → session + OTP request; POST /verify {sessionId,uan,otp} → member record; GET /health. The live portal navigation is stubbed behind EPFO_LIVE (default STUB: OTP 000000 → matched) until the real selectors/OTP are validated against a live session.
  • App proxies: /api/epfo/otp + /api/epfo (gated by verify_bank_epf) → EPFO_SERVICE_URL. EpfDetail += epfoMemberName + epfoCheckedAt; recordEpfoCheck persists the lookup result + audit.
  • UI: an EPFO check affordance on the verification EPF rows — request OTP → enter OTP → matched member → record. Sits next to the existing manual Verify/Reject.

Aadhaar — intentionally not handled

UIDAI restricts Aadhaar verification to licensed AUA/KUA via consented e-KYC; it can't be portal-scraped. Aadhaar stays assisted-manual (only aadhaarLast4 stored, masked). The EpfoService README spells this out.

Tests & docs

  • Integration: verification.test.ts gains recordEpfoCheck (records name + timestamp, Accounts-only gating).
  • type-check clean; full unit (245) + integration (213) green (RESEND_API_KEY unset).
  • .env.example (EPFO_SERVICE_URL/EPFO_LIVE), CLAUDE.md, EpfoService/README.md.

⚠️ The live EPFO portal selectors + OTP flow are TODO(live) stubs — validate against a real session before setting EPFO_LIVE=true. (Same posture GstService started from.)

🤖 Generated with Claude Code

## Crewing — EPFO / UAN assisted verification (GstService pattern) Builds EPFO/UAN verification the same way GST works (per spec **A3** — *"EPFO proxy microservice, GstService pattern"*). Stacks on **#88** (follow-ups); base `feat/crewing-followups`. Behind `NEXT_PUBLIC_CREWING_ENABLED`. ### What's in - **`EpfoService/`** — new standalone microservice mirroring `GstService` (Express + Playwright). EPFO is **OTP-gated** (no anonymous captcha lookup like GST), so the handshake is two steps: `POST /otp {uan}` → session + OTP request; `POST /verify {sessionId,uan,otp}` → member record; `GET /health`. The live portal navigation is **stubbed behind `EPFO_LIVE`** (default STUB: OTP `000000` → matched) until the real selectors/OTP are validated against a live session. - **App proxies:** `/api/epfo/otp` + `/api/epfo` (gated by `verify_bank_epf`) → `EPFO_SERVICE_URL`. `EpfDetail += epfoMemberName + epfoCheckedAt`; `recordEpfoCheck` persists the lookup result + audit. - **UI:** an **EPFO check** affordance on the verification EPF rows — request OTP → enter OTP → matched member → record. Sits next to the existing manual Verify/Reject. ### Aadhaar — intentionally not handled UIDAI restricts Aadhaar verification to licensed AUA/KUA via consented e-KYC; it can't be portal-scraped. Aadhaar stays **assisted-manual** (only `aadhaarLast4` stored, masked). The `EpfoService` README spells this out. ### Tests & docs - Integration: `verification.test.ts` gains `recordEpfoCheck` (records name + timestamp, Accounts-only gating). - `type-check` clean; full unit (245) + integration (213) green (`RESEND_API_KEY` unset). - `.env.example` (`EPFO_SERVICE_URL`/`EPFO_LIVE`), `CLAUDE.md`, `EpfoService/README.md`. > ⚠️ The live EPFO portal selectors + OTP flow are `TODO(live)` stubs — validate against a real session before setting `EPFO_LIVE=true`. (Same posture GstService started from.) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
shad0w added 1 commit 2026-06-22 17:13:51 +00:00
feat(crewing): EPFO/UAN assisted verification (GstService pattern, flagged)
All checks were successful
PR checks / checks (pull_request) Successful in 40s
PR checks / integration (pull_request) Successful in 30s
e193e26368
Scaffolds EPFO/UAN verification the same way GST works — a standalone Playwright
proxy microservice + an /api proxy + an assisted affordance that records the
result. Aadhaar stays manual (UIDAI-restricted). Stacks on the follow-ups branch.
Behind NEXT_PUBLIC_CREWING_ENABLED.

What's in
- EpfoService/ (new microservice, GstService pattern): Express + Playwright.
  POST /otp {uan} → session + OTP request; POST /verify {sessionId,uan,otp} →
  member record; GET /health. EPFO is OTP-gated (no anonymous captcha lookup like
  GST), so the handshake is two steps. Live portal navigation is gated behind
  EPFO_LIVE (default STUB: OTP 000000 → matched) until real selectors/OTP are
  validated. README documents the differences + that Aadhaar is out of scope.
- App: /api/epfo/otp + /api/epfo proxies (gated by verify_bank_epf) to
  EPFO_SERVICE_URL. EpfDetail += epfoMemberName + epfoCheckedAt (migration
  crewing_epfo_check). recordEpfoCheck action persists the EPFO result + audit.
- UI: an "EPFO check" affordance on the verification EPF rows — request OTP →
  enter OTP → matched member → record. Aadhaar noted as manual-only.

Tests & docs
- Integration: verification.test.ts gains recordEpfoCheck (records name+timestamp,
  Accounts-only gating). type-check clean; full unit (245) + integration (213)
  green (RESEND_API_KEY unset).
- .env.example (EPFO_SERVICE_URL/EPFO_LIVE), CLAUDE.md, EpfoService/README.

Note: the EpfoService live portal selectors/OTP are stubbed and must be validated
against a real EPFO session before enabling EPFO_LIVE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
shad0w merged commit 63858f0b5c into feat/crewing-followups 2026-06-22 18:54:50 +00:00
Sign in to join this conversation.
No description provided.