Skip to main content

Like Groups model

Planned

The like_groups, like_group_members and like_group_approvals tables are not yet shipped. This is the design they'll follow on the new Hono + Supabase + Drizzle stack.

A like group is the application a user (and optional friends) submits to attend an event. See Approval algorithm for the threshold logic and side effects.

like_groups

ColumnTypeNotes
idUUID PKdefaultRandom()
event_idUUID FK → events.id ON DELETE CASCADE
creator_idUUID FK → auth.users.id
chat_idUUID FK → chats.idnullable; populated on approved
statusenum like_group_statuspending, approved, rejected, expired
created_attimestamptz
CREATE TYPE like_group_status AS ENUM (
'pending', 'approved', 'rejected', 'expired'
);

CREATE INDEX like_groups_event_idx ON like_groups (event_id);
CREATE INDEX like_groups_status_idx ON like_groups (status);

-- A user can only have one pending application per event
-- (enforced jointly with like_group_members; see below)

like_group_members

ColumnType
group_idUUID FK → like_groups.id ON DELETE CASCADE
user_idUUID FK → auth.users.id
created_attimestamptz
CREATE UNIQUE INDEX like_group_members_uniq
ON like_group_members (group_id, user_id);
CREATE INDEX like_group_members_user_idx ON like_group_members (user_id);

"One pending group per (event, user)"

Enforced via a partial unique index. We need to look at like_groups.event_id (parent), so the simplest implementation is a generated column or a constraint trigger. A pragmatic approach:

-- Materialize event_id on the junction for indexing
ALTER TABLE like_group_members
ADD COLUMN event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE;

CREATE UNIQUE INDEX like_group_members_pending_uniq
ON like_group_members (event_id, user_id)
WHERE EXISTS (
SELECT 1 FROM like_groups g
WHERE g.id = like_group_members.group_id AND g.status = 'pending'
);

(Final shape may differ; the constraint will be re-evaluated when the module lands.)

like_group_approvals

ColumnTypeNotes
idUUID PK
group_idUUID FK → like_groups.id ON DELETE CASCADE
author_idUUID FK → auth.users.idMust be an event author at time of approval
approvedbooleantrue = approve, false = reject
created_attimestamptz
CREATE INDEX like_group_approvals_group_idx ON like_group_approvals (group_id);
CREATE UNIQUE INDEX like_group_approvals_uniq
ON like_group_approvals (group_id, author_id);

The threshold check (approvals_received >= min(authors_count, members_count)) runs in the service layer, inside the same transaction that flips like_groups.status and creates the chat — see Approval algorithm.

Relationship overview