42 lines
1.5 KiB
JavaScript
42 lines
1.5 KiB
JavaScript
// Phase 5 — live features: message edits/deletes, reactions, read state.
|
|
|
|
/** @param {import('node-pg-migrate').MigrationBuilder} pgm */
|
|
exports.up = (pgm) => {
|
|
pgm.addColumns('messages', {
|
|
edited_at: { type: 'timestamptz' },
|
|
deleted_at: { type: 'timestamptz' },
|
|
});
|
|
|
|
pgm.createTable('reactions', {
|
|
message_id: { type: 'uuid', notNull: true, references: 'messages', onDelete: 'CASCADE' },
|
|
user_id: { type: 'uuid', notNull: true, references: 'users', onDelete: 'CASCADE' },
|
|
emoji: { type: 'text', notNull: true },
|
|
created_at: { type: 'timestamptz', notNull: true, default: pgm.func('now()') },
|
|
});
|
|
pgm.addConstraint('reactions', 'reactions_pkey', {
|
|
primaryKey: ['message_id', 'user_id', 'emoji'],
|
|
});
|
|
pgm.createIndex('reactions', 'message_id');
|
|
|
|
pgm.createTable('read_state', {
|
|
conversation_id: {
|
|
type: 'uuid',
|
|
notNull: true,
|
|
references: 'conversations',
|
|
onDelete: 'CASCADE',
|
|
},
|
|
user_id: { type: 'uuid', notNull: true, references: 'users', onDelete: 'CASCADE' },
|
|
last_read_seq: { type: 'bigint', notNull: true, default: 0 },
|
|
updated_at: { type: 'timestamptz', notNull: true, default: pgm.func('now()') },
|
|
});
|
|
pgm.addConstraint('read_state', 'read_state_pkey', {
|
|
primaryKey: ['conversation_id', 'user_id'],
|
|
});
|
|
};
|
|
|
|
/** @param {import('node-pg-migrate').MigrationBuilder} pgm */
|
|
exports.down = (pgm) => {
|
|
pgm.dropTable('read_state');
|
|
pgm.dropTable('reactions');
|
|
pgm.dropColumns('messages', ['edited_at', 'deleted_at']);
|
|
};
|