Like Groups model
| Status | Implementation |
|---|---|
| ✅ Shipped | src/infra/db/schema/like-group.schema.ts |
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
| Column | Type | Notes |
|---|---|---|
id | UUID PK | defaultRandom() |
event_id | UUID FK → events.id ON DELETE CASCADE | |
creator_id | UUID FK → auth.users.id | |
member_key | text | Canonical sorted member IDs for uniqueness |
chat_id | UUID FK → chats.id | nullable; populated on approved |
status | enum like_group_status | pending, approved, rejected, expired |
created_at | timestamptz |
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);
-- Unique pending group composition per event
CREATE UNIQUE INDEX like_groups_pending_uniq
ON like_groups (event_id, member_key)
WHERE status = 'pending';
like_group_members
| Column | Type |
|---|---|
group_id | UUID FK → like_groups.id ON DELETE CASCADE |
user_id | UUID FK → auth.users.id |
created_at | timestamptz |
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 the member_key column on like_groups. The key is a
canonical sorted string of all member UUIDs, and a partial unique index
ensures no duplicate pending group compositions per event.
like_group_approvals
| Column | Type | Notes |
|---|---|---|
id | UUID PK | |
group_id | UUID FK → like_groups.id ON DELETE CASCADE | |
author_id | UUID FK → auth.users.id | Must be an event author at time of approval |
decision | enum | consent (approve) or refuse (reject) |
created_at | timestamptz |
CREATE TYPE approval_decision AS ENUM ('consent', 'refuse');
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 uses min(consentThreshold, eligible_organizers) and
runs in the service layer, inside the same transaction that flips
like_groups.status and creates the chat — see
Approval algorithm.
like_group_audit
Append-only audit log for approval decisions.
| Column | Type | Notes |
|---|---|---|
id | UUID PK | |
group_id | UUID FK → like_groups.id | |
actor_id | UUID FK → auth.users.id | Who made the decision |
decision | enum | consent or refuse |
resulting_status | enum like_group_status | Status after decision |
created_at | timestamptz |