E2-F4: Match Stadium Configuration¶
Epic: E2: Match & Stadium Management
Size: M (Medium)
Problem / Outcome¶
Admins configure stadium for specific match (sector availability, pricing).
Scope¶
In-Scope:
- Configure sectors for match (active/closed/maintenance)
- Price category assignment per sector
- Price categories as the match's sellable products (Istok, Zapad sredina, VIP…), each with a price ("Cijena") and an optional match-day price ("Cijena na dan utakmice"), and the match's switch from when the match-day price applies ("Cijena na dan utakmice vrijedi od": empty = 00:00 Zagreb time on the kick-off date, so it follows a moved kick-off; a set moment must be before the kick-off) (HNSTIK-276)
- Sterile zones configuration
Out-of-Scope:
- Seat-level blocking (covered in E3)
Acceptance Criteria¶
- AC1: Given match, when admin sets sector to "Closed", then sector excluded from sellable capacity
- AC2: Given sector, when admin assigns price category, then all seats in sector inherit its price
- AC2a: Before the match's switch the zones, the cart and the order charge the category's price; from the switch on its match-day price, or its price where it has none. A FREE sector stays 0 €. The price is fixed when the seat goes into the cart: a cart opened just before the switch keeps its price for its 20 minutes (HNSTIK-276)
- AC2b: The match card's price range ("od – do") shows the prices that apply now; the fan app does not announce a coming price
- AC2c: A negative match-day price or one with more than two decimals is rejected with 422, and so is a switch at or after the kick-off
- AC3: Given configuration complete, when admin saves, then configuration is versioned and locked
Data Model Impact¶
MatchStadiumConfig table:
- id (UUID, PK)
- match_id (UUID, FK)
- stadium_id (UUID, FK)
- version (INTEGER)
- locked (BOOLEAN)
- created_at (TIMESTAMP)
MatchSector table:
- id (UUID, PK)
- match_id (UUID, FK)
- sector_id (UUID, FK)
- status (ENUM: active, closed, maintenance)
- price_category_id (UUID, FK)
PriceCategory table:
- price (DECIMAL 10,2) — "Cijena"
- match_day_price (DECIMAL 10,2, nullable) — "Cijena na dan utakmice"; NULL = price (HNSTIK-276)
Match table:
- match_day_price_from (TIMESTAMP UTC, nullable) — "Cijena na dan utakmice vrijedi od"; NULL = 00:00 Europe/Zagreb on the kick-off date (HNSTIK-276)
Permissions/Roles¶
- Admin (Match Manager)
How to Verify¶
npm test -- --grep "match stadium config"
Expected: Sectors configurable, pricing applies, versioning works.
Dependencies¶
Implementation Tasks¶
See E2: Match ## Doc References Stadium Tasks
Doc References¶
Last Updated: January 2026