feat(v3): restructure project + add complete frontend
- Restructure: move backend from new_project/ to backend/ - Add full React/TypeScript frontend (37 pages, 17 services, 16 type defs, 11 query hooks) - Add docs/ with SRS specs, user stories, and workflow documentation - Update .gitignore for new directory layout Workflows implemented: WF1 User Signup, WF2 Placement Test, WF3 Exam Configuration, WF4 General English Exam, WF5 Course Generation, WF6 Entity Student Onboarding, AI Course Generation, Adaptive Learning Engine UI, White-Label Branding, Score Release Made-with: Cursor
This commit is contained in:
344
frontend/docs/ARCHITECTURE.md
Normal file
344
frontend/docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,344 @@
|
||||
# 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 |
|
||||
Reference in New Issue
Block a user