Julien Gautier 00c7170d86
CI / scan (pull_request) Successful in 2m39s
CI / commits (pull_request) Successful in 3m1s
CI / check (pull_request) Successful in 3m2s
CI / a11y (pull_request) Successful in 2m28s
CI / perf (pull_request) Successful in 5m52s
feat(portal-admin): user directory viewer screen
Final PR of the portal-admin User-list chantier per ADR-0020 §"v1
scope — User list (read-only)". Ships the SPA viewer at /users that
consumes GET /api/admin/users (PR #141) and renders a filter form
+ paginated table mirroring the audit viewer's shape (PR #136).

What lands

- AdminUsersService (apps/portal-admin/src/app/pages/users/
  admin-users.service.ts): thin HttpClient wrapper around
  GET /api/admin/users. Drops empty-string filter values (Nest's
  ValidationPipe rejects ?foo= as ''). providedIn 'root' — the
  users page is the single v1 consumer.

- UsersPage component (apps/portal-admin/src/app/pages/users/
  users.ts): signal-driven page composing:
  - Filter form: username (prefix), displayName (contains),
    audience enum, lastSeenAt range (datetime-local → ISO),
    page-size selector (25 / 50 / 100 / 200 matching BFF MAX_LIMIT).
  - Result table: displayName, username, audience badge, firstSeen,
    lastSeen (locale-formatted), oid (monospaced).
  - Pagination: previous/next disabled at boundaries; offset
    resets to 0 on Apply Filters or Reset.
  - States: loading line, empty state, error with 403 vs 5xx
    differentiation matching the audit viewer's posture.

Route + sidebar

- /users route lazy-loaded in app.routes.ts with the
  route.users.title i18n marker. messages.fr.xlf updated with the
  French translation ('Utilisateurs — Administration APF Portal');
  the prod build's i18nMissingTranslation=error policy fails
  otherwise.
- AdminSidebar 'User list' entry promoted from aria-disabled
  placeholder ('Soon' badge) to a live RouterLink at /users. The
  matching spec is updated.

Tests: +15 specs (AdminUsersService 3 covering URL params + empty
+ undefined; UsersPage 11 covering initial fetch, result range,
empty/error states, filter forwarding, Apply offset reset, Reset,
pagination boundaries, display badges; sidebar 1 for the promoted
link). 45 portal-admin specs total.

Build verified: 14.59 KB raw / 3.76 KB gzip for the lazy users
chunk — well under any per-chunk budget. The /audit chunk
remains 18.16 KB / 4.35 KB; the two viewers ship as separate
lazy bundles since each pulls its own service and components.

Chantier portal-admin User-list closed — 3 PRs total (140 schema
+ write, 141 read endpoint, this PR for the viewer).
2026-05-14 20:11:32 +02:00

Documentation index

This is the entry point to all project documentation. It is maintained automatically: any addition, rename, or removal of a .md file under docs/ must be reflected here in the same change.

Conventions

  • Documentation is written in English.
  • One topic per file. Group related files into a folder when there are three or more.
  • Cross-reference with relative links so they keep working in GitHub, IDEs, and exported sites.
  • For architectural decisions, do not add them here — they belong in decisions/ as MADR 4.0.0 ADRs.

Sections

Daily development

  • development.md — repo layout, prerequisites, initial setup, daily commands, observability dev-loop (Jaeger UI, log ↔ trace correlation), dependency updates (Renovate), conventional commit cycle. Day-to-day reference for working on the project.

Architecture

  • architecture.md — cross-cutting Mermaid diagrams: C4 system context, C4 containers, Nx module boundaries, CI/CD pipeline. Single-decision diagrams (auth sequence, ERD, etc.) live inline in their ADR.

Onboarding & environment

Setup guides for new contributors:

Operations & runbooks

Empty — to be populated when we deploy.

Security, performance, accessibility

Empty — placeholders to be filled with rationale docs alongside their corresponding ADRs.

S
Description
No description provided
Readme 42 MiB
Languages
TypeScript 85.3%
JavaScript 5.4%
SCSS 4.3%
HTML 3.9%
Shell 0.8%
Other 0.3%