nordabiz/database/migrations/088_message_groups.sql
Maciej Pienczyn 3a18ebcb28
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
feat(messages): group messaging and search
- Search bar in inbox/sent: filters by subject, content, sender/recipient
- Group chats: create named or ad-hoc groups with Norda members
- Group roles: owner, moderator, member with permission hierarchy
- Group management: add/remove members, change roles
- Photo avatars in message list (fallback to initials)
- Unread count API extended to include group messages
- Migration 088: message_group, message_group_member, group_message tables

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 11:11:57 +01:00

60 lines
2.3 KiB
PL/PgSQL

-- 088_message_groups.sql
-- Group messaging tables + alter message_attachments
BEGIN;
-- Group/channel for multi-person chats
CREATE TABLE message_group (
id SERIAL PRIMARY KEY,
name VARCHAR(255),
description TEXT,
owner_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
is_named BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_message_group_owner ON message_group(owner_id);
-- Group membership with roles
CREATE TABLE message_group_member (
group_id INTEGER NOT NULL REFERENCES message_group(id) ON DELETE CASCADE,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role VARCHAR(20) NOT NULL DEFAULT 'member' CHECK (role IN ('owner', 'moderator', 'member')),
last_read_at TIMESTAMP,
joined_at TIMESTAMP NOT NULL DEFAULT NOW(),
added_by_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
PRIMARY KEY (group_id, user_id)
);
CREATE INDEX idx_message_group_member_user ON message_group_member(user_id);
-- Messages within a group
CREATE TABLE group_message (
id SERIAL PRIMARY KEY,
group_id INTEGER NOT NULL REFERENCES message_group(id) ON DELETE CASCADE,
sender_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
content TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_group_message_group ON group_message(group_id);
CREATE INDEX idx_group_message_created ON group_message(group_id, created_at);
-- Extend message_attachments to support group messages
ALTER TABLE message_attachments ALTER COLUMN message_id DROP NOT NULL;
ALTER TABLE message_attachments ADD COLUMN group_message_id INTEGER REFERENCES group_message(id) ON DELETE CASCADE;
ALTER TABLE message_attachments ADD CONSTRAINT chk_attachment_one_parent
CHECK ((message_id IS NOT NULL) != (group_message_id IS NOT NULL));
CREATE INDEX idx_message_attachments_group ON message_attachments(group_message_id) WHERE group_message_id IS NOT NULL;
-- Grants
GRANT ALL ON TABLE message_group TO nordabiz_app;
GRANT ALL ON TABLE message_group_member TO nordabiz_app;
GRANT ALL ON TABLE group_message TO nordabiz_app;
GRANT USAGE, SELECT ON SEQUENCE message_group_id_seq TO nordabiz_app;
GRANT USAGE, SELECT ON SEQUENCE group_message_id_seq TO nordabiz_app;
COMMIT;