Skip to main content

01 — Flex Programs

What it is: The top-level configuration container for a Flex store. Everything a team configures — how fans pick events, how packs are structured, what pricing is used — hangs off a program.


Core idea

A store can have many published programs but only one active at a time. The active program drives the whole store. To run a flash sale or change mid-season, a team pre-configures a second program and flips which one is active — no code changes, no manual edits.

Three program types:

  • Build Your Own (BYO) — fan picks any events within a min/max range
  • Game Packs — structured packs, each with one or more tiers
  • Preset Packages — fixed or flexible bundles of specific events

Tables

tbl_flex_programs — the root

FieldNotes
programTypebuild_your_own, game_packs, preset_packages
isActiveonly ONE should be true at a time (app enforced)
statusdraft, published, archived

tbl_flex_program_configs — per-program settings (JSONB)

One row per key per program. Keys:

KeyWhat it controls
inventoryinventoryType (seat vs suite level), ADA filter, multi-pricing, block limiter
ledgerwhich ledger this program uses
pack_structurepacks_with_tiers or packs_only
payment_planenabled / required toggles

tbl_flex_program_class_names — which class names (access groups) this program sells

Previously stored as JSONB; moved to its own table. TM uses className, other vendors use classNameId.

tbl_flex_program_pricing_labels — for multi-pricing per seat

Only used when multiplePricingPerSeat.isEnabled = true. Defines labels like "Cash Price" / "Flex Credit" with optional price/ticket-type code filters.


BYO tables

tbl_build_your_own_config

Just minEvents + maxEvents per program. Eligible events are not "all of tbl_events" — they come from the tbl_build_your_own_events junction below, intersected with the live catalog (findByProgramIdWithEvents + filterAndSortEvents).

tbl_build_your_own_events

The program's event eligibility list (one row per eligible event) — also carries each event's buildStatus (not_builtbuildingbuilt) + isSoldOut. Only events present here (and live in the catalog) are offered to fans.


Game Pack tables

tbl_game_packs

FieldNotes
selectionModeexact (min = max) or range (min < max)
minEvents / maxEventspack-level constraints
isDefaultPackpre-selected in UI; only one per program

tbl_game_pack_tiers

Every pack must have at least one tier. Tiers have their own minEvents/maxEvents. Sum of tier minEvents must be ≥ pack minEvents (and ≤ pack maxEvents when set).

tbl_pack_tier_events

Links events to tiers. An event can appear in multiple packs/tiers across packs, but not in two tiers of the same pack.


Preset Package tables

tbl_preset_packages

Two types:

  • preset — fixed event list; optionally allow replacement of sold-out events
  • flexible — fan selects from an event pool (min/max)

Both can allow allowOptionalEvents (fan adds extra events from tbl_events outside the package).

tbl_package_events

For preset: these are the fixed events. For flexible: this is the pool to choose from.


Unlock Special Games ⚠️ (spec only — not implemented)

⚠️ These tables are a design spec, not yet built — don't expect them in the running schema or code.

tbl_unlock_special_games

Special/exclusive events hidden from normal listings. Unlock when conditions are met. Can be configured as removable or locked to cart.

tbl_unlock_conditions

Conditions that trigger an unlock. Logic rules:

  • Multiple rows for same unlock = OR (any row satisfying = unlocks)
  • Multiple non-null fields in one row = AND (all must be true)

Condition types: min_event_count, specific_pack, specific_package, custom.


Key rules

  • Only one active program at a time (app enforced, not DB)
  • Every game pack must have at least one tier
  • Unlocks (once built) would be re-evaluated on every cart change; if conditions fail, the special game is removed
  • Class names migrated from JSONB to tbl_flex_program_class_names — don't look for them in the config JSONB