Add yes/no RSVP answers with required login
RSVPs now carry a status ('yes'/'no'). When auth is enabled, answering
requires login for all events, not just capped ones. Answers are deduped
one per user and re-answering updates in place. A 'no' zeroes plus_one,
is excluded from Going counts and cap math, frees the person's slot
claims, and shows in a separate "Can't make it" list.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,7 @@ type Rsvp struct {
|
||||
Name string
|
||||
Note string
|
||||
PlusOne int64
|
||||
Status string
|
||||
UserID sql.NullInt64
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
+8
-4
@@ -64,12 +64,16 @@ DELETE FROM claims WHERE id = ?;
|
||||
-- name: CountClaimsBySlot :one
|
||||
SELECT COUNT(*) FROM claims WHERE slot_id = ?;
|
||||
|
||||
-- name: DeleteClaimsByEventAndName :exec
|
||||
DELETE FROM claims WHERE slot_id IN (SELECT id FROM slots WHERE event_id = ?)
|
||||
AND claims.name = ? COLLATE NOCASE;
|
||||
|
||||
-- name: ListRsvps :many
|
||||
SELECT * FROM rsvps WHERE event_id = ? ORDER BY created_at;
|
||||
|
||||
-- name: CreateRsvp :one
|
||||
INSERT INTO rsvps (event_id, name, note, plus_one, user_id)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
INSERT INTO rsvps (event_id, name, note, plus_one, status, user_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
RETURNING *;
|
||||
|
||||
-- name: DeleteRsvp :exec
|
||||
@@ -85,7 +89,7 @@ SELECT * FROM rsvps WHERE event_id = ? AND name = ? COLLATE NOCASE LIMIT 1;
|
||||
SELECT * FROM rsvps WHERE event_id = ? AND user_id = ? LIMIT 1;
|
||||
|
||||
-- name: CountGoing :one
|
||||
SELECT CAST(COALESCE(SUM(1 + plus_one), 0) AS INTEGER) FROM rsvps WHERE event_id = ?;
|
||||
SELECT CAST(COALESCE(SUM(1 + plus_one), 0) AS INTEGER) FROM rsvps WHERE event_id = ? AND status = 'yes';
|
||||
|
||||
-- name: DeleteDuplicateRsvps :exec
|
||||
DELETE FROM rsvps WHERE id NOT IN (
|
||||
@@ -140,7 +144,7 @@ UPDATE events SET user_id = ? WHERE id = ?;
|
||||
SELECT * FROM rsvps WHERE id = ?;
|
||||
|
||||
-- name: UpdateRsvp :exec
|
||||
UPDATE rsvps SET name = ?, note = ?, plus_one = ? WHERE id = ?;
|
||||
UPDATE rsvps SET name = ?, note = ?, plus_one = ?, status = ? WHERE id = ?;
|
||||
|
||||
-- name: CreateSmsConsent :exec
|
||||
INSERT INTO sms_consents (phone, ip_address, user_agent) VALUES (?, ?, ?);
|
||||
|
||||
+33
-9
@@ -23,7 +23,7 @@ func (q *Queries) CountClaimsBySlot(ctx context.Context, slotID int64) (int64, e
|
||||
}
|
||||
|
||||
const countGoing = `-- name: CountGoing :one
|
||||
SELECT CAST(COALESCE(SUM(1 + plus_one), 0) AS INTEGER) FROM rsvps WHERE event_id = ?
|
||||
SELECT CAST(COALESCE(SUM(1 + plus_one), 0) AS INTEGER) FROM rsvps WHERE event_id = ? AND status = 'yes'
|
||||
`
|
||||
|
||||
func (q *Queries) CountGoing(ctx context.Context, eventID int64) (int64, error) {
|
||||
@@ -115,9 +115,9 @@ func (q *Queries) CreateEvent(ctx context.Context, arg CreateEventParams) (Event
|
||||
}
|
||||
|
||||
const createRsvp = `-- name: CreateRsvp :one
|
||||
INSERT INTO rsvps (event_id, name, note, plus_one, user_id)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
RETURNING id, event_id, name, note, plus_one, user_id, created_at
|
||||
INSERT INTO rsvps (event_id, name, note, plus_one, status, user_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
RETURNING id, event_id, name, note, plus_one, status, user_id, created_at
|
||||
`
|
||||
|
||||
type CreateRsvpParams struct {
|
||||
@@ -125,6 +125,7 @@ type CreateRsvpParams struct {
|
||||
Name string
|
||||
Note string
|
||||
PlusOne int64
|
||||
Status string
|
||||
UserID sql.NullInt64
|
||||
}
|
||||
|
||||
@@ -134,6 +135,7 @@ func (q *Queries) CreateRsvp(ctx context.Context, arg CreateRsvpParams) (Rsvp, e
|
||||
arg.Name,
|
||||
arg.Note,
|
||||
arg.PlusOne,
|
||||
arg.Status,
|
||||
arg.UserID,
|
||||
)
|
||||
var i Rsvp
|
||||
@@ -143,6 +145,7 @@ func (q *Queries) CreateRsvp(ctx context.Context, arg CreateRsvpParams) (Rsvp, e
|
||||
&i.Name,
|
||||
&i.Note,
|
||||
&i.PlusOne,
|
||||
&i.Status,
|
||||
&i.UserID,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
@@ -271,6 +274,21 @@ func (q *Queries) DeleteClaim(ctx context.Context, id int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteClaimsByEventAndName = `-- name: DeleteClaimsByEventAndName :exec
|
||||
DELETE FROM claims WHERE slot_id IN (SELECT id FROM slots WHERE event_id = ?)
|
||||
AND claims.name = ? COLLATE NOCASE
|
||||
`
|
||||
|
||||
type DeleteClaimsByEventAndNameParams struct {
|
||||
EventID int64
|
||||
Name string
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteClaimsByEventAndName(ctx context.Context, arg DeleteClaimsByEventAndNameParams) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteClaimsByEventAndName, arg.EventID, arg.Name)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteDuplicateRsvps = `-- name: DeleteDuplicateRsvps :exec
|
||||
DELETE FROM rsvps WHERE id NOT IN (
|
||||
SELECT MIN(id) FROM rsvps GROUP BY event_id, name COLLATE NOCASE
|
||||
@@ -391,7 +409,7 @@ func (q *Queries) GetEventBySlug(ctx context.Context, slug string) (Event, error
|
||||
}
|
||||
|
||||
const getRsvp = `-- name: GetRsvp :one
|
||||
SELECT id, event_id, name, note, plus_one, user_id, created_at FROM rsvps WHERE id = ?
|
||||
SELECT id, event_id, name, note, plus_one, status, user_id, created_at FROM rsvps WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetRsvp(ctx context.Context, id int64) (Rsvp, error) {
|
||||
@@ -403,6 +421,7 @@ func (q *Queries) GetRsvp(ctx context.Context, id int64) (Rsvp, error) {
|
||||
&i.Name,
|
||||
&i.Note,
|
||||
&i.PlusOne,
|
||||
&i.Status,
|
||||
&i.UserID,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
@@ -410,7 +429,7 @@ func (q *Queries) GetRsvp(ctx context.Context, id int64) (Rsvp, error) {
|
||||
}
|
||||
|
||||
const getRsvpByName = `-- name: GetRsvpByName :one
|
||||
SELECT id, event_id, name, note, plus_one, user_id, created_at FROM rsvps WHERE event_id = ? AND name = ? COLLATE NOCASE LIMIT 1
|
||||
SELECT id, event_id, name, note, plus_one, status, user_id, created_at FROM rsvps WHERE event_id = ? AND name = ? COLLATE NOCASE LIMIT 1
|
||||
`
|
||||
|
||||
type GetRsvpByNameParams struct {
|
||||
@@ -427,6 +446,7 @@ func (q *Queries) GetRsvpByName(ctx context.Context, arg GetRsvpByNameParams) (R
|
||||
&i.Name,
|
||||
&i.Note,
|
||||
&i.PlusOne,
|
||||
&i.Status,
|
||||
&i.UserID,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
@@ -434,7 +454,7 @@ func (q *Queries) GetRsvpByName(ctx context.Context, arg GetRsvpByNameParams) (R
|
||||
}
|
||||
|
||||
const getRsvpByUser = `-- name: GetRsvpByUser :one
|
||||
SELECT id, event_id, name, note, plus_one, user_id, created_at FROM rsvps WHERE event_id = ? AND user_id = ? LIMIT 1
|
||||
SELECT id, event_id, name, note, plus_one, status, user_id, created_at FROM rsvps WHERE event_id = ? AND user_id = ? LIMIT 1
|
||||
`
|
||||
|
||||
type GetRsvpByUserParams struct {
|
||||
@@ -451,6 +471,7 @@ func (q *Queries) GetRsvpByUser(ctx context.Context, arg GetRsvpByUserParams) (R
|
||||
&i.Name,
|
||||
&i.Note,
|
||||
&i.PlusOne,
|
||||
&i.Status,
|
||||
&i.UserID,
|
||||
&i.CreatedAt,
|
||||
)
|
||||
@@ -653,7 +674,7 @@ func (q *Queries) ListEventsByUser(ctx context.Context, userID sql.NullInt64) ([
|
||||
}
|
||||
|
||||
const listRsvps = `-- name: ListRsvps :many
|
||||
SELECT id, event_id, name, note, plus_one, user_id, created_at FROM rsvps WHERE event_id = ? ORDER BY created_at
|
||||
SELECT id, event_id, name, note, plus_one, status, user_id, created_at FROM rsvps WHERE event_id = ? ORDER BY created_at
|
||||
`
|
||||
|
||||
func (q *Queries) ListRsvps(ctx context.Context, eventID int64) ([]Rsvp, error) {
|
||||
@@ -671,6 +692,7 @@ func (q *Queries) ListRsvps(ctx context.Context, eventID int64) ([]Rsvp, error)
|
||||
&i.Name,
|
||||
&i.Note,
|
||||
&i.PlusOne,
|
||||
&i.Status,
|
||||
&i.UserID,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
@@ -811,13 +833,14 @@ func (q *Queries) UpdateEventLocation(ctx context.Context, arg UpdateEventLocati
|
||||
}
|
||||
|
||||
const updateRsvp = `-- name: UpdateRsvp :exec
|
||||
UPDATE rsvps SET name = ?, note = ?, plus_one = ? WHERE id = ?
|
||||
UPDATE rsvps SET name = ?, note = ?, plus_one = ?, status = ? WHERE id = ?
|
||||
`
|
||||
|
||||
type UpdateRsvpParams struct {
|
||||
Name string
|
||||
Note string
|
||||
PlusOne int64
|
||||
Status string
|
||||
ID int64
|
||||
}
|
||||
|
||||
@@ -826,6 +849,7 @@ func (q *Queries) UpdateRsvp(ctx context.Context, arg UpdateRsvpParams) error {
|
||||
arg.Name,
|
||||
arg.Note,
|
||||
arg.PlusOne,
|
||||
arg.Status,
|
||||
arg.ID,
|
||||
)
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user