mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
The cycle gate checked only the per-user toggle and gender, never the operator server-wide availability layer. With the Cycle module turned off by the operator, /api/cycle/* kept serving, the coach injected the cycle block, the Apple-Health importer kept writing cycle rows, and the cycle-reminder cron kept firing CYCLE_PERIOD pushes — while nav and the doctor report already honoured the operator switch. Add isCycleAvailableForUser, which delegates to isModuleEnabled(userId, "cycle"): the cycle ModuleKey resolves the per-user toggle AND the operator availability map, so there is one source of truth and no duplicated operator logic. Route requireCycleEnabled, the coach cycle block, and the import accumulator through it; switch the cron to the injectable isModuleEnabled gate, matching the mood and measurement reminder crons, and add a skippedModuleDisabled counter. Correct the cron comment that claimed isCycleEnabled was itself the module gate. isCycleEnabled stays the pure per-user (user-layer) resolver the module foundation AND-s at layer one. Tests: assert requireCycleEnabled returns a 403 cycle.disabled envelope and the cron skips the push when the operator turns the module off.