examforge / ARCHITECTURE.md
Benjahmin's picture
feat(ui): implement design token system and core components
bf954c9
|
Raw
History Blame Contribute Delete
9.81 kB
# ExamForge Engine Architecture & System Design Blueprint
> Proprietary Core Platform Design for Multi-School, Multi-Tenant Scaling (up to 1,000+ Schools)
---
## 1. Single-Page Architecture Overview
ExamForge leverages a **Modular Monolith ("Engine Architecture")** structure built using **React+Vite** in the frontend, backed by a robust and secure **Firebase Firestore** persistence layer + server-side validation proxies.
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ CLIENT LAYER β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ UI Engine β”‚ β”‚ Auth Engine β”‚ β”‚
β”‚ β”‚ (Design System) β”‚ β”‚ (Tenant Boundary) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Parsing Engine β”‚ β”‚ Exam Engine β”‚ β”‚
β”‚ β”‚ (Extraction Layer) β”‚ β”‚ (Submission Loop) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚
β–Ό Secure API HTTP/S β–Ό WebSocket Channels (Realtime)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BACKEND CORE β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Server-Side Controllers β”‚ β”‚
β”‚ β”‚ - Multi-Tenant Rule App β”‚ β”‚
β”‚ β”‚ - AI NVIDIA NIM Router β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό Secure SDK
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ DATA WAREHOUSE β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Multi-Tenant Cloud Store β”‚ β”‚
β”‚ β”‚ (Firestore Isolated Node) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
---
## 2. Directory & Folder Structure
To scale past 100,000+ operations without component namespace clashing, our files are partitioned strictly into context-isolated Engine namespaces.
```
/src
β”œβ”€β”€ /engines # Shared Application Micro-Engines
β”‚ β”œβ”€β”€ /ui # UI Engine Core (Tokens, Layouts, Spring Assets)
β”‚ β”‚ β”œβ”€β”€ /components # Atomic design pieces (Button, Card, Input...)
β”‚ β”‚ β”œβ”€β”€ /hooks # useLayoutValidator, etc.
β”‚ β”‚ └── tokens.ts # Global 8px grid tokens
β”‚ β”‚
β”‚ β”œβ”€β”€ /auth # Authentication & Identity Engine
β”‚ β”‚ β”œβ”€β”€ /services # TenantAuthService
β”‚ β”‚ β”œβ”€β”€ /validators # Identity, PIN, & schema rules
β”‚ β”‚ └── types.ts # Tenancy schema maps
β”‚ β”‚
β”‚ └── /parsing # Content Parsing Engine
β”‚ β”œβ”€β”€ /services # Orchestrators and OCR Pipelines
β”‚ β”œβ”€β”€ /validators # Syntactic structural rules
β”‚ └── types.ts # Extraction payloads
β”‚
β”œβ”€β”€ /pages # Standard View Compositions
β”‚ β”œβ”€β”€ /teacher # Teacher Dashboard & Classroom portals
β”‚ β”œβ”€β”€ CreateExam.tsx # Exam configuration bounds
β”‚ └── ExamInterface.tsx # Realtime assessment loop
β”‚
β”œβ”€β”€ /services # Core server communications
└── /types # Domain types
```
---
## 3. Modular Service Boundaries & Shared Contracts
* **Boundary Isolations**: Direct mutations of raw databases are strictly forbidden. To talk across engine lines, engines must consume public contract classes (`TenantAuthService`, `ParsingEngineService`).
* **No Circular Dependencies**: Lower-level engines (like `/ui` and `/auth`) *never* import components or hooks from higher-level features (like `/parsing`).
---
## 4. Multi-Tenant Firestore Schema Design
To guarantee perfect performance and isolation for over **100 schools** without rewriting, schools are split utilizing **Single-Collection Multi-Tenant Partitioning**.
### 1. `schools` Collection
Stores metadata regarding active institutional tenants.
```json
// Collection: schools/{schoolId}
{
"id": "school-british-academy",
"name": "British International School",
"domain": "britishacademy.edu",
"tenantStatus": "active",
"createdAt": "2026-06-03T12:00:00Z"
}
```
### 2. `users` Collection
Explicitly binds users to their parent `schoolId` to guarantee robust multi-school data safety.
```json
// Collection: users/{uid}
{
"id": "usr_stu_0091",
"fullName": "Jane Doe",
"email": "jane.doe@britishacademy.edu",
"role": "student",
"schoolId": "school-british-academy", // Partition key
"createdAt": "2026-06-03T12:00:00Z"
}
```
### 3. `exams` Collection
```json
// Collection: exams/{examId}
{
"id": "exam_math_01",
"schoolId": "school-british-academy", // Partition key
"title": "Algebraic Differential Topology",
"status": "published",
"questionIds": ["q_01", "q_02"],
"duration": 60
}
```
---
## 5. Row-Level Security Rules (firestore.rules)
To enforce multi-tenant isolation directly on the database node, we apply strict token-to-record matching rules in `firestore.rules`:
```javascript
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Match current user payload
function getUserData() {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
}
// Verify school membership
function belongsToSameSchool(resourceData) {
return request.auth != null && getUserData().schoolId == resourceData.schoolId;
}
match /users/{userId} {
allow read, write: if request.auth != null && (request.auth.uid == userId || getUserData().role == 'school_admin');
}
match /exams/{examId} {
allow read: if belongsToSameSchool(resource.data);
allow write: if request.auth != null && getUserData().role == 'teacher' && belongsToSameSchool(request.resource.data);
}
}
}
```
---
## 6. Intelligent Caching Strategy (Latency Reduction)
1. **AI Cache Resolution**: Background compilation prompts and analytics reviews are cached using a secure, client-server Redis or server-side memory buffer map (`aiCache`) with a 60-minute TTL.
2. **Snapshot Preservation**: High-frequency exam questions are stored locally during student CBT assessments as a JSON snapshot in the `Attempt` state, bypassing Firestore real-time reads on every navigation.
---
## 7. Integrated Performance, Logging & Monitoring Strategy
To prevent high-cost bills or unexpected cloud latency during active CBT exams:
* **System Telemetry Logging**: Every AI extraction, classification, or scoring action calls `logAiOperation`, recording latency metrics in a local append-only database.
* **Optimistic Sync Reconciliation**: Progress coordinates are batched and saved asynchronously during active exams every **30 seconds** rather than on every keystroke, reducing network requests by **95%**.
---
## 8. Relational Postgres (SQL) Migration Pathway
When transitioning from 100 to 1,000+ schools, we migrate to PostgreSQL utilizing an execution flow that preserves our existing backend router interfaces cleanly:
1. **Phase 1: Abstract Service Interfaces**: Ensure all data calls utilize repository wrappers (`DataService`).
2. **Phase 2: Relational Schema Mapping**: Translate JSON models into relational tables (e.g. `schools` table has many-to-one relationship on `users` and `exams`).
3. **Phase 3: Database Driver Switchover**: Replace SDK implementations in `DataService` with a PostgreSQL driver (via Prisma or Knex), leaving the frontend completely unchanged.