feat: tickets-by-user endpoint + Nostr-driven inventory sync #15
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "tickets-nostr-sync"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Two pieces the webapp needs to restore the ticket purchase + "tickets
visible in the events area" loop after the activities module was
extracted into a standalone Nostr-driven PWA.
1. GET /api/v1/tickets/user/{user_id} (commit
814581f)The webapp's MyTickets view + the owned-ticket badges across the
activities feed both rely on this endpoint to enumerate a buyer's
tickets across events. The CRUD function
get_tickets_by_user_idalready existed; just expose it.
to other LNbits endpoints).
user_idmust match the token-bounduser.id— userscan only enumerate their own tickets, not anyone else's by ID
guessing.
Ticketrows (notPublicTicket) because the ownerneeds the payment_hash (for the QR) + the
extraenvelope (forrefund / promo / notification state) in My Tickets.
2. Ticket counts in NIP-52 tags + republish on sale (commit
edf1493)Inventory sync over Nostr, mirroring how
nostrmarketrepublisheskind 30018 product events when stock changes. Connected webapp /
other-client subscriptions pick up the new state via their existing
relay subscription — no REST polling needed.
build_nip52_eventgrows four AIO custom tags on every publishedkind 31922/31923 event:
tickets_availableamount_tickets > 0. Omitted when capacity is unlimited (the schema's0sentinel) so clients can tell unlimited from sold-out.tickets_soldoriginal_capacity = available + soldand render progress bars.tickets_priceprice_per_ticket.0means free.tickets_currencycurrencyfield.Tags are AIO additions outside the NIP-52 spec; spec-compliant
clients MUST ignore unknown tags so this stays backwards-compatible.
set_ticket_paidnow callspublish_or_delete_nostr_event(event)after the counter update so the new state lands on relays. The
whole sequence (counter update + republish) is wrapped in a per-
event-id
asyncio.Lockto address the existing# todo: lockandto ensure two paid invoices for the same event can't reorder the
published state.
Failures inside the Nostr publish are logged + swallowed by the
existing wrapper, so a relay outage can never break the payment
flow.
Smoke
Static smoke against the local regtest stack — tag construction
verified for the three cases:
amount_ticketstickets_available=10,tickets_sold=3,tickets_price=100.0,tickets_currency=sats).tickets_availablecorrectly omitted; the other three present.Endpoint smoke:
GET /events/api/v1/tickets/user/{user_id}rejectsunauthenticated requests with 401 (
Missing user ID or access token.).End-to-end smoke (recommended before merge)
The companion webapp PR (forthcoming) consumes these tags. Before
merging:
— confirm the four new tags are present.
tickets_soldincrements and the event is republished.simultaneously, confirm
soldincrements by 2 (lock preventsthe double-publish race) and the final published event reflects
the latest counters.
Test plan
tickets_sold/tickets_availableupdatein the republished event.
tickets_availabletag staysabsent across multiple sales.
auth and refuses cross-user enumeration with 403.
🤖 Generated with Claude Code