mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 20:32:25 +03:00
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!
68 lines
2.4 KiB
TypeScript
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,
|
|
}));
|
|
}
|