@@ -7,6 +7,7 @@ import { redirect, typedjson, useTypedLoaderData } from "remix-typedjson";
77import { prisma } from "~/db.server" ;
88import { requireUser } from "~/services/session.server" ;
99import {
10+ FEATURE_FLAG ,
1011 flags as getGlobalFlags ,
1112 getAllFlagControlTypes ,
1213 validatePartialFeatureFlags ,
@@ -62,23 +63,35 @@ export const action = async ({ request }: ActionFunctionArgs) => {
6263 const controlTypes = getAllFlagControlTypes ( ) ;
6364 const catalogKeys = Object . keys ( controlTypes ) ;
6465
66+ // Split keys into upserts and deletes
67+ const keysToDelete : string [ ] = [ ] ;
68+ const upsertOps : ReturnType < typeof prisma . featureFlag . upsert > [ ] = [ ] ;
69+
6570 for ( const key of catalogKeys ) {
6671 if ( key in newFlags ) {
67- const value = newFlags [ key ] ;
68- const partial = { [ key ] : value } ;
69- const result = validatePartialFeatureFlags ( partial ) ;
72+ const result = validatePartialFeatureFlags ( { [ key ] : newFlags [ key ] } ) ;
7073 if ( result . success ) {
71- await prisma . featureFlag . upsert ( {
72- where : { key } ,
73- create : { key, value : value as any } ,
74- update : { value : value as any } ,
75- } ) ;
74+ const validatedValue = ( result . data as Record < string , unknown > ) [ key ] ;
75+ upsertOps . push (
76+ prisma . featureFlag . upsert ( {
77+ where : { key } ,
78+ create : { key, value : validatedValue as any } ,
79+ update : { value : validatedValue as any } ,
80+ } )
81+ ) ;
7682 }
7783 } else {
78- await prisma . featureFlag . deleteMany ( { where : { key } } ) ;
84+ keysToDelete . push ( key ) ;
7985 }
8086 }
8187
88+ await prisma . $transaction ( [
89+ ...upsertOps ,
90+ ...( keysToDelete . length > 0
91+ ? [ prisma . featureFlag . deleteMany ( { where : { key : { in : keysToDelete } } } ) ]
92+ : [ ] ) ,
93+ ] ) ;
94+
8295 return json ( { success : true } ) ;
8396} ;
8497
@@ -153,7 +166,7 @@ export default function AdminFeatureFlagsRoute() {
153166 const control = ( controlTypes as Record < string , FlagControlType > ) [ key ] ;
154167 const isSet = key in values ;
155168
156- const isWorkerGroup = key === " defaultWorkerInstanceGroupId" ;
169+ const isWorkerGroup = key === FEATURE_FLAG . defaultWorkerInstanceGroupId ;
157170
158171 return (
159172 < div
@@ -361,10 +374,10 @@ function ConfirmDialog({
361374 if ( wasSet && isSet && stableStringify ( oldVal ) === stableStringify ( newVal ) ) return [ ] ;
362375
363376 const displayKey =
364- key === " defaultWorkerInstanceGroupId" ? "defaultWorkerInstanceGroup" : key ;
377+ key === FEATURE_FLAG . defaultWorkerInstanceGroupId ? "defaultWorkerInstanceGroup" : key ;
365378
366379 const formatVal = ( val : unknown ) => {
367- if ( key === " defaultWorkerInstanceGroupId" && typeof val === "string" ) {
380+ if ( key === FEATURE_FLAG . defaultWorkerInstanceGroupId && typeof val === "string" ) {
368381 const name = workerGroupMap . get ( val ) ;
369382 return name ? `${ name } (${ val . slice ( 0 , 8 ) } ...)` : String ( val ) ;
370383 }
0 commit comments