feat(portal-admin): profile page on /profile guarded by authGuard #150
Reference in New Issue
Block a user
Delete Branch "feat/portal-admin-profile-page"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
PR 2 of 3 from the user-menu / profile / cross-app-link chantier. Lands a
/profilepage onportal-adminso the Profile entry the user menu wired in PR 1 stops 404-ing. Portal-shell already had a demo/profileroute that fits this slot — left as-is rather than churned.UserMenudropdown + integration./profilepage onportal-admin;CurrentUser.rolestyped (the BFF already returns it)./api/me/capabilities+ sidebar role widget + cross-app links.What lands
New page —
apps/portal-admin/src/app/pages/profile/Lazy-loaded at
/profile, guarded byauthGuard(fromfeature-auth). Two cards:oid, tenanttid. The two ids are monospaced + break-anywhere so they don't push the layout on narrow viewports.Portal.Adminfor v1, future business roles once ADR-0011 step-up lands its real consumers). Hidden entirely when therolesarray is empty so anonymous-then-promoted accounts don't see a "no roles" affordance that doesn't help anyone.The
@if (user())template guard narrows the type so the page is single-branch —authGuardalready blocked anonymous traffic upstream.Lazy chunk lands at 5.37 KB raw / 1.57 KB gzip — comfortably under the per-chunk lazy budget.
Route —
apps/portal-admin/src/app/app.routes.tsroute.profile.titleadded tomessages.fr.xlf(FR target retained for parity with the other route titles, even though portal-admin doesn't expose a locale switcher in v1 per ADR-0020).Type —
libs/feature/auth/src/lib/auth.types.ts/api/admin/auth/mealready returnsroles(PR #129), butCurrentUserwas discarding it through the typed deserialization. Marking the field optional captures the existing BFF response without surfacing the claim on the user portal — ADR-0009's "curated public view" stays intact on/api/auth/me, which simply doesn't populate it.Notes for the reviewer
portal-shell's/profiletoo? The existing demo page already has the same shape (displayName, username, oid, tid) and is functionally fine. Refreshing for parity would be incidental scope creep against PR 2's goal (unblock the Profile menu entry on the admin surface). PR 3 may revisit when it adds the role display widget.User profileentry in the admin sidebar? The user menu already exposes Profile and ADR-0020's v1 sidebar catalogue is "modules", not "self-service shortcuts". Adding a sidebar entry would duplicate the user-menu access path and break the rule that the sidebar maps to admin business modules.i18nMissingTranslation=errorpolicy would fail otherwise — the page body text doesn't need to be./api/me/capabilitiesdesign (the user picked the dedicated capabilities endpoint overroles-on-user-/me). Adding any role-related rendering here would pre-empt that choice.Test plan
pnpm nx test portal-admin— 50 specs pass (was 46, +4 for the newProfilePagespec).pnpm nx run-many -t lint test build --projects=portal-shell,portal-admin,shared-ui,shared-state,feature-auth— 15/15 tasks green, including the i18n-strictportal-shell:build:production.Portal.Admin(if you have the role assigned), Settings entry of the user menu still greyed with the Soon badge.What's next
PR 3 lands the cross-app machinery —
GET /api/me/capabilitiesendpoint, real role surfacing on the user-portal sidebar widget (Anonymous→Authenticated/ role label, no more hardcode), and the symmetric "Open Portal Admin" / "Open Portal Shell" entries in each app's user menu, gated on the capabilities response.