- migration 037: offerings.price_amount/price_currency, offering_registrations.reservation_expires_at, payment_transactions, payment_webhook_events (webhook_event_id as real PK — the idempotency mechanism) - payment-provider.js: StripeProvider (real SDK, HMAC webhook verification) + TestProvider (deterministic, in-process, no network) behind one interface, selected via PAYMENT_PROVIDER - commerce.js: createCheckoutSession (server-side price, never caller-supplied), processWebhookEvent (idempotent), handlePaymentSuccess/Failure/CheckoutAbandoned/Refund, reservation reaper support - offerings.js: computeReservationExpiry, updateOffering (allowlisted PATCH), readiness gained price/payment_provider checks, convertRegistrationToEnrollment now fires the activation email every other enrollment path already triggers, and links the registration's guardian_id into student_guardians on conversion (real bug: a converted minor had no guardian link, so the new activation email had nowhere to resolve a recipient to) - server.js: raw-body middleware scoped to /api/webhooks/payment, reservation-reaper poller
19 lines
573 B
JSON
19 lines
573 B
JSON
{
|
|
"name": "rootnode-platform-api",
|
|
"version": "0.1.0",
|
|
"description": "RootNode Academy Platform API — students, cohorts, curriculum, progress, sessions, instructor/admin control plane. No k3s, no --privileged, no Lab terminal runtime.",
|
|
"private": true,
|
|
"main": "src/server.js",
|
|
"scripts": {
|
|
"start": "node src/server.js",
|
|
"migrate-sqlite": "node migrate-sqlite.js",
|
|
"bootstrap-owner": "node bootstrap-owner.js"
|
|
},
|
|
"dependencies": {
|
|
"better-sqlite3": "^9.4.3",
|
|
"express": "^4.19.2",
|
|
"pg": "^8.11.5",
|
|
"stripe": "^22.6.0"
|
|
}
|
|
}
|