46 lines
2.2 KiB
JavaScript
46 lines
2.2 KiB
JavaScript
// Phase 4 — reshape rooms into a unified "conversations" model (direct + group)
|
|
// and add contacts. Renames preserve existing group data (existing rooms become
|
|
// type='group').
|
|
|
|
/** @param {import('node-pg-migrate').MigrationBuilder} pgm */
|
|
exports.up = (pgm) => {
|
|
// rooms -> conversations
|
|
pgm.renameTable('rooms', 'conversations');
|
|
pgm.renameColumn('conversations', 'name', 'title');
|
|
pgm.alterColumn('conversations', 'title', { notNull: false });
|
|
pgm.addColumns('conversations', {
|
|
type: { type: 'text', notNull: true, default: 'group' },
|
|
// Canonical sorted user-pair for a direct conversation; unique so a 1:1 is
|
|
// never duplicated. NULL for groups (Postgres allows many NULLs in UNIQUE).
|
|
direct_key: { type: 'text' },
|
|
last_message_at: { type: 'timestamptz', notNull: true, default: pgm.func('now()') },
|
|
});
|
|
pgm.addConstraint('conversations', 'conversations_direct_key_uq', { unique: ['direct_key'] });
|
|
|
|
// room_members -> conversation_members
|
|
pgm.renameTable('room_members', 'conversation_members');
|
|
pgm.renameColumn('conversation_members', 'room_id', 'conversation_id');
|
|
|
|
// messages.room_id -> conversation_id (indexes + dedupe constraint follow the rename)
|
|
pgm.renameColumn('messages', 'room_id', 'conversation_id');
|
|
|
|
pgm.createTable('contacts', {
|
|
owner_id: { type: 'uuid', notNull: true, references: 'users', onDelete: 'CASCADE' },
|
|
contact_id: { type: 'uuid', notNull: true, references: 'users', onDelete: 'CASCADE' },
|
|
created_at: { type: 'timestamptz', notNull: true, default: pgm.func('now()') },
|
|
});
|
|
pgm.addConstraint('contacts', 'contacts_pkey', { primaryKey: ['owner_id', 'contact_id'] });
|
|
};
|
|
|
|
/** @param {import('node-pg-migrate').MigrationBuilder} pgm */
|
|
exports.down = (pgm) => {
|
|
pgm.dropTable('contacts');
|
|
pgm.renameColumn('messages', 'conversation_id', 'room_id');
|
|
pgm.renameColumn('conversation_members', 'conversation_id', 'room_id');
|
|
pgm.renameTable('conversation_members', 'room_members');
|
|
pgm.dropConstraint('conversations', 'conversations_direct_key_uq');
|
|
pgm.dropColumns('conversations', ['type', 'direct_key', 'last_message_at']);
|
|
pgm.alterColumn('conversations', 'title', { notNull: true });
|
|
pgm.renameColumn('conversations', 'title', 'name');
|
|
pgm.renameTable('conversations', 'rooms');
|
|
};
|