Skip to main content

Frontend Developer Quickstart

Canonical onboarding guide for frontend contributors.

Use this document as the single starting point, then follow linked source docs for detail.


Legacy Archive Note​

Historical frontend implementation has been moved to:

  • frontend/archive/legacy-v1/

Active implementation must use:

  • frontend/src/routes
  • frontend/src/lib/components

Do not implement new features inside archive paths.


0) Preflight Checklist (Required)​

Before running commands:

  1. Clone repo and set root variable:
export REPO_ROOT="$(git rev-parse --show-toplevel)"
  1. Docker Desktop (or Docker Engine) is running.
  2. 1Password CLI is installed and signed in (op whoami succeeds).
  3. env.1password exists at repo root.
  4. Node and npm are aligned with project runtime:
    • Node 20.x (matches frontend/Dockerfile)
    • npm 10.x recommended

Quick check:

node -v
npm -v

reference:

  • docs/platform-config/1password-cli.md

1) What You Are Building​

Evalium frontend is a SvelteKit app over a backend-first execution ledger.

Your job is to build a simple, fast UI that does not break backend truth:

  • backend owns rules, policy, and defensibility semantics
  • frontend renders backend intent consistently
  • no per-page ad-hoc contracts

2) First-Day Read Order (Do Not Skip)​

  1. docs/architecture/FOUNDATION.md
  2. docs/architecture/architecture
  3. docs/product/implementation-status-feature-matrix.md
  4. docs/product/frontend-implementation-status-matrix.md
  5. docs/ux/UX-FRONTEND-CONVENTIONS.md
  6. docs/ux/UX-SHARED-COMPONENTS-CONTRACT.md
  7. docs/ux/COMPONENT-INTERACTION-MAP.md
  8. docs/ux/UX-GLOBAL-NAVIGATION-AND-SCOPE-SWITCHER.md
  9. docs/ux/ux-lessons-learned.md
  10. docs/ux/UX-FRONTEND-READINESS-CHECKLIST.md
  11. docs/ux/UX-ACCESSIBILITY-STANDARDS-AND-GUARDRAILS.md
  12. docs/ux/UX-MOBILE-AND-TASK-TIER-POLICY.md
  13. openapi/dist/openapi.bundle.yaml

3) Local Setup​

3.1 Install frontend dependencies​

cd "$REPO_ROOT/frontend"
npm install

3.2 Choose Runtime Mode (Canonical Default: Stable Full Stack)​

Default for frontend contributors:

  • Stable mode (recommended): containerized built frontend (web:3000) + local HTTPS proxy + Cloudflare tunnel.

Optional:

  • HMR mode: explicit opt-in that swaps web back to Vite/HMR while keeping the same proxy + tunnel entrypoints.

Do not run both modes at once.

3.3 Start the default full stack (non-destructive)​

Start the normal workflow stack (safe startup; does not run db-init):

cd "$REPO_ROOT"
./scripts/op-compose-up.sh

Equivalent direct compose command:

cd "$REPO_ROOT"
op run --env-file env.1password -- \
docker compose -f docker-compose.yml -f docker-compose.local.yml up -d --build \
db minio minio-init api web proxy cloudflared

3.4 Default runtime notes​

  • BACKEND_BASE_URL for the containerized frontend is already set in compose to http://api:8081.
  • Browser API calls stay on the public app origin (/api/...) unless you intentionally point them at another public HTTPS domain such as https://api-dev.evalium.me.
  • Browser defaults must never point at loopback/container-only hosts such as 127.0.0.1, localhost, api, or web.
  • You do not need frontend/.env.local for the default containerized workflow.
  • Default local proxy traffic goes to the built web runtime on web:3000.
  • Default tunnel ingress also goes to the built web runtime on web:3000.

3.5 Open the app​

Primary local entrypoint:

  • https://localhost:8443

Tunnel entrypoint (kept on as part of the normal workflow):

  • https://app-dev.evalium.me

3.6 Authenticate frontend session (required for protected pages)​

Seed baseline dev data in the default tenant/org:

cd "$REPO_ROOT"
op run --env-file env.1password -- \
bash -lc 'backend/tests/seed_dev_data.sh'

Mint a browser session using the owner auth helper + frontend login script:

cd "$REPO_ROOT"
op run --env-file env.1password -- bash -lc '
source backend/tests/auth_login_helper.sh
login_as_owner
ELEVATE_PERMISSIONS=0 USER_ID="$AUTH_USER_ID" scripts/frontend_dev_auth_login.sh
'

Verify session identity:

  • https://localhost:8443/api/v1/auth/me (stable mode)
  • https://app-dev.evalium.me/api/v1/auth/me (tunnel path)

If auth/me is 200 but protected pages return 403 missing permission, run the helper with permission elevation:

cd "$REPO_ROOT"
op run --env-file env.1password -- bash -lc '
source backend/tests/auth_login_helper.sh
login_as_owner
ELEVATE_PERMISSIONS=1 USER_ID="$AUTH_USER_ID" scripts/frontend_dev_auth_login.sh
'

Dev-only quick path:

  • GlobalNav includes a temporary Sign in as Owner (Dev) button in dev/approved hosts.
  • Use only for early development; remove once the real login journey is implemented.

3.7 Optional HMR mode (explicit opt-in)​

cd "$REPO_ROOT"
FRONTEND_MODE=hmr ./scripts/op-compose-up.sh

This keeps the same public entrypoints (https://localhost:8443 and https://app-dev.evalium.me) but swaps the web service to frontend/Dockerfile.dev + Vite on port 5173.

3.8 Destructive reset (opt-in only)​

This drops and rebuilds DB schema; run only when you explicitly need a clean reset:

cd "$REPO_ROOT"
op run --env-file env.1password -- \
docker compose -f docker-compose.yml -f docker-compose.local.yml --profile local run --rm db-init

4) OpenAPI Contract Source and Generation (Required)​

Use OpenAPI as source of truth for request/response shapes.

Source files:

  • Authoritative editable spec: openapi/openapi.yaml
  • Frontend generation input (bundled): openapi/dist/openapi.bundle.yaml

Why this matters:

  • generation and mocks work from one resolved bundle
  • compile-time errors catch contract drift early
  • avoids per-screen fetch-shape drift

Generate frontend client + mocks:

cd "$REPO_ROOT/frontend"
npm run generate

If backend endpoints changed and bundle is stale, refresh bundle first:

cd "$REPO_ROOT/openapi"
npm install
npm run bundle
cd "$REPO_ROOT/frontend"
npm run generate

5) Non-Negotiable Frontend Rules​

  1. No hardcoded user-facing strings in components.
  2. Use Inlang Paraglide-JS message keys/functions for all UI copy.
  3. Translation fallback precedence is org -> tenant -> product.
  4. Centralize status/reason mappings; never map enums ad-hoc per page.
  5. Use shared primitives (EntityLink, drawer contract, table/hub shells, status chips).
  6. For idempotent backend writes, attach and reuse Idempotency-Key correctly.
  7. Never infer permissions in frontend; consume backend capability and response contracts.
  8. Accessibility and mobile/task-tier rules are release gates, not polish.

5.1 Where to Implement and Verify Key Rules​

RuleImplement InVerifyAutomation Status
i18n only (no hardcoded UI text)UI components/routes in frontend/src/routes and frontend/src/lib/components via Paraglide messagescd "$REPO_ROOT/frontend" && npm run lint && npm run testPartial
Translation fallback (org -> tenant -> product)shared i18n resolver in frontend contract layer (single module consumed by pages/drawers/toasts)unit tests in frontend for fallback order; runtime smoke on language switchPlanned
Idempotency key handlingshared write path used by all mutating calls (no per-page ad-hoc logic)request-layer tests for retry/same-key semantics; integration smoke against idempotent endpointsPlanned
Status/reason mapping centralizationone shared status/reason mapper utility for chips, filters, tables, exportssnapshot/unit tests for canonical labels and no raw enum leakagePlanned

Interpretation:

  • Partial/Planned means lint/build/test alone are not full proof yet.
  • Treat these rows as implementation requirements plus explicit test backlog until coverage is complete.

reference contracts:

  • docs/ux/UX-FRONTEND-CONVENTIONS.md
  • docs/ux/UX-SHARED-COMPONENTS-CONTRACT.md
  • docs/ux/language-and-tone-guidelines.md

6) Implementation Order​

Use docs/product/frontend-implementation-status-matrix.md as the source of truth.

Beta-required sequence:

  1. Frontend contract layer
  2. Shared app shell/primitives
  3. authoring baseline (Questions + Evaluations publish slice)
  4. Identity targeting baseline
  5. Assignments baseline
  6. Candidate delivery baseline (resilience included)
  7. Review workspace baseline
  8. Insights readiness/exceptions baseline

Deferred to post-beta:

  • Glass Box full rollout
  • Content Packs full rollout
  • Claims/Disputes full rollout
  • Compliance case orchestration UI
  • Audit explorer advanced views
  • Advanced taxonomy/skills-adjacent UX

7) Validation Commands​

Frontend checks:

cd "$REPO_ROOT/frontend"
npm run lint
npm run check
npm run test
npm run build

Accessibility/component gate (required before release):

cd "$REPO_ROOT/frontend"
npx playwright install
npm run test:component

Backend/full-stack safety run:

cd "$REPO_ROOT"
op run --env-file env.1password -- \
bash -lc 'make ci'

8) Definition of Done (Frontend Surface)​

A surface is done only when all are true:

  1. Contract-safe against OpenAPI models.
  2. Uses shared primitives and canonical status/label mappings.
  3. No hardcoded strings; Paraglide wired.
  4. Accessibility gates pass (automated + critical-path manual smoke).
  5. Mobile/task-tier behavior is explicit (including desktop handoff for complex tasks).
  6. Error/warning states are deterministic and non-ambiguous.
  7. Added/updated in frontend matrix status tracking.

9) Where to Ask "Is This Ready?"​

Use these three docs together:

  • readiness gate checklist: docs/ux/UX-FRONTEND-READINESS-CHECKLIST.md
  • surface status matrix: docs/product/frontend-implementation-status-matrix.md
  • backend capability truth: docs/product/implementation-status-feature-matrix.md

If they disagree, backend capability matrix + architecture docs win.