Groups (E2E via pairwise fan-out — sender encrypts each message separately to every member with existing Signal sessions; server holds only name+membership): - migration 0003: groups + group_members; routes/groups.js (create/list/get/add/leave) - client: unified DM+group chat model, group create modal w/ member chips, fan-out deliver, groupId payload routing on receive, lazy group fetch, sender names in group bubbles, group info + leave UI overhaul — glassmorphism redesign: - animated aurora backdrop, blurred glass panels, violet→cyan gradient brand - color-hashed gradient avatars (per name), group avatars - message bubbles with rise animation + tails, gradient outgoing bubbles - polished auth card w/ gradient border, pill actions, modal pop-in, toast styling - responsive: full-width thread on mobile with back button Verified live: 3-user group message fans out and both members decrypt. SW cache v4->v5. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
18 lines
711 B
SQL
18 lines
711 B
SQL
-- Group chats. The server stores group METADATA (name + membership) so members
|
|
-- can discover each other, but message content is still E2E: the sender encrypts
|
|
-- each message separately to every member (pairwise Signal fan-out).
|
|
|
|
CREATE TABLE groups (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
created_by TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE group_members (
|
|
group_id TEXT NOT NULL REFERENCES groups(id) ON DELETE CASCADE,
|
|
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
added_at INTEGER NOT NULL,
|
|
PRIMARY KEY (group_id, user_id)
|
|
);
|
|
CREATE INDEX idx_group_members_user ON group_members(user_id);
|