Skip to content

Commit 10361dd

Browse files
feat: base code for providerChains and chainMembers (#449)
1 parent c85726d commit 10361dd

File tree

14 files changed

+687
-0
lines changed

14 files changed

+687
-0
lines changed
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
import {
2+
MigrationInterface,
3+
QueryRunner,
4+
Table,
5+
TableColumn,
6+
TableForeignKey,
7+
TableIndex,
8+
TableUnique,
9+
} from 'typeorm';
10+
11+
export class FallbackProviderChanges1752904253632 implements MigrationInterface {
12+
public async up(queryRunner: QueryRunner): Promise<void> {
13+
// 1. Create notify_provider_chains table
14+
await queryRunner.createTable(
15+
new Table({
16+
name: 'notify_provider_chains',
17+
columns: [
18+
{
19+
name: 'chain_id',
20+
type: 'int',
21+
isPrimary: true,
22+
isGenerated: true,
23+
generationStrategy: 'increment',
24+
},
25+
{
26+
name: 'chain_name',
27+
type: 'varchar',
28+
length: '255',
29+
isNullable: false,
30+
},
31+
{
32+
name: 'application_id',
33+
type: 'int',
34+
isNullable: false,
35+
},
36+
{
37+
name: 'provider_type',
38+
type: 'smallint',
39+
isNullable: false,
40+
},
41+
{
42+
name: 'description',
43+
type: 'text',
44+
isNullable: true,
45+
},
46+
{
47+
name: 'is_default',
48+
type: 'smallint',
49+
default: '0',
50+
isNullable: false,
51+
},
52+
{
53+
name: 'created_on',
54+
type: 'timestamp',
55+
default: 'CURRENT_TIMESTAMP',
56+
isNullable: false,
57+
},
58+
{
59+
name: 'updated_on',
60+
type: 'timestamp',
61+
default: 'CURRENT_TIMESTAMP',
62+
onUpdate: 'CURRENT_TIMESTAMP',
63+
isNullable: false,
64+
},
65+
{
66+
name: 'status',
67+
type: 'smallint',
68+
default: '1',
69+
isNullable: false,
70+
},
71+
],
72+
}),
73+
true,
74+
);
75+
76+
// 2. Create notify_provider_chain_members table
77+
await queryRunner.createTable(
78+
new Table({
79+
name: 'notify_provider_chain_members',
80+
columns: [
81+
{
82+
name: 'id',
83+
type: 'int',
84+
isPrimary: true,
85+
isGenerated: true,
86+
generationStrategy: 'increment',
87+
},
88+
{
89+
name: 'chain_id',
90+
type: 'int',
91+
isNullable: false,
92+
},
93+
{
94+
name: 'provider_id',
95+
type: 'int',
96+
isNullable: false,
97+
},
98+
{
99+
name: 'priority_order',
100+
type: 'smallint',
101+
isNullable: false,
102+
},
103+
{
104+
name: 'is_active',
105+
type: 'smallint',
106+
default: '1',
107+
isNullable: false,
108+
},
109+
{
110+
name: 'created_on',
111+
type: 'timestamp',
112+
default: 'CURRENT_TIMESTAMP',
113+
isNullable: false,
114+
},
115+
{
116+
name: 'updated_on',
117+
type: 'timestamp',
118+
default: 'CURRENT_TIMESTAMP',
119+
onUpdate: 'CURRENT_TIMESTAMP',
120+
isNullable: false,
121+
},
122+
{
123+
name: 'status',
124+
type: 'smallint',
125+
default: '1',
126+
isNullable: false,
127+
},
128+
],
129+
}),
130+
true,
131+
);
132+
133+
// 3. Add Foreign Key Constraints for notify_provider_chains
134+
await queryRunner.createForeignKey(
135+
'notify_provider_chains',
136+
new TableForeignKey({
137+
columnNames: ['application_id'],
138+
referencedColumnNames: ['application_id'],
139+
referencedTableName: 'notify_applications',
140+
onDelete: 'CASCADE',
141+
name: 'FK_PROVIDER_CHAINS_APPLICATION',
142+
}),
143+
);
144+
145+
await queryRunner.createForeignKey(
146+
'notify_provider_chains',
147+
new TableForeignKey({
148+
columnNames: ['provider_type'],
149+
referencedColumnNames: ['provider_type_id'],
150+
referencedTableName: 'notify_provider_types',
151+
onDelete: 'RESTRICT',
152+
name: 'FK_PROVIDER_CHAINS_PROVIDER_TYPE',
153+
}),
154+
);
155+
156+
// 4. Add Foreign Key Constraints for notify_provider_chain_members
157+
await queryRunner.createForeignKey(
158+
'notify_provider_chain_members',
159+
new TableForeignKey({
160+
columnNames: ['chain_id'],
161+
referencedColumnNames: ['chain_id'],
162+
referencedTableName: 'notify_provider_chains',
163+
onDelete: 'CASCADE',
164+
name: 'FK_CHAIN_MEMBERS_CHAIN',
165+
}),
166+
);
167+
168+
await queryRunner.createForeignKey(
169+
'notify_provider_chain_members',
170+
new TableForeignKey({
171+
columnNames: ['provider_id'],
172+
referencedColumnNames: ['provider_id'],
173+
referencedTableName: 'notify_providers',
174+
onDelete: 'CASCADE',
175+
name: 'FK_CHAIN_MEMBERS_PROVIDER',
176+
}),
177+
);
178+
179+
// 5. Create Indexes for notify_provider_chains
180+
await queryRunner.createIndex(
181+
'notify_provider_chains',
182+
new TableIndex({
183+
columnNames: ['application_id', 'provider_type'],
184+
name: 'IDX_CHAINS_APPLICATION_CHANNEL',
185+
}),
186+
);
187+
188+
await queryRunner.createIndex(
189+
'notify_provider_chains',
190+
new TableIndex({
191+
columnNames: ['status'],
192+
name: 'IDX_CHAINS_STATUS',
193+
}),
194+
);
195+
196+
await queryRunner.createIndex(
197+
'notify_provider_chains',
198+
new TableIndex({
199+
columnNames: ['application_id', 'provider_type', 'is_default'],
200+
name: 'IDX_CHAINS_DEFAULT',
201+
}),
202+
);
203+
204+
// 6. Create Indexes for notify_provider_chain_members
205+
await queryRunner.createIndex(
206+
'notify_provider_chain_members',
207+
new TableIndex({
208+
columnNames: ['chain_id', 'priority_order'],
209+
name: 'IDX_CHAIN_MEMBERS_CHAIN_ORDER',
210+
}),
211+
);
212+
213+
await queryRunner.createIndex(
214+
'notify_provider_chain_members',
215+
new TableIndex({
216+
columnNames: ['provider_id'],
217+
name: 'IDX_CHAIN_MEMBERS_PROVIDER',
218+
}),
219+
);
220+
221+
await queryRunner.createIndex(
222+
'notify_provider_chain_members',
223+
new TableIndex({
224+
columnNames: ['status'],
225+
name: 'IDX_CHAIN_MEMBERS_STATUS',
226+
}),
227+
);
228+
229+
// 7. Add Unique Constraints for both tables
230+
await queryRunner.createUniqueConstraint(
231+
'notify_provider_chains',
232+
new TableUnique({
233+
columnNames: ['application_id', 'chain_name'],
234+
name: 'UQ_APP_CHAIN_NAME',
235+
}),
236+
);
237+
238+
await queryRunner.createUniqueConstraint(
239+
'notify_provider_chain_members',
240+
new TableUnique({
241+
columnNames: ['chain_id', 'priority_order'],
242+
name: 'UQ_CHAIN_PRIORITY',
243+
}),
244+
);
245+
246+
await queryRunner.createUniqueConstraint(
247+
'notify_provider_chain_members',
248+
new TableUnique({
249+
columnNames: ['chain_id', 'provider_id'],
250+
name: 'UQ_CHAIN_PROVIDER',
251+
}),
252+
);
253+
254+
// 8. Table modifications for notify_notifications
255+
await queryRunner.addColumn(
256+
'notify_notifications',
257+
new TableColumn({
258+
name: 'provider_chain_id',
259+
type: 'int',
260+
isNullable: true,
261+
}),
262+
);
263+
264+
await queryRunner.createForeignKey(
265+
'notify_notifications',
266+
new TableForeignKey({
267+
columnNames: ['provider_chain_id'],
268+
referencedColumnNames: ['chain_id'],
269+
referencedTableName: 'notify_provider_chains',
270+
onDelete: 'SET NULL',
271+
name: 'FK_NOTIFICATIONS_PROVIDER_CHAIN',
272+
}),
273+
);
274+
275+
await queryRunner.createIndex(
276+
'notify_notifications',
277+
new TableIndex({
278+
columnNames: ['provider_chain_id'],
279+
name: 'IDX_NOTIFICATIONS_PROVIDER_CHAIN',
280+
}),
281+
);
282+
283+
// 9. Table modifications for notify_archived_notifications
284+
await queryRunner.addColumn(
285+
'notify_archived_notifications',
286+
new TableColumn({
287+
name: 'provider_chain_id',
288+
type: 'int',
289+
isNullable: true,
290+
}),
291+
);
292+
293+
await queryRunner.createForeignKey(
294+
'notify_archived_notifications',
295+
new TableForeignKey({
296+
columnNames: ['provider_chain_id'],
297+
referencedColumnNames: ['chain_id'],
298+
referencedTableName: 'notify_provider_chains',
299+
onDelete: 'SET NULL',
300+
name: 'FK_ARCHIVED_NOTIFICATIONS_PROVIDER_CHAIN',
301+
}),
302+
);
303+
304+
await queryRunner.createIndex(
305+
'notify_archived_notifications',
306+
new TableIndex({
307+
columnNames: ['provider_chain_id'],
308+
name: 'IDX_ARCHIVED_NOTIFICATIONS_PROVIDER_CHAIN',
309+
}),
310+
);
311+
}
312+
313+
public async down(queryRunner: QueryRunner): Promise<void> {
314+
// 1. Revert changes from table notify_archived_notifications
315+
await queryRunner.dropIndex(
316+
'notify_archived_notifications',
317+
'IDX_ARCHIVED_NOTIFICATIONS_PROVIDER_CHAIN',
318+
);
319+
await queryRunner.dropForeignKey(
320+
'notify_archived_notifications',
321+
'FK_ARCHIVED_NOTIFICATIONS_PROVIDER_CHAIN',
322+
);
323+
await queryRunner.dropColumn('notify_archived_notifications', 'provider_chain_id');
324+
325+
// 2. Revert changes from table notify_notifications
326+
await queryRunner.dropIndex('notify_notifications', 'IDX_NOTIFICATIONS_PROVIDER_CHAIN');
327+
await queryRunner.dropForeignKey('notify_notifications', 'FK_NOTIFICATIONS_PROVIDER_CHAIN');
328+
await queryRunner.dropColumn('notify_notifications', 'provider_chain_id');
329+
330+
// 3. Drop Unique Constraints
331+
await queryRunner.dropUniqueConstraint('notify_provider_chain_members', 'UQ_CHAIN_PROVIDER');
332+
await queryRunner.dropUniqueConstraint('notify_provider_chain_members', 'UQ_CHAIN_PRIORITY');
333+
await queryRunner.dropUniqueConstraint('notify_provider_chains', 'UQ_APP_CHAIN_NAME');
334+
335+
// 4. Drop Indexes
336+
await queryRunner.dropIndex('notify_provider_chain_members', 'IDX_CHAIN_MEMBERS_STATUS');
337+
await queryRunner.dropIndex('notify_provider_chain_members', 'IDX_CHAIN_MEMBERS_PROVIDER');
338+
await queryRunner.dropIndex('notify_provider_chain_members', 'IDX_CHAIN_MEMBERS_CHAIN_ORDER');
339+
340+
await queryRunner.dropIndex('notify_provider_chains', 'IDX_CHAINS_DEFAULT');
341+
await queryRunner.dropIndex('notify_provider_chains', 'IDX_CHAINS_STATUS');
342+
await queryRunner.dropIndex('notify_provider_chains', 'IDX_CHAINS_APPLICATION_CHANNEL');
343+
344+
// 5. Drop Foreign Key Constraints
345+
await queryRunner.dropForeignKey('notify_provider_chain_members', 'FK_CHAIN_MEMBERS_PROVIDER');
346+
await queryRunner.dropForeignKey('notify_provider_chain_members', 'FK_CHAIN_MEMBERS_CHAIN');
347+
await queryRunner.dropForeignKey('notify_provider_chains', 'FK_PROVIDER_CHAINS_PROVIDER_TYPE');
348+
await queryRunner.dropForeignKey('notify_provider_chains', 'FK_PROVIDER_CHAINS_APPLICATION');
349+
350+
// 6. Drop tables in reverse order of creation to respect dependencies
351+
await queryRunner.dropTable('notify_provider_chain_members');
352+
await queryRunner.dropTable('notify_provider_chains');
353+
}
354+
}

apps/api/src/modules/applications/entities/application.entity.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { Notification } from 'src/modules/notifications/entities/notification.en
1313
import { ServerApiKey } from 'src/modules/server-api-keys/entities/server-api-key.entity';
1414
import { ArchivedNotification } from 'src/modules/archived-notifications/entities/archived-notification.entity';
1515
import { GraphQLJSONObject } from 'graphql-type-json';
16+
import { ProviderChain } from 'src/modules/provider-chains/entities/provider-chain.entity';
1617

1718
@Entity({ name: 'notify_applications' })
1819
@ObjectType()
@@ -76,6 +77,10 @@ export class Application {
7677
)
7778
archivedNotifications: ArchivedNotification[];
7879

80+
@OneToMany(() => ProviderChain, (providerChain) => providerChain.applicationDetails)
81+
@Field(() => [ProviderChain], { nullable: true })
82+
providerChains: ProviderChain[];
83+
7984
constructor(application: Partial<Application>) {
8085
Object.assign(this, application);
8186
}

0 commit comments

Comments
 (0)