This web application architecture guidance is still in draft and is subject to change.
Web Application Architecture Overview
This guide defines the standard architecture for RMC web applications. All new web applications should follow this three-tier pattern to ensure consistency, maintainability, and separation of concerns.
Three-Tier Architecture
RMC web applications follow a three-tier architecture that separates the user interface, server logic, and calculation logic into distinct layers. This separation provides several key benefits:
- Maintainability: Changes to one layer don't require changes to others
- Testability: Each layer can be tested independently
- Reusability: Calculation libraries can be shared across multiple applications
- Scalability: Layers can be scaled independently based on demand
- Security: Sensitive operations are isolated in the backend
┌─────────────────────────────────────────────────────────────┐
│ FRONTEND (React + Vite) │
│ │
│ What users see and interact with: forms, buttons, charts │
│ Runs in the user's web browser │
│ Technology: React, JavaScript, Tailwind CSS │
└─────────────────────┬───────────────────────────────────────┘
│
│ HTTP/JSON
│ RESTful API calls over the network
↓
┌─────────────────────────────────── ──────────────────────────┐
│ BACKEND API (ASP.NET Core) │
│ │
│ The "server" that handles requests, manages data, security │
│ Runs on a web server (not in the user's browser) │
│ Technology: ASP.NET Core, Entity Framework Core, PostgreSQL │
└─────────────────────┬───────────────────────────────────────┘
│
│ HTTP/JSON
│ API calls to calculation service
↓
┌─────────────────────────────────────────────────────────────┐
│ CALCULATION LIBRARIES (.NET Libraries) │
│ │
│ Pure engineering calculations with no knowledge of web/DB │
│ Exposed via a lightweight HTTP API │
│ Technology: .NET (latest), RMC.Numerics │
└─────────────────────────────────────────────────────────────┘
Understanding Each Layer
Frontend Layer
The frontend is everything the user sees and interacts with in their web browser. When a user visits a web application, the browser downloads HTML, CSS, and JavaScript files that render the user interface.
Key Concepts:
- React is a JavaScript library for building user interfaces using reusable "components" (buttons, forms, charts, etc.)
- Vite is a build tool that bundles application code and provides a fast development server
- Tailwind CSS is a utility-first CSS framework for styling components
What the Frontend Does:
- Renders the user interface (forms, buttons, navigation)
- Captures user input (typing, clicking, selecting)
- Sends requests to the backend API
- Displays data and results from the backend
- Provides immediate feedback (loading spinners, validation messages)
What the Frontend Does NOT Do:
- Store sensitive data (passwords, tokens should not persist in the browser)
- Perform engineering calculations (these belong in calculation libraries)
- Access the database directly (always goes through the backend)
- Make security decisions (backend validates everything)
Backend API Layer
The backend is a server application that runs on a remote machine (not in the user's browser). It receives requests from the frontend, processes them, and sends back responses.
Key Concepts:
- ASP.NET Core is Microsoft's framework for building web APIs in C#
- Controllers are classes that handle incoming HTTP requests (like POST, GET, PUT, DELETE)
- Entity Framework Core is an ORM (Object-Relational Mapper) that allows working with database records as C# objects instead of writing raw SQL
- JWT (JSON Web Token) is a standard for securely transmitting user identity information
What the Backend Does:
- Authentication: Verifies who the user is (login, tokens)
- Authorization: Checks what the user is allowed to do
- Data Persistence: Saves and retrieves data from the database
- Request Validation: Ensures incoming data is valid before processing
- Orchestration: Coordinates between the database and calculation libraries
- Response Formatting: Structures data for the frontend to consume
What the Backend Does NOT Do:
- Perform complex engineering calculations (delegates to libraries)
- Render HTML or UI components (that's the frontend's job)
- Trust data from the frontend without validation
Calculation Library Layer
Calculation libraries are standalone .NET class libraries containing engineering calculations. They have no knowledge of web frameworks, databases, or user interfaces—they are pure computational logic.
Key Concepts:
- A class library is a collection of reusable code that other applications can reference
- Stateless means the library doesn't remember anything between calls—all inputs are passed in, and outputs are returned
- Deterministic means the same inputs always produce the same outputs
What Calculation Libraries Do:
- Implement engineering algorithms and formulas
- Run Monte Carlo simulations
- Compute statistics and probabilities
- Provide validated, tested calculation methods
What Calculation Libraries Do NOT Do:
- Make HTTP requests or network calls
- Read from or write to databases
- Handle user authentication
- Render any user interface
Why This Separation Matters:
By keeping calculations in a separate library, the same code can be used by:
- A web application (through the backend API)
- A desktop application (direct reference)
- A command-line batch processing tool
- Automated testing systems
Data Flow Example
The following diagram shows how data flows through the system when a user performs an analysis.
1. User interacts with the UI
└── Enters parameters and clicks "Run Analysis"
│
↓
2. Frontend Controller hook prepares request
└── Collects form values and transforms to API format
│
↓
3. Frontend HTTP layer sends request to backend
└── POST /api/analyses/{id}/calculate
│
↓
4. Backend Controller receives the HTTP request
├── Extracts and validates the JWT token (who is this user?)
├── Queries the database for the analysis record
└── Verifies the user owns this analysis (authorization)
│
↓
5. Backend Service orchestrates the calculation
├── Loads analysis parameters from the database
├── Creates a configuration object for the library
└── Calls: var result = await model.RunAsync();
│
↓
6. Calculation library performs the analysis
├── Validates inputs
├── Samples from probability distributions
├── Runs Monte Carlo iterations
└── Computes statistics (mean, percentiles, etc.)
│
↓
7. Backend saves results and returns response
├── Persists results to database (JSON column)
└── Returns structured JSON following messaging contract
│
↓
8. Frontend receives and displays results
├── Controller hook transforms response for display
└── UI components render charts, tables, and messages
Repository Structure
RMC web applications typically involve multiple repositories, each with a specific role.
Web Application Repository
A web application repository contains both the frontend and backend code, plus deployment configuration.
my-web-app/
├── frontend/ # React application (runs in browser)
│ ├── src/
│ │ ├── app/ # Entry point and root setup
│ │ │ ├── main.jsx # React DOM mount
│ │ │ ├── router.jsx # React Router configuration
│ │ │ └── index.css # Global styles + Tailwind
│ │ ├── api/ # HTTP utilities + API modules
│ │ │ ├── common/
│ │ │ │ └── apiFetch.js # Low-level HTTP wrapper
│ │ │ └── {domain}/ # Domain-specific API modules
│ │ ├── components/ # Reusable UI components
│ │ │ ├── common/ # Generic (Button, Input, Table, etc.)
│ │ │ │ ├── ui/
│ │ │ │ ├── layout/
│ │ │ │ ├── feedback/
│ │ │ │ ├── table/
│ │ │ │ └── chart/
│ │ │ └── {domain}/ # Domain-specific components
│ │ ├── pages/ # Page components organized by feature
│ │ │ └── {feature}/
│ │ │ ├── FeaturePage.jsx
│ │ │ └── hooks/
│ │ │ ├── useFeatureController.js # Controller hook
│ │ │ └── useFeatureData.js # Data hook
│ │ ├── hooks/ # Shared custom hooks
│ │ │ └── common/
│ │ ├── contexts/ # React Context providers
│ │ ├── data/ # Static config, lookup tables
│ │ ├── utils/ # Helper functions
│ │ └── assets/ # Fonts, images
│ └── package.json
│
├── backend/ # ASP.NET Core API (runs on server)
│ └── src/
│ ├── MyApp.Domain/ # Entities, enums, business rules
│ ├── MyApp.Application/ # Services, interfaces, DTOs
│ ├── MyApp.Infrastructure/# DbContext, repositories, HTTP clients
│ └── MyApp.API/ # Controllers, middleware, Program.cs
│
├── docker-compose.yml # Container orchestration
└── README.md
Calculation Library Repository
Calculation libraries live in their own repository so they can be versioned and shared independently.
calc-library/
├── CalcLibrary/ # Main library project
│ ├── Common/ # Shared utilities across calculations
│ │ ├── DistributionSampler.cs
│ │ └── StatisticsHelper.cs
│ ├── Analyses/ # Domain-specific calculations
│ │ ├── SettlementAnalysis/
│ │ │ ├── SettlementConfig.cs # Input configuration
│ │ │ ├── SettlementModel.cs # Calculation implementation
│ │ │ └── SettlementResult.cs # Output structure
│ │ └── SeepageAnalysis/
│ │ ├── SeepageConfig.cs
│ │ ├── SeepageModel.cs