Brand match and question sponsorships¶
The page at /admin/brand-sponsorships lets you assign a brand to matches in
two independent ways: whole-match sponsor, and/or per-question
sponsorships. You can set a match sponsor without configuring any question
sponsorships.
Concepts¶
| Kind | Storage | Claim / edit |
|---|---|---|
| Whole-match sponsor | Match.sponsor_brand_id |
Brand Sponsorships page or match detail |
| Question sponsorships | question_sponsorships rows |
Pre-allocated; claimed at issue time onto QuestionIssuance |
Each question sponsorship has a strategy, optional target, optional best_effort (period only), and optional question definition pin:
| Strategy | Target | Claim rule |
|---|---|---|
question_number |
1-based sequence string ("3") |
Exact match on next issuance sequence |
period |
Period label ("1", "1:T") |
First unused for that issued_in_period; best_effort defaults on |
period + best_effort: false |
Same | Exact period only (no fallback after the period is past) |
random |
null | Next unused random sponsorship |
Optional question definition: when the slot would claim next, the listener forces that definition (still subject to allowlists / active / triggers). If it cannot issue, no question is issued for that event. The brand is stamped only when the issued definition matches the pin.
Claim order at issue: question_number → period (exact) → period (best
effort, target already past) → random. Capacity:
sponsored_slot_count <= match.question_max_count.
Data source¶
- Match sponsor:
PATCH /api/matches/{id}withsponsor_brand_id - Question sponsorships write:
POST /api/brands/{brand_id}/question-sponsorships - Question sponsorships read:
GET /api/brands/{brand_id}/question-sponsorships(optionalmatch_ids); match detail also includes all brands’question_sponsorships
Edits require the match to be scheduled with no listener (same as question overrides). The matches list only shows those editable matches.
Workflow¶
- Open Manage → Brand Sponsorships.
From the Matches board, the Question sponsorships count
deep-links here with
match_id, local calendarday, andleague. When the match is editable (scheduled, no listener), it is auto-selected and filtered into view. If it cannot be selected (wrong day/league, already started, or load error), a toast explains why and the page loads normally for that day. - Select a Brand and filter/check matches (day range, league, search,
Match sponsor Any/None/by brand, Question sponsorships comparison like
>= 1or=0on total count). Use Clear filters to reset search, league, sponsor, and sponsorship-count filters (does not clear the selected brand or day range). Only unstarted (scheduled) matches with no listener appear. Sponsor shows the whole-match sponsor brand (highlighted when it is the selected brand). Sponsorships is always a clickable count (selected brand’s when a brand is chosen; otherwise the match total). Click opens the modal (search/filter and column sort for strategy, target, best effort, brand). - Whole-match sponsor (optional, standalone):
- Set as match sponsor — PATCHes selected matches with this brand
- Clear match sponsor — clears
sponsor_brand_idon selected matches - Question sponsorships (optional, standalone):
- Configure rows (strategy + target; Best effort on by default for period) → Apply question sponsorships
- Random share — enter 1–100% → Apply random share replaces this
brand’s slots on each selected match with
round(question_max_count × % / 100)randomslots (count can differ per match). Claimed when no more-specific unused slot matches. - Clear this brand’s sponsorships sends empty
slotswith replace
Match detail also edits the match sponsor and shows a read-only question sponsorships table. For test clones, set sponsor and slots on Clone Past Match (listener starts immediately).
Related¶
- Brands — brand identity CRUD
- Matches — match detail and overrides
- Clone Past Match — sponsor + slots on clone create
- API resources — brands and matches endpoints