feat: expose ticket waves on public event responses
Some checks failed
lint.yml / feat: expose ticket waves on public event responses (pull_request) Failing after 0s
Some checks failed
lint.yml / feat: expose ticket waves on public event responses (pull_request) Failing after 0s
A buyer cannot choose a ticket wave without its id, and nothing public carried one: `PublicEventExtra` is `EventExtraBase`, which did not include `ticket_waves`, and the NIP-52 tags deliberately publish only the active wave with no identifier (#61). So `GET /events/{id}` and `/events/public` gave a client everything except the one field it needs to say which tier it wants — and the purchase endpoint refuses when several waves are open. Moves `ticket_waves` from `EventExtra` to `EventExtraBase`, leaving `promo_codes` as the only organizer-private field in `extra`. A wave holds an id, title, date window, currency, price, remaining stock and the fiat flags — the sales information a buyer needs in order to choose. The only thing publishing it reveals is the upcoming price schedule, which is precisely what #61 recorded as the cost of settling on flat Nostr tags; over REST it is a gain rather than a leak. Prerequisite for wave support in the webapp, which otherwise cannot offer a wave picker to anyone but the organizer. Two tests pin the projection: the public extra carries waves and never promo codes, and a serialised `PublicEvent` shows the same.
This commit is contained in:
parent
6bdebe4562
commit
209a895415
2 changed files with 79 additions and 7 deletions
22
models.py
22
models.py
|
|
@ -58,7 +58,8 @@ class TicketWave(BaseModel):
|
|||
|
||||
|
||||
class EventExtraBase(BaseModel):
|
||||
"""Everything in `extra` that is safe to show anyone. `EventExtra` adds
|
||||
"""Everything in `extra` that is safe to show anyone — ticket waves
|
||||
included, since a buyer needs a wave id to choose one. `EventExtra` adds
|
||||
the organizer-only promo codes on top; `PublicEventExtra` is this base,
|
||||
so anonymous responses can never carry them."""
|
||||
|
||||
|
|
@ -73,6 +74,19 @@ class EventExtraBase(BaseModel):
|
|||
# `effective_payment_methods`. Same field name/shape as upstream v2 so the
|
||||
# eventual rebase (#33) merges cleanly.
|
||||
payment_methods: list[str] = Field(default_factory=list)
|
||||
# Upstream v1.6.8 ticket waves — time-boxed pricing tiers. The
|
||||
# event-level `currency` / `allow_fiat` / `amount_tickets` /
|
||||
# `price_per_ticket` fields become derived values (see
|
||||
# `sync_event_ticket_waves`), which is why fork code that reads them
|
||||
# needs auditing — aiolabs/events#61.
|
||||
#
|
||||
# Public, not organizer-only: a buyer cannot choose a wave without its
|
||||
# id, and neither the public event response nor the NIP-52 tags carried
|
||||
# one before. A wave holds price, dates and remaining stock — the sales
|
||||
# information a buyer needs — so the only thing exposing it reveals is
|
||||
# the upcoming price schedule, which is what #61 regretted giving up
|
||||
# when it settled on flat Nostr tags.
|
||||
ticket_waves: list[TicketWave] = Field(default_factory=list)
|
||||
|
||||
@validator("payment_methods", pre=True)
|
||||
def normalize_payment_methods(cls, v):
|
||||
|
|
@ -92,12 +106,6 @@ class EventExtraBase(BaseModel):
|
|||
|
||||
class EventExtra(EventExtraBase):
|
||||
promo_codes: list[PromoCode] = Field(default_factory=list)
|
||||
# Upstream v1.6.8 ticket waves — time-boxed pricing tiers. The
|
||||
# event-level `currency` / `allow_fiat` / `amount_tickets` /
|
||||
# `price_per_ticket` fields become derived values (see
|
||||
# `sync_event_ticket_waves`), which is why fork code that reads them
|
||||
# needs auditing — aiolabs/events#61.
|
||||
ticket_waves: list[TicketWave] = Field(default_factory=list)
|
||||
|
||||
|
||||
PublicEventExtra = EventExtraBase
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue