Full React 18 + TypeScript + Vite frontend with: - 90+ pages (admin, student, teacher, public) - shadcn/ui component library with 50+ components - JWT authentication with role-based access control - TanStack React Query for server state management - 30+ API service modules - AI-powered features (coaching, grading, generation) - Adaptive learning UI (diagnostics, proficiency, plans) - Institutional LMS management (courses, batches, timetable) - Communication suite (discussions, announcements, DMs) - Full CRUD with validation and confirmation dialogs Made-with: Cursor
345 lines
13 KiB
Markdown
345 lines
13 KiB
Markdown
# EnCoach Platform -- Architecture & Connectivity Document
|
|
|
|
## Overview
|
|
|
|
EnCoach is an **IELTS preparation and English proficiency testing platform** composed of four repositories that work together as a distributed system. The platform supports exam taking, AI-powered grading, training content, multi-tenant entity management, payments, and a public-facing marketing website.
|
|
|
|
---
|
|
|
|
## Repositories at a Glance
|
|
|
|
- **[ielts-ui](ielts-ui)** -- Full-stack Next.js 14 app. The main platform for students, teachers, admins, and corporate users. Serves both the browser UI and internal API routes.
|
|
- **[ielts-be](ielts-be)** -- Python/FastAPI backend. Handles AI/ML workloads: exam generation, grading (writing/speaking), audio transcription, TTS, and training content.
|
|
- **[encoachcms](encoachcms)** -- Strapi v4 headless CMS. Manages bilingual (EN/AR) marketing content for the landing page.
|
|
- **[encoach-landing-page](encoach-landing-page)** -- Next.js 13 marketing website. Consumes CMS content and links users into the main platform.
|
|
|
|
---
|
|
|
|
## System Architecture Diagram
|
|
|
|
```mermaid
|
|
graph TB
|
|
subgraph publicFacing ["Public-Facing Layer"]
|
|
LP["encoach-landing-page<br/>(Next.js 13)"]
|
|
CMS["encoachcms<br/>(Strapi v4)"]
|
|
end
|
|
|
|
subgraph platformCore ["Platform Core"]
|
|
UI["ielts-ui<br/>(Next.js 14 + API Routes)"]
|
|
BE["ielts-be<br/>(FastAPI / Python)"]
|
|
end
|
|
|
|
subgraph dataStores ["Data Stores"]
|
|
MongoDB["MongoDB"]
|
|
MySQL["MySQL<br/>(CMS)"]
|
|
FirebaseAuth["Firebase Auth"]
|
|
FirebaseStorage["Firebase Storage"]
|
|
GCS["Google Cloud Storage<br/>(CMS uploads)"]
|
|
end
|
|
|
|
subgraph externalServices ["External Services"]
|
|
OpenAI["OpenAI GPT-4o"]
|
|
Whisper["OpenAI Whisper<br/>(local)"]
|
|
Polly["AWS Polly<br/>(TTS)"]
|
|
ELAI["ELAI<br/>(AI Video)"]
|
|
GPTZero["GPTZero<br/>(AI Detection)"]
|
|
Stripe["Stripe"]
|
|
PayPal["PayPal"]
|
|
Paymob["Paymob"]
|
|
end
|
|
|
|
LP -->|"REST + Bearer token"| CMS
|
|
LP -->|"GET /api/packages, POST /api/tickets"| UI
|
|
LP -->|"Links to platform.encoach.com"| UI
|
|
|
|
CMS --> MySQL
|
|
CMS --> GCS
|
|
|
|
UI --> MongoDB
|
|
UI --> FirebaseAuth
|
|
UI -->|"Proxy: Bearer JWT"| BE
|
|
|
|
BE --> MongoDB
|
|
BE --> FirebaseAuth
|
|
BE --> FirebaseStorage
|
|
BE --> OpenAI
|
|
BE --> Whisper
|
|
BE --> Polly
|
|
BE --> ELAI
|
|
BE --> GPTZero
|
|
|
|
UI --> Stripe
|
|
UI --> PayPal
|
|
UI --> Paymob
|
|
LP --> Stripe
|
|
```
|
|
|
|
---
|
|
|
|
## 1. ielts-ui (Main Platform)
|
|
|
|
**Tech:** Next.js 14, React 18, TypeScript, Tailwind CSS + DaisyUI, Zustand, SWR, iron-session, Firebase Auth, MongoDB (direct)
|
|
|
|
**Role:** The central application. Serves the browser UI and acts as a **BFF (Backend-for-Frontend)** via Next.js API routes. It directly queries MongoDB for user/entity/group data and proxies AI-related requests to `ielts-be`.
|
|
|
|
### Key Modules
|
|
|
|
| Module | Description |
|
|
|--------|-------------|
|
|
| **Auth** | Firebase email/password auth + iron-session cookies. SSR-protected via `withIronSessionSsr`. |
|
|
| **Dashboards** | Role-based: student, teacher, admin, corporate, mastercorporate, developer, agent. |
|
|
| **Exams** | Taking exams (Reading, Listening, Writing, Speaking, Level). Zustand store tracks session, progress, solutions. |
|
|
| **Exam Editor** | Create/edit exams with dedicated components under `src/components/ExamEditor/`. |
|
|
| **Training** | Training content consumed from `ielts-be`. |
|
|
| **Grading** | Writing and speaking grading proxied to `ielts-be` as background tasks; UI polls for results. |
|
|
| **Entities** | Multi-tenant entity management (schools, organizations). |
|
|
| **Classrooms** | Classroom and group management for teachers. |
|
|
| **Assignments** | Assign exams to students with deadlines. |
|
|
| **Stats** | Performance statistics and PDF report generation (via `@react-pdf/renderer`). |
|
|
| **Payments** | Stripe, PayPal, Paymob webhook handlers in API routes. |
|
|
| **Tickets** | Support ticket system. |
|
|
| **User Mgmt** | Bulk import, permissions, role-based access. |
|
|
|
|
### How it Connects to ielts-be
|
|
|
|
API routes in `src/pages/api/` proxy to `BACKEND_URL` with `Authorization: Bearer ${BACKEND_JWT}`:
|
|
|
|
| UI API Route | Backend Endpoint |
|
|
|--------------|------------------|
|
|
| `/api/evaluate/writing` | `BACKEND_URL/grade/writing/{task}` |
|
|
| `/api/evaluate/speaking` | `BACKEND_URL/grade/speaking/{task}` |
|
|
| `/api/transcribe` | `BACKEND_URL/listening/transcribe` |
|
|
| `/api/training` | `BACKEND_URL/training/` |
|
|
| `/api/exam/upload` | `BACKEND_URL/{endpoint}` |
|
|
| `/api/exam/media/*` | `BACKEND_URL/{endpoint}/media` |
|
|
| `/api/exam/generate/*` | `BACKEND_URL/{endpoint}` |
|
|
| `/api/exam/avatars` | `BACKEND_URL/speaking/avatars` |
|
|
| `/api/exam/[module]/import` | `BACKEND_URL/{module}/import` |
|
|
| `/api/stats/[id]/[export]/pdf` | `BACKEND_URL/grade/summary` |
|
|
| `/api/batch_users` | `BACKEND_URL/user/import` |
|
|
|
|
### How it Connects to the Landing Page
|
|
|
|
Exposes public-ish API routes consumed by the landing page:
|
|
|
|
- `GET /api/packages` -- subscription packages (CORS-enabled)
|
|
- `POST /api/tickets` -- contact form submissions (CORS-enabled)
|
|
- `GET /api/users/agents` -- list sales agents (CORS-enabled)
|
|
|
|
---
|
|
|
|
## 2. ielts-be (AI/ML Backend)
|
|
|
|
**Tech:** Python 3.11, FastAPI, Motor (async MongoDB), Poetry, dependency-injector, OpenAI, Whisper, AWS Polly, ELAI, FAISS
|
|
|
|
**Role:** Handles all AI/ML-intensive operations -- exam content generation, grading, transcription, text-to-speech, AI video, and training recommendations. Runs as a standalone service on port 8000.
|
|
|
|
### Architecture Layers
|
|
|
|
```
|
|
API Routes --> Controllers --> Services --> Repositories
|
|
|
|
|
Third-Party Services
|
|
(OpenAI, Whisper, Polly, ELAI, GPTZero)
|
|
```
|
|
|
|
Wired together via `dependency-injector`.
|
|
|
|
### Key Capabilities
|
|
|
|
| Capability | Implementation |
|
|
|------------|----------------|
|
|
| **Writing Grading** | GPT-4o evaluates against IELTS rubric (Task Achievement, Coherence, Lexical Resource, Grammar). GPTZero checks for AI-generated text. Runs as background task; results stored in `evaluation` collection. |
|
|
| **Speaking Grading** | Whisper transcribes audio, then GPT grades (Fluency, Lexical, Grammar, Pronunciation). Parts 1/2/3 supported. |
|
|
| **Exam Generation** | GPT generates reading passages, listening dialogs, writing prompts, speaking tasks, and level-test exercises. |
|
|
| **Audio (TTS)** | AWS Polly synthesizes MP3 for listening sections. |
|
|
| **Video** | ELAI generates AI avatar videos for speaking prompts. |
|
|
| **Transcription** | Whisper (local model) for speech-to-text. |
|
|
| **Training** | FAISS + sentence-transformers for semantic search over tips; GPT for personalized recommendations. |
|
|
| **Short Answer Grading** | GPT-4o for reading/listening fill-in-the-blank answers. |
|
|
|
|
### Authentication
|
|
|
|
All endpoints (except `/api/healthcheck`) require a Bearer JWT token validated with `JWT_SECRET_KEY` (HS256). The `ielts-ui` sends this as `BACKEND_JWT`.
|
|
|
|
---
|
|
|
|
## 3. encoachcms (Content Management)
|
|
|
|
**Tech:** Strapi v4.21, Node.js 18, MySQL (prod) / SQLite (dev), Google Cloud Storage for uploads
|
|
|
|
**Role:** Headless CMS for managing the marketing website content. Editors create/update bilingual (EN/AR) content via the Strapi admin panel at `/admin`.
|
|
|
|
### Content Types (all Single Types)
|
|
|
|
`home`, `about`, `services`, `contact`, `footer`, `nav-bar`, `history`, `price`, `terms-and-conditions`, `privacy-policy`, `country-managers-contact`
|
|
|
|
### How it Connects
|
|
|
|
- Exposes REST API at `STRAPI_URL/api/{content-type}/?populate=deep&locale={en|ar}`
|
|
- Authenticated via API token (`STRAPI_TOKEN`)
|
|
- **Only consumed by `encoach-landing-page`** -- neither `ielts-ui` nor `ielts-be` use it
|
|
|
|
### Plugins
|
|
|
|
- `strapi-plugin-populate-deep` -- deep relation population
|
|
- `strapi-plugin-import-export-entries` -- content import/export
|
|
- `strapi-plugin-publisher` -- scheduled publishing
|
|
- `@strapi/plugin-i18n` -- internationalization
|
|
- `@strapi/plugin-documentation` -- OpenAPI docs
|
|
|
|
---
|
|
|
|
## 4. encoach-landing-page (Marketing Website)
|
|
|
|
**Tech:** Next.js 13 (App Router), TypeScript, Tailwind CSS + DaisyUI, Stripe
|
|
|
|
**Role:** Public marketing website at `encoach.com`. Bilingual (EN at `/`, AR at `/ar/`). Fetches content from the CMS and links users into the main platform.
|
|
|
|
### Pages
|
|
|
|
`/` (Home), `/about`, `/services`, `/price`, `/history`, `/contact`, `/terms`, `/privacy-policy`, `/contacts/[country]`, `/success` -- all mirrored under `/ar/` for Arabic.
|
|
|
|
### How it Connects
|
|
|
|
| Target | Connection |
|
|
|--------|------------|
|
|
| **encoachcms** | `getData()` fetches `STRAPI_URL/api/{page}/?populate=deep&locale={locale}` with Bearer token |
|
|
| **ielts-ui** | `GET /api/packages` for pricing, `POST /api/tickets` for contact form, `GET /api/users/agents` for sales agents |
|
|
| **Stripe** | Checkout flow; `/api/success` route validates session and POSTs to `WEBHOOK_URL` |
|
|
| **Platform links** | Buttons link to `platform.encoach.com/register`, `platform.encoach.com/official-exam` |
|
|
|
|
---
|
|
|
|
## Data Flow Diagrams
|
|
|
|
### Authentication Flow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Browser
|
|
participant UI as ielts-ui
|
|
participant Firebase as Firebase Auth
|
|
participant Mongo as MongoDB
|
|
|
|
Browser->>UI: POST /api/login (email, password)
|
|
UI->>Firebase: signInWithEmailAndPassword
|
|
Firebase-->>UI: Firebase UID + token
|
|
UI->>Mongo: Find user by Firebase UID
|
|
Mongo-->>UI: User document
|
|
UI->>UI: Save to iron-session cookie
|
|
UI-->>Browser: Set-Cookie (eCrop/ielts)
|
|
Browser->>UI: Subsequent requests with cookie
|
|
UI->>UI: withIronSessionSsr validates cookie
|
|
```
|
|
|
|
### Exam Grading Flow (Writing)
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Student
|
|
participant UI as ielts-ui API Route
|
|
participant BE as ielts-be
|
|
participant GPT as OpenAI GPT-4o
|
|
participant GPTZero as GPTZero
|
|
participant Mongo as MongoDB
|
|
|
|
Student->>UI: Submit writing answer
|
|
UI->>BE: POST /api/exam/grade/writing/{task}
|
|
BE->>BE: Start background task
|
|
BE-->>UI: 200 OK (accepted)
|
|
UI-->>Student: "Grading in progress"
|
|
|
|
par Parallel Grading
|
|
BE->>GPT: Evaluate against IELTS rubric
|
|
GPT-->>BE: Scores + feedback
|
|
and AI Detection
|
|
BE->>GPTZero: Check for AI content
|
|
GPTZero-->>BE: AI probability
|
|
end
|
|
|
|
BE->>Mongo: Save evaluation result
|
|
Student->>UI: Poll for result
|
|
UI->>Mongo: Query evaluation
|
|
Mongo-->>UI: Grading result
|
|
UI-->>Student: Display scores + feedback
|
|
```
|
|
|
|
### Landing Page Content Flow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Visitor
|
|
participant LP as encoach-landing-page
|
|
participant CMS as encoachcms (Strapi)
|
|
participant Platform as ielts-ui
|
|
|
|
Visitor->>LP: Visit encoach.com
|
|
LP->>CMS: GET /api/home/?populate=deep&locale=en
|
|
CMS-->>LP: Home content (JSON)
|
|
LP-->>Visitor: Rendered page
|
|
|
|
Visitor->>LP: View pricing
|
|
LP->>CMS: GET /api/price/?populate=deep&locale=en
|
|
LP->>Platform: GET /api/packages
|
|
Platform-->>LP: Package list
|
|
LP-->>Visitor: Pricing page with packages
|
|
|
|
Visitor->>LP: Submit contact form
|
|
LP->>Platform: POST /api/tickets
|
|
Platform-->>LP: Ticket created
|
|
```
|
|
|
|
---
|
|
|
|
## Shared Infrastructure
|
|
|
|
| Resource | Used By | Details |
|
|
|----------|---------|---------|
|
|
| **MongoDB** | ielts-ui, ielts-be | Same database (`MONGODB_URI` / `MONGODB_DB`). UI reads users, groups, stats directly. BE reads/writes evaluations, training. |
|
|
| **Firebase Auth** | ielts-ui, ielts-be | Shared Firebase project. UI handles login/signup; BE imports users. |
|
|
| **Firebase Storage** | ielts-be | Stores exam media (audio, images). |
|
|
| **Google Cloud Storage** | encoachcms | CMS file uploads (images, media). |
|
|
|
|
---
|
|
|
|
## Deployment Topology
|
|
|
|
| Service | Port | URL (Production) |
|
|
|---------|------|-------------------|
|
|
| ielts-ui | 3000 | `platform.encoach.com` |
|
|
| ielts-be | 8000 | Internal (proxied by ielts-ui) |
|
|
| encoachcms | 1337 | Internal (consumed by landing page) |
|
|
| encoach-landing-page | 3000 | `encoach.com` |
|
|
|
|
Both Next.js apps use `output: "standalone"` and have Dockerfiles. The BE is not directly exposed to the internet -- it sits behind ielts-ui's API route proxy layer.
|
|
|
|
---
|
|
|
|
## User Roles
|
|
|
|
| Role | Access |
|
|
|------|--------|
|
|
| **student** | Take exams, view stats, training, assignments |
|
|
| **teacher** | Manage classrooms, assignments, view student performance |
|
|
| **admin** | Full platform management, user management, entities |
|
|
| **corporate** | Corporate dashboard, bulk operations |
|
|
| **mastercorporate** | Multi-entity corporate management |
|
|
| **developer** | Developer dashboard, system tools |
|
|
| **agent** | Sales agent, visible on landing page |
|
|
|
|
---
|
|
|
|
## Key Environment Variables (Cross-Service)
|
|
|
|
| Variable | Service | Purpose |
|
|
|----------|---------|---------|
|
|
| `MONGODB_URI` / `MONGODB_DB` | ielts-ui, ielts-be | Shared MongoDB |
|
|
| `BACKEND_URL` | ielts-ui | URL of ielts-be |
|
|
| `BACKEND_JWT` / `JWT_SECRET_KEY` | ielts-ui / ielts-be | Shared JWT secret for service-to-service auth |
|
|
| `FIREBASE_*` | ielts-ui, ielts-be | Shared Firebase project credentials |
|
|
| `STRAPI_URL` / `STRAPI_TOKEN` | encoach-landing-page | CMS connection |
|
|
| `STRIPE_KEY` / `STRIPE_SECRET` | ielts-ui, encoach-landing-page | Payment processing |
|
|
| `OPENAI_API_KEY` | ielts-be | AI grading and generation |
|
|
| `AWS_ACCESS_KEY_ID/SECRET` | ielts-be | AWS Polly TTS |
|