Files
adam-acs/config/exchange_store.ts
T
Kevin L'Hereec 0c83a4ccb2 feat: TR-069 Exchange Viewer - structured MongoDB storage with SSE streaming and sequence diagram UI
- MongoDB storage: cwmp_exchanges collection with indexes (deviceId+timestamp, deviceId+sequenceNumber unique, TTL 24h)
- ExchangeStoreService: CWMP method extraction, per-device queue for ordering, retry logic, message cap (5000/device)
- Exchange API: GET/DELETE/SSE stream endpoints with Last-Event-ID reconnection
- CwmpLoggerMiddleware: dual-write (MongoDB + legacy files) with fire-and-forget
- Frontend: SequenceViewer (CPE↔ACS lifelines, arrows, auto-scroll, virtual scroll) + InspectorPanel (formatted XML, copy, syntax highlighting)
- Tr069Trace page: integrated new viewer with col-6/col-6 layout
- DeviceDetail page: collapsible exchange section when device is traced
- 14 property-based tests, 40+ unit tests, 5 integration tests
- Health check includes index verification
- Config: feature flags, SSE timeouts, retry policy
2026-06-03 15:52:44 +02:00

99 lines
3.1 KiB
TypeScript

import env from '#start/env'
const exchangeStoreConfig = {
/**
* Maximum number of exchanges stored per device.
* Oldest messages are deleted when this cap is exceeded.
*/
maxMessagesPerDevice: env.get('EXCHANGE_STORE_MAX_MESSAGES', 5000),
/**
* TTL (time-to-live) in seconds for exchanges.
* MongoDB TTL index auto-removes documents older than this value.
* Default: 86400 seconds (24 hours).
*/
ttlSeconds: env.get('EXCHANGE_STORE_TTL_SECONDS', 86400),
/**
* SSE (Server-Sent Events) configuration.
*/
sse: {
/**
* Inactivity timeout in milliseconds.
* Connection is closed if no new exchange is pushed within this period.
* Default: 300000ms (5 minutes).
*/
inactivityTimeoutMs: env.get('EXCHANGE_STORE_SSE_INACTIVITY_TIMEOUT_MS', 300_000),
/**
* Absolute timeout in milliseconds.
* Connection is closed after this duration regardless of activity.
* Default: 7200000ms (2 hours).
*/
absoluteTimeoutMs: env.get('EXCHANGE_STORE_SSE_ABSOLUTE_TIMEOUT_MS', 7_200_000),
/**
* Maximum concurrent SSE connections per device.
* Additional connections beyond this limit are rejected.
*/
maxConnectionsPerDevice: env.get('EXCHANGE_STORE_SSE_MAX_CONNECTIONS_PER_DEVICE', 5),
/**
* Retry interval in milliseconds sent to clients via SSE `retry` field.
* Clients use this value when reconnecting after a disconnect.
* Default: 3000ms (3 seconds).
*/
retryIntervalMs: env.get('EXCHANGE_STORE_SSE_RETRY_INTERVAL_MS', 3000),
},
/**
* Retry policy for critical message persistence.
*/
retry: {
/**
* Maximum number of retry attempts for critical messages.
*/
maxAttempts: env.get('EXCHANGE_STORE_RETRY_MAX_ATTEMPTS', 3),
/**
* Base delay in milliseconds for exponential backoff.
* Actual delays: baseDelayMs, baseDelayMs*2, baseDelayMs*4, ...
* Default: 1000ms → retries at 1s, 2s, 4s.
*/
baseDelayMs: env.get('EXCHANGE_STORE_RETRY_BASE_DELAY_MS', 1000),
},
/**
* Read timeout in milliseconds for exchange retrieval queries.
* If a query exceeds this duration, partial results are returned with `isTruncated: true`.
* Default: 5000ms (5 seconds).
*/
readTimeoutMs: env.get('EXCHANGE_STORE_READ_TIMEOUT_MS', 5000),
/**
* Feature flags for gradual rollout and rollback.
*/
featureFlags: {
/**
* Enable/disable MongoDB persistence of exchanges.
* When false, exchanges are not written to MongoDB (CWMP sessions unaffected).
*/
persistence: env.get('FEATURE_EXCHANGE_PERSISTENCE', true),
/**
* Enable/disable SSE streaming endpoint.
* When false, the SSE endpoint returns 503 and clients fall back to REST polling.
*/
sseEnabled: env.get('FEATURE_SSE_ENABLED', true),
/**
* Data source for the Exchange API.
* 'mongodb': read from structured MongoDB collection (new system).
* 'file': read from legacy file-based logs (old system).
*/
apiSource: env.get('FEATURE_EXCHANGE_API_SOURCE', 'mongodb') as 'mongodb' | 'file',
},
}
export default exchangeStoreConfig