feat(portal-admin): skeleton app per ADR-0020 #100
Reference in New Issue
Block a user
Delete Branch "feat/portal-admin/skeleton"
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
First step of the admin track per ADR-0020. Scaffold the second Angular SPA in the workspace alongside
portal-shell, with the architectural decisions from the v1 ADRs already wired so subsequent feature PRs can drop straight into modules.What lands
nx g @nx/angular:application(with the matching e2e project skeleton). Standalone, zoneless-ready, prefixapp, scss component styles, css root stylesheet, no SSR.scope:portal-admin, type:app— module-boundary lint now treatsportal-admindistinctly fromportal-shelland lets it depend only onscope:portal-admin+scope:sharedlibs..postcssrc.json,@import 'tailwindcss', class-based dark variant, and@import '../../../libs/shared/tokens/src/brand-tokens.css'— identical visual baseline to portal-shell.en, targetfr, baseHref/{locale}/per locale,@angular/localize/initpolyfill,localize: ["en", "fr"]on production,i18nMissingTranslation: "error"so CI blocks any PR that adds a marker without translating it. Seedmessages.fr.xlfcarries the four marked strings used today./—<h1>+ intro paragraph + "Skeleton — coming soon" chip in the brand-accent palette. All marked for i18n.serve-statictarget withoutspa: true— locale-prefixed routing in production is handled by the reverse proxy (per ADR-0019), same as portal-shell since PR #92.CLAUDE.md
Picked up the second app in the Naming entry and the Commands snippet (
<app>is now one ofportal-shell,portal-admin,portal-bff).Verification
pnpm exec nx run-many -t lint test build --projects=portal-shell,portal-admin,shared-ui,shared-state,shared-tokens— green.portal-admintest: 1 spec (skip-link + main landmark present).portal-admin: 62 KB gzip initial per locale (vs 500 KB budget — plenty of headroom for the upcoming modules).dist/apps/portal-admin/browser/{en,fr}/emit with the right<html lang>and<base href>. FR bundle contains"Administration"/"Squelette"/"bientôt disponible"— translations applied.Out of scope (each its own follow-up PR)
service.name=portal-adminper ADR-0012).environment.tswiring (per ADR-0018) for admin-specific endpoints.AdminModule+AdminRoleGuard+ smoke/api/admin/me(per ADR-0020 §"Auth").Test plan
pnpm exec nx serve portal-adminboots on:4300, smoke page renders.pnpm exec nx run portal-admin:serve-static→http://localhost:4300/en/and/fr/show the placeholder with the matching language.First step of the admin track. Scaffold the second Angular SPA in the workspace alongside `portal-shell`, with the architectural decisions from the v1 ADRs already wired so subsequent feature PRs can drop straight into modules. What lands: - App generated via `nx g @nx/angular:application` (with the matching e2e project skeleton). Standalone, zoneless-ready, prefix `app`, scss component styles, css root stylesheet, no SSR. - Tags `scope:portal-admin, type:app` so module-boundary lint treats `portal-admin` distinctly from `portal-shell` and only allows it to depend on `scope:portal-admin` + `scope:shared` libs. - Tailwind v4 wired (`.postcssrc.json` + `@import 'tailwindcss'`), class-based dark mode (`@custom-variant dark ...`), brand palette imported from `libs/shared/tokens/src/brand-tokens.css` — identical visual baseline to portal-shell. ADR-0016 a11y baseline applies; ADR-0017 perf budget relaxed to **500 KB gzip initial** per ADR-0020 §"Performance budgets". - i18n configured to mirror portal-shell (per ADR-0019): sourceLocale `en`, target `fr`, baseHref `/{locale}/` per locale, `@angular/localize/init` polyfill, `localize: ["en", "fr"]` on production, `i18nMissingTranslation: "error"` so CI blocks any PR that adds a marker without translating it. Seed `messages.fr.xlf` carries the four marked strings used by the placeholder page + skip-link + route title. - Skeleton home page at `/` with a placeholder `<h1>`, intro paragraph, and a small "Skeleton — coming soon" status chip in the brand-accent palette. Marked for i18n. - Skip-link landmark (WCAG 2.4.1) at the App level, with the same styling as portal-shell (component-scoped scss). - Wildcard catch-all route bounces unknown paths to home, same defensive pattern as PR #96 on portal-shell. - Dev server on port **4300** (vs 4200 for portal-shell) so both can run in parallel during cross-app development. - `serve-static` target without `spa: true` — locale-prefixed routing in production will be handled by the reverse proxy (per ADR-0019), same as portal-shell since PR #92. Production build: 62 KB gzip initial per locale (vs the 500 KB relaxed budget). Both `dist/apps/portal-admin/browser/{en,fr}/` emitted with the right `<html lang>` and `<base href>`. Out of scope (each its own follow-up PR): - Admin app shell (header / sidebar / footer with "Admin" badge). - OpenTelemetry tracing setup (will register as `service.name=portal-admin` per ADR-0012). - `environment.ts` wiring (per ADR-0018) for the admin's own BFF endpoints. - BFF `AdminModule` + `AdminRoleGuard` + first `/api/admin/me` smoke route (per ADR-0020 §"Auth"). - First functional module (CMS / menu / users / audit viewer). CLAUDE.md picks up the second app in its naming + commands sections.