Some checks are pending
offline / test (push) Waiting to run
Account-balance stores display names and looks up by name. Edge writes names on customer create/edit; staff UIs join from edge when needed. New verae-staff-session issues a host cookie; department HTML redirects when STAFF_AUTH=1. JOBS_EVENTS_EXCLUSIVE lets jobs-events own the durable consumer. Catalog index is cards; disabled fleet machines are grey.
65 lines
2 KiB
TypeScript
65 lines
2 KiB
TypeScript
/**
|
|
* Prepaid mutations. Account-balance is the writer when NATS or HTTP books exist.
|
|
* Tests (no NATS_URL, no ACCOUNT_BALANCE_URL) keep a local cache only.
|
|
*/
|
|
import { natsAdjust, natsPublish, natsStatement } from './billing-nats';
|
|
import type { AccessPlane } from './billing-nats';
|
|
|
|
export type PrepaidRow = {
|
|
customerId: string;
|
|
veraeUserId?: string;
|
|
cents: number;
|
|
reason: string;
|
|
agent: string;
|
|
kind?: string;
|
|
prepaidCents?: number;
|
|
};
|
|
|
|
function booksUrl(): string {
|
|
return (process.env.ACCOUNT_BALANCE_URL || '').replace(/\/$/, '');
|
|
}
|
|
|
|
export function booksConfigured(): boolean {
|
|
return Boolean(process.env.NATS_URL || booksUrl());
|
|
}
|
|
|
|
export async function ledgerAdjust(row: PrepaidRow, plane: AccessPlane): Promise<PrepaidRow | null> {
|
|
const viaNats = await natsAdjust(row, plane);
|
|
if (viaNats && typeof viaNats === 'object' && viaNats !== null && 'prepaidCents' in viaNats) {
|
|
return viaNats as PrepaidRow;
|
|
}
|
|
const base = booksUrl();
|
|
if (!base) return null;
|
|
const r = await fetch(`${base}/adjust`, {
|
|
method: 'POST',
|
|
headers: { 'content-type': 'application/json' },
|
|
body: JSON.stringify(row),
|
|
});
|
|
if (!r.ok) return null;
|
|
return (await r.json()) as PrepaidRow;
|
|
}
|
|
|
|
export async function ledgerPutCustomer(row: {
|
|
customerId: string;
|
|
name?: string;
|
|
veraeUserId?: string;
|
|
}): Promise<void> {
|
|
natsPublish('verae.billing.customer.put', row, 'staff');
|
|
const base = booksUrl();
|
|
if (!base) return;
|
|
await fetch(`${base}/customer`, {
|
|
method: 'POST',
|
|
headers: { 'content-type': 'application/json' },
|
|
body: JSON.stringify(row),
|
|
}).catch(() => {});
|
|
}
|
|
|
|
export async function ledgerStatement(customerId: string, plane: AccessPlane, veraeUserId?: string) {
|
|
const nats = await natsStatement(customerId, plane, veraeUserId);
|
|
if (nats) return nats;
|
|
const base = booksUrl();
|
|
if (!base) return null;
|
|
const r = await fetch(`${base}/statement/${encodeURIComponent(customerId)}`);
|
|
if (!r.ok) return null;
|
|
return r.json();
|
|
}
|