PH0.5 — Web skeleton: Angular workspace, PKCE login, shell, complete routes and nav, Transloco #5
Labels
No labels
in-progress
in-review
ready-for-agent
seam-request
No milestone
No project
No assignees
2 participants
Notifications
Total time spent: 19 minutes 27 seconds
Due date
patrick
19 minutes 27 seconds
No due date set.
Blocks
Reference
patrick/Polaris#5
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Parent
Row PH0.5 in
docs/12-implementation-plan.md(branch, owned paths and doc section are defined there).What to build
A user opens the web app, logs in through Keycloak PKCE, sees a shell whose "hello" page shows the roles from their token, can switch the UI between
nlanden, and can navigate to every feature listed in docs/06-ux.md — each rendering a "not built yet" placeholder. All frontend dependencies are declared, the OpenAPI client is generated into a git-ignored folder, and a lint rule rejects user-facing string literals.Acceptance criteria
en) and every shell string has bothnlandenkeys; the key-parity script passesapp.routes.tsandcore/nav.tslist every feature from docs/06-ux.md as a lazy route to a placeholdernpm run api:genproduces the client frombackend/openapi.jsoninto a git-ignored folderBlocked by
🚧 Started — session working this on branch
feature/web-skeleton(owns: frontend/**), in an isolated worktree offmain. Will tick acceptance criteria live as they are met and open a PR (Closes #5) when done.PR #50 opened: feature/web-skeleton -> main.
Notes for reviewers / things the ticket didn't foresee:
openapi-typescriptpeer conflict: it still declarestypescript@^5.xwhile Angular 22 needstypescript@~6.0.2, so a plainnpm cifails without help. Addedfrontend/.npmrcwithlegacy-peer-deps=true(comment in the file explains why) rather than pin an older TypeScript. Worth revisiting once openapi-typescript widens its peer range./apiupstream: the self-containeddocker/nginx.confresolves theapiupstream lazily (Docker embedded DNS +resolver) instead of at config-load time, so thewebcontainer doesn't crash-loop ifapiisn't up yet or if this image is run standalone.feedbackandadmin-crudare reachable from within other pages there, not top-nav items). Since the row says routes+nav must cover every feature,core/nav.tsincludes all 13 with a comment explaining the discrepancy.docker build/docker runlocally to confirm the Dockerfile actually serves the SPA and rendersconfig.jsfromPOLARIS_*env vars correctly (not just that it builds).Live login now verified, per request. Brought up the real Keycloak/LDAP/compose stack from PR #49 (
feature/infra-compose-base) in a scratch clone (not merged into this PR/branch —infra/**stays #3's, this PR touches only files already listed above), spun it up withdocker compose -f infra/compose/docker-compose.yml up, torn down afterwards. Drove PH0.5's actual frontend (ng serve) through a headless-browser PKCE login (Playwright/Chromium) for all five LDAP users.Two real bugs found and fixed (neither
ng build, eslint, nor vitest caught either — only an actual browser hitting a real Keycloak did):provideAppInitializer(bootstrapApp())calledbootstrapApp()immediately at module-eval time (before Angular's injector exists), instead of passing the function reference for Angular to call inside its own injection context —inject(AuthService)threwNG0203on every load, so login never started.ScopedTranslocoLoaderassumed Transloco'sgetTranslation(lang, data)first argument was a bare language code; for a scoped load it's actually"<scope>/<lang>"(confirmed against the library source). Every scoped fetch 404'd (core/i18n/shell/en.jsoninstead ofcore/i18n/en.json), so the shell rendered with empty text.Also fixed
environment.development.ts's Keycloak URL — guessed atlocalhost:8081before infra's compose file existed; the real one exposes Keycloak on8080(8081is the unrelated nginx gateway).Results (scripted PKCE token check + real-browser login):
Nav counts match the permission matrix exactly (docs/02-roles-and-glossary.md): admin sees everything except
today(technician-only) = 12; planner sees dashboard/plan/jobs/vehicles/sites/crews/feedback/audit = 8; technician sees onlytoday= 1; viewer sees dashboard/plan = 2; ingest (a machine/service role with no UI pages) sees 0.Pushed as a follow-up commit on
feature/web-skeleton(PR #50):fix(web): fix PKCE bootstrap and scoped i18n loader.npm run build/lint/testall still green after the fixes. Ticked off the first acceptance criterion above.