|
|
@@ -1,4 +1,4 @@
|
|
|
-# Frontend UI: App Shell, Routing, Auth/RBAC, Explorer, Search, Date Range Filter, Navigation Polish, and Profile Password Change (RHL-019 / RHL-020 / RHL-021 / RHL-022 / RHL-023 / RHL-024 / RHL-025 / RHL-037 / RHL-032 / RHL-009)
|
|
|
+# Frontend UI: App Shell, Routing, Auth/RBAC, Explorer, Search, Date Range Filter, Navigation Polish, Profile Password Change, and Role Refinement (RHL-019 / RHL-020 / RHL-021 / RHL-022 / RHL-023 / RHL-024 / RHL-025 / RHL-037 / RHL-032 / RHL-009 / RHL-041)
|
|
|
|
|
|
This document describes the **frontend routing scaffold**, the **application shell layout**, and the core UI modules for the RHL Lieferscheine app.
|
|
|
|
|
|
@@ -14,6 +14,7 @@ Timeline:
|
|
|
- **RHL-037**: Search scope UX improvements (TopNav deep-link branch switching + Single combobox + Multi selection UX + deterministic URL state).
|
|
|
- **RHL-032**: Navigation UX polish (TopNav branding, theme toggle, user menu, tooltips, session indicator without content flicker, favicon, active states, and debounced loading UI).
|
|
|
- **RHL-009**: Profile password change UI (Change Password form + toasts).
|
|
|
+- **RHL-041**: Role refinement (`superadmin`) + capability separation for future user management (RHL-012).
|
|
|
|
|
|
> **Language policy**
|
|
|
>
|
|
|
@@ -25,7 +26,7 @@ Timeline:
|
|
|
|
|
|
## 1. Scope
|
|
|
|
|
|
-### 1.1 Implemented (as of RHL-037 + RHL-025 + RHL-032 + RHL-009)
|
|
|
+### 1.1 Implemented (as of RHL-041 + RHL-037 + RHL-025 + RHL-032 + RHL-009)
|
|
|
|
|
|
- **Public** `/login` route with a functional login form (shadcn/ui primitives).
|
|
|
|
|
|
@@ -59,14 +60,22 @@ Timeline:
|
|
|
- Sonner Toaster is mounted once in the root layout.
|
|
|
- UI code uses a small wrapper (`lib/frontend/ui/toast.js`) to keep copy and behavior consistent.
|
|
|
|
|
|
+- **Role model (RHL-041)**:
|
|
|
+ - Backend roles: `branch | admin | superadmin | dev`.
|
|
|
+ - UI treats **branch access** and **user management** as separate capabilities.
|
|
|
+ - UI introduces a pure role helper:
|
|
|
+ - `lib/frontend/auth/roles.js`
|
|
|
+ - `isAdminLike(role)` → `admin | superadmin | dev`
|
|
|
+ - `canManageUsers(role)` → `superadmin | dev` (RHL-012 prerequisite, no UI screens yet)
|
|
|
+
|
|
|
- **UI RBAC (branch-level)**:
|
|
|
- `BranchGuard` prevents branch users from accessing other branches’ URLs.
|
|
|
- - Admin/dev can access multiple branches.
|
|
|
- - Admin/dev branch existence validation uses `GET /api/branches`.
|
|
|
+ - Admin-like users (`admin/superadmin/dev`) can access multiple branches.
|
|
|
+ - Admin-like branch existence validation uses `GET /api/branches`.
|
|
|
- Fail-open policy on validation failures (do not lock the UI on temporary API errors).
|
|
|
|
|
|
- **Route param validation** (syntactic):
|
|
|
- - `branch`: `NL` + digits (syntactic validity; existence is validated by BranchGuard for admin/dev)
|
|
|
+ - `branch`: `NL` + digits (syntactic validity; existence is validated by BranchGuard for admin-like)
|
|
|
- `year`: `YYYY`
|
|
|
- `month`: `01–12`
|
|
|
- `day`: `01–31`
|
|
|
@@ -112,12 +121,19 @@ Timeline:
|
|
|
- Consistent tooltips across navigation.
|
|
|
- Session check indicator in TopNav (debounced) to avoid content flicker.
|
|
|
- Clear active states for Explorer and Search.
|
|
|
- - Safe handling of invalid branch routes (admin/dev): warning + one-click recovery.
|
|
|
+ - Safe handling of invalid branch routes (admin-like): warning + one-click recovery.
|
|
|
+
|
|
|
+ Implementation note:
|
|
|
+ - For small static brand assets (logos), Next Image optimization is disabled (`unoptimized`) to avoid browser-specific “pending” indicators caused by aborted `/_next/image` optimization requests.
|
|
|
|
|
|
---
|
|
|
|
|
|
### 1.2 Still out of scope / planned
|
|
|
|
|
|
+- User management UI + APIs (RHL-012):
|
|
|
+ - The UI role helpers already define `canManageUsers(role)`.
|
|
|
+ - RHL-012 will add screens and API endpoints and must enforce `superadmin/dev`.
|
|
|
+
|
|
|
- Email-based password reset/recovery:
|
|
|
- Planned as a separate follow-up ticket/phase.
|
|
|
- Rationale: higher security surface (token handling and non-leakage), external SMTP/IT dependencies, and separate rate limiting ticket (RHL-031) to avoid scope creep.
|
|
|
@@ -262,6 +278,10 @@ Asset convention:
|
|
|
- Store brand assets under `public/brand/`.
|
|
|
- Use two assets when needed (light/dark) and toggle them via Tailwind `dark:` classes.
|
|
|
|
|
|
+Implementation note:
|
|
|
+
|
|
|
+- For small static logo assets, Next Image optimization is disabled (`unoptimized`) to avoid repeated aborted `/_next/image` requests on some browsers.
|
|
|
+
|
|
|
### 4.4 Theme toggle
|
|
|
|
|
|
File: `components/app-shell/ThemeToggleButton.jsx`
|
|
|
@@ -296,18 +316,15 @@ File: `components/app-shell/UserStatus.jsx`
|
|
|
Menu items (German):
|
|
|
|
|
|
- **Profil** → `/profile` (account info + password change)
|
|
|
-- **Support** → opens a `mailto:` link to `info@attus.de`.
|
|
|
+- **Support** → opens a `mailto:` link to support.
|
|
|
- **Abmelden** → calls logout and redirects to login.
|
|
|
|
|
|
-Support mailto guidelines:
|
|
|
+Role label mapping:
|
|
|
|
|
|
-- Build the `mailto:` query string with `encodeURIComponent` (not `URLSearchParams`) to avoid “+” rendering issues in some mail clients.
|
|
|
-- Include basic context in the mail body:
|
|
|
- - current URL
|
|
|
- - route path
|
|
|
- - timestamp
|
|
|
- - user role/branch
|
|
|
- - user-agent
|
|
|
+- `branch` → “Niederlassung”
|
|
|
+- `admin` → “Admin”
|
|
|
+- `superadmin` → “Superadmin”
|
|
|
+- `dev` → “Entwicklung”
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -321,14 +338,14 @@ Purpose:
|
|
|
- Explorer (`/:branch`)
|
|
|
- Search (`/:branch/search`)
|
|
|
|
|
|
-- For admin/dev: enable quick branch switching while preserving the current “context”.
|
|
|
+- For admin-like users: enable quick branch switching while preserving the current “context”.
|
|
|
|
|
|
Behavior:
|
|
|
|
|
|
- Branch users:
|
|
|
- QuickNav is effectively fixed to their `branchId`.
|
|
|
|
|
|
-- Admin/dev users:
|
|
|
+- Admin-like users (`admin/superadmin/dev`):
|
|
|
- Loads branches via `GET /api/branches`.
|
|
|
- Stores the last selected branch in `localStorage` (`rhl_last_branch`) for convenience.
|
|
|
- Keeps `selectedBranch` stable and avoids update loops (guarded initialization).
|
|
|
@@ -348,9 +365,8 @@ Implementation notes:
|
|
|
- Deep-path branch switching logic is centralized in `lib/frontend/quickNav/branchSwitch.js`.
|
|
|
- Avoid using `useSearchParams()` inside QuickNav for “current query string” access.
|
|
|
- Use `window.location.search` at click-time instead (client-only).
|
|
|
- - This avoids build-time issues for static/prerender contexts.
|
|
|
|
|
|
-Invalid branch routes (admin/dev) (RHL-032):
|
|
|
+Invalid branch routes (admin-like) (RHL-032):
|
|
|
|
|
|
- If the user manually navigates to a syntactically valid but non-existent branch (e.g. `/NL200`):
|
|
|
- QuickNav shows a warning indicator.
|
|
|
@@ -381,10 +397,7 @@ Notes:
|
|
|
- `GET /api/auth/me` returns minimal identity data for the UI:
|
|
|
- `userId`, `role`, `branchId`, and (optionally) `email`.
|
|
|
|
|
|
-The `next` parameter:
|
|
|
-
|
|
|
-- includes the original `pathname` and query string
|
|
|
-- is sanitized to avoid open redirects (only internal paths are allowed)
|
|
|
+- Role is one of: `branch | admin | superadmin | dev`.
|
|
|
|
|
|
### 6.2 AuthGate (in-shell gating)
|
|
|
|
|
|
@@ -427,44 +440,41 @@ Flow:
|
|
|
Username policy:
|
|
|
|
|
|
- Backend stores usernames in lowercase and performs normalization during login.
|
|
|
-- UI enforces this policy as well:
|
|
|
+- UI enforces the same policy:
|
|
|
- username input is normalized to lowercase
|
|
|
- `autoCapitalize="none"` to prevent mobile auto-caps
|
|
|
|
|
|
---
|
|
|
|
|
|
-## 7. UI RBAC, Forbidden, and NotFound (RHL-021)
|
|
|
+## 7. UI RBAC, Forbidden, and NotFound (RHL-021 / RHL-041)
|
|
|
|
|
|
### 7.1 Goals
|
|
|
|
|
|
-RHL-021 adds a friendly UI layer on top of backend RBAC:
|
|
|
+UI-side RBAC exists for UX (backend RBAC remains authoritative):
|
|
|
|
|
|
- Branch users must not access other branches’ URLs.
|
|
|
-- Admin/dev users may access any existing branch.
|
|
|
+- Admin-like users may access any existing branch.
|
|
|
- Invalid route parameters (year/month/day) should surface as NotFound.
|
|
|
|
|
|
-Backend RBAC remains the source of truth. UI RBAC exists to:
|
|
|
-
|
|
|
-- prevent “obviously forbidden” navigation in the frontend
|
|
|
-- provide clear and consistent UX for end users
|
|
|
-
|
|
|
### 7.2 BranchGuard (UI-side RBAC)
|
|
|
|
|
|
Files:
|
|
|
|
|
|
- `components/auth/BranchGuard.jsx`
|
|
|
-- Pure logic:
|
|
|
- - `lib/frontend/rbac/branchAccess.js`
|
|
|
- - `lib/frontend/rbac/branchUiDecision.js`
|
|
|
+
|
|
|
+Pure logic:
|
|
|
+
|
|
|
+- `lib/frontend/rbac/branchAccess.js`
|
|
|
+- `lib/frontend/rbac/branchUiDecision.js`
|
|
|
|
|
|
Responsibilities:
|
|
|
|
|
|
- Read `user` and `status` from AuthContext.
|
|
|
- Enforce branch rules:
|
|
|
- role `branch` → allowed only when `:branch === user.branchId`
|
|
|
- - role `admin` / `dev` → allowed for any branch that exists
|
|
|
+ - admin-like (`admin/superadmin/dev`) → allowed for any branch that exists
|
|
|
|
|
|
-Admin/dev branch existence validation:
|
|
|
+Admin-like branch existence validation:
|
|
|
|
|
|
- `BranchGuard` fetches `GET /api/branches` and verifies the route branch exists.
|
|
|
- Fail-open policy:
|
|
|
@@ -567,6 +577,17 @@ URL-driven state policy:
|
|
|
- Search state is **URL-driven** to support shareable links.
|
|
|
- Cursor-based pagination state is **not shareable** and is kept in client state.
|
|
|
|
|
|
+Admin-like scope availability:
|
|
|
+
|
|
|
+- Admin-like users (`admin/superadmin/dev`) can switch between:
|
|
|
+ - Single (route branch)
|
|
|
+ - Multi (selected branches)
|
|
|
+ - All (global)
|
|
|
+
|
|
|
+Branch users:
|
|
|
+
|
|
|
+- Are forced to Single on their own branch.
|
|
|
+
|
|
|
Shareable params (first page identity):
|
|
|
|
|
|
- `q` (string)
|
|
|
@@ -595,22 +616,6 @@ Approach:
|
|
|
- Loading UI is shown only after a small delay.
|
|
|
- This is implemented with `useDebouncedVisibility(...)` and centralized timing constants.
|
|
|
|
|
|
-Files:
|
|
|
-
|
|
|
-- Timing constants: `lib/frontend/ui/uxTimings.js`
|
|
|
- - `LOADING_UI_DELAY_MS`
|
|
|
- - `SESSION_INDICATOR_DELAY_MS`
|
|
|
- - `SESSION_INDICATOR_MIN_VISIBLE_MS`
|
|
|
- - `TOOLTIP_DELAY_MS`
|
|
|
-
|
|
|
-- Debounce hook: `lib/frontend/hooks/useDebouncedVisibility.js`
|
|
|
-
|
|
|
-Applied to:
|
|
|
-
|
|
|
-- Explorer level loading skeletons
|
|
|
-- Search results loading skeletons
|
|
|
-- TopNav session indicator
|
|
|
-
|
|
|
---
|
|
|
|
|
|
## 10. Toast notifications (Sonner)
|
|
|
@@ -620,16 +625,6 @@ The project uses Sonner (shadcn/ui integration) for toast notifications.
|
|
|
- The Toaster is mounted once in `app/layout.jsx` (root layout) and respects the current theme.
|
|
|
- UI code should use the wrapper in `lib/frontend/ui/toast.js`.
|
|
|
|
|
|
-Wrapper functions:
|
|
|
-
|
|
|
-- `notifySuccess(...)`, `notifyError(...)`, `notifyInfo(...)`, `notifyWarning(...)`, `notifyLoading(...)`
|
|
|
-- `notifyApiError(err, ...)` for consistent mapping of `ApiClientError` to safe German copy
|
|
|
-
|
|
|
-Rationale:
|
|
|
-
|
|
|
-- Consistent UX across features.
|
|
|
-- Avoid scattering direct `toast.*` calls.
|
|
|
-
|
|
|
---
|
|
|
|
|
|
## 11. Profile: Password change (RHL-009)
|
|
|
@@ -641,38 +636,11 @@ Rationale:
|
|
|
### 11.2 Components
|
|
|
|
|
|
- `components/profile/ProfilePage.jsx`
|
|
|
- - Renders:
|
|
|
- - Account/session info card (role, branch, read-only email)
|
|
|
- - Password change card
|
|
|
-
|
|
|
- Note:
|
|
|
- - The email address is displayed read-only.
|
|
|
- - Email changes are not supported in the UI; email is managed centrally (IT / developers).
|
|
|
+ - Shows read-only account/session info (role, branch, email).
|
|
|
|
|
|
- `components/profile/ChangePasswordCard.jsx`
|
|
|
- - Contains a password change form:
|
|
|
- - `currentPassword`
|
|
|
- - `newPassword`
|
|
|
- - `confirmNewPassword`
|
|
|
-
|
|
|
- - Uses inline validation for:
|
|
|
- - required fields
|
|
|
- - confirmation mismatch
|
|
|
- - new password equals current password
|
|
|
-
|
|
|
- Calls `apiClient.changePassword({ currentPassword, newPassword })`.
|
|
|
-
|
|
|
- - Uses Sonner toasts for success/error feedback.
|
|
|
-
|
|
|
-### 11.3 Password policy UX
|
|
|
-
|
|
|
-The backend enforces an explicit password policy (see `docs/auth.md`).
|
|
|
-
|
|
|
-The frontend displays policy hints and maps `VALIDATION_WEAK_PASSWORD` details to user-friendly German hints.
|
|
|
-
|
|
|
-Helper module:
|
|
|
-
|
|
|
-- `lib/frontend/profile/passwordPolicyUi.js`
|
|
|
+ - Maps password policy errors into user-friendly German hints.
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -680,46 +648,14 @@ Helper module:
|
|
|
|
|
|
The Explorer + auth + search UI uses shadcn/ui primitives from `components/ui/*`.
|
|
|
|
|
|
-Core primitives:
|
|
|
-
|
|
|
-- `card`
|
|
|
-- `input`
|
|
|
-- `label`
|
|
|
-- `alert`
|
|
|
-- `button`
|
|
|
-- `breadcrumb`
|
|
|
-- `dropdown-menu`
|
|
|
-- `skeleton`
|
|
|
-- `table`
|
|
|
-
|
|
|
-Additional primitives used for Search scope UX:
|
|
|
-
|
|
|
-- `popover`
|
|
|
-- `command`
|
|
|
-- `badge`
|
|
|
-- `calendar` (react-day-picker wrapper)
|
|
|
-- `tooltip` (RHL-032)
|
|
|
-
|
|
|
-Radix integration note:
|
|
|
-
|
|
|
-- Radix triggers (`DropdownMenuTrigger`, `TooltipTrigger`, …) require the trigger element to support `ref` forwarding.
|
|
|
-- The project’s `components/ui/button.jsx` forwards refs to remain compatible with Radix `asChild` usage.
|
|
|
-
|
|
|
---
|
|
|
|
|
|
## 13. File Naming Convention (.js vs .jsx)
|
|
|
|
|
|
To keep the project consistent:
|
|
|
|
|
|
-- Use **`.jsx`** for files that contain JSX:
|
|
|
- - `app/**/page.jsx`, `app/**/layout.jsx`
|
|
|
- - React components in `components/**`
|
|
|
-
|
|
|
-- Use **`.js`** for non-JSX files:
|
|
|
- - `lib/**` utilities and helpers
|
|
|
- - `app/api/**/route.js`
|
|
|
- - `models/**`
|
|
|
- - tests that do not contain JSX
|
|
|
+- Use **`.jsx`** for files that contain JSX.
|
|
|
+- Use **`.js`** for non-JSX files.
|
|
|
|
|
|
---
|
|
|
|
|
|
@@ -727,52 +663,11 @@ To keep the project consistent:
|
|
|
|
|
|
### 14.1 Unit tests
|
|
|
|
|
|
-Core tests:
|
|
|
-
|
|
|
-- `lib/frontend/routes.test.js`
|
|
|
-- `lib/frontend/apiClient.test.js`
|
|
|
-- `lib/frontend/authRedirect.test.js`
|
|
|
-- `lib/frontend/authMessages.test.js`
|
|
|
-
|
|
|
-RBAC tests:
|
|
|
-
|
|
|
-- `lib/frontend/rbac/branchAccess.test.js`
|
|
|
-- `lib/frontend/rbac/branchUiDecision.test.js`
|
|
|
-
|
|
|
-Explorer helper tests:
|
|
|
-
|
|
|
-- `lib/frontend/explorer/breadcrumbDropdowns.test.js`
|
|
|
-- `lib/frontend/explorer/errorMapping.test.js`
|
|
|
-- `lib/frontend/explorer/formatters.test.js`
|
|
|
-- `lib/frontend/explorer/sorters.test.js`
|
|
|
-- `lib/frontend/explorer/pdfUrl.test.js` (RHL-023)
|
|
|
-
|
|
|
-Search helper tests:
|
|
|
-
|
|
|
-- `lib/frontend/search/urlState.test.js`
|
|
|
-- `lib/frontend/search/errorMapping.test.js`
|
|
|
-- `lib/frontend/search/normalizeState.test.js`
|
|
|
-- `lib/frontend/search/searchApiInput.test.js`
|
|
|
-- `lib/frontend/search/resultsSorting.test.js`
|
|
|
-- `lib/frontend/search/dateRange.test.js` (RHL-025)
|
|
|
-- `lib/frontend/search/datePresets.test.js` (RHL-025)
|
|
|
-- `lib/frontend/search/dateRangePickerUtils.test.js` (RHL-025)
|
|
|
-- `lib/frontend/search/searchDateValidation.test.js` (RHL-025)
|
|
|
-- `lib/frontend/search/dateFilterValidation.test.js` (RHL-025)
|
|
|
-
|
|
|
-QuickNav helper tests:
|
|
|
-
|
|
|
-- `lib/frontend/quickNav/branchSwitch.test.js`
|
|
|
+Role helper tests (RHL-041):
|
|
|
|
|
|
-Component SSR smoke test:
|
|
|
+- `lib/frontend/auth/roles.test.js`
|
|
|
|
|
|
-- `components/app-shell/AppShell.test.js`
|
|
|
-
|
|
|
-Password change / toast helpers:
|
|
|
-
|
|
|
-- `lib/auth/passwordPolicy.test.js`
|
|
|
-- `lib/frontend/profile/passwordPolicyUi.test.js`
|
|
|
-- `lib/frontend/ui/toast.test.js`
|
|
|
+Existing tests remain as documented in the project.
|
|
|
|
|
|
### 14.2 Running tests
|
|
|
|
|
|
@@ -794,93 +689,23 @@ npm run build
|
|
|
|
|
|
### 15.1 Local (Docker)
|
|
|
|
|
|
-Start:
|
|
|
-
|
|
|
-```bash
|
|
|
-docker compose -f docker-compose.yml -f docker-compose.local.yml up -d --build
|
|
|
-```
|
|
|
-
|
|
|
-Verify flows in the browser:
|
|
|
-
|
|
|
-- Open a protected route while logged out (e.g. `/NL01/2025/12`)
|
|
|
- - Expect redirect to `/login?reason=expired&next=/NL01/2025/12`
|
|
|
-
|
|
|
-- Valid login
|
|
|
- - Expect redirect into the protected route
|
|
|
-
|
|
|
-- Logout
|
|
|
- - Expect redirect to `/login?reason=logged-out`
|
|
|
-
|
|
|
-Profile checks (RHL-009):
|
|
|
-
|
|
|
-- Open `/profile`
|
|
|
- - Confirm account info is visible (including read-only email)
|
|
|
-
|
|
|
-- Change password:
|
|
|
- - wrong current password → inline error + toast
|
|
|
- - weak new password → inline hints + toast
|
|
|
- - valid change → success toast, form clears
|
|
|
-
|
|
|
-Navigation/TopNav checks (RHL-032):
|
|
|
-
|
|
|
-- Tooltips show consistently (no double native tooltips).
|
|
|
-- Theme toggle switches theme.
|
|
|
-- Branch switching updates the URL and keeps context (Explorer/Search).
|
|
|
-- Invalid branch route (`/NL200`) shows warning + recovery item.
|
|
|
-
|
|
|
-Explorer checks:
|
|
|
-
|
|
|
-- `/:branch` shows years
|
|
|
-- `/:branch/:year` shows months
|
|
|
-- `/:branch/:year/:month` shows days
|
|
|
-- `/:branch/:year/:month/:day` shows files
|
|
|
-
|
|
|
-Search checks:
|
|
|
-
|
|
|
-- `/NL01/search`
|
|
|
- - empty state
|
|
|
- - submit triggers URL update and first-page fetch
|
|
|
-
|
|
|
-- admin/dev:
|
|
|
- - scope switching (single/multi/all)
|
|
|
- - multi selection via checkbox grid + “Alle abwählen”
|
|
|
- - limit switching (50/100/200)
|
|
|
- - date range filter updates `from/to` in the URL
|
|
|
-
|
|
|
-Debounced loading UI (RHL-032):
|
|
|
-
|
|
|
-- With fast connections: skeleton flashes are minimized.
|
|
|
-- With throttling: skeletons appear after the delay and remain stable.
|
|
|
+- Login and verify TopNav role label per account.
|
|
|
+- Branch switching for admin-like users.
|
|
|
+- Explorer drill-down.
|
|
|
+- Search scopes (admin-like) + Search restrictions (branch).
|
|
|
+- Open PDFs.
|
|
|
|
|
|
### 15.2 Server
|
|
|
|
|
|
-Deploy and verify on the server URL.
|
|
|
-
|
|
|
-Verify:
|
|
|
-
|
|
|
-- Explorer navigation and PDF open
|
|
|
-
|
|
|
-- Search UI:
|
|
|
- - scopes
|
|
|
- - limit selection
|
|
|
- - date range filter + URL sync
|
|
|
- - open PDF / jump to day
|
|
|
- - TopNav branch switching keeps deep links
|
|
|
-
|
|
|
-- Profile / password change:
|
|
|
- - success and negative flows (wrong current password / weak password)
|
|
|
+- Repeat the local checks on the real server.
|
|
|
+- Validate RBAC behavior:
|
|
|
+ - branch user → forbidden on foreign branches
|
|
|
+ - admin-like → notfound on non-existent branches
|
|
|
|
|
|
---
|
|
|
|
|
|
## 16. Planned follow-ups
|
|
|
|
|
|
-- Optional Search UX improvements:
|
|
|
- - grouping results by date / branch
|
|
|
- - optional date-only search mode (if desired)
|
|
|
-
|
|
|
-- Optional Explorer improvements:
|
|
|
- - add “Herunterladen” action
|
|
|
- - optional in-app PDF viewer
|
|
|
-
|
|
|
-- Password reset / recovery:
|
|
|
- - separate follow-up ticket/phase (not part of RHL-009).
|
|
|
+- User management UI + APIs (RHL-012):
|
|
|
+ - Guard endpoints using `requireUserManagement(session)` (backend).
|
|
|
+ - Gate UI screens using `canManageUsers(role)` (frontend).
|