feat(parcel-sync): add ANCPI ePay CF extract ordering backend
Foundation (Phase 1): - CfExtract Prisma model with version tracking, expiry, MinIO path - epay-types.ts: all ePay API response types - epay-counties.ts: WORKSPACE_ID → ePay county index mapping (42 counties) - epay-storage.ts: MinIO helpers (bucket, naming, upload, download) - docker-compose.yml: ANCPI env vars ePay Client (Phase 2): - epay-client.ts: full HTTP client (login, credits, cart, search estate, submit order, poll status, download PDF) with cookie jar + auto-relogin - epay-session-store.ts: separate session from eTerra Queue + API (Phase 3): - epay-queue.ts: sequential FIFO queue (global cart constraint), 10-step workflow per order with DB status updates at each step - POST /api/ancpi/session: connect/disconnect - POST /api/ancpi/order: create single or bulk orders - GET /api/ancpi/orders: list all extracts - GET /api/ancpi/credits: live credit balance - GET /api/ancpi/download: stream PDF from MinIO Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Server-side ePay session store (global singleton).
|
||||
* Separate from eTerra session — different auth system.
|
||||
*/
|
||||
|
||||
type EpaySession = {
|
||||
username: string;
|
||||
password: string;
|
||||
connectedAt: string;
|
||||
credits: number;
|
||||
creditsCheckedAt: string;
|
||||
};
|
||||
|
||||
const g = globalThis as { __epaySession?: EpaySession | null };
|
||||
|
||||
export function createEpaySession(
|
||||
username: string,
|
||||
password: string,
|
||||
credits: number,
|
||||
): void {
|
||||
g.__epaySession = {
|
||||
username,
|
||||
password,
|
||||
connectedAt: new Date().toISOString(),
|
||||
credits,
|
||||
creditsCheckedAt: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
export function destroyEpaySession(): void {
|
||||
g.__epaySession = null;
|
||||
}
|
||||
|
||||
export function getEpayCredentials(): {
|
||||
username: string;
|
||||
password: string;
|
||||
} | null {
|
||||
const session = g.__epaySession;
|
||||
if (!session) return null;
|
||||
return { username: session.username, password: session.password };
|
||||
}
|
||||
|
||||
export function getEpaySessionStatus(): {
|
||||
connected: boolean;
|
||||
username?: string;
|
||||
connectedAt?: string;
|
||||
credits?: number;
|
||||
creditsCheckedAt?: string;
|
||||
} {
|
||||
const session = g.__epaySession;
|
||||
if (!session) return { connected: false };
|
||||
return {
|
||||
connected: true,
|
||||
username: session.username,
|
||||
connectedAt: session.connectedAt,
|
||||
credits: session.credits,
|
||||
creditsCheckedAt: session.creditsCheckedAt,
|
||||
};
|
||||
}
|
||||
|
||||
export function updateEpayCredits(credits: number): void {
|
||||
if (g.__epaySession) {
|
||||
g.__epaySession.credits = credits;
|
||||
g.__epaySession.creditsCheckedAt = new Date().toISOString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user