Add-on Types — Reference
The lookup matrix for add-on behavior. For the concept and examples (tents included), read Add-ons — anything can be sold.
Verified against
flex-v3-backendcode (src/modules/addon/), 2026-06-10.
The four behaviors
"Type" is really two boolean flags + a category on tbl_addon_types:
| Behavior | isForcedAddon | isInformational | addonCategory | Transacts? | Fan chooses? |
|---|---|---|---|---|---|
| Optional | false | false | any (except overflow) | yes | yes |
| Forced | true | false | any (except overflow) | yes — separate vendor event | no — auto-attached |
| Informational | true | true | any | no — display only | no |
| Overflow | false | false | overflow | yes | yes |
Notes:
- Forced add-ons are displayed rolled into the suite price (e.g. $4,672 suite + $327
sales-tax "event" shown as ~$5k all-in), but in code they are separate cart line items
priced
price × seatCount, transacted as separate vendor events. The hold is atomic with the seats: if the forced add-on hold fails, the whole event rolls back. - Informational add-ons never create a cart entry ("comes with 8 parking passes").
- Forced + overflow is rejected by the config sanitizer (discarded with a WARN log).
- The same item can differ per product — parking may be forced in one store, informational in another.
Transaction event code (how an add-on maps to a vendor event)
Every add-on is itself a vendor event. An add-on row (tbl_addons) attaches to a game via
gameEventCode; each add-on option (tbl_addon_options) names the transaction event it
buys into via eventCode, plus priceCode + ticketTypeCode + a seat count — resolved with
best-available. So an add-on definition is just: what event to buy, at what price/ticket-type
code, how many seats.
Teams configure these codes on the vendor side; two real patterns:
- Per-event parallel codes — each game has its own add-on event (game
26B0403→ parking26E0403). - One shared code (Miami pattern) — every game's tax/parking reuses the same
eventCode, distinguished only by a different price-code / ticket-type-code combo.
Sandbox convention (arbitrary): SS1–SS5 = games, SS6–SS10 = parking, SS11–SS15 = F&B — or reuse one code.
Enums
| Enum | Values |
|---|---|
AddonCategory | catering · parking · merchandise · access · upgrade · overflow |
AddonLevel | event_level · order_level · suite_level |
SelectionMode (on tbl_addon_types) | exact · range — forced add-ons must be exact |
SelectionType (on tbl_addons) | single · multi — ⚠️ multi not working properly yet |
SeatCountSource | addon_defined · event_seat_count · event_count · overflow_mapping_count |
Overflow requirements (v1 contract)
An overflow add-on (extra seats beyond suite capacity) must have:
- Exactly one price option (multi-price is deferred).
suiteIdandgameEventCodeset,addonLevel = 'suite_level'.- Seats mapped in
tbl_suite_overflow_seat_mapping— composite PK(suiteId, sectionName, rowName, seatNumber), one row per overflow seat. The mapping is the inventory (these seats are not intbl_seats); all seat counts are clamped to the mapping size. An empty mapping silently drops the add-on from the catalog. - Holds use specific seats on both vendors (Host
reserveTicketswithaccept_best_available: false; ArchticsseatsHoldSpecific). Host sends each (section, row) as a min→max range, so mapped seats should be contiguous within a row.