Files
OmniRoute/src/lib/logExport/registry.ts
Damian Pozimski 385e90f444 feat(dashboard): continuous call-log export to pluggable destinations (BigQuery first) (#11945)
Feature grande e bem construída: exportação contínua de call logs para destinos plugáveis (BigQuery primeiro). Revisei especificamente o tratamento de segredos (`src/lib/logExport/secrets.ts`) e a migração — encryption gate real (`requiresEncryptionKey` recusa gravação em texto plano quando `STORAGE_ENCRYPTION_KEY` não está setada), redação antes de qualquer resposta de API, e a migração cria a tabela com `enabled=0`/`include_bodies=0` por padrão (opt-in, sem exportar nada até o operador configurar). 62/62 testes focados verdes, typecheck limpo.

Resolvido o conflito com o barrel `src/lib/localDb.ts` (removido nesta mesma sessão, #11795 fase 5 — todo consumidor já migrado para `src/lib/db/*`); a PR só adicionava um re-export nele, que não é mais necessário. Obrigado pela contribuição!
2026-08-30 09:16:52 -03:00

68 lines
2.4 KiB
TypeScript

/**
* Log-export destination registry.
*
* The single place that knows which destinations exist. Adding Datadog, Grafana Loki
* or Sentry means writing `destinations/<name>.ts` and adding it to this array — the
* runner, the REST layer and the dashboard form all read from the descriptors below.
*/
import { bigQueryDestination } from "./destinations/bigquery";
import type { LogExportConfigField, LogExportDestinationType } from "./types";
const DESTINATIONS: ReadonlyArray<LogExportDestinationType> = [bigQueryDestination];
/**
* Types registered at runtime. Only tests use this: it lets the runner, the REST layer
* and the secret handling be exercised through a fake destination, proving the pipeline
* carries no BigQuery-specific knowledge.
*/
const testDestinations = new Map<string, LogExportDestinationType>();
export function listLogExportDestinationTypes(): ReadonlyArray<LogExportDestinationType> {
return testDestinations.size === 0
? DESTINATIONS
: [...DESTINATIONS, ...testDestinations.values()];
}
export function getLogExportDestinationType(id: string): LogExportDestinationType | undefined {
return DESTINATIONS.find((destination) => destination.id === id) ?? testDestinations.get(id);
}
/** Test-only: register a destination type for the duration of a test. */
export function __registerLogExportDestinationTypeForTest(
destination: LogExportDestinationType
): void {
testDestinations.set(destination.id, destination);
}
/** Test-only: drop every runtime-registered destination type. */
export function __resetLogExportDestinationTypesForTest(): void {
testDestinations.clear();
}
export function isKnownLogExportDestinationType(id: string): boolean {
return getLogExportDestinationType(id) !== undefined;
}
export interface LogExportDestinationTypeDescriptor {
id: string;
label: string;
description: string;
docsUrl: string | null;
fields: readonly LogExportConfigField[];
}
/**
* Serializable descriptors for the UI. The dashboard renders any destination's form
* from these, so a new destination needs no UI change.
*/
export function describeLogExportDestinationTypes(): LogExportDestinationTypeDescriptor[] {
return listLogExportDestinationTypes().map((destination) => ({
id: destination.id,
label: destination.labelFallback,
description: destination.descriptionFallback,
docsUrl: destination.docsUrl ?? null,
fields: destination.fields,
}));
}