Files
grow-api/src/database/migrations/1721500000000-AddNotifications.ts
T

179 lines
5.2 KiB
TypeScript

import {
MigrationInterface,
QueryRunner,
Table,
TableForeignKey,
TableIndex,
} from 'typeorm';
import { NOTIFICATION_SCENARIOS } from '../../notifications/constants/notification-scenarios.constants';
import { NotificationScenarioKey } from '../../notifications/enums/notification-scenario-key.enum';
/** Keys that exist on the enum created in this migration (deposit key is seeded later). */
const INITIAL_NOTIFICATION_KEYS = [
NotificationScenarioKey.RESERVE_CREATED,
NotificationScenarioKey.RESERVE_CONFIRMED,
NotificationScenarioKey.RESERVE_CANCELLED,
NotificationScenarioKey.RESERVE_REMINDER_SENT,
NotificationScenarioKey.CAMPAIGN_SENT,
NotificationScenarioKey.CAMPAIGN_FAILED,
];
export class AddNotifications1721500000000 implements MigrationInterface {
name = 'AddNotifications1721500000000';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
CREATE TYPE "notification_scenario_key_enum" AS ENUM (
'reserve_created',
'reserve_confirmed',
'reserve_cancelled',
'reserve_reminder_sent',
'campaign_sent',
'campaign_failed'
)
`);
await queryRunner.createTable(
new Table({
name: 'notification_scenario_settings',
columns: [
{
name: 'id',
type: 'uuid',
isPrimary: true,
generationStrategy: 'uuid',
default: 'gen_random_uuid()',
},
{
name: 'key',
type: 'notification_scenario_key_enum',
isUnique: true,
},
{ name: 'title', type: 'varchar', length: '300', isNullable: true },
{ name: 'body', type: 'text', isNullable: true },
{ name: 'isActive', type: 'boolean', default: true },
{ name: 'createdAt', type: 'timestamp', default: 'now()' },
{ name: 'updatedAt', type: 'timestamp', default: 'now()' },
],
}),
true,
);
await queryRunner.createIndex(
'notification_scenario_settings',
new TableIndex({
name: 'IDX_notification_scenario_settings_key',
columnNames: ['key'],
isUnique: true,
}),
);
await queryRunner.createTable(
new Table({
name: 'notifications',
columns: [
{
name: 'id',
type: 'uuid',
isPrimary: true,
generationStrategy: 'uuid',
default: 'gen_random_uuid()',
},
{ name: 'salonId', type: 'uuid' },
{ name: 'userId', type: 'uuid' },
{
name: 'scenarioKey',
type: 'notification_scenario_key_enum',
},
{ name: 'title', type: 'varchar', length: '300' },
{ name: 'body', type: 'text' },
{ name: 'link', type: 'varchar', length: '500', isNullable: true },
{
name: 'relatedEntityType',
type: 'varchar',
length: '50',
isNullable: true,
},
{
name: 'relatedEntityId',
type: 'uuid',
isNullable: true,
},
{ name: 'isRead', type: 'boolean', default: false },
{ name: 'createdAt', type: 'timestamp', default: 'now()' },
{ name: 'updatedAt', type: 'timestamp', default: 'now()' },
],
}),
true,
);
await queryRunner.createIndex(
'notifications',
new TableIndex({
name: 'IDX_notifications_salonId_createdAt',
columnNames: ['salonId', 'createdAt'],
}),
);
await queryRunner.createIndex(
'notifications',
new TableIndex({
name: 'IDX_notifications_userId_isRead_createdAt',
columnNames: ['userId', 'isRead', 'createdAt'],
}),
);
await queryRunner.createIndex(
'notifications',
new TableIndex({
name: 'IDX_notifications_scenarioKey',
columnNames: ['scenarioKey'],
}),
);
await queryRunner.createForeignKey(
'notifications',
new TableForeignKey({
name: 'FK_notifications_salonId',
columnNames: ['salonId'],
referencedTableName: 'salons',
referencedColumnNames: ['id'],
onDelete: 'CASCADE',
}),
);
await queryRunner.createForeignKey(
'notifications',
new TableForeignKey({
name: 'FK_notifications_userId',
columnNames: ['userId'],
referencedTableName: 'users',
referencedColumnNames: ['id'],
onDelete: 'CASCADE',
}),
);
for (const key of INITIAL_NOTIFICATION_KEYS) {
const scenario = NOTIFICATION_SCENARIOS.find((item) => item.key === key);
if (!scenario) {
continue;
}
await queryRunner.query(
`
INSERT INTO notification_scenario_settings (key, title, body, "isActive")
VALUES ($1, $2, $3, true)
ON CONFLICT (key) DO NOTHING
`,
[scenario.key, scenario.defaultTitle, scenario.defaultBody],
);
}
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropTable('notifications', true);
await queryRunner.dropTable('notification_scenario_settings', true);
await queryRunner.query('DROP TYPE "notification_scenario_key_enum"');
}
}