mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 13:52:20 +00:00
refactor(settings): remove duplicate toggles, route to canonical owner
Phase B6 commit 3 of 4. The audit (`docs/audit/v1416-settings-audit.md` §2.5 + §2.6) found no live duplicate user-facing toggle between `/settings` and `/admin`: - Notification channels: per-user credentials in `/settings/notifications`, system-wide enable/disable in `/admin` via the global-services API. Different scope, no overlap. - AI providers: per-user override in `/settings/ai`, system default in admin AI settings. Different scope, no overlap. - Channel test buttons appear in both `<NotificationStatusCard>` and the per-channel cards (`<TelegramCard>` etc.) but they're different intents (post-failure smoke vs. post-config smoke), kept. - The export buttons (CSV/JSON, doctor-report PDF) used to live in Advanced AND Export — the duplication was already collapsed by phase B7 when the consolidated Export section shipped. What this commit actually does is document the rule in `CLAUDE.md` so future agents don't re-introduce a duplicate. Dead i18n keys (`settings.adminAreaTitle`, `settings.adminAreaDescription`, `settings.openAdminConsole`) are marked stale in the audit doc and will be removed in a follow-up hygiene PR — leaving them in place keeps the i18n locale-parity test green for now. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
a432cb2e26
commit
ed0cfda13f
1 file changed
+1
@@ -104,6 +104,7 @@ docker compose logs -f app # Tail app logs
|
||||
- **Notifications**: 3 channels (Telegram, ntfy, Web Push). Dispatcher at `src/lib/notifications/dispatcher.ts`. Opt-out model (all events enabled by default)
|
||||
- **Gravatar**: Server-side SHA-256 hash via `src/lib/gravatar.ts`. URL returned in `/api/auth/me` response as `gravatarUrl` field
|
||||
- **Sidebar**: Collapsible (localStorage-persisted). Settings mode with section shortcuts. User section at bottom with three-dot dropdown menu
|
||||
- **Settings vs Admin scope rule (v1.4.16 phase B6 audit)**: `/settings/<slug>` is **per-user** — toggles, credentials, layout, target ranges that affect one account. `/admin/<slug>` is **system-wide** — defaults, feature gating, host metrics, audit log read-access. Two surfaces overlap by design: (a) notification channels — admin can disable a channel system-wide via `/api/settings/global-services`, the user sets their own credentials in `/settings/notifications`; (b) AI providers — admin sets the default Codex/OpenAI key, user can override with their own. **No user-facing toggle should appear in both surfaces.** Keys like `settings.adminAreaTitle` are dead code (planned admin-shortcut tile that never shipped) and stay in JSON marked deprecated until a hygiene PR removes them. See `docs/audit/v1416-settings-audit.md`.
|
||||
- **ESLint**: Strict `react-hooks/set-state-in-effect` rule — avoid `setState` inside `useEffect`. Use lazy `useState()` initializer for localStorage reads
|
||||
- **Proxy route protection**: `src/proxy.ts` checks `healthlog_session` cookie; PUBLIC_PATHS array bypasses auth. Security headers (CSP, HSTS, X-Frame-Options) applied to all responses
|
||||
- **PWA safe area**: Root layout has `viewportFit: "cover"`. Bottom-nav uses `pb-[env(safe-area-inset-bottom)]` for iOS safe area
|
||||
|
||||
Reference in new issue
Block a user