|
1 | 1 | # Nightscout CGM Remote Monitor |
2 | 2 |
|
3 | 3 | ## Overview |
4 | | -Nightscout is a web-based Continuous Glucose Monitor (CGM) system designed to allow caregivers to remotely view a patient's glucose data in real-time. The project aims to provide robust, real-time glucose monitoring, data visualization, and alert capabilities, supporting both patient care and clinical research. Key capabilities include multiple API versions for data access, comprehensive data storage, and a plugin-based architecture for extensibility. Future ambitions include enhanced AI agent collaboration through a dedicated control plane, modernized testing frameworks, and advanced authentication mechanisms. |
| 4 | +Nightscout is a web-based Continuous Glucose Monitor (CGM) system enabling remote, real-time viewing of patient glucose data. Its core purpose is to provide robust glucose monitoring, data visualization, and alert capabilities for patient care and clinical research. The project supports multiple API versions and features a plugin-based architecture for extensibility. Future ambitions include enhanced AI agent collaboration via a dedicated control plane, modernized testing, and advanced authentication mechanisms. |
5 | 5 |
|
6 | 6 | ## User Preferences |
7 | 7 | I want iterative development. Ask before making major architectural changes. Provide detailed explanations for complex technical decisions. |
8 | 8 |
|
9 | 9 | ## System Architecture |
10 | | -The Nightscout system is built around a Node.js server with a MongoDB database. It features a modular structure, separating server core, API versions (v1, v2, v3), authorization, plugins, and client-side code. |
| 10 | +The Nightscout system is a modular Node.js application backed by MongoDB. It separates server core, API versions (v1, v2, v3), authorization, plugins, and client-side components. |
11 | 11 |
|
12 | 12 | ### UI/UX Decisions |
13 | | -The frontend utilizes Webpack for asset bundling and features charting with D3/jQuery, providing a dynamic dashboard experience. |
| 13 | +The frontend uses Webpack for asset bundling and D3/jQuery for dynamic charting, delivering a comprehensive dashboard experience. |
14 | 14 |
|
15 | 15 | ### Technical Implementations |
16 | 16 | - **API Versions:** |
17 | | - - **API v1 (`/api/v1`):** Provides core CGM data, treatments, profiles, and device status. Uses `API_SECRET` for basic authentication. |
18 | | - - **API v2 (`/api/v2`):** Extends v1 with advanced authorization, including JWT tokens, roles, subjects, and permissions management. |
19 | | - - **API v3 (`/api/v3`):** A modern REST API based on OpenAPI 3.0, offering comprehensive CRUD operations for collections like entries, treatments, and devicestatus. Swagger UI is available at `/api3-docs`. |
| 17 | + - **API v1 (`/api/v1`):** Core CGM data, treatments, profiles, device status with `API_SECRET` authentication. |
| 18 | + - **API v2 (`/api/v2`):** Extends v1 with JWT-based authorization, roles, and permissions. |
| 19 | + - **API v3 (`/api/v3`):** Modern OpenAPI 3.0 REST API for comprehensive CRUD operations; Swagger UI available at `/api3-docs`. |
20 | 20 | - **Authentication:** |
21 | | - - **API v1:** SHA1 hash of `API_SECRET` in headers or as a query parameter. |
22 | | - - **API v2/v3:** JWT-based authentication with `Bearer` tokens, managed through an authorization subsystem that defines subjects, roles, and fine-grained permissions (e.g., `api:entries:read`). |
23 | | -- **Real-time Data:** Implemented using Socket.IO for real-time updates on data storage and alarm notifications. |
24 | | -- **Plugin Architecture:** A robust plugin system (e.g., ar2, basal, bolus, cob, iob) allows for extending functionality. |
25 | | -- **Agentic Control Plane (Proposed):** A clean separation between control plane (policy, configuration, intent) and data plane (observations, telemetry, delivery) to facilitate AI agent collaboration with AID systems. This includes JSON schemas for event envelopes, profile definitions, override instances, and delivery requests/observations. Key concepts include event-driven architecture, authority hierarchy (Human > Agent > Controller), and bridge modes for legacy data. |
26 | | -- **Testing & Modernization (Proposed):** A three-track approach for modernizing testing: |
27 | | - 1. **Testing Foundation:** Update core testing libraries (Mocha, Supertest, NYC) and secure existing tests. |
28 | | - 2. **Logic/DOM Separation:** Extract pure logic into `lib/client-core/` for isolated, DOM-free testing. |
29 | | - 3. **UI Modernization Discovery:** Evaluate new UI technologies and define a migration roadmap. |
30 | | -- **Security:** Brute-force protection for authentication is implemented via `delaylist.js` (IP-based progressive delay). |
31 | | -- **MongoDB Driver 5.x Compatibility:** Updates to handle multi-document writes and race conditions, ensuring correct processing of array inputs for `devicestatus` and WebSocket `dbAdd` operations. |
32 | | -- **MongoDB Connection Pool Configuration:** Connection pool size reduced from driver default of 100 to 5 to prevent socket exhaustion. Configurable via environment variables: |
33 | | - |
34 | | - | Variable | Default | Description | |
35 | | - |----------|---------|-------------| |
36 | | - | `MONGO_POOL_SIZE` | 5 | Maximum connections per server (set to 100 for legacy behavior) | |
37 | | - | `MONGO_MIN_POOL_SIZE` | 0 | Minimum connections kept warm | |
38 | | - | `MONGO_MAX_IDLE_TIME_MS` | 30000 | Close idle connections after 30 seconds | |
39 | | - | `MONGO_POOL_DEBUG` | (unset) | Set to `true` to enable connection pool event logging | |
40 | | - |
41 | | - To restore legacy behavior: `MONGO_POOL_SIZE=100` |
42 | | - |
43 | | - Test environment uses `MONGO_POOL_SIZE=5` (configured in `my.test.env`) - increased from 2 to improve stability during parallel test runs. |
44 | | - |
45 | | -- **Prediction Array Truncation:** Prediction arrays (IOB, COB, UAM, ZT) in devicestatus documents are automatically truncated to 288 elements (24 hours of 5-minute readings) before storage. This prevents MongoDB issues with excessively large documents. Controlled by `PREDICTIONS_MAX_SIZE` environment variable: |
46 | | - - **Default:** 288 (truncation enabled) |
47 | | - - **Custom value:** Set `PREDICTIONS_MAX_SIZE=<number>` to change the limit |
48 | | - - **Disable truncation:** Set `PREDICTIONS_MAX_SIZE=0` to preserve full prediction arrays |
49 | | -- **OIDC Actor Identity (Proposed - High Priority):** OpenID Connect integration to replace freeform `enteredBy` with cryptographically-verified actor identities. Enables care coordination, audit trails, and delegation tracking. See `docs/proposals/oidc-actor-identity-proposal.md` for full RFC including: |
50 | | - - OAuth2/OIDC protocol flows with NRG Gateway (Ory Hydra/Kratos) |
51 | | - - JWT claims specification with actor and delegation support |
52 | | - - Actor lookup collection schema |
53 | | - - Nightscout Core plugin requirements |
54 | | - - Migration path from `enteredBy` to verified `actor_ref` |
55 | | - - Comprehensive test plan (unit/integration/E2E/security) |
| 21 | + - **API v1:** SHA1 hash of `API_SECRET`. |
| 22 | + - **API v2/v3:** JWT `Bearer` tokens with fine-grained permissions. |
| 23 | +- **Real-time Data:** Socket.IO for live data updates and alarms. |
| 24 | +- **Plugin Architecture:** Extensible system supporting various plugins (e.g., ar2, basal, bolus). |
| 25 | +- **Agentic Control Plane (Proposed):** A clean separation of control plane (policy, configuration) and data plane (telemetry, delivery) to facilitate AI agent collaboration using event-driven architecture and JSON schemas for event envelopes. |
| 26 | +- **Testing & Modernization (Proposed):** Strategy to update testing libraries, separate logic from DOM for isolated testing, and evaluate new UI technologies. |
| 27 | +- **Security:** IP-based brute-force protection for authentication. |
| 28 | +- **MongoDB Compatibility:** Updates for MongoDB Driver 5.x, addressing multi-document writes, race conditions, and optimized connection pooling (default `MONGO_POOL_SIZE=5`). |
| 29 | +- **Prediction Array Truncation:** Automatic truncation of prediction arrays to 288 elements by default to prevent oversized MongoDB documents, configurable via `PREDICTIONS_MAX_SIZE`. |
| 30 | +- **OIDC Actor Identity (Proposed):** OpenID Connect integration for cryptographically-verified actor identities, replacing `enteredBy` for enhanced audit trails and delegation tracking. |
56 | 31 |
|
57 | 32 | ### System Design Choices |
58 | | -- **Event-driven architecture** for control plane interactions. |
59 | | -- **Append-only event streams** with cursor-based synchronization. |
60 | | -- **Config vs Runtime vs Computed** separation for clarity and maintainability. |
61 | | -- **Monorepo structure** for managing various components. |
62 | | -- **Environment variables** for flexible configuration, including `PORT`, `MONGO_CONNECTION`, `API_SECRET`, and `DISPLAY_UNITS`. |
63 | | - |
64 | | -## Data Schema Documentation |
65 | | - |
66 | | -New schema documentation has been added based on code analysis and domain expert interviews: |
67 | | - |
68 | | -- **`docs/data-schemas/treatments-schema.md`** - Comprehensive documentation of the treatments collection, including: |
69 | | - - Field inventory (eventType, created_at, glucose, carbs, insulin, etc.) |
70 | | - - 20+ event types from careportal and controller plugins |
71 | | - - Timestamp semantics (created_at vs srvCreated) |
72 | | - - Client compatibility notes (AAPS, Loop, xDrip sync identity patterns) |
73 | | - - Known bugs (basal slice display, override duration issues) |
74 | | - |
75 | | -- **`docs/data-schemas/profiles-schema.md`** - Profile structure documentation including: |
76 | | - - Store-based profile organization |
77 | | - - Time-value pair format for basal/carbratio/sens/targets |
78 | | - - Loop-specific loopSettings and overridePresets |
79 | | - - Profile switch treatment embedding (AAPS pattern) |
80 | | - - Timezone handling quirks |
81 | | - |
82 | | -Key insights from schema documentation: |
83 | | -- Different controllers use different fields for sync deduplication (AAPS: `identifier`, Loop: pump fields, xDrip: `uuid`) |
84 | | -- The `eventType` field is essentially free-form - controllers can send any value |
85 | | -- Report plugins serve as implicit schema documentation by revealing which fields are actually used |
86 | | - |
87 | | -## Documentation Structure |
88 | | - |
89 | | -Documentation is organized into purpose-specific folders. Start at `docs/INDEX.md` for navigation. |
90 | | - |
91 | | -| Folder | Purpose | |
92 | | -|--------|---------| |
93 | | -| `docs/meta/` | Project-level navigation: architecture overview, modernization roadmap, documentation progress | |
94 | | -| `docs/audits/` | System analysis: API, data layer, security, real-time, plugin, messaging, dashboard audits | |
95 | | -| `docs/requirements/` | Formal requirements by area (shape handling, authorization, API v1 compatibility) | |
96 | | -| `docs/test-specs/` | Test specifications with progress tracking; each area tracks its own gaps | |
97 | | -| `docs/proposals/` | RFC-style proposals for new features (OIDC, control plane, testing modernization) | |
98 | | -| `docs/data-schemas/` | Collection and field documentation (treatments, profiles) | |
99 | | -| `docs/plugins/` | Plugin-specific documentation | |
100 | | - |
101 | | -### For AI Agents |
102 | | -Each test area is self-contained with requirements, test specs, progress tracking, and priority gaps. This enables focused iteration on one topical area at a time. See `docs/INDEX.md` for the full taxonomy. |
103 | | - |
104 | | -## Test Documentation |
105 | | - |
106 | | -Test specifications and requirements are organized in `docs/test-specs/` and `docs/requirements/`. Each test area tracks its own progress, discoveries, and coverage gaps. |
107 | | - |
108 | | -### Test Spec Files |
109 | | -| Area | Test Spec | Requirements | |
110 | | -|------|-----------|--------------| |
111 | | -| Shape Handling | `docs/test-specs/shape-handling-tests.md` | `docs/requirements/data-shape-requirements.md` | |
112 | | -| Authorization | `docs/test-specs/authorization-tests.md` | `docs/requirements/authorization-security-requirements.md` | |
113 | | -| API v1 Compatibility | (integrated) | `docs/requirements/api-v1-compatibility-requirements.md` | |
114 | | - |
115 | | -### Test Organization (Updated January 2026) |
116 | | - |
117 | | -Tests are organized for efficient execution in resource-constrained environments: |
118 | | - |
119 | | -| Script | Purpose | Tests | Execution | |
120 | | -|--------|---------|-------|-----------| |
121 | | -| `npm run test:unit` | Pure unit tests (no DB) | 240 tests / 43 files | Parallel (2 workers) | |
122 | | -| `npm run test:integration` | DB/API tests | 335+ tests / 62 files | Serial | |
123 | | -| `npm run test:all` | Complete suite | Both | Unit then Integration | |
124 | | -| `npm run test:unit:ci` | CI unit tests | Same as unit | Uses ci.test.env | |
125 | | -| `npm run test:integration:ci` | CI integration | Same as integration | Uses ci.test.env | |
126 | | - |
127 | | -**Resource Configuration:** |
128 | | -- Replit: `MONGO_POOL_SIZE=3` (fits 15 socket limit with 2 workers) |
129 | | -- CI: `MONGO_POOL_SIZE=5` (more resources available) |
130 | | -- Parallel jobs reduced from 4 to 2 workers |
131 | | - |
132 | | -**Environment Files:** |
133 | | -- `my.test.env` - Local/Replit development (uses shared test MongoDB, requires remote connection since Replit has no local MongoDB) |
134 | | -- `tests/ci.test.env` - GitHub Actions CI (uses localhost MongoDB service container) |
135 | | - |
136 | | -### Quick Test Commands |
137 | | -```bash |
138 | | -npm run test:unit # Fast parallel unit tests |
139 | | -npm run test:integration # Serial integration tests |
140 | | -npm run test:all # Complete test suite |
141 | | -npm test -- --grep "Shape Handling" |
142 | | -npm test -- --grep "Security" |
143 | | -npm test -- tests/concurrent-writes.test.js |
144 | | -``` |
145 | | - |
146 | | -### Flaky Test Detection |
147 | | -A flaky test runner is available to identify tests that pass inconsistently: |
148 | | - |
149 | | -```bash |
150 | | -npm run test:flaky # Run 10 iterations (default) |
151 | | -npm run test:flaky:quick # Run 3 iterations (quick check) |
152 | | -npm run test:flaky:thorough # Run 20 iterations (thorough analysis) |
153 | | -``` |
154 | | - |
155 | | -Configuration via environment variables: |
156 | | -- `FLAKY_TEST_ITERATIONS` - Number of test runs (default: 10) |
157 | | -- `FLAKY_TEST_TIMEOUT` - Timeout per run in ms (default: 300000) |
158 | | -- `FLAKY_OUTPUT_DIR` - Output directory (default: ./flaky-test-results) |
159 | | - |
160 | | -Reports are generated in `flaky-test-results/` including: |
161 | | -- Markdown report with flaky tests sorted by failure rate |
162 | | -- JSON data file with detailed per-test run history |
163 | | -- Individual iteration JSON results for debugging |
164 | | - |
165 | | -### Isolation Testing for Specific Test Files |
166 | | -To run a single test file multiple times and detect flakiness: |
167 | | -```bash |
168 | | -TEST=api.entries npm run test:flaky:isolate # Test entries API |
169 | | -TEST=api3.socket npm run test:flaky:isolate # Test socket API |
170 | | -FLAKY_ITERATIONS=20 TEST=security npm run test:flaky:isolate # 20 iterations |
171 | | -``` |
172 | | - |
173 | | -### Timing-Aware Testing |
174 | | -Run tests with timing warnings enabled to identify slow operations: |
175 | | -```bash |
176 | | -npm run test:timing # Full suite with timing warnings |
177 | | -npm run test:timing:single # Single test file (set TEST env var) |
178 | | -npm run test:slow # Tests with slow threshold logging |
179 | | -``` |
180 | | - |
181 | | -### Known Test Issues (Last Analysis: January 19, 2026) |
182 | | - |
183 | | -**Summary:** ✅ **TESTS STABLE** - Stress testing (3-5 iterations per test file) shows 100% pass rate across all test files including api.shape-handling (now optimized). |
184 | | - |
185 | | -**Recent Fixes:** |
186 | | -- `boluswizardpreview.test.js` - Fixed floating-point precision issue in `roundInsulinForDisplayFormat()` by adding epsilon (1e-9) before floor operation; test "set a pill to the BWP with infos" now stable |
187 | | -- `api.shape-handling.test.js` - Fixed by optimizing server boot (beforeEach→before); now runs in ~6s with 172ms/test avg |
188 | | -- `api.deduplication.test.js` - Fixed timeout issues by increasing timeout to 30s and optimizing cleanup |
189 | | -- `api3.renderer.test.js` - XML/CSV content type tests now pass |
190 | | - |
191 | | -**Known Infrastructure Issue:** |
192 | | -- Full test suite runs may hang during server teardown (tick cycles continue after tests complete). Individual test files pass when run in isolation. This is a test cleanup issue, not test flakiness. |
193 | | - |
194 | | -**Flaky Test Status:** See `docs/test-specs/flaky-tests.md` for current status summary and improvement roadmap. |
195 | | - |
196 | | -#### Slow Tests |
197 | | -Some tests are slow due to server boot overhead (2-3s per test): |
198 | | -- `concurrent-writes.test.js` - AAPS sync simulation tests are slow by design but pass consistently |
199 | | -- `v1 API Batch Operations` - Large batch operations take longer but pass consistently |
200 | | - |
201 | | -#### Test Helpers Available |
202 | | -The `tests/lib/test-helpers.js` module provides utilities to reduce flakiness: |
203 | | -- `waitForConditionWithWarning()` - Polling-based waits instead of setTimeout |
204 | | -- `waitForConditionAsync()` - Promise-based version for async/await |
205 | | -- `startTestTimer()` - Monitor test execution time |
206 | | -- `enableSetTimeoutWarnings()` - Detect setTimeout anti-patterns |
207 | | - |
208 | | -See `docs/test-specs/coverage-gaps.md` for aggregated coverage gaps across all areas. |
| 33 | +- **Event-driven architecture** for control plane. |
| 34 | +- **Append-only event streams**. |
| 35 | +- **Monorepo structure**. |
| 36 | +- **Environment variables** for flexible configuration (`PORT`, `MONGO_CONNECTION`, `API_SECRET`). |
209 | 37 |
|
210 | 38 | ## External Dependencies |
211 | | -- **MongoDB:** Primary database for data storage. |
212 | | -- **Socket.IO:** For real-time data communication. |
213 | | -- **Webpack:** For bundling frontend assets. |
214 | | -- **Nodemon:** For development server auto-restarts. |
| 39 | +- **MongoDB:** Primary database. |
| 40 | +- **Socket.IO:** Real-time communication. |
| 41 | +- **Webpack:** Frontend asset bundling. |
| 42 | +- **Nodemon:** Development server. |
215 | 43 | - **Mocha, Supertest, NYC:** Testing frameworks. |
216 | | -- **Pushover, IFTTT Maker:** Messaging and notification services. |
217 | | -- **Alexa, Google Home:** Integrations for voice assistant interaction. |
| 44 | +- **Pushover, IFTTT Maker:** Messaging and notifications. |
| 45 | +- **Alexa, Google Home:** Voice assistant integrations. |
0 commit comments