chore(ui): a11y touch-targets sweep + useUserDisplay JSDoc refresh

This commit is contained in:
Александр Зимин
2026-05-27 15:49:17 +00:00
parent 2868e8635a
commit c1a006765f
3 changed files with 26 additions and 12 deletions
+17 -10
View File
@@ -3,15 +3,20 @@ import { useAuth } from '@/auth/useAuth'
import { apiClient } from '@/api/client'
/**
* Lookup user display info по UUID (JWT sub). Backed by backend in-memory
* cache (заполняется на каждом authenticated request через
* JwtUserCaptureFilter). Returns null если sub не в кэше — frontend
* fallback'нёт на short UUID.
* Lookup user display info по UUID (JWT sub). Backed by backend trio:
* hot ConcurrentHashMap → Postgres user_display_cache → Keycloak Admin
* REST (Tier 3 on-demand). См. UserDisplayService.find в backend.
*
* <p>Stale-while-revalidate: TanStack Query кэширует 5 минут, refetch
* on focus. Cheap — endpoint = O(1) hash lookup, no DB hit.
* on focus. Cheap — hot cache hit = O(1), даже tier 3 KC lookup
* ~10-50ms на cold sub.
*
* <p>404 → данных нет; не считаем error (через retry: false + handle null).
* <p>404 → данных нет (sub неизвестен realm'у); не считаем error
* (через retry: false + handle null). Frontend fallback'нёт на em-dash
* placeholder (см. useUserDisplay).
*
* <p>Note: JwtUserCaptureFilter был удалён в Phase 2 — cache теперь
* lazy-populated через первое чтение на cache miss (tier 3).
*/
type UserDisplayInfo = {
sub: string
@@ -67,10 +72,12 @@ const useResolveUserDisplay = (uuid: string | null | undefined) =>
* <li><b>null/undefined uuid</b> → {@code "anonymous"}.</li>
* </ul>
*
* <p>Backend endpoint: {@code GET /api/v1/admin/users/{sub}/display} — backed
* by in-memory cache (заполняется JwtUserCaptureFilter на каждом authenticated
* request). Если backend pod restart'нулся, кэш пуст — postepenно заполняется
* обратно. Frontend gracefully fallback'ит на short UUID.
* <p>Backend endpoint: {@code GET /api/v1/admin/users/{sub}/display} —
* backed by three-tier cache (hot ConcurrentHashMap → Postgres
* user_display_cache → Keycloak Admin REST on-demand). Cold pod
* стартует с пустого hot cache, но DB persists — sub'ы будут резолвиться
* сразу. Новые юзеры (никогда не появлялись в audit'е) — резолв через
* tier 3 KC Admin lookup на первый запрос.
*
* <p>Используется везде где UI показывает actor: AUTHOR в таблицах
* /reviews (record + schema), USER в /audit log, AUTHOR в schema draft