feat: add user_id ticket support and public events endpoint
Some checks failed
lint / lint (push) Has been cancelled
Some checks failed
lint / lint (push) Has been cancelled
- Tickets can be created with user_id instead of name/email
- name/email default to empty string in DB (not NULL-safe)
- New endpoints: GET /api/v1/events/public, GET /api/v1/tickets/user/{user_id}
- POST /api/v1/tickets/{event_id} accepts user_id in body
- Migration m007 adds user_id column to tickets table
- CreateTicket validates: either user_id or (name + email) required
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f06bd9a668
commit
2740d73678
4 changed files with 105 additions and 9 deletions
57
views_api.py
57
views_api.py
|
|
@ -21,11 +21,13 @@ from .crud import (
|
|||
delete_event,
|
||||
delete_event_tickets,
|
||||
delete_ticket,
|
||||
get_all_events,
|
||||
get_event,
|
||||
get_event_tickets,
|
||||
get_events,
|
||||
get_ticket,
|
||||
get_tickets,
|
||||
get_tickets_by_user_id,
|
||||
update_event,
|
||||
update_ticket,
|
||||
)
|
||||
|
|
@ -49,6 +51,12 @@ async def api_events(
|
|||
return [event.dict() for event in await get_events(wallet_ids)]
|
||||
|
||||
|
||||
@events_api_router.get("/api/v1/events/public")
|
||||
async def api_events_public():
|
||||
"""Retrieve all events (read-only, no auth required)."""
|
||||
return [event.dict() for event in await get_all_events()]
|
||||
|
||||
|
||||
@events_api_router.post("/api/v1/events")
|
||||
@events_api_router.put("/api/v1/events/{event_id}")
|
||||
async def api_event_create(
|
||||
|
|
@ -131,14 +139,20 @@ async def api_tickets(
|
|||
return await get_tickets(wallet_ids)
|
||||
|
||||
|
||||
@events_api_router.get("/api/v1/tickets/user/{user_id}")
|
||||
async def api_tickets_by_user_id(user_id: str) -> list[Ticket]:
|
||||
"""Get all tickets for a specific user by their user_id."""
|
||||
return await get_tickets_by_user_id(user_id)
|
||||
|
||||
|
||||
@events_api_router.post("/api/v1/tickets/{event_id}")
|
||||
async def api_ticket_create(event_id: str, data: CreateTicket):
|
||||
name = data.name
|
||||
email = data.email
|
||||
if data.user_id:
|
||||
return await api_ticket_make_ticket_with_user_id(event_id, data.user_id)
|
||||
promo_code = data.promo_code.upper() if data.promo_code else None
|
||||
refund_address = data.refund_address
|
||||
return await api_ticket_make_ticket(
|
||||
event_id, name, email, promo_code, refund_address
|
||||
event_id, data.name, data.email, promo_code, refund_address
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -198,6 +212,43 @@ async def api_ticket_make_ticket(event_id, name, email, promo_code, refund_addre
|
|||
return {"payment_hash": payment.payment_hash, "payment_request": payment.bolt11}
|
||||
|
||||
|
||||
async def api_ticket_make_ticket_with_user_id(event_id: str, user_id: str):
|
||||
event = await get_event(event_id)
|
||||
if not event:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Event does not exist."
|
||||
)
|
||||
|
||||
price = event.price_per_ticket
|
||||
extra = {"tag": "events", "user_id": user_id}
|
||||
|
||||
if event.currency != "sats":
|
||||
extra["fiat"] = True
|
||||
extra["currency"] = event.currency
|
||||
extra["fiatAmount"] = event.price_per_ticket
|
||||
extra["rate"] = await get_fiat_rate_satoshis(event.currency)
|
||||
price = await fiat_amount_as_satoshis(event.price_per_ticket, event.currency)
|
||||
|
||||
try:
|
||||
payment = await create_invoice(
|
||||
wallet_id=event.wallet,
|
||||
amount=price,
|
||||
memo=f"{event_id}",
|
||||
extra=extra,
|
||||
)
|
||||
await create_ticket(
|
||||
payment_hash=payment.payment_hash,
|
||||
wallet=event.wallet,
|
||||
event=event.id,
|
||||
user_id=user_id,
|
||||
)
|
||||
except Exception as exc:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(exc)
|
||||
) from exc
|
||||
return {"payment_hash": payment.payment_hash, "payment_request": payment.bolt11}
|
||||
|
||||
|
||||
@events_api_router.post("/api/v1/tickets/{event_id}/{payment_hash}")
|
||||
async def api_ticket_send_ticket(event_id, payment_hash):
|
||||
event = await get_event(event_id)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue