learning_ai_invt_trdg/backend/src/bootstrap.ts
Saravana Achu Mac 4cfb446f57 feat(backend): WebSocket namespaces, audit persistence, tab flags, telemetry
- Add /trading and /admin named Socket.IO namespaces; root namespace kept for
  backward compat; admin namespace rejects non-admins at connect time
- Wire auditRepository.ts: persist TradeAuditEvent to Cosmos audit-events
  container (best-effort); expose GET /api/admin/audit for admin queries
- Add tradingTelemetry singleton (Node.js Map-based storage adapter); init
  and fatal-error tracking wired in index.ts main()
- Add TAB_MARKETPLACE_ENABLED / TAB_MEMBERSHIP_ENABLED config flags; expose
  tabs.* shape in GET /api/feature-flags response
- Fix SupabaseService URL validation (regex check before createClient)
- Wire check:api-contract and check:audit-repository into npm run test
- Switch @bytelyst/* deps to file:../vendor/* references

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 19:35:00 -04:00

33 lines
1.6 KiB
TypeScript

/**
* Startup bootstrap — resolves secrets from Azure Key Vault before loading
* the main application. Uses DefaultAzureCredential (Azure CLI in dev,
* Managed Identity in production). Falls back gracefully to .env values
* if Key Vault is unreachable or AZURE_KEYVAULT_URL is not set.
*
* Secret resolution happens here so that config/index.ts reads fully-populated
* process.env values when it is evaluated via the dynamic import below.
*/
import { resolveSecrets, type SecretMapping } from '@bytelyst/config';
const INVTTRDG_SECRETS: SecretMapping[] = [
{ kvName: 'invttrdg-cosmos-endpoint', envVar: 'COSMOS_ENDPOINT' },
{ kvName: 'invttrdg-cosmos-key', envVar: 'COSMOS_KEY' },
{ kvName: 'invttrdg-cosmos-database', envVar: 'COSMOS_DATABASE' },
{ kvName: 'invttrdg-azure-openai-endpoint', envVar: 'AZURE_OPENAI_ENDPOINT' },
{ kvName: 'invttrdg-azure-openai-key', envVar: 'AZURE_OPENAI_KEY' },
{ kvName: 'invttrdg-azure-openai-deployment', envVar: 'AZURE_OPENAI_DEPLOYMENT' },
{ kvName: 'invttrdg-product-id', envVar: 'PRODUCT_ID' },
];
// AZURE_KEYVAULT_URL must be set to trigger Key Vault resolution.
// If absent, resolveSecrets() is a no-op and .env values are used as-is.
await resolveSecrets(INVTTRDG_SECRETS, {
vaultUrl: process.env.AZURE_KEYVAULT_URL,
});
// Dynamic import ensures config/index.ts (and all transitive modules) evaluate
// AFTER process.env is fully populated above.
// tradingTelemetry.init() is called at the start of main() in index.ts.
await import('./index.js');