tenantpilot/worker/jobs/syncPolicies.ts

116 lines
3.3 KiB
TypeScript

import logger from '../logging';
import { fetchFromGraph } from './graphFetch';
import { parsePolicySettings } from './policyParser';
import { upsertPolicySettings } from './dbUpsert';
const GRAPH_ENDPOINTS = [
'/deviceManagement/deviceConfigurations',
'/deviceManagement/deviceCompliancePolicies',
'/deviceManagement/configurationPolicies',
'/deviceManagement/intents',
];
export async function syncPolicies(job: any) {
const tenantId = job?.data?.tenantId || 'default-tenant';
logger.info({
event: 'syncPolicies:start',
jobId: job?.id,
tenantId,
timestamp: new Date().toISOString()
});
try {
// Step 1: Fetch all policies from Graph API endpoints
logger.info({ event: 'syncPolicies:fetch:start', endpoints: GRAPH_ENDPOINTS.length });
const allPolicies = [];
for (const endpoint of GRAPH_ENDPOINTS) {
try {
const policies = await fetchFromGraph(endpoint);
allPolicies.push(...policies);
logger.info({
event: 'syncPolicies:fetch:endpoint',
endpoint,
count: policies.length
});
} catch (error) {
logger.error({
event: 'syncPolicies:fetch:error',
endpoint,
error: error instanceof Error ? error.message : String(error)
});
// Continue with other endpoints even if one fails
}
}
logger.info({
event: 'syncPolicies:fetch:complete',
totalPolicies: allPolicies.length
});
if (allPolicies.length === 0) {
logger.info({ event: 'syncPolicies:done', result: 'no policies found' });
return { processed: true, policiesFound: 0, settingsUpserted: 0 };
}
// Step 2: Parse and flatten all policies
logger.info({ event: 'syncPolicies:parse:start', policies: allPolicies.length });
const allSettings = [];
for (const policy of allPolicies) {
try {
const settings = parsePolicySettings(policy);
allSettings.push(...settings);
} catch (error) {
logger.error({
event: 'syncPolicies:parse:error',
policyId: policy.id,
error: error instanceof Error ? error.message : String(error)
});
}
}
logger.info({
event: 'syncPolicies:parse:complete',
totalSettings: allSettings.length
});
// Step 3: Upsert to database
logger.info({ event: 'syncPolicies:upsert:start', settings: allSettings.length });
const result = await upsertPolicySettings(tenantId, allSettings);
logger.info({
event: 'syncPolicies:upsert:complete',
inserted: result.inserted,
updated: result.updated
});
// Done
logger.info({
event: 'syncPolicies:done',
jobId: job?.id,
policiesFound: allPolicies.length,
settingsUpserted: result.inserted + result.updated,
timestamp: new Date().toISOString()
});
return {
processed: true,
policiesFound: allPolicies.length,
settingsUpserted: result.inserted + result.updated
};
} catch (error) {
logger.error({
event: 'syncPolicies:error',
jobId: job?.id,
error: error instanceof Error ? error.message : String(error),
stack: error instanceof Error ? error.stack : undefined
});
throw error;
}
}
export default syncPolicies;