Clean prepaid SoT, identity mailbox, public access planes, leaf policy, fleet spawn
Some checks are pending
offline / test (push) Waiting to run
Some checks are pending
offline / test (push) Waiting to run
Persist account-balance books; edge caches prepaid from books. Add zappier-identity, verae-nats-accounts, verae-jobs-events, verae-access-staff, zapier-decisions. Edge binds loopback; lan-134 stays off; HTTP services prefer local spawn.
This commit is contained in:
parent
345aeeead9
commit
ddf772454b
153 changed files with 2236 additions and 116 deletions
|
|
@ -13,7 +13,8 @@ import { UsageRepo } from './usage';
|
|||
import { CreditLedger } from './credits';
|
||||
import { invoicesToAccountingCsv, invoicesToQuickBooksIif } from './accounting-export';
|
||||
import { composeStatement } from './statement';
|
||||
import { BILLING_SUBJECTS, natsAdjust, natsPublish, natsStatement } from './billing-nats';
|
||||
import { BILLING_SUBJECTS, natsPublish } from './billing-nats';
|
||||
import { booksConfigured, ledgerAdjust, ledgerStatement } from './ledger';
|
||||
|
||||
// Issued login tokens (in-memory; a restart simply requires logging in again).
|
||||
const sessions = new Map<string, number>();
|
||||
|
|
@ -229,7 +230,7 @@ export function adminRouter(
|
|||
|
||||
/* ---------------- customer service: credits ---------------- */
|
||||
|
||||
router.post('/credits', (req, res) => {
|
||||
router.post('/credits', async (req, res) => {
|
||||
const { customerId, cents, reason, agent } = req.body ?? {};
|
||||
if (typeof customerId !== 'string' || !Number.isFinite(Number(cents))) {
|
||||
res.status(400).json({ error: 'customerId and cents required' });
|
||||
|
|
@ -247,9 +248,7 @@ export function adminRouter(
|
|||
reason: typeof reason === 'string' ? reason : 'credit adjustment',
|
||||
agent: typeof agent === 'string' ? agent : 'admin',
|
||||
});
|
||||
customers.save({ ...customer, balanceCents: (customer.balanceCents ?? 0) + delta });
|
||||
natsPublish(BILLING_SUBJECTS.CREDIT_APPLIED, { ...rec, veraeUserId: customer.veraeUserId }, 'staff');
|
||||
void natsAdjust(
|
||||
const row = await ledgerAdjust(
|
||||
{
|
||||
customerId,
|
||||
veraeUserId: customer.veraeUserId,
|
||||
|
|
@ -260,7 +259,12 @@ export function adminRouter(
|
|||
},
|
||||
'staff',
|
||||
);
|
||||
res.status(201).json(rec);
|
||||
let prepaid = customer.balanceCents ?? 0;
|
||||
if (row && typeof row.prepaidCents === 'number') prepaid = row.prepaidCents;
|
||||
else if (!booksConfigured()) prepaid += delta;
|
||||
customers.save({ ...customer, balanceCents: prepaid });
|
||||
natsPublish(BILLING_SUBJECTS.CREDIT_APPLIED, { ...rec, veraeUserId: customer.veraeUserId }, 'staff');
|
||||
res.status(201).json({ ...rec, prepaidCents: prepaid });
|
||||
});
|
||||
|
||||
router.get('/credits', (req, res) => {
|
||||
|
|
@ -274,9 +278,9 @@ export function adminRouter(
|
|||
res.status(404).json({ error: 'customer not found' });
|
||||
return;
|
||||
}
|
||||
const fromNats = await natsStatement(customer.id, 'staff', customer.veraeUserId);
|
||||
if (fromNats) {
|
||||
res.json({ ...fromNats, name: customer.name, tierId: customer.tierId, source: 'nats' });
|
||||
const fromBooks = await ledgerStatement(customer.id, 'staff', customer.veraeUserId);
|
||||
if (fromBooks) {
|
||||
res.json({ ...fromBooks, name: customer.name, tierId: customer.tierId, source: fromBooks.source || 'account-balance' });
|
||||
return;
|
||||
}
|
||||
res.json({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue