Skip to main content

Components

Inside Express, each module owns its tables and exposes functions to the others. HTTP handlers are thin: they validate input, call a module, and map the result to JSON. Cross-module writes that must succeed or fail together run in one Prisma transaction.

Module map​

ModuleTablesCalled by
Authenticationusers, user_credentials, refresh_tokens, account_setup_tokens, password_reset_tokens, user_mfa_factorsEvery private route
Catalogservices, service_packagesOrders
BookingsbookingsOrders, galleries, rewards
Ordersorders, order_items, idempotency_keysPayments, rewards
Paymentspayments, payment_webhook_eventsBookings, rewards, notifications
Galleriesgalleries, gallery_access_reviews, photos, photo_ratingsNotifications
Rewardsreferral_codes, referrals, reward_policies, referral_rewards, reward_ledger, reward_redemptionsOrders, payments
Notificationsnotifications, notification_deliveries, background_jobsBookings, galleries, rewards
Auditaudit_logsAuthentication, bookings, galleries, rewards

Request path for a paid booking​

  1. The catalog module loads the active package and returns price_cents.
  2. The orders module inserts the order and item snapshot. The bookings module inserts the booking. A referral code, if present and valid, inserts an attribution in the same transaction.
  3. The payments module creates a Stripe checkout for total_cents and USD.
  4. The webhook handler verifies the signature, inserts payment_webhook_events, and only then marks the order paid and the booking PENDING_APPROVAL.
  5. The rewards module may attach the qualifying order and insert a PENDING reward. It does not post a ledger credit yet.
  6. The notifications module queues photographer email and an in-app notification.

The photographer decision is a later call. Approval confirms the booking and posts the reward credit if the order is still paid. Rejection enqueues a refund and withholds the credit.

Background jobs​

Job typePurpose
email.deliverSend one notification delivery and update notification_deliveries.
image.thumbnailRead the original from private storage, write a thumbnail, and set the photo to READY.
payment.refundCall Stripe for a refund that was committed with a rejection or cancellation.
payment.reconcileRead a stuck payment from the provider when a webhook was missed.
reward.expirePost an expiration ledger entry for an available reward past expires_at.

Jobs are claimed with a row lock on background_jobs where status is pending and available_at is due. A failure increments attempt_count, stores last_error, and sets a later available_at.

Documentation container​

Docusaurus is a separate static site. It holds the pages in this project and the OpenAPI document. It does not read PostgreSQL.