gis-api POST /enrichment/cf only inserts a pending row; no orchestrator
worker executes the ePay purchase, so pilot-flag orders silently never
complete. EPAY_ORDERING_VIA_GIS_AC=false routes all paid orders through
/api/ancpi/order and restores the connected+credits gating on the
per-parcel button. Flip the constant after the orchestrator ePay worker
ships.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Yesterday's pin to /api/ancpi exposed a real architecture split: there
are two CfExtract stores with no overlap and the previous pilot routing
only ever showed one at a time:
architools_postgres.CfExtract → ePay paid orders (type=epay)
gis_core.CfExtract via gis-api → CF intern (type=intern)
The pin made today's 50198 ePay visible but hid the 51 historic intern
rows; the pre-pin state was the opposite. Neither was right — users
think of "my CF extracts" as one timeline regardless of source.
Revert the pin and add client-side merge for pilot users (`useGisAc=true`):
fetchCfOrdersList now fans out to both /api/ancpi/orders and /api/cf/orders
in parallel, normalizes each row through a dedicated adapter (legacy or
gisApi), dedupes by id, and sorts by createdAt descending. fetchCfHas-
CompletedForCadastral checks both backends too (either a fresh intern
or a recent ePay row means "you already have one").
CfExtractRecord grows a required `type: 'epay' | 'intern'` field; the
existing rendering adds a small colored badge (sky=intern, emerald=ePay)
next to the status pill so users can tell where each row came from at
a glance. cfDownloadUrl is now type-aware — intern rows download via
/api/cf/:id/pdf, ePay rows via /api/ancpi/download regardless of pilot
flag, matching how each store keeps its files. Legacy (useGisAc, id)
signature still works for the few call sites that don't have the full
row in scope.
No data was deleted yesterday; the 51 intern rows in gis_core stayed
intact (verified via gis_superuser). The single edit was cancelling
the stuck 354686 pending row from 2026-05-19.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three independent issues from the live test on 50198:
1. CfOrderModal poll timeout was 90s but ANCPI orders routinely take
60-180s end-to-end. The 50198 order completed at 129s (logs show
6 polls before docs matched), but the modal had already errored
out 39s before that with "Procesarea durează mai mult decât ne-am
așteptat". Bump to 180s + update the user-facing copy from "60 de
secunde" to "3 minute" so the expectation matches reality.
2. cfApiBase(useGisAc=true) routed pilot users to /api/cf which proxies
to gis-api → gis_core."CfExtract", but the ePay queue still writes
ONLY to architools_postgres."CfExtract". Pilot users were therefore
blind to their own fresh orders in the listing + catalog checks
(50198 invisible despite being completed + downloadable). Pin all
CF API calls to legacy /api/ancpi until Faza H mirrors writes to
gis-api too; the source of truth then becomes a single table.
3. Manual cleanup of one stuck order in gis_enrichment.CfExtract
(354686, pending since 2026-05-19) — never advanced past `pending`,
was showing up as "În coadă" in the Extrase CF tab for ~4 days.
Set status=cancelled with an explanatory errorMessage.
(Applied via direct SQL on postgres-gis; no code change for this.)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Plan 003 Faza F. Pilot users (session.useGisAc=true) get their CF
extract flow routed through api.gis.ac (RLS-filtered, RLS-owned
writes); everyone else keeps the legacy /api/ancpi/* path
unchanged. Feature-flag preserves rollback.
New routes (5):
- POST /api/cf/order → gisApi.enrichment.cf.create. Forwards
409 catalog_hit verbatim.
- GET /api/cf/orders → gisApi.enrichment.cf.list (limit, offset, status).
- GET /api/cf/[id] → gisApi.enrichment.cf.get.
- PATCH /api/cf/[id] → gisApi.enrichment.cf.patch.
- GET /api/cf/[id]/pdf → streams gisApi.enrichment.cf.getPdf
through to browser. Filename from documentName via cf.get; falls
back to cf-<id>.pdf.
- GET /api/cf/catalog → gisApi.enrichment.catalog.
All use getAuthSession() → 401 on no session, forward GisApiError
status+code+body, fallback {error:"internal_error", hint} at 500.
runtime=nodejs, dynamic=force-dynamic.
Helper module `cf-api-base.ts`:
- cfApiBase(useGisAc) → "/api/cf" | "/api/ancpi"
- adaptCfRow(row) → maps gisApi.CfExtractRow into the UI shape
expected by epay-tab.tsx (CfExtractRecord). Fields not in gis-api
(siruta, judetName, uatName, errorMessage, etc.) default to
empty/zero — filter-by-judet/uat on the pilot path is reduced
until gis-api enriches the response.
- fetchCfOrdersList, fetchCfHasCompletedForCadastral, placeCfOrder,
cfDownloadUrl — used by components.
UI changes:
- epay-tab.tsx: reads session.useGisAc; list fetch, reorder, single
+ bulk download routed via helpers. UI shape unchanged.
- epay-order-button.tsx: existence check uses catalog endpoint on
gis-ac path; order placement uses placeCfOrder which treats 409
catalog_hit as a soft success ("Extras CF valid").
Known gaps (followups):
- /api/ancpi/session still serves ePay session/credits — no gis-api
equivalent today. epay-connect.tsx untouched.
- ZIP bulk download has no gis-api analog; "Descarcă tot" falls back
to N tabs on gis-ac path.
- src/app/api/geoportal/cf-status returns hardcoded /api/ancpi/download
URL — separate followup.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>