| Health & metrics |
routes/system.js |
GET /health, GET /metrics |
Uptime/heap reporting, academic-year stamp |
formatting |
— |
test/routes/system.test.js |
| Users list/search/detail |
routes/users.js |
GET /users, /users?kind=, /users/search?q=, /users/:id |
Kind filter, name search (min 2 chars), normalization |
jupiter, normalizers, formatting |
— |
test/routes/users.test.js |
| Events + archived + detail |
routes/events.js |
GET /events, ?erasmusOnly=false, /events/archived, /events/:id |
Academic-year + ERASMUS visibility filter, sort desc |
jupiter, normalizers, formatting |
— |
test/routes/events.test.js |
| Event subscriptions |
routes/events.js |
GET /events/:id/subscriptions, .../:userId |
Status aggregation (byStatus), subscription normalization |
jupiter, normalizers |
— |
test/routes/events.test.js |
| Section info |
routes/section.js |
GET /section |
Cached section lookup |
jupiter |
— |
test/routes/section.test.js |
| National events |
routes/nationalEvents.js |
GET /national-events |
Cached national events passthrough |
jupiter |
— |
test/routes/nationalEvents.test.js |
| Registration requests |
routes/requests.js |
GET /requests |
Pending requests normalized as users |
jupiter, normalizers |
— |
test/routes/requests.test.js |
| Treasury cash-flow |
routes/treasury.js |
GET /treasury/cash-flow?since=&to= |
Required params, strict YYYY-MM-DD validation |
jupiter |
— |
test/routes/treasury.test.js |
| Stats: nationality / field-of-study / overview / cities |
routes/stats.js |
GET /stats/* |
Distribution math over cached users |
jupiter, normalizers, nationality, fieldsOfStudy, formatting |
— |
test/routes/stats.test.js |
| Stats: comprehensive |
routes/stats.js |
GET /stats/comprehensive |
15-min cache, batched subscription fan-out, inactive-member computation |
jupiter, normalizers, nationality, fieldsOfStudy, formatting |
— |
covered indirectly by unit tests (heavy fan-out) |
| Google Contacts export |
routes/export.js + googleContacts.js |
GET /export/google-contacts |
CSV row building, phone dedupe, streaming via csv-stringify |
jupiter, formatting, nationality, fieldsOfStudy |
— |
test/routes/export.test.js |
| Auth login/refresh/verify/me/logout |
routes/auth.js |
POST /auth/login, /auth/refresh, /auth/verify, GET /auth/me, POST /auth/logout |
Cognito SDK flows; generic auth-failure errors; sub-based board flag |
Cognito SDK, middleware/jwtAuth, config |
— |
test/routes/auth.test.js |
| JWT verification gate |
middleware/jwtAuth.js |
(used by /hercules/*) |
JWKS fetch + 1 h cache, kid-rotation retry, RS256 verify, board check |
jsonwebtoken, config |
— |
board gate exercised via test/routes/hercules.test.js (jwtAuth stubbed there); JWKS/token-verify path untested |
| Hercules records CRUD |
routes/hercules.js |
`POST/PUT/DELETE /hercules/events |
meetings |
offices |
trainings` |
Validation → Firestore write, audit fields (addedBy, lastModifiedBy) |
| Fidelity entries |
routes/hercules.js |
POST /hercules/fidelity, DELETE /hercules/fidelity/:id |
Transaction updates progress counters; pointsOverride wins over points |
firebase-admin, validation |
fidelityEntries, progress |
test/routes/hercules.test.js |
| Progress updates |
routes/hercules.js |
PUT /hercules/progress/:id |
Field whitelist (mass-assignment protection) |
firebase-admin, validation |
progress |
test/routes/hercules.test.js |
| Board approval |
routes/hercules.js |
POST /hercules/board/:id |
Sets boardOk/status on progress, appends history |
firebase-admin, validation |
progress, boardApprovalHistory |
test/routes/hercules.test.js |
| Meeting attendance |
routes/hercules.js |
POST /hercules/attendance, PUT/DELETE /hercules/attendance/:id |
Status enum enforcement, semester/year defaults |
firebase-admin, validation |
meetings_attendance |
test/routes/hercules.test.js |
| Audit logging |
routes/hercules.js |
POST /hercules/audit |
Sanitized, truncated audit entries |
firebase-admin |
auditLogs |
test/routes/hercules.test.js |
| Upstream client |
jupiter.js |
(internal) |
Cognito token cache (55 min), response cache (5 min), "null"-string absorption, 400-means-404 for subscriptions |
axios, Cognito SDK |
— |
mocked in every suite that calls upstream |
| Config & fail-fast |
config.js |
(internal) |
Core env validation at require time; all env parsing |
dotenv |
— |
exercised by every suite's env setup |