81 lines
2.2 KiB
JavaScript
81 lines
2.2 KiB
JavaScript
const path = require('path');
|
|
const { randomUUID } = require('crypto');
|
|
const { snapshotsSystemDir, snapshotsTenantsDir } = require('./paths');
|
|
const { readJsonIfExists, writeJson } = require('./fs');
|
|
const { listAllResources } = require('./resources');
|
|
|
|
function buildResourceDiff(resource) {
|
|
return {
|
|
in_sync: JSON.stringify(resource.desired_state || {}) === JSON.stringify(resource.current_state || {}),
|
|
desired_state: resource.desired_state || {},
|
|
current_state: resource.current_state || {},
|
|
};
|
|
}
|
|
|
|
function filterTenantResources(resources, tenantId) {
|
|
const filtered = {};
|
|
|
|
for (const [resourceType, items] of Object.entries(resources)) {
|
|
filtered[resourceType] = items.filter((item) => {
|
|
if (!item) {
|
|
return false;
|
|
}
|
|
|
|
if (resourceType === 'tenant') {
|
|
return item.id === tenantId;
|
|
}
|
|
|
|
return item.desired_state && item.desired_state.tenant_id === tenantId;
|
|
});
|
|
}
|
|
|
|
return filtered;
|
|
}
|
|
|
|
async function createSnapshot(scope, context) {
|
|
const resources = await listAllResources();
|
|
const selected = scope === 'system'
|
|
? resources
|
|
: filterTenantResources(resources, scope.replace('tenant:', ''));
|
|
|
|
const snapshot = {
|
|
snapshot_id: randomUUID(),
|
|
schema_version: 'v1',
|
|
scope,
|
|
created_at: new Date().toISOString(),
|
|
request_id: context.request_id,
|
|
correlation_id: context.correlation_id,
|
|
resources: selected,
|
|
diffs: Object.fromEntries(
|
|
Object.entries(selected).map(([resourceType, items]) => [
|
|
resourceType,
|
|
items.map((item) => ({
|
|
resource_id: item.id,
|
|
diff: buildResourceDiff(item),
|
|
})),
|
|
])
|
|
),
|
|
};
|
|
|
|
const filePath = scope === 'system'
|
|
? path.join(snapshotsSystemDir, 'latest.json')
|
|
: path.join(snapshotsTenantsDir, `${scope.replace('tenant:', '')}.json`);
|
|
|
|
await writeJson(filePath, snapshot);
|
|
return snapshot;
|
|
}
|
|
|
|
async function getLatestSystemSnapshot() {
|
|
return readJsonIfExists(path.join(snapshotsSystemDir, 'latest.json'));
|
|
}
|
|
|
|
async function getLatestTenantSnapshot(tenantId) {
|
|
return readJsonIfExists(path.join(snapshotsTenantsDir, `${tenantId}.json`));
|
|
}
|
|
|
|
module.exports = {
|
|
createSnapshot,
|
|
getLatestSystemSnapshot,
|
|
getLatestTenantSnapshot,
|
|
};
|