The frontend RSVP flow is complete (event detail screen, ConfirmModal, RsvpSuccessToast) but currently uses a temporary in-memory store (app/lib/rsvpStore.ts). This ticket replaces that with real backend support.
Build steps
- Create
event_rsvps table in D1:
CREATE TABLE event_rsvps (
user_id TEXT NOT NULL,
event_id INTEGER NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
PRIMARY KEY (user_id, event_id)
);
POST /events/:id/rsvp — auth-gated, inserts a row (idempotent)
DELETE /events/:id/rsvp — auth-gated, removes row
- Expose
is_rsvped: boolean on GET /events/:id response (join against event_rsvps using the authed user's ID)
- Update
app/lib/rsvpStore.ts callers to use the real API once endpoints are live
Notes
- Caller signatures in
rsvpStore.ts are already designed to match the future API — function names and Promise return types should not need to change
- Gate all writes on a valid JWT; unauthenticated requests → 401
The frontend RSVP flow is complete (event detail screen, ConfirmModal, RsvpSuccessToast) but currently uses a temporary in-memory store (
app/lib/rsvpStore.ts). This ticket replaces that with real backend support.Build steps
event_rsvpstable in D1:POST /events/:id/rsvp— auth-gated, inserts a row (idempotent)DELETE /events/:id/rsvp— auth-gated, removes rowis_rsvped: booleanonGET /events/:idresponse (join againstevent_rsvpsusing the authed user's ID)app/lib/rsvpStore.tscallers to use the real API once endpoints are liveNotes
rsvpStore.tsare already designed to match the future API — function names and Promise return types should not need to change