Add 5 new SQLAlchemy models (Conversation, ConversationMember, ConvMessage, MessageReaction, MessagePin) and extend MessageAttachment with conv_message_id FK. Migration 091 creates all tables with indexes, FKs, and grants. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
97 lines
4.0 KiB
PL/PgSQL
97 lines
4.0 KiB
PL/PgSQL
-- 091_messaging_redesign.sql
|
|
-- Unified conversation model: replaces separate private_messages + message_group
|
|
-- Conversations (1:1 and group), messages, reactions, pins
|
|
|
|
BEGIN;
|
|
|
|
-- Unified conversations (1:1 or group)
|
|
CREATE TABLE conversations (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255),
|
|
is_group BOOLEAN NOT NULL DEFAULT FALSE,
|
|
owner_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
last_message_id INTEGER -- FK added below after conv_messages exists
|
|
);
|
|
|
|
CREATE INDEX idx_conversations_owner ON conversations(owner_id);
|
|
CREATE INDEX idx_conversations_updated ON conversations(updated_at DESC);
|
|
|
|
-- Conversation membership
|
|
CREATE TABLE conversation_members (
|
|
conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
role VARCHAR(20) NOT NULL DEFAULT 'member',
|
|
last_read_at TIMESTAMP,
|
|
is_muted BOOLEAN NOT NULL DEFAULT FALSE,
|
|
is_archived BOOLEAN NOT NULL DEFAULT FALSE,
|
|
joined_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
added_by_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
PRIMARY KEY (conversation_id, user_id)
|
|
);
|
|
|
|
CREATE INDEX idx_conversation_members_user ON conversation_members(user_id);
|
|
|
|
-- Messages within a conversation
|
|
CREATE TABLE conv_messages (
|
|
id SERIAL PRIMARY KEY,
|
|
conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
|
|
sender_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
content TEXT NOT NULL,
|
|
reply_to_id INTEGER REFERENCES conv_messages(id) ON DELETE SET NULL,
|
|
edited_at TIMESTAMP,
|
|
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
|
link_preview JSONB,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_conv_messages_conversation ON conv_messages(conversation_id);
|
|
CREATE INDEX idx_conv_messages_created ON conv_messages(created_at);
|
|
CREATE INDEX idx_conv_messages_conversation_created ON conv_messages(conversation_id, created_at);
|
|
|
|
-- Now add the deferred FK from conversations.last_message_id -> conv_messages.id
|
|
ALTER TABLE conversations
|
|
ADD CONSTRAINT fk_conversations_last_message
|
|
FOREIGN KEY (last_message_id) REFERENCES conv_messages(id) ON DELETE SET NULL;
|
|
|
|
-- Emoji reactions on messages
|
|
CREATE TABLE message_reactions (
|
|
id SERIAL PRIMARY KEY,
|
|
message_id INTEGER NOT NULL REFERENCES conv_messages(id) ON DELETE CASCADE,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
emoji VARCHAR(10) NOT NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT uq_message_reaction UNIQUE (message_id, user_id, emoji)
|
|
);
|
|
|
|
CREATE INDEX idx_message_reactions_message ON message_reactions(message_id);
|
|
|
|
-- Pinned messages
|
|
CREATE TABLE message_pins (
|
|
id SERIAL PRIMARY KEY,
|
|
conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
|
|
message_id INTEGER NOT NULL REFERENCES conv_messages(id) ON DELETE CASCADE,
|
|
pinned_by_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_message_pins_conversation ON message_pins(conversation_id);
|
|
|
|
-- Extend message_attachments to support conv_messages
|
|
ALTER TABLE message_attachments ADD COLUMN conv_message_id INTEGER REFERENCES conv_messages(id) ON DELETE CASCADE;
|
|
CREATE INDEX idx_message_attachments_conv ON message_attachments(conv_message_id) WHERE conv_message_id IS NOT NULL;
|
|
|
|
-- Grants
|
|
GRANT ALL ON TABLE conversations TO nordabiz_app;
|
|
GRANT ALL ON TABLE conversation_members TO nordabiz_app;
|
|
GRANT ALL ON TABLE conv_messages TO nordabiz_app;
|
|
GRANT ALL ON TABLE message_reactions TO nordabiz_app;
|
|
GRANT ALL ON TABLE message_pins TO nordabiz_app;
|
|
GRANT USAGE, SELECT ON SEQUENCE conversations_id_seq TO nordabiz_app;
|
|
GRANT USAGE, SELECT ON SEQUENCE conv_messages_id_seq TO nordabiz_app;
|
|
GRANT USAGE, SELECT ON SEQUENCE message_reactions_id_seq TO nordabiz_app;
|
|
GRANT USAGE, SELECT ON SEQUENCE message_pins_id_seq TO nordabiz_app;
|
|
|
|
COMMIT;
|