guard(epay): force legacy queue for paid CF orders — gis-api has no fulfiller yet

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>
This commit is contained in:
Claude VM
2026-06-04 17:45:55 +03:00
parent 372a9c55ea
commit 077ec401fb
2 changed files with 23 additions and 7 deletions
@@ -15,6 +15,15 @@
import type { CfExtractRow } from "@/lib/gis-api-client"; import type { CfExtractRow } from "@/lib/gis-api-client";
// GUARD (2026-06-04): ePay ordering via gis-api is NOT live yet. gis-api's
// POST /enrichment/cf only inserts a pending CfExtract row — there is no
// orchestrator-side worker that executes the paid ePay purchase, so orders
// placed through /api/cf/order silently never complete (UI even shows
// "Extras CF valid"). Until that fulfiller ships and is verified, ALL paid
// ePay orders MUST go through the legacy local queue (/api/ancpi/order).
// Flip to true only after the orchestrator ePay worker is deployed.
export const EPAY_ORDERING_VIA_GIS_AC = false;
export function cfApiBase(useGisAc: boolean): string { export function cfApiBase(useGisAc: boolean): string {
return useGisAc ? "/api/cf" : "/api/ancpi"; return useGisAc ? "/api/cf" : "/api/ancpi";
} }
@@ -254,7 +263,9 @@ export async function placeCfOrder(
gisFeatureId?: string; gisFeatureId?: string;
}, },
): Promise<{ ok: boolean; error?: string }> { ): Promise<{ ok: boolean; error?: string }> {
if (useGisAc) { // See EPAY_ORDERING_VIA_GIS_AC — gis-api can't fulfill paid orders yet,
// so the pilot flag alone must NOT route ordering away from the queue.
if (useGisAc && EPAY_ORDERING_VIA_GIS_AC) {
try { try {
const res = await fetch("/api/cf/order", { const res = await fetch("/api/cf/order", {
method: "POST", method: "POST",
@@ -13,6 +13,7 @@ import {
import { cn } from "@/shared/lib/utils"; import { cn } from "@/shared/lib/utils";
import type { EpaySessionStatus } from "./epay-connect"; import type { EpaySessionStatus } from "./epay-connect";
import { import {
EPAY_ORDERING_VIA_GIS_AC,
fetchCfHasCompletedForCadastral, fetchCfHasCompletedForCadastral,
placeCfOrder, placeCfOrder,
} from "./cf-api-base"; } from "./cf-api-base";
@@ -49,6 +50,10 @@ export function EpayOrderButton({
const useGisAc = Boolean( const useGisAc = Boolean(
(session as { useGisAc?: boolean } | null)?.useGisAc, (session as { useGisAc?: boolean } | null)?.useGisAc,
); );
// Effective ordering route: even on pilot accounts, paid ePay orders go
// through the legacy queue until the gis-api fulfiller ships — see
// EPAY_ORDERING_VIA_GIS_AC in cf-api-base.ts.
const orderViaGisAc = useGisAc && EPAY_ORDERING_VIA_GIS_AC;
const [ordering, setOrdering] = useState(false); const [ordering, setOrdering] = useState(false);
const [ordered, setOrdered] = useState(false); const [ordered, setOrdered] = useState(false);
@@ -114,13 +119,13 @@ export function EpayOrderButton({
} }
}, [nrCadastral, siruta, judetName, uatName, useGisAc]); }, [nrCadastral, siruta, judetName, uatName, useGisAc]);
// On the gis.ac path, the orchestrator dispatches ePay calls through // On the (future) gis.ac path, the orchestrator dispatches ePay calls
// a shared account pool — the user doesn't need a personally-connected // through a shared account pool — no personally-connected ePay session
// ePay session, and we don't have per-user credit info to gate on. // needed. The legacy queue (current route while the guard is on)
// Legacy path still requires local connection + credits. // requires local connection + credits.
const disabled = const disabled =
ordering || ordering ||
(!useGisAc && (!orderViaGisAc &&
(!epayStatus.connected || (!epayStatus.connected ||
(epayStatus.credits != null && epayStatus.credits < 1))); (epayStatus.credits != null && epayStatus.credits < 1)));
@@ -131,7 +136,7 @@ export function EpayOrderButton({
if (error) return error; if (error) return error;
if (ordering) return "Se comanda..."; if (ordering) return "Se comanda...";
if (ordered) return "Extras CF valid"; if (ordered) return "Extras CF valid";
if (!useGisAc) { if (!orderViaGisAc) {
if (!epayStatus.connected) return "ePay neconectat"; if (!epayStatus.connected) return "ePay neconectat";
if (epayStatus.credits != null && epayStatus.credits < 1) return "Credite insuficiente"; if (epayStatus.credits != null && epayStatus.credits < 1) return "Credite insuficiente";
} }