From 977db6d63a9d356fea8c2088ae99042f4c60343f Mon Sep 17 00:00:00 2001 From: Claude VM Date: Mon, 18 May 2026 08:16:43 +0300 Subject: [PATCH] feat(cutover): Faza C feature-flag infra for api.gis.ac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Server-side helper useGisAcFlag(email) → boolean, gated by: - USE_GIS_AC=1 (global rollout switch), OR - GIS_AC_PILOT_USERS=a@x,b@y (per-email staged rollout) Both defaults are off (USE_GIS_AC=0, pilot list empty) in Infisical /architools — this PR is dormant; no call sites consume the flag yet. Future Faza D/E call sites in src/lib/gis-api-client.ts and src/modules/geoportal/* will branch on it. Exposed on session.useGisAc so client components can branch identically to server routes without a separate API roundtrip. Re-evaluated per request → flag flip via Infisical + container restart, no rebuild. Per-user override (PILOT_USERS) is the rollout vehicle: 1. Deploy with flag=0 (default) → nothing changes 2. Set GIS_AC_PILOT_USERS=marius@... → Marius sees new code path 3. Watch 24-48h → set USE_GIS_AC=1 → global cutover 4. Rollback = unset USE_GIS_AC Co-Authored-By: Claude Opus 4.7 (1M context) --- src/core/auth/auth-options.ts | 5 +++++ src/core/feature-flags/use-gis-ac.ts | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/core/feature-flags/use-gis-ac.ts diff --git a/src/core/auth/auth-options.ts b/src/core/auth/auth-options.ts index 0a35617..fe2b9b5 100644 --- a/src/core/auth/auth-options.ts +++ b/src/core/auth/auth-options.ts @@ -1,5 +1,6 @@ import type { NextAuthOptions } from "next-auth"; import AuthentikProvider from "next-auth/providers/authentik"; +import { useGisAcFlag } from "@/core/feature-flags/use-gis-ac"; export const authOptions: NextAuthOptions = { providers: [ @@ -55,6 +56,10 @@ export const authOptions: NextAuthOptions = { (session.user as any).company = token.company || "group"; } (session as any).accessToken = token.accessToken; + // Faza C cutover flag — exposed on session so client components can + // branch the same way server routes do (env-driven, evaluated per + // request so flag flip + container restart picks up without rebuild). + (session as any).useGisAc = useGisAcFlag(session.user?.email); return session; }, }, diff --git a/src/core/feature-flags/use-gis-ac.ts b/src/core/feature-flags/use-gis-ac.ts new file mode 100644 index 0000000..b517835 --- /dev/null +++ b/src/core/feature-flags/use-gis-ac.ts @@ -0,0 +1,20 @@ +// Server-side feature flag for the api.gis.ac cutover (Plan 003, Faza C). +// +// Off by default → all parcel/eterra/geoportal call sites keep using the +// legacy local-DB code path. Flip via Infisical /architools: +// USE_GIS_AC=1 → global enable +// GIS_AC_PILOT_USERS=a@x,b@y → per-email override for staged rollout +// +// After redeploy, call sites read useGisAcFlag(session.user.email) and +// branch between the legacy path and the gis-api thin client (Faza D). + +const PILOT_USERS = (process.env.GIS_AC_PILOT_USERS || "") + .split(",") + .map((s) => s.trim().toLowerCase()) + .filter(Boolean); + +export function useGisAcFlag(userEmail?: string | null): boolean { + if (process.env.USE_GIS_AC === "1") return true; + if (!userEmail) return false; + return PILOT_USERS.includes(userEmail.toLowerCase()); +}