Architecture Instructions – React SPA (Feature-Based, Query/Mutation-Centric, Fully Observable)


1. Architectural Style

  • Feature-based architecture with hard boundaries.
  • Explicit separation of:

    • Queries → read-only server state
    • Mutations → state-changing operations
  • Hooks manage server state and orchestration.
  • Components are presentation-only.
  • React Query → server state (single source of truth).
  • Zustand → UI / session / ephemeral cross-feature state only.
  • Wouter → routing.
  • Mantine → UI, theming, notifications.
  • Centralized fetch client for all HTTP communication.
  • Backend errors returned as ProblemDetails are normalized and surfaced via notifications according to strict rules.
  • All feature calls, queries, mutations, workflows, and user-visible errors MUST be traced to Azure Application Insights.

2. Project Structure

src/
├── api/
│   ├── client.ts                 # fetch wrapper, error normalization, tracing
│   └── telemetry.ts              # Application Insights abstraction (only SDK usage)
│
├── assets/                       # images, icons, fonts
│
├── components/                   # reusable UI components
│
├── features/                     # feature modules
│   ├── <feature>/
│   │   ├── service.ts            # semantic API (business intent)
│   │   ├── hooks/
│   │   │   ├── useQueries.ts
│   │   │   └── useMutations.ts
│   │   ├── store.ts              # feature-scoped Zustand (UI only)
│   │   ├── components/           # feature UI
│   │   └── types.ts
│
├── workflows/                    # cross-feature orchestration
│   ├── <workflow>/
│   │   ├── use<Workflow>.ts
│   │   ├── state.ts              # optional local workflow state
│   │   └── types.ts
│
├── hooks/
│   ├── useApiError.ts            # notification + telemetry-driven error handling
│   └── useTrace.ts               # standardized tracing helper
│
├── layouts/                      # MainLayout, AuthLayout
│
├── routes/                       # Wouter routes, PrivateRoute
│
├── store/                        # global Zustand (if needed)
│
├── styles/                       # Mantine theme overrides
│
├── utils/                        # helpers
│
├── App.tsx
├── main.tsx
└── index.css

3. API Client (api/client.ts)

Responsibilities (Non-Negotiable)

  • Base URL and headers
  • Auth token injection
  • Correlation ID propagation
  • Request execution
  • Normalize all failures into a single error model
  • Automatic dependency telemetry
  • Never leak raw fetch errors upstream

Unified Error Model

All failures are converted into:

ApiError {
  type: 'network' | 'auth' | 'validation' | 'server'
  status?: number
  title: string
  detail?: string
  errors?: Record<string, string[]>
}

ProblemDetails, network failures, CORS issues, and proxy errors must all map here and be logged to Application Insights.


4. Telemetry & Tracing (Mandatory)

Tooling

  • Azure Application Insights
  • Direct SDK usage is allowed only in api/telemetry.ts

What Must Be Traced

Event Required Metadata
Query start / failure feature, queryKey
Mutation start / success / failure feature, operationName
Workflow start / success / failure workflowName
Workflow step failure workflowName, step
HTTP dependency method, url, status
User-visible notification severity, source
Auth / network fatal errors always

No silent paths.


Telemetry Ownership

  • api/client.ts

    • HTTP dependencies
    • Correlation IDs
  • Feature hooks

    • Semantic intent (loadProfile, updatePassword)
  • Workflows

    • Business processes
  • useApiError

    • User-visible failures only

5. Feature Service Layer (features/<feature>/service.ts)

Purpose

Semantic boundary, not a transport wrapper.

Rules

  • Express business intent, not URLs.
  • Normalize backend responses into frontend invariants.
  • Hide backend naming, structure, and quirks.
  • No React Query usage.
  • No side effects.
  • Every exported function defines a stable operation name for tracing.

Ownership

  • One feature owns its services.
  • Other features may consume, never redefine.

6. Queries & Mutations (React Query)

Queries

  • Read-only server state.
  • Cached globally.
  • Namespaced query keys:
['<feature>', '<resource>', ...]
  • Feature that defines the query owns invalidation.
  • Query lifecycle events are traced.

Mutations

  • State-changing only.
  • Always user-initiated.
  • Must:

    • Emit telemetry (start, success, failure)
    • Trigger invalidation
    • Trigger notifications via useApiError

Mutation hooks own side effects and observability.


7. Error Notification Policy (Critical)

Not all errors are equal.

Notification Rules

Context Notification
Mutation error Always
Query – initial blocking load Yes
Query – background refetch No
Query – polling No
Network / auth fatal errors Yes

useApiError Responsibilities

  • Decide if error is visible
  • Decide severity (info | warning | error)
  • Format ProblemDetails and validation errors
  • Deduplicate notifications
  • Emit telemetry for all user-visible errors

Hooks must pass explicit context:

{ silent, isBackground, severity, source }

Components never handle errors.


8. Zustand State Rules (Strict)

Zustand may contain only:

  • UI state (dialogs, steps, filters)
  • Ephemeral cross-feature state

Zustand must never contain:

  • Server entities
  • Lists
  • Cached data
  • Error state
  • Retry counters
  • Telemetry state

React Query is the only source of server state.


9. Components

  • Presentation-only.
  • Receive data via hooks or props.
  • No API calls.
  • No mutations directly.
  • No orchestration.
  • No error handling.
  • No telemetry.
  • Display loading / empty / success states only.

10. Routing (Wouter)

  • One route → one page component.
  • Route components:

    • Extract route params
    • Pass params to page-level hooks
  • Routing layer contains zero business logic.
  • Authentication enforced via PrivateRoute.

11. Workflows

Definition

Workflows are explicit cross-feature orchestration units representing business processes.


Characteristics

  • Orchestrate multiple features.
  • Span multiple mutations and queries.
  • Own:

    • Ordering
    • Retry logic
    • Compensation / rollback
    • Cross-feature error semantics
    • User-visible notifications
    • Business-level telemetry
  • Expose one semantic operation.
  • No UI.
  • No direct API access.
  • Located at top level:
src/workflows/<workflow>/

Rules (Hard)

  1. Workflows may call feature hooks only
  2. Workflows must not call feature services directly
  3. Features must never depend on workflows
  4. Components may call workflows
  5. No orchestration in components
  6. No orchestration in feature services
  7. No React Query usage inside workflows
  8. Workflows emit start / success / failure telemetry
  9. Workflows are isolated and testable

12. Layouts

  • Apply Mantine providers.
  • Configure theme and notifications.
  • Contain no feature logic.

13. SSR / Preloading Position

  • SPA-first architecture.
  • SSR not assumed.
  • Query keys are deterministic.
  • Side effects isolated in mutations.
  • SSR or preloading can be added later without structural rewrite.

14. Mental Model

Component (UI)
   ├─> Feature Hook (Query / Mutation)
   │     ├─> service.ts (semantic intent)
   │     ├─> React Query (server state)
   │     ├─> telemetry (feature-level)
   │     └─> api/client
   │           ├─> HTTP
   │           ├─> dependency telemetry
   │           └─> ApiError
   │
   └─> Workflow Hook (optional)
         ├─> Feature Hook A
         ├─> Feature Hook B
         ├─> telemetry (workflow-level)
         └─> useApiError → Notification

15. Hard Rules (Enforced)

  1. Feature services express business intent, not transport
  2. Hooks are the only layer allowed to call services
  3. React Query owns all server state
  4. Zustand never mirrors server data
  5. Query keys are feature-namespaced
  6. Only owning feature invalidates its queries
  7. Mutations always notify; queries notify selectively
  8. Components never handle errors or orchestration
  9. Workflows are explicit and isolated
  10. No feature call without telemetry
  11. No user-visible error without an Application Insights trace
  12. No direct Application Insights SDK usage outside telemetry layer
  13. Workflows are the unit of business observability
  14. If it cannot be traced, it must not exist
  15. No exceptions