Portal

Markdown Portal

This file provides guidance for the housing cooperative portal ("Portalen").

Commands

yarn start                # Dev server on port 3000 (Vite)
yarn build                # Production build
yarn test                 # Run Jest tests (watch mode, 50% workers)
yarn test:ci              # Run Jest tests (CI mode, no watch)
yarn test -- --testPathPattern="path/to/test"  # Run a single test file
yarn test:pwui            # Playwright E2E tests with UI
yarn test:pwci            # Playwright E2E tests (CI mode)
yarn lint                 # ESLint

Architecture

React 19 + TypeScript SPA for a housing cooperative portal ("Portalen"). Built with Vite, served at base path /portal/.

Key layers

  • State management: Redux Toolkit + Redux Saga for side effects. RTK Query for API data fetching.
  • Styling: Tailwind CSS (using @bbl-digital/snorre-v2 preset) + Emotion CSS-in-JS.
  • UI components: @bbl-digital/snorre / snorre-v2 (BBL design system).
  • Auth: OIDC via oidc-client-ts. Token injected by axios interceptors in src/axiosConfig.ts.
  • Routing: React Router v5 with a custom history object (src/browserHistory.ts).
  • API: Axios with interceptors adding bearer token, APIM subscription key, and BBLCode header. window.config provides runtime URLs.

Forms: Formik + Yup for form handling and validation.

Source layout (src/)

Directory Purpose
App/ Root component, routing (Routes.tsx), layouts
Auth/ OIDC auth context, login/logout flows
Modules/ Feature modules (Boardwork, Economy, Communication, etc.) — each self-contained with own components, hooks, store slices
Widgets/ Reusable widget components
shared/api/ API service definitions
shared/components/ ~50 reusable UI components
shared/hooks/ Custom React hooks
shared/microServices/ Micro-service integration models
shared/store/ Redux reducers, sagas, selectors, RTK Query services
shared/utils/ Helper functions

Path aliases

Vite and Jest are configured with these import aliases: App, Auth, Modules, shared, Widgets, ErrorBoundary, axiosConfig, browserHistory. Use bare imports (e.g., import Foo from 'shared/components/Foo').

Runtime configuration

The app reads window.config (injected via script tag) for API URLs, subscription keys, and bblCode (organization identifier). Environment-specific configs live in configs/.

Preferences for New Code

  • Design system: Always use @bbl-digital/snorre-v2, not the legacy snorre package
  • Styling: Use TailwindCSS utility classes, not Emotion CSS-in-JS
  • Data fetching: Use RTK Query, not Redux Saga

Conventions

  • Formatting: Prettier — no semicolons, single quotes, trailing commas (ES5), 2-space indent.
  • TypeScript: Strict mode enabled but strictNullChecks is off. JSX import source is @emotion/react.
  • Testing: Test files in __tests__/ directories or *.test.ts(x). Uses @swc/jest for fast transforms. Test setup in testutils/.
  • Branching: Feature branches: feature/<PBI-number>-<short-description>. PRs target develop. Releases from release/* and hotfix/* branches.
  • CI/CD: Azure DevOps pipeline (infrastructure/azure-pipelines.yml). Deploys to Azure Blob Storage + CDN across test/stage/prod environments.