Skip to content

refactor(web): full frontend architecture overhaul#540

Open
eoaksnes wants to merge 9 commits into
mainfrom
stack/03-web
Open

refactor(web): full frontend architecture overhaul#540
eoaksnes wants to merge 9 commits into
mainfrom
stack/03-web

Conversation

@eoaksnes
Copy link
Copy Markdown
Collaborator

@eoaksnes eoaksnes commented May 9, 2026

Stack 3/4 — base: `stack/02-api` (#539)

Complete frontend rewrite: tooling, generated SDK, shared platform foundation, and TanStack Router app shell + Todos cutover.

Stack

  1. chore(infra): IaC, compose, redis, oauth2-proxy baseline #538 stack/01-infra
  2. feat(api): add monitoring feature with track_events use case #539 stack/02-api
  3. stack/03-web ← you are here
  4. stack/04-docs (base: stack/03-web)

This pull request introduces significant improvements to the web application's frontend development workflow, focusing on code quality, maintainability, and modern tooling. The changes include the integration of TanStack Query and Router, enhanced linting with ESLint for TanStack Query best practices, improved handling of generated files, and updates to dependencies and configuration for a more robust developer experience.

Linting and Code Quality Enhancements

  • Added a dedicated ESLint flat config (eslint.config.mts) to enforce TanStack Query usage rules and project-specific import boundaries, supplementing Biome for comprehensive linting.
  • Updated linting scripts and configuration (package.json, .mise/tasks/lint.toml) to include a new lint:query command and ensure TanStack Query rules are checked during lint runs. [1] [2]

Generated Files and Tooling

  • Marked OpenAPI and TanStack Router generated files as linguist-generated and excluded them from linting and language statistics, and updated Biome config to ignore these files. [1] [2]
  • Updated the OpenAPI generator config to output to src/api-generated and include plugins for TanStack Query and Zod, enabling type-safe API hooks and schema validation.
  • Added the auto-generated TanStack Query hooks file (src/api-generated/@tanstack/react-query.gen.ts) for type-safe API queries and mutations.

Dependency and Configuration Updates

  • Upgraded and added key dependencies: TanStack Query, TanStack Router, TailwindCSS, Application Insights, and supporting libraries for modern frontend development.
  • Added Yarn SDKs for TypeScript and ESLint, and updated Yarn and Biome configurations for improved editor and linting support. [1] [2] [3] [4] [5]

Developer Experience Improvements

  • Added a color scheme script to index.html to prevent flashes of incorrect theme before React mounts, improving perceived performance.
  • Updated Docker and environment variable handling for Vite, ensuring proper authentication and telemetry configuration in development.

Cleanup and Refactoring

  • Removed legacy authentication and router code from App.tsx and deleted the outdated App.test.tsx, preparing the codebase for the new TanStack Router and Query integration. [1] [2]

These changes collectively modernize the frontend stack, enforce best practices, and streamline the development workflow for future features and maintenance.

@eoaksnes eoaksnes requested a review from a team as a code owner May 9, 2026 11:44
@eoaksnes eoaksnes marked this pull request as draft May 9, 2026 13:39
@eoaksnes eoaksnes marked this pull request as ready for review May 11, 2026 06:54
@eoaksnes eoaksnes force-pushed the stack/02-api branch 3 times, most recently from 519be8c to ac3beba Compare May 13, 2026 19:34
Comment thread web/eslint.config.mts
// through its public barrel (`@/features/<name>`), never deep paths
// like `@/features/<name>/api/...`. Inside-feature code uses
// relative paths and is exempted by the override below.
'no-restricted-imports': [
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understand the use of eslint for the tanstack plugin (we should definitely pay attention to wether Biome adds support for the plugin at some point), but I don't understand adding more rules for eslint to handle. We should decide on biome, eslint or oxlint

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

@sutne sutne May 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i am understanding this correctly, biome also supports defining noRestrictedImports in biome.json, so the relvant parts from eslint could be moved there.

https://biomejs.dev/linter/rules/no-restricted-imports/

Screenshot 2026-05-26 at 08 47 43

@eoaksnes eoaksnes force-pushed the stack/02-api branch 4 times, most recently from 1f00490 to 4330b61 Compare May 19, 2026 19:16
Base automatically changed from stack/02-api to main May 19, 2026 19:26
Comment thread web/src/app/error-pages/components/StatusPanel/StatusPanel.tsx Fixed
Comment thread web/src/app/error-pages/components/StatusPanel/StatusPanel.tsx Fixed
eoaksnes and others added 8 commits May 20, 2026 09:39
Infra & deployment topology:
- IaC: app-registration + resources deploy scripts, bicep updates
- docker-compose: align dev/override, wire oauth2-proxy service
- radixconfig: updated config
- redis: standalone Dockerfile + entrypoint
- secrets: README and .gitignore
- root: env template, gitattributes, release-please, mise lint task,
  dependabot, pre-commit hooks

OAuth2 proxy & nginx:
- web/oauth2: dedicated Dockerfile, entrypoint, oauth2-proxy config
- web/nginx: oauth2 auth_request/redirect snippets, security headers,
  default.conf updates
- web/Dockerfile: align with oauth2 split

# Conflicts:
#	.env-template
#	.github/dependabot.yml
#	.pre-commit-config.yaml
#	IaC/app-registration.bicep
#	README.md
#	docker-compose.override.yml
#	docker-compose.yml
#	radixconfig.yaml
#	redis/.dockerignore
#	redis/Dockerfile
#	secrets/README.md
#	web/Dockerfile
#	web/nginx/rootfs/etc/nginx/conf.d/default.conf
#	web/oauth2/.dockerignore
#	web/oauth2/Dockerfile
#	web/oauth2/entrypoint.sh
#	web/oauth2/oauth2-proxy.toml
- features/monitoring: new feature module + track_events endpoint
- app.py / authentication / config: wire up monitoring + tweaks
- features/todo/use_cases: minor adjustments
- Dockerfile + install-equinor-certificates.sh: build infra
- openapi.json + uv.lock + pyproject: dependency updates

� Conflicts:
�	api/src/app/app.py
�	api/src/app/config.py
�	api/src/app/features/monitoring/use_cases/track_events/__init__.py
�	api/uv.lock
Tooling:
- eslint flat config + biome update
- yarn .yarnrc + sdks for editor support
- package.json + yarn.lock dependency bumps
- tsconfig, vite, vitest, openapi-ts config refresh
- mise: add lint:web:query task (TanStack Query lint)
- .gitattributes: mark routeTree.gen.ts and api-generated/ as linguist-generated
- docker-compose.override: pass VITE_AUTH + VITE_TELEMETRY into dev SPA

Generated SDK:
- Move api/generated -> api-generated
- Add @tanstack/react-query.gen.ts (query/mutation hooks)
- Add zod.gen.ts (runtime schema validation)

Shared platform foundation:
- shared/platform/api: configureApiClient, query client factory, ApiError
- shared/platform/auth: current/anonymous user, reauth flow, session watcher
- shared/platform/telemetry: AppInsights/console/noop backends + error boundary
- shared/platform/{theme,toast,feature-flags,access-control}
- shared/components: EmptyState, ErrorPanel, IconButton, LoadingState, PageHeader, Popover
- config/: env, accessControl, featureFlags
- mocks/: MSW server + handlers
- setupTests.ts updated

App shell + Todos cutover:
- app/bootstrap: Providers, ApplicationError, createQueryClient
- app/error-pages: Forbidden/NotFound/StatusPage/RouteErrorBoundary/UnexpectedError
- app/layout: RootLayout, Header, VersionText
- app/routes + routeTree.gen.ts (TanStack Router)
- app/styles, app/auth/SessionExpiredDialog
- features/todos: api (queries/mutations/keys/invalidations/schema), pages/TodosPage with NewTodoForm, TodoItem, TodoList, TodosFilter
- index.tsx + index.html: new bootstrap
- Removed legacy: App.tsx, router.tsx, auth.ts, common/components/*, contexts/TodoContext, hooks/useTodoAPI, pages/TodoListPage, features/todos/todo-list/*
The `npx -y only-allow yarn` preinstall script breaks `yarn install`
under Yarn PnP. PnP intercepts Node's module resolution, so when the
hook spawns `npx` (or `yarn dlx`, which goes via corepack), those
binaries try to require their own internals (`@npmcli/config`,
`corepack`) which are not part of the PnP dependency graph, and the
install fails before linking can complete.

The hook only existed to guard against accidental `npm install`; it is
incompatible with the PnP linker configured in `.yarnrc.yml` and is
safe to drop.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants