Thank you for contributing to the SaaS Business App frontend. This guide describes how to set up the project locally and what is expected of a pull request before it is merged.
- Node.js >= 22.18.0 (Angular 22 requires Node 22+; CI and Docker use Node 24)
- npm >= 11 (the repo pins
packageManager: npm@11.16.0inpackage.json) - Angular CLI is optional;
npx ngworks against the local@angular/clidevDependency
git clone <repo-url> angular-codebase
cd angular-codebase
npm ci # strict, reproducible install from package-lock.json
npm start # ng serve -> http://localhost:4200npm start runs the dev-server configuration (optimization: false, source maps on).
On startup, src/main.ts starts the MSW mock worker (src/mocks/worker.ts), so the app
serves mock API responses out of the box; no backend is required for development.
Useful scripts (from package.json):
| Command | Description |
|---|---|
npm start |
Dev server with HMR |
npm run build |
Production build to dist/saas-business-app/browser/ |
npm run watch |
Build in watch mode (development configuration) |
npm test |
Unit tests (Vitest) |
npm run lint |
ESLint over the workspace |
npm run format |
Prettier --write |
npm run format:check |
Prettier --check (used in CI) |
-
Branch from
main(the CI workflow triggers onmain). Use descriptive branch names prefixed by type, e.g.feat/users-bulk-delete,fix/auth-refresh-loop. -
Commits must follow Conventional Commits. The
commit-msgHusky hook runs commitlint and will reject non-conforming messages.feat(users): add bulk delete action fix(auth): prevent refresh loop on expired refresh token docs(architecture): document API layer refactor(core): simplify error interceptorAllowed types:
feat,fix,docs,style,refactor,perf,test,build,ci,chore,revert(seecommitlint.config.js).
Husky (installed via npm run prepare / postinstall) wires two hooks:
| Hook | Runs | Effect |
|---|---|---|
pre-commit |
lint-staged |
Prettier --write + eslint --fix on staged files only (see lint-staged in package.json) |
commit-msg |
commitlint --edit |
Validates the commit message against Conventional Commits |
Hooks are mandatory; a failing hook blocks the commit. Fix the reported issues rather than bypassing the hooks.
All of the following must pass locally:
npm run lint
npm test -- --no-watch
npm run buildThese mirror the three CI jobs in .github/workflows/ci.yml (lint, test, build).
CI runs on Ubuntu with Node 24; if your local Node differs, prefer Node 22+ and verify
npm run build succeeds.
- Conventional commit messages; branch is up to date with
main. -
npm run lint,npm test -- --no-watch, andnpm run buildall pass. - No
anyin new or changed code (@typescript-eslint/no-explicit-anyiserror). Useunknownand narrow. - New components are standalone, OnPush, and use signal inputs
(
input()/model()); templates use@if/@for(not*ngIf/*ngFor). - New HTTP calls go through
ApiService(returningResult<T>) and a repository interface + implementation + mapper; no directHttpClientuse in features. - New feature state is a
signalStorewithrxMethodfor async work;withMethodsblocks are split when methods call other store methods. - Styling uses design tokens (
var(--color-*),var(--spacing-*), ...); no hardcoded colors/sizes/radii. - Accessibility: semantic HTML, ARIA where needed, visible focus, keyboard operability (WCAG AA).
- Tests added for new stores, interceptors, services, and mappers (unit) and for critical user flows (E2E).
- User-facing strings: the codebase does not yet implement i18n. Strings are currently hardcoded in templates; keep them consistent and note any i18n impact.
- Docs updated if you change architecture, routing, interceptors, or
conventions (update
ARCHITECTURE.md/CODING_STANDARDS.md/FOLDER_STRUCTURE.mdand add an ADR underdocs/adr/for significant decisions).
| Test type | Scope | Tooling |
|---|---|---|
| Unit | Stores (*.store.ts), interceptors, *ApiService, mappers, pure domain logic |
Vitest (*.spec.ts), tsconfig.spec.json |
| Component | UI atoms/molecules/organisms and pages with their store | Vitest + @angular/build:unit-test |
| E2E | Critical flows: login, refresh-on-401, navigation, CRUD | Playwright (planned) |
Conventions:
- Colocate specs with source (
*.spec.ts);tsconfig.spec.jsonincludessrc/**/*.spec.tsand setstypes: ["vitest/globals"]. - Mock
ApiService/ repository implementations rather than hitting network; use theResult<T>helpers (success(...),failure(new Error(...))) frominfrastructure/http/result.ts. - For interceptors, use
HttpClientTestingModulestyle request mocking and assert header cloning and refresh-replay behavior. - Spec files may relax
no-non-null-assertionandno-unsafe-assignment(seeeslint.config.jsoverrides) but must still avoidany.
When filing an issue, include: Angular/Node versions, reproduction steps, expected vs
actual behavior, and relevant logs from the LOGGER output. For security-sensitive
matters, do not open a public issue; contact the maintainers directly.