Skip to content

Commit aefd3ca

Browse files
committed
chore: cascade flow_connections
1 parent 3210537 commit aefd3ca

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

packages/backend/src/graphql/__tests__/mutations/update-step.itest.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -588,10 +588,12 @@ describe('updateStep mutation', () => {
588588
// Mock FlowConnections query for getConnection validation
589589
// Since role is 'editor', getConnection will query FlowConnections table
590590
vi.spyOn(FlowConnections, 'query').mockReturnValue({
591-
findOne: vi.fn().mockReturnValue({
592-
withGraphFetched: vi.fn().mockReturnValue({
593-
throwIfNotFound: vi.fn().mockResolvedValue({
594-
connection: { id: mockConnectionId, key: 'slack' },
591+
withSoftDeleted: vi.fn().mockReturnValue({
592+
findOne: vi.fn().mockReturnValue({
593+
withGraphFetched: vi.fn().mockReturnValue({
594+
throwIfNotFound: vi.fn().mockResolvedValue({
595+
connection: { id: mockConnectionId, key: 'slack' },
596+
}),
595597
}),
596598
}),
597599
}),

packages/backend/src/graphql/mutations/delete-connection.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import FlowConnections from '@/models/flow-connections'
2+
13
import type { MutationResolvers } from '../__generated__/types.generated'
24

35
const deleteConnection: MutationResolvers['deleteConnection'] = async (
@@ -13,6 +15,11 @@ const deleteConnection: MutationResolvers['deleteConnection'] = async (
1315
})
1416
.throwIfNotFound()
1517

18+
// also delete the connection from the flow_connections table for flows with collaborators
19+
await FlowConnections.query()
20+
.delete()
21+
.where({ connection_id: params.input.id })
22+
1623
return true
1724
}
1825

packages/backend/src/services/connection.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,47 @@ export const getConnection = async (params: GetConnectionParams) => {
2626
// it could be their own connection or a shared connection
2727
// 2. the user is the owner of a pipe that has been transferred to them
2828
// it should include connections from the flow_connections table as well
29+
//
30+
// NOTE: if the connection was deleted, we don't want to throw an error,
31+
// we just want to return null so we can show 'Not connected'
32+
//
2933
// TODO (kevinkim-ogp): phase 2 will allow editors to add their own connections, so owner's connections
3034
// will need to include connections from the flow_connections table
3135

32-
return await Connection.query(trx)
36+
const connection = await Connection.query(trx)
3337
.findById(connectionId)
3438
.where(function () {
3539
// connection is either owned by the user
3640
this.where('connections.user_id', context.currentUser.id).orWhereExists(
3741
// or accessible via flow_connections table
3842
FlowConnections.query(trx)
43+
.withSoftDeleted()
3944
.whereColumn('flow_connections.connection_id', 'connections.id')
4045
.where('flow_connections.flow_id', flowId),
4146
)
4247
})
4348
.throwIfNotFound({ message: 'Connection not found' })
49+
50+
if (connection?.deletedAt) {
51+
return null
52+
}
53+
54+
return connection
4455
}
4556

4657
// NOTE: editor and viewer can only access shared connections from the flow_connections table
4758
const flowConnection = await FlowConnections.query(trx)
59+
.withSoftDeleted()
4860
.findOne({
4961
connection_id: connectionId,
5062
flow_id: flowId,
5163
})
5264
.withGraphFetched('connection')
5365
.throwIfNotFound({ message: 'Connection not found' })
5466

67+
if (flowConnection?.deletedAt) {
68+
return null
69+
}
70+
5571
return flowConnection?.connection
5672
}

0 commit comments

Comments
 (0)