Initial commit: React frontend (SLP Software) + AIDLC workflow docs

Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
2026-07-20 00:19:44 +02:00
co-authored by Junie
commit e299f1c745
73 changed files with 7275 additions and 0 deletions
@@ -0,0 +1,42 @@
# Logical Components — react-frontend-app
## Component/Provider Overview
```mermaid
graph TD
router["Router Instance\n(TanStack Router, hash history)"]
query_client["QueryClientProvider\n(staleTime: Infinity for placeholder queries)"]
theme_provider["ThemeProvider\n(theme state + localStorage persistence)"]
error_boundary["ErrorBoundary\n(on-brand fallback UI)"]
root_route["Root Route (__root.tsx)"]
fonts["Self-hosted Fonts\n(bundled static assets)"]
router --> root_route
root_route --> error_boundary
error_boundary --> theme_provider
theme_provider --> query_client
root_route -.->|"loads"| fonts
classDef infra fill:#9C27B0,stroke:#4a148c,stroke-width:1px,color:#000;
classDef guard fill:#FF9800,stroke:#e65100,stroke-width:1px,color:#000;
classDef layout fill:#2196F3,stroke:#0d47a1,stroke-width:1px,color:#000;
classDef asset fill:#4CAF50,stroke:#2e7d32,stroke-width:1px,color:#000;
class router,query_client infra;
class error_boundary guard;
class theme_provider,root_route layout;
class fonts asset;
```
Text alternative: The router hosts the root route, which is wrapped by an ErrorBoundary, which wraps ThemeProvider, which wraps QueryClientProvider; the root route also loads self-hosted font assets (purple = infra provider, orange = guard/boundary, blue = layout/route, green = static asset).
## Logical Component Definitions
| Component | Type | Responsibility |
|---|---|---|
| **Router Instance** | Infrastructure | Created via TanStack Router with `createHashHistory()`; defines the root route and index route tree. |
| **QueryClientProvider** | Infrastructure | Wraps the app with a single shared `QueryClient`; configures default `staleTime: Infinity` for this iteration's placeholder queries. |
| **ThemeProvider** | Layout/Context | Owns `theme` state (`'red' \| 'purple'`), reads/writes `localStorage`, applies the active theme class to the document root; exposes `theme` + `toggleTheme()` via React context (implements BR-1, BR-2, BR-3). |
| **ErrorBoundary** | Guard | Top-level React error boundary; renders the on-brand fallback UI on unexpected render errors (implements the Resilience Pattern). |
| **Root Route (`__root.tsx`)** | Layout/Route | Composes `ErrorBoundary``ThemeProvider``QueryClientProvider``RootLayout` (Nav/Footer) → routed content (`<Outlet />`). |
| **Self-hosted Fonts** | Static Asset | Sora, Instrument Sans, and JetBrains Mono font files bundled with the app and declared via local `@font-face`/`@fontsource` imports — no external CDN dependency. |
@@ -0,0 +1,26 @@
# NFR Design Patterns — react-frontend-app
## Resilience Pattern: Top-Level Error Boundary
A single React error boundary wraps the routed content inside the root route. On an unexpected rendering error it shows a minimal, on-brand fallback message styled with the currently active theme (e.g. "Er ging iets mis. Probeer de pagina te vernieuwen."), with no stack traces or technical details exposed (satisfies SECURITY-09 and SECURITY-15 from NFR Requirements).
## Scalability Pattern: Not Applicable (Justified)
This is a static single-page marketing site with no server-side component to scale. The only forward-looking "scalability" concern — adding more routes and swapping the placeholder query for a real API — is already accommodated structurally by the Functional Design's root/index route split and the `usePackagesQuery` hook shape, so no additional scalability pattern is introduced at this stage.
## Performance Patterns
### Query Caching
The `usePackagesQuery` placeholder hook is configured with `staleTime: Infinity` (and no automatic refetch-on-window-focus), since its `queryFn` currently always returns the same static array. This is a deliberate choice anticipating the future real-data swap, where refetch behavior can be tuned once real network latency/staleness exists.
### Font Loading
Fonts (Sora, Instrument Sans, JetBrains Mono) are **self-hosted** as static assets bundled with the app (via `@fontsource/*` packages or locally vendored font files + `@font-face` declarations), rather than loaded from the Google Fonts CDN.
- **Impact on Security Baseline SECURITY-13 (integrity)**: Self-hosting removes the need for Subresource Integrity (SRI) hashes on font `<link>` tags entirely, since no external CDN resource is loaded for fonts anymore. The NFR Requirements SECURITY-13 note ("SRI where feasible") is superseded by this decision — self-hosting is a stronger mitigation (no external dependency at all) than SRI on a CDN resource.
- **Trade-off accepted**: Slightly larger initial bundle/setup effort, in exchange for one fewer external dependency and a fully offline-buildable app.
## Security Patterns
- **Dependency/supply chain (SECURITY-10)**: `package-lock.json` committed; `npm audit` step documented in build instructions (implemented in Build and Test stage).
- **Integrity (SECURITY-13)**: Satisfied via the font self-hosting decision above (no external CDN assets requiring SRI remain in this iteration).
- **Hardening (SECURITY-09) & fail-safe defaults (SECURITY-15)**: Satisfied via the Resilience Pattern (error boundary) above and a standard production build with no demo/sample routes.
- **HTTP security headers (SECURITY-04)**: Remains deferred to Deployment Setup (Operations phase), unchanged from NFR Requirements — no hosting decision has been finalized yet.
## Logical Components
See `logical-components.md` for the concrete component/provider list implementing these patterns.