Frontend, backend, pricing engine, and payments.


The client's domain understanding was still evolving during the build. Pricing rules, enrollment constraints, and fee configuration all shifted within a compressed window. Every migration had to leave existing data valid.
fix_discount_rule_sessions_duplicate_fk) resolved the ambiguity by collapsing to a single FK path. In a live system, the first migration would have meant silent data corruption. In a migration-driven schema, it was a recoverable two-step correction with a full audit trail.Once the schema was stable, the pricing engine could be built.
Before checkout completes, every item in the cart runs through a multi-step pricing pipeline:
A deterministic pricing engine is only useful if you can actually collect the money.
This isn't a Stripe integration. The payment processor is Elavon's EPG, a bank-grade gateway used by enterprise and institutional clients. No SDK. HTTP Basic auth with a merchant alias. HATEOASHypermedia as the Engine of Application StateA REST pattern where API responses include links to related resources. The client navigates by following those links rather than constructing URLs. Each step returns the href needed for the next.-style resource references.
href pointers into Elavon's system.The payment flow is four layers deep. Each layer has a security checkpoint.
doCapture: false on installments. Separates card collection from charging.crypto.timingSafeEqual prevents credential brute-forcing via response time.isAuthorized, not status code.// Node.js runtime enforced — edge lacks crypto.timingSafeEqual
export const runtime = "nodejs";
// Timing-safe auth comparison
const expectedBuf = Buffer.from(expected);
const actualBuf = Buffer.from(
authHeader.padEnd(expected.length, "\0").slice(0, expected.length),
);
authValid =
expectedBuf.length === Buffer.from(authHeader).length &&
crypto.timingSafeEqual(expectedBuf, actualBuf);
// Never trust the notification body — always re-fetch
let transaction;
try {
transaction = await fetchEpgTransaction(resource);
} catch (err) {
return NextResponse.json(
{ error: "Failed to fetch transaction" },
{ status: 500 }
);
}
// Terminal state replay protection
const terminalStates = [
"authorized", "captured", "settled",
"declined", "voided", "refunded"
];
if (terminalStates.includes(payment.state)) {
return NextResponse.json({ ok: true });
}Pricing and payments solved, the hardest concurrency problem remained.
Registration is a multi-step flow. A family shouldn't lose their spot while filling out a payment form. But you can't reserve spots indefinitely — abandoned carts would lock out real registrations. And two families can't both hold the last spot in a class.
pending_payment status and a hold_expires_at timestamp written at checkout start. The spot is theirs while they're in the flow.Before a registration is written, every enrollment is validated against a configurable rule engine:
The alternative (trust the client, compute on the frontend, use application-level locks) would have been faster to build initially. But every one of these features has a failure mode that client-side logic can't catch: stale quotes, race conditions, partial payment failures, abandoned checkouts. Building at the database layer made each failure mode explicit, testable, and recoverable.
Key technical implementations from the challenges above.
WHERE status = 'pending'). The webhook is the sole writer of confirmation state.Every table in the production schema, organized by domain. Arcs are sized by table count. Chords show cross-domain foreign key coupling. Hover any arc to explore.
The client portal leads with a near-black hero — it reads as a stage before the first word registers, placing the studio's 30-year identity front and center. The violet-to-rose gradient on ‘Center Stage’ is the only decorative moment. Below, a cool lavender-tinted off-white grounds the enrollment flows.
The admin surface flips to a light, high-contrast environment. Staff spending hours in the dashboard need legibility over atmosphere. Deep crimson anchors primary actions without competing with data-dense tables.