Files
tilbudgivern/codemaps/frontend.md
T
f37adae2cb
CI - Test & Build / Lint & Type Check (push) Waiting to run
CI - Test & Build / Backend Unit Tests (push) Waiting to run
CI - Test & Build / Frontend Build (push) Waiting to run
CI - Test & Build / E2E Tests (Playwright) (push) Blocked by required conditions
CI - Test & Build / Security Scan (push) Waiting to run
CI - Test & Build / CI Summary (push) Blocked by required conditions
feat: deliver auditable Smart Pakke quote flow and free site geometry (#31)
* feat: move login credentials to a DB-backed users table with an admin management page

Replaces the hardcoded AUTH_USERNAME/AUTH_PASSWORD login check with a new
auth_accounts table (bcrypt-hashed passwords, admin/user roles). Adds
admin-only /api/users CRUD routes and a "Brugere" admin page in the
frontend for managing logins without redeploying. Removes the unused,
unmounted duplicate login route in src/routes/auth.js.

* docs: add architecture codemaps with diagrams for the whole system

Adds codemaps/architecture.md, backend.md, frontend.md, and data.md —
Mermaid-diagrammed design documentation verified against the live
codebase and database rather than assumed from CLAUDE.md. Covers the
unified-server.js request flow (mounted routers + ~183 inline routes),
68 backend services grouped by domain, the frontend's state-driven
view-switch (no React Router in practice despite BrowserRouter being
present), and the full 122-table DB schema with the auth_accounts vs
unrelated users table naming trap flagged explicitly. Links added from
the root README.

Co-Authored-By: Claude Sonnet 5 <[email protected]>

* feat: ship canonical roof quote workflow

* fix: keep migration dry-run idempotent

* [verified] feat: complete Smart Pakker management

* [verified] fix: ignore blank task dependencies

* [verified] fix: align package duplication with schema

* [verified] fix: enforce Discord status limits

* [verified] fix: link Smart Pakke materials safely

* [verified] fix: harden material link review

* [verified] feat: improve material matching

* fix: scope pitch validation to roof packages

* fix: support canonical snapshots on production schema

* [verified] fix: hide internal package metadata from PDF

* [verified] feat: deliver sales-ready customer PDF

* [verified] feat: ship sales-ready PDF with AI overview

* [verified] fix: authenticate project list requests

* [verified] fix: refresh project-list authentication

* [verified] fix: open existing project details

* [verified] fix: keep roof components searchable in builder

* [verified] fix: expose all Smart Package categories

* [verified] fix: authenticate project creation

* [verified] feat: make Smart Pakker the universal project flow

* [verified] feat: preview Smart Package contents

* [verified] test: keep generic release isolated from downpipe work

* feat: add first-class Smart Pakke rentals

* [verified] feat: add gutter and downpipe smart packages

* [verified] fix: prepare six-house gutter quote flow

* [verified] fix: open generic quotes without roof geometry

* [verified] fix: review generic quotes with authenticated APIs

* [verified] fix: calculate generic Smart Package quotes

* [verified] fix: return generic calculation breakdown

* feat: checkpoint generic signed snapshot validation with red-green tests

* feat: complete fail-closed generic quote approval and customer PDF flow

* feat: use generic signed snapshot in final review

* feat: redesign generic quote final review

* fix: harden generic review summaries

* feat: add auditable six-house package basis

* [verified] feat: finish auditable Smart Pakke UI

* [verified] fix: bind auditable quantity and price bases

* [verified] fix: keep six-house basis across package versions

* [verified] fix: complete smart package discovery management

* [verified] fix: simplify composition and generic scope

* [verified] test: keep explicit roof contracts fail closed

* [verified] fix: harden generic quote snapshots

* fix: make generic quote delivery customer safe

* [verified] fix: secure package catalog reads

* [verified] fix: close workspace provenance blockers

* fix: harden customer document language boundary

* [verified] fix: secure smart package internal reads

* fix: version package child mutations atomically

* feat: add generic customer quote text flow

* [verified] fix: allow manual customer numbers

* [verified] fix: expose optional roof geometry

* [verified] fix: rebase hydrated packages after geometry edits

* [verified] feat: add free editable site area map

* [verified] fix: harden map recovery and geocoding gate

* fix: bind map quantities to authoritative geometry

* fix: release geocoder lock before dispatch

* fix: separate roof and site geometry provenance

* fix: revoke stale admin authorization

* fix: migrate task geometry basis

* fix: make backend CI dependency-complete

* ci: seed isolated e2e login account

* fix: allow clean database bootstrap

* fix: skip indexes for optional tables

* test: use canonical mansard geometry in e2e

* [verified] fix(auth): enforce live operator boundary

* fix: fail close Ordrestyring offer transport

* fix(frontend): authenticate customer project requests

* fix: align canonical roof type contract

* [verified] fix: reconcile legacy package labor safely

* [verified] fix: audit site geometry deletion

* docs: add PR 31 reviewer guide

* docs: synchronize Obsidian vault

* docs: sync integrated reviewer guide to Obsidian

* ci: seed isolated auth account explicitly

* fix: close offer bootstrap and service readiness gaps

* fix: authenticate protected package callers

* fix: provision initial admin and disable generic send

* [verified] fix: close final quote release blockers

* [verified] fix: seed gutter packages before deployment

---------

Co-authored-by: alexpolo1 <[email protected]>
Co-authored-by: Claude Sonnet 5 <[email protected]>
2026-09-26 22:39:18 +02:00

4.2 KiB

Frontend Structure

React 18 + Material-UI, built statically and served by the backend (see architecture.md) — there's no separate frontend deployment.

Navigation is a state switch, not a router

react-router-dom is a dependency and frontend/src/index.js wraps the tree in <BrowserRouter> — but that's vestigial. Nothing in the codebase uses <Route>, useNavigate, or useParams (verified by grep). All real navigation is plain React state in App.js: NAV_VIEWS (an array of view IDs) + VIEW_CONFIG (icon/label/description per ID) drive the nav bar, and currentView (persisted to localStorage) picks which lazy-loaded component renders via a long currentView === '...' ? <X /> : ... chain. There are no URLs per view and no deep links — "adding a page" means adding an entry to VIEW_CONFIG/NAV_VIEWS and a branch in that chain, not adding a <Route>.

flowchart TB
    Login["LoginForm\n(unauthenticated)"] -- "AuthContext.login()" --> Gate{"isAuthenticated?"}
    Gate -- no --> Login
    Gate -- yes --> AppContent["AppContent\ncurrentView state"]
    AppContent --> Nav["Nav bar\n(navViews = NAV_VIEWS\n+ 'users' if role==admin)"]
    Nav --> Switch{"currentView"}
    Switch -->|projects| ProjectFlow
    Switch -->|planning| PlanningDashboard
    Switch -->|mobile| MobileOrders
    Switch -->|materials| MaterialsList
    Switch -->|smart-packages| SmartPackagesRoutes
    Switch -->|openai-usage| AIUsageView["inline AI usage view"]
    Switch -->|noegletal| NoeglatalDashboard
    Switch -->|dashboard| AdvancedDashboard
    Switch -->|users, admin only| UsersManagement

Top-level components (frontend/src/components/, lazy-loaded ones especially)

Component Role
ProjectFlow.js The core quote-building wizard: project data → geometry → smart packages → final review
EnhancedGeometry.js Roof geometry input with SVG visualizations for all 7 supported roof types
InlineSmartPackage.js Smart Package step-by-step wizard embedded in the project flow
FinalReview.js Quote review + Ordrestyring offer creation
MaterialsList.js Material search/selection with cached API queries
PlanningDashboard.js Order/calendar planning view
MobileOrders.js Field/besigtigelse intake against Ordrestyring order history
NoeglatalDashboard.js, AdvancedDashboard.js Metrics/KPI dashboards
UsersManagement.js New (2026-09-04). Admin-only user CRUD page ("Brugere" nav item), only rendered when AuthContext.user.role === 'admin'
LoginForm.js Credential form, calls AuthContext.login

Smart Packages subsystem (components/smartPackages/, 19 files)

SmartPackages.js is the management shell; supporting pieces: SmartPackageWizard.js / SmartPackageForm.js (creation flow), PackageDetailsDialog.js, TaskManagement.js, StatisticsView.js, SmartPackageReviewQueue.js, HaandvaerkPriserImportPanel.js (haandvaerkpriser.dk import), BackupImport.js, ComponentsLibrary.js, smartPackageCategories.js / smartPackageManagementQuery.js (data/query helpers). Routed into the main app via frontend/src/routes/SmartPackagesRoutes.js (lazy-loaded as the smart-packages view).

Auth (frontend/src/contexts/AuthContext.js)

  • Login posts to /api/auth/login; on success stores accessToken in localStorage and sets it as the axios default Authorization header for every subsequent request.
  • user is now { username, role } — role was added 2026-09-04 to gate the users nav view/component; it comes straight from the login response (response.data.user.role), matching the backend's auth_accounts.role column (see data.md, backend.md).
  • A refresh-token flow (/api/auth/refresh, HttpOnly cookie) is scaffolded in the axios response interceptor but the backend endpoint doesn't exist yet — this is explicitly flagged in the file's own TODO/WARNING comments as incomplete, not a bug to silently "fix" without checking backend readiness first.
  • logout() clears localStorage and the axios header; there's no server-side session invalidation (JWTs just expire, 24h access / 7d refresh).