happa is the Giant Swarm web UI: a React 18 SPA (TypeScript, Redux + redux-thunk,
styled-components, OIDC via oidc-client-ts, Sentry for error reporting). The
notes below are non-obvious things that are easy to get wrong — read them before
adding code or tests.
- Package manager is yarn 1 (classic) (
yarn.lock). Don't use npm. package.jsonpinsengines.node: "20". On any other local Node version,yarn add/yarn installfail the engine check — add--ignore-engines(local only; don't change the pin).- Dependencies are pinned exact (no
^), e.g."react": "18.3.1". Install new deps withyarn add --exact <pkg>@<version>.
- Absolute imports resolve from both
src/andsrc/components/(tsconfigpaths: "*": ["src/components/*", "src/*"], plus jestmoduleDirectories). Somodel/...,utils/...aresrc-rooted, whileRoute,UI/...,Auth/...,MAPI/...aresrc/components-rooted. Both forms are correct — match the surrounding file.
- Test files are named after the module under test, inside a
__tests__/dir — e.g.src/utils/errors/__tests__/ErrorReporter.ts, NOTErrorReporter.test.ts. Jest's defaulttestMatchpicks up everything under__tests__/. window.configandwindow.featureFlagsare injected into every test viaglobalsinjest.config.ts, withenvironment: 'development'. Code gated on the environment therefore runs in dev mode by default in tests; overridewindow.config.environmentper-test to exercise other branches.- Useful scripts:
yarn test,yarn typecheck(tsc),yarn lint(eslint --ext .js,.ts,.tsx ./src/),yarn lint:fix.
GlobalEnvironment(src/@types/global.d.ts) is'development' | 'kubernetes' | 'docker-container'— there is no'production'/'staging'. Runtime config (apiEndpoint,environment, installation info, feature flags, Sentry DSN, …) is injected intowindow.config/window.featureFlagsby the EJS template at serve time.
- React Router v5 (not v6), integrated with
redux-first-history. Current location is in Redux atstate.router.location; routing hooks/matchPathcome fromreact-router. - Auth lives in Redux at
state.main.loggedInUser(selectorgetLoggedInUser).components/Layout.tsxis the authenticated root (redirects to/loginwhen there's no user);/login,/admin-login,/logoutrender outside it.
- The app shell is
src/index.ejs, rendered by webpack'sHtmlWebpackPlugin.dist/is a gitignored build artifact — never edit files indist/(e.g. a staledist/index.ejs); only changesrc/index.ejs.