74 lines
2.1 KiB
TypeScript
74 lines
2.1 KiB
TypeScript
import { db } from '../../lib/db';
|
|
import { policySettings } from '../../lib/db/schema/policySettings';
|
|
import type { NewPolicySetting } from '../../lib/db/schema/policySettings';
|
|
import type { FlattenedSetting } from './policyParser';
|
|
import logger from '../logging';
|
|
|
|
/**
|
|
* Upsert policy settings to database with conflict resolution
|
|
*/
|
|
export async function upsertPolicySettings(
|
|
tenantId: string,
|
|
settings: FlattenedSetting[]
|
|
): Promise<{ inserted: number; updated: number }> {
|
|
if (settings.length === 0) {
|
|
logger.info({ event: 'dbUpsert:skip', reason: 'no settings to upsert' });
|
|
return { inserted: 0, updated: 0 };
|
|
}
|
|
|
|
const now = new Date();
|
|
|
|
// Convert to database insert format
|
|
const records: NewPolicySetting[] = settings.map((setting) => ({
|
|
tenantId,
|
|
policyName: setting.policyName,
|
|
policyType: setting.policyType,
|
|
settingName: setting.settingName,
|
|
settingValue: setting.settingValue,
|
|
graphPolicyId: setting.graphPolicyId,
|
|
lastSyncedAt: now,
|
|
}));
|
|
|
|
try {
|
|
// Batch upsert with conflict resolution
|
|
// Uses the unique constraint: (tenantId, graphPolicyId, settingName)
|
|
const result = await db
|
|
.insert(policySettings)
|
|
.values(records)
|
|
.onConflictDoUpdate({
|
|
target: [
|
|
policySettings.tenantId,
|
|
policySettings.graphPolicyId,
|
|
policySettings.settingName,
|
|
],
|
|
set: {
|
|
policyName: policySettings.policyName,
|
|
policyType: policySettings.policyType,
|
|
settingValue: policySettings.settingValue,
|
|
lastSyncedAt: now,
|
|
},
|
|
});
|
|
|
|
// Drizzle doesn't return row counts in all cases, so we estimate
|
|
const total = records.length;
|
|
logger.info({
|
|
event: 'dbUpsert:success',
|
|
total,
|
|
tenantId,
|
|
policies: [...new Set(settings.map(s => s.graphPolicyId))].length
|
|
});
|
|
|
|
return { inserted: total, updated: 0 };
|
|
} catch (error) {
|
|
logger.error({
|
|
event: 'dbUpsert:error',
|
|
error: error instanceof Error ? error.message : String(error),
|
|
tenantId,
|
|
settingsCount: settings.length
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export default upsertPolicySettings;
|