| # 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. |
|
|