Skip to content

Commit 27dd66b

Browse files
committed
feat: add mutation to allow adding of gsi - admin only
1 parent e8d4b65 commit 27dd66b

File tree

6 files changed

+92
-0
lines changed

6 files changed

+92
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { flattenJsonb } from '@/helpers/knex-jsonb-flatten'
2+
import { GSIS } from '@/models/dynamodb/table-row'
3+
import TableColumnMetadata from '@/models/table-column-metadata'
4+
5+
import type { AdminMutationResolvers } from '../../__generated__/types.generated'
6+
7+
const createTable: AdminMutationResolvers['addGsi'] = async (
8+
_parent,
9+
params,
10+
context,
11+
) => {
12+
const { tableId, columnId, indexName } = params.input
13+
14+
if (!tableId || !columnId) {
15+
throw new Error('Table id and column id required')
16+
}
17+
18+
const correspondingGsi = GSIS.find((g) => g.gsi === indexName)
19+
if (!correspondingGsi) {
20+
throw new Error('Invalid index name')
21+
}
22+
23+
const table = await context.currentUser
24+
.$relatedQuery('tables')
25+
.findById(tableId)
26+
.withGraphFetched('columns')
27+
.throwIfNotFound()
28+
29+
const correspondingColumn = table.columns.find((c) => c.id === columnId)
30+
if (!correspondingColumn) {
31+
throw new Error('Column not found')
32+
}
33+
34+
const alreadyHasGsi = table.columns.some((c) => !!c.config.gsi)
35+
if (alreadyHasGsi) {
36+
throw new Error('Table already has a GSI')
37+
}
38+
39+
await TableColumnMetadata.query()
40+
.patch(
41+
flattenJsonb({
42+
config: {
43+
gsi: {
44+
indexName: correspondingGsi.gsi,
45+
type: correspondingGsi.type,
46+
status: 'pending',
47+
},
48+
},
49+
}),
50+
)
51+
.where({ id: columnId })
52+
53+
return true
54+
}
55+
56+
export default createTable
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { AdminMutationResolvers } from '../../__generated__/types.generated'
2+
3+
import addGsi from './add-gsi'
4+
5+
export default {
6+
addGsi,
7+
} satisfies AdminMutationResolvers

packages/backend/src/graphql/mutation-resolvers.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,9 @@ export default {
8282
deleteUploadedFile,
8383
generatePresignedUrl,
8484
...tilesMutationResolvers,
85+
86+
// This is a special stub that enables us to group all our admin-related
87+
// mutations into a special AdminMutation object; each "mutations" is handled by field
88+
// resolvers defined in @/graphql/admin/mutations.
89+
admin: () => ({}),
8590
} satisfies MutationResolvers

packages/backend/src/graphql/resolvers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Resolvers } from './__generated__/types.generated'
2+
import adminMutationResolvers from './admin/mutations'
23
import adminQueryResolvers from './admin/queries'
34
import customResolvers from './custom-resolvers'
45
import mutationResolvers from './mutation-resolvers'
@@ -8,5 +9,6 @@ export default {
89
Query: queryResolvers,
910
Mutation: mutationResolvers,
1011
AdminQuery: adminQueryResolvers,
12+
AdminMutation: adminMutationResolvers,
1113
...customResolvers,
1214
} satisfies Resolvers

packages/backend/src/graphql/schema.graphql

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ type Mutation {
115115
# Flow transfers
116116
createFlowTransfer(input: CreateFlowTransferInput!): FlowTransfer!
117117
updateFlowTransferStatus(input: UpdateFlowTransferStatusInput): FlowTransfer!
118+
# Admin mutations
119+
admin: AdminMutation!
120+
}
121+
122+
type AdminMutation {
123+
addGsi(input: AddGsiInput!): Boolean
118124
}
119125

120126
"""
@@ -762,6 +768,13 @@ input DeleteTableInput {
762768

763769
type TableColumnConfig {
764770
width: Int
771+
gsi: TableColumnGsiConfig
772+
}
773+
774+
type TableColumnGsiConfig {
775+
indexName: String!
776+
type: String!
777+
status: String!
765778
}
766779

767780
type TableColumnMetadata {
@@ -834,6 +847,13 @@ input DeleteTableRowsInput {
834847
tableId: ID!
835848
rowIds: [ID!]!
836849
}
850+
851+
input AddGsiInput {
852+
tableId: ID!
853+
columnId: ID!
854+
indexName: String!
855+
}
856+
837857
# End Tiles row types
838858

839859
type AppHealth {

packages/backend/src/helpers/authentication.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ const authentication = shield(
103103
// Not OTP, but no real reason to be looser than OTP.
104104
loginWithSgid: rateLimitRule({ window: '1s', max: 5 }),
105105
loginWithSelectedSgid: rateLimitRule({ window: '1s', max: 5 }),
106+
admin: isAdminOperation,
106107
},
108+
AdminMutation: isAdminOperation,
107109
},
108110
{
109111
allowExternalErrors: true,

0 commit comments

Comments
 (0)