mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 22:02:16 +00:00
chore(planning): mark Phase 4b admin refactor complete
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1a7e3d6c2c
commit
265095b774
2 files changed
+121
-7
No files matched your search
+11
-7
@@ -64,13 +64,17 @@ Last update: 2026-05-09T16:10:00+02:00
|
||||
|
||||
## Phase 4b — Admin Panel refactor (Settings-style dynamic routes)
|
||||
|
||||
- [ ] /admin/[section]/page.tsx + admin-shell sidebar
|
||||
- [ ] Sections moved to /admin/<slug> routes (system-status, services, integrations, feedback, reminders, users, api-tokens, login-overview, backups, danger-zone)
|
||||
- [ ] Status-card CTAs use real routes (no #anchor)
|
||||
- [ ] i18n keys reorganised under admin.section.<slug>.\*
|
||||
- [ ] Sidebar nav expandable Admin group
|
||||
- [ ] Legacy #anchor → new route redirect in proxy.ts
|
||||
- [ ] Bundle-size win on /admin overview verified
|
||||
- [x] /admin/[section]/page.tsx + admin-shell sidebar — commit `d8b71b3`
|
||||
- [x] Sections moved to /admin/<slug> routes (system-status, general, services, integrations, feedback, reminders, users, api-tokens, login-overview, backups, danger-zone) — commit `12b280b`
|
||||
- [x] T2.6 Backups dedicated admin section + manual run — commit `69c5225`
|
||||
- [x] T2.7 /admin/users with role filters + force-logout — commit `5957e18`
|
||||
- [x] i18n keys reorganised under admin.section.<slug>.\* (EN + DE parity) — commit `a34cd8c`
|
||||
- [x] Sidebar nav expandable Admin group — commit `73965cd`
|
||||
- [x] Status-card CTAs use real routes (no #anchor) — commit `961e2a9`
|
||||
- [x] Legacy section-anchor → new route redirect in proxy.ts (path-style only; pure `#fragments` cannot be redirected server-side, callsites rewritten directly) — commit `7a47532`
|
||||
- [x] Tests: status-card-grid asserts route existence + per-section render smoke + i18n parity (existing) — commit `1a7e3d6`
|
||||
- [x] Bundle-size win verified architecturally (overview no longer imports section components); `pnpm build` blocked by pre-existing Node 25 issue
|
||||
- Result: ok / commits `d8b71b3 12b280b 69c5225 5957e18 a34cd8c 73965cd 961e2a9 7a47532 1a7e3d6`
|
||||
- Detailed report: `.planning/phase-4b-report.md`
|
||||
|
||||
## Phase 5 — UX polish
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
# Phase 4b — Admin Panel refactor report
|
||||
|
||||
Status: done. 9 atomic commits, `pnpm typecheck`, `pnpm lint` (warnings
|
||||
only, all pre-existing), `pnpm test --run` (96 files / 745 tests) all
|
||||
green. `pnpm format:check` flags two pre-existing planning reports
|
||||
owned by Phase 3/4 — not touched by this phase.
|
||||
|
||||
## Scaffolding (commit `d8b71b3`)
|
||||
|
||||
`src/components/admin/section-slugs.ts` declares the 11-slug enum
|
||||
(`system-status`, `general`, `services`, `integrations`, `feedback`,
|
||||
`reminders`, `users`, `api-tokens`, `login-overview`, `backups`,
|
||||
`danger-zone`) plus the legacy-anchor → slug map. The shell at
|
||||
`src/components/admin/admin-shell.tsx` mirrors `<SettingsShell>`: mobile
|
||||
horizontal scroll strip, desktop sticky 220px sidebar with an "Overview"
|
||||
entry pointing back to `/admin`. Dynamic route at
|
||||
`src/app/admin/[section]/page.tsx` is a server component that calls
|
||||
`generateStaticParams()` and delegates to a client renderer in
|
||||
`renderer.tsx`. The renderer's `switch` carries an `_exhaustive: never`
|
||||
guard so a future slug added to the enum without a wired component is
|
||||
caught at type-check time.
|
||||
|
||||
## Section relocation + overview reduction (commit `12b280b`)
|
||||
|
||||
Every existing component (`SystemStatusSection`, `GeneralSettingsSection`,
|
||||
`ServicesSection`, `UmamiSection`, `GlitchtipSection`,
|
||||
`WebPushVapidSection`, `BugReportSection`, `FeedbackInboxSection`,
|
||||
`RemindersSection`, `UserManagementSection`, `ApiTokenOverviewSection`,
|
||||
`LoginOverviewSection`, `DangerZoneSection`) had its `id` prop made
|
||||
optional so it works under the new dynamic route. The composite
|
||||
`<IntegrationsGroupSection>` at
|
||||
`src/components/admin/integrations-group-section.tsx` wraps the four
|
||||
integration sub-sections under one `/admin/integrations` route. The
|
||||
old monolithic `/admin/page.tsx` is now a true overview: status-card
|
||||
grid + a quick-jump menu of the 11 sections.
|
||||
|
||||
## Backups (commit `69c5225`, T2.6)
|
||||
|
||||
`GET /api/admin/backups` returns metadata-only DataBackup rows
|
||||
(username, type, byte size, createdAt — never the encrypted blob).
|
||||
`POST /api/admin/backups/run` enqueues an ad-hoc `data-backup` pg-boss
|
||||
job using the global boss instance from `boss-instance.ts`; returns
|
||||
503 if the worker isn't running. `<BackupsSection>` lists rows in a
|
||||
table with size pretty-printed (B/KB/MB) and a "Backup now" button
|
||||
that surfaces a sonner toast.
|
||||
|
||||
## Users management (commit `5957e18`, T2.7)
|
||||
|
||||
`<UserManagementSection>` now has filter pills (All / Admins / Users)
|
||||
and a per-row force-logout action behind an `<AlertDialog>`
|
||||
confirmation. The "suspended" filter from the original spec was
|
||||
mapped to `all` because the User model has no `suspended` field
|
||||
today — documented in a comment in `user-management-section.tsx` for
|
||||
forward compatibility. `POST /api/admin/users/[id]/force-logout`
|
||||
deletes every Session row for the target and writes
|
||||
`admin.user.force-logout` to the audit log. Rejects self-target via
|
||||
the `disabled` flag on the row button.
|
||||
|
||||
## i18n (commit `a34cd8c`)
|
||||
|
||||
`admin.shell.{overview,sectionsNav}` plus
|
||||
`admin.section.<slug>.{title,subtitle}` for every slug, `users.filter.*`
|
||||
for the filter pills, and the new force-logout / backups copy. EN
|
||||
canonical, DE mirrors. The existing `i18n-locale-integrity.test.ts`
|
||||
already enforces parity at PR time — no new test was needed.
|
||||
|
||||
## Sidebar nav (commit `73965cd`)
|
||||
|
||||
`src/components/layout/sidebar-nav.tsx` now reads `useAuth()` to
|
||||
conditionally render an "Admin Console" entry between Bug Report and
|
||||
Settings. When the active route starts with `/admin/`, the entry
|
||||
expands into an indented sub-list of every section (collapsed-mode
|
||||
keeps the icon-only button without the sub-list).
|
||||
|
||||
## Status-card hrefs (commit `961e2a9`)
|
||||
|
||||
Every CTA in `status-card-grid.tsx` switched from `/admin#section-*` to
|
||||
`/admin/<slug>`. The honesty problem from v1.4.6 T6 is permanently
|
||||
fixed.
|
||||
|
||||
## Legacy redirects (commit `7a47532`)
|
||||
|
||||
`proxy.ts` adds `LEGACY_ADMIN_ANCHORS`, a 13-entry 301 map from
|
||||
`/admin/section-<id>` (path style) to `/admin/<slug>`. **Pure URL
|
||||
fragments (`#foo`) never reach the server**, so the only legacy form
|
||||
this phase can handle server-side is the path-style mistype. Every
|
||||
in-app callsite has been rewritten to use the new route directly, so
|
||||
no live link relies on the redirect — it's defence for hand-typed
|
||||
bookmarks and referrer rewriters.
|
||||
|
||||
## Tests (commit `1a7e3d6`)
|
||||
|
||||
`status-card-grid.test.tsx` replaces the v1.4.6 anchor-id allowlist
|
||||
with three checks per card: href matches `/admin/<slug>`, slug is in
|
||||
`ADMIN_SECTION_SLUGS`, and `src/app/admin/[section]/page.tsx` exists
|
||||
on disk via `existsSync`. New `sections.test.tsx` SSR-renders every
|
||||
section component reachable from the renderer (uses `vi.mock` on
|
||||
TanStack Query, the auth hook, and `next/navigation`) and asserts the
|
||||
v1.5 fold-ins (filter pills, "Backup now" button) paint.
|
||||
|
||||
## Bundle-size verification
|
||||
|
||||
`pnpm build` aborts on the documented Node 25 `Cannot read private
|
||||
member #state` regression (already noted in STATE.md). Static
|
||||
inspection of the dependency graph confirms the win: `/admin/page.tsx`
|
||||
now imports only `<AdminShell>`, `<StatusCardGrid>`,
|
||||
`<ADMIN_SECTIONS>`, and `useAdminSettings`. The 13 section components
|
||||
that previously lived in the monolithic page no longer ship in the
|
||||
overview chunk; each is reachable only from its own dynamic-route
|
||||
bundle.
|
||||
Reference in new issue
Block a user