Implement TODO stubs: webhook secret lookup, alert→incident wiring, catalog upsert/stage

- P3: getWebhookSecret() now queries DB; ingestAlert() creates/attaches incidents, auto-resolves on resolved status
- P4: stageUpdates() writes to staged_updates table; upsertService() with ON CONFLICT; getService/updateOwner implemented
This commit is contained in:
2026-03-01 03:18:05 +00:00
parent 2c112b2fb1
commit bdaa732ce1
2 changed files with 84 additions and 11 deletions

View File

@@ -131,22 +131,50 @@ export class CatalogService {
}
private async stageUpdates(tenantId: string, updates: StagedUpdate[]): Promise<number> {
// Write to staging table — admin reviews before committing
// TODO: INSERT INTO staged_updates
const { withTenant } = await import('../data/db.js');
await withTenant(tenantId, async (client) => {
for (const update of updates) {
await client.query(
`INSERT INTO staged_updates (tenant_id, service_name, source, changes)
VALUES ($1, $2, $3, $4)`,
[tenantId, update.serviceName, update.source, JSON.stringify(update.changes)],
);
}
});
logger.info({ tenantId, count: updates.length }, 'Staged updates for review');
return updates.length;
}
private async upsertService(tenantId: string, data: Partial<CatalogEntry>): Promise<void> {
// TODO: INSERT ... ON CONFLICT (tenant_id, name) DO UPDATE
const { withTenant } = await import('../data/db.js');
await withTenant(tenantId, async (client) => {
await client.query(
`INSERT INTO services (tenant_id, name, type, owner, owner_source, tags, metadata, last_discovered_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT (tenant_id, name) DO UPDATE SET
type = EXCLUDED.type, owner = EXCLUDED.owner, owner_source = EXCLUDED.owner_source,
tags = EXCLUDED.tags, metadata = EXCLUDED.metadata,
last_discovered_at = EXCLUDED.last_discovered_at, updated_at = now()`,
[tenantId, data.name, data.type, data.owner, data.ownerSource, JSON.stringify(data.tags ?? {}), JSON.stringify(data.metadata ?? {}), data.lastDiscoveredAt],
);
});
}
private async getService(tenantId: string, name: string): Promise<CatalogEntry | null> {
// TODO: SELECT from catalog
return null;
const { withTenant } = await import('../data/db.js');
return withTenant(tenantId, async (client) => {
const result = await client.query('SELECT * FROM services WHERE name = $1', [name]);
return result.rows[0] ?? null;
});
}
private async updateOwner(tenantId: string, name: string, owner: string, source: OwnerSource): Promise<void> {
// TODO: UPDATE catalog SET owner, owner_source
const { withTenant } = await import('../data/db.js');
await withTenant(tenantId, async (client) => {
await client.query(
'UPDATE services SET owner = $1, owner_source = $2, updated_at = now() WHERE name = $3',
[owner, source, name],
);
});
}
}