d005080aca
Hosts can optionally cap total attendance (RSVPs + plus-ones) when creating an event. Capped events require guests to log in via the existing email code flow; RSVPs are tied to accounts and deduped per user. The event page shows spots left and replaces the form with a full notice when the cap is reached; the server rejects over-cap RSVPs and edits with 409 as a race backstop. Also threads a safeNext-validated ?next= param through the login and name-setup flow so guests land back on the event after signing in. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
75 lines
2.7 KiB
SQL
75 lines
2.7 KiB
SQL
CREATE TABLE IF NOT EXISTS events (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
slug TEXT NOT NULL UNIQUE,
|
|
title TEXT NOT NULL,
|
|
date TEXT NOT NULL, -- e.g. "Saturday, June 14"
|
|
time TEXT NOT NULL, -- e.g. "2:00 PM"
|
|
location TEXT NOT NULL,
|
|
admin_token TEXT NOT NULL UNIQUE,
|
|
description TEXT NOT NULL DEFAULT '',
|
|
attendee_cap INTEGER NOT NULL DEFAULT 0, -- 0 = uncapped; capped events require login to RSVP
|
|
user_id INTEGER REFERENCES users(id),
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS slots (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
event_id INTEGER NOT NULL REFERENCES events(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
emoji TEXT NOT NULL DEFAULT '',
|
|
max_claims INTEGER NOT NULL DEFAULT 1,
|
|
sort_order INTEGER NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS claims (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
slot_id INTEGER NOT NULL REFERENCES slots(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
note TEXT NOT NULL DEFAULT '',
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS rsvps (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
event_id INTEGER NOT NULL REFERENCES events(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
note TEXT NOT NULL DEFAULT '',
|
|
plus_one INTEGER NOT NULL DEFAULT 0,
|
|
user_id INTEGER REFERENCES users(id),
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
phone TEXT UNIQUE,
|
|
email TEXT UNIQUE,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
token TEXT PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
expires_at DATETIME NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS verification_codes (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
identifier TEXT NOT NULL,
|
|
code TEXT NOT NULL,
|
|
expires_at DATETIME NOT NULL,
|
|
used INTEGER NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS sms_consents (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
phone TEXT NOT NULL,
|
|
ip_address TEXT NOT NULL DEFAULT '',
|
|
user_agent TEXT NOT NULL DEFAULT '',
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_slots_event ON slots(event_id);
|
|
CREATE INDEX IF NOT EXISTS idx_claims_slot ON claims(slot_id);
|
|
CREATE INDEX IF NOT EXISTS idx_rsvps_event ON rsvps(event_id);
|