03 — Inventory Snapshots
What it is: A pre-computed cache of suite availability per event, rebuilt every ~5 minutes by a cron job. The home page reads this instead of recomputing pricing on every request.
Why it exists
The home page needs to show available suites + "from" price per event. Computing that live means walking the full pipeline (active program → inventory type → pricing → build suites → add-ons) on every request. Under a marketing blast (thousands of fans at once), even a warm cache can get stampeded. The snapshot pre-bakes the answer.
Trade-off: data can be up to ~5 minutes stale. This is intentional.
Table: tbl_inventory_snapshots
Composite PK: (programId, eventCode) — one row per program/event combination.
| Field | Notes |
|---|---|
programId | which program this snapshot was built for |
eventCode | which event |
data | JSONB array of suite offering objects (sorted cheapest first) |
computedAt | when this snapshot was last computed |
data JSONB structure
Each element in the array = one suite offering (full or partial):
{
"offeringKey": "suite-19-full",
"suiteId": 19,
"suiteName": "Suite 19",
"displayName": "Private Luxury Suite",
"suiteTypeId": 1,
"seatCount": 18,
"isPartial": false,
"totalBasePrice": 4200.00,
"totalServiceFee": 300.00,
"totalAllInPrice": 4500.00,
"forcedAddonTotal": 200.00,
"grandTotal": 4700.00
}
Offering key format:
- Full suite:
suite-{suiteId}-full - Count-based partial:
suite-{suiteId}-partial-{seatCount} - Block-based partial:
suite-{suiteId}-block-{blockId}
In API responses, keys are prefixed with event code: {eventCode}-suite-{suiteId}-full.
Lifecycle
- On each cron run: rows for the program being rebuilt are hard-deleted and reinserted in one transaction (other programs untouched)
- No history retained — only the latest snapshot per program exists
- If no events have inventory for a program, no rows exist for it
- Results are also cached in Redis with a standard TTL
Key rules
- Suite-level programs only (this is the home page for Premium/suite stores)
- Snapshot is sorted by
grandTotalascending (cheapest first) - Stale by design — don't try to make this real-time