# happymite/testbuddy architecture

> Architecture diagram of the GitHub repository happymite/testbuddy, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-10). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/happymite/testbuddy
- Repository: https://github.com/happymite/testbuddy

## Overview

TestBuddy is a dual-portal examination platform with student and administrator access plus unauthenticated guest practice. The main workflow is to discover or create an exam, take it, submit answers for grading, and review results or performance; administration also covers users and subjects, while question media can use Cloudinary or Supabase Storage. The sampled routes, controller references and README support the main boundaries; several frontend API and backend subsystems are unsampled, so their internal call paths are not expanded.

Main entry points: [`backend/config/db.js`](https://github.com/happymite/testbuddy/blob/main/backend/config/db.js) (PostgreSQL), [`backend/routes/examRoutes.js`](https://github.com/happymite/testbuddy/blob/main/backend/routes/examRoutes.js) (Exam routes), [`backend/app.js`](https://github.com/happymite/testbuddy/blob/main/backend/app.js) (API routing), [`backend/services/questionImageService.js`](https://github.com/happymite/testbuddy/blob/main/backend/services/questionImageService.js) (Question media)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_portals["User portals"]
  node_student_portal["Student portal"]
  node_guest_exam["Guest practice<br/>[guestTakeExam.jsx]"]
  node_admin_portal["Admin console"]
  node_guest_storage["Guest session storage"]
end

subgraph group_assessment["Exam lifecycle"]
  node_exam_routes["Exam routes<br/>[examRoutes.js]"]
  node_exam_manage["Exam management<br/>[examController.js]"]
  node_question_manage["Question management"]
  node_attempts["Attempt handling"]
  node_guest_attempts["Guest attempts"]
  node_grading["Grading engine<br/>[gradingService.js]"]
  node_results["Results"]
end

subgraph group_insights["Results and insights"]
  node_performance["Performance analysis"]
  node_performance_service["Performance metrics"]
  node_student_insights["Student insights"]
  node_admin_insights["Admin insights"]
end

subgraph group_services["Identity and services"]
  node_student_auth["Student identity<br/>[AuthContext.jsx]"]
  node_admin_auth["Admin identity"]
  node_auth_api["Auth API"]
  node_api_server["API routing<br/>[app.js]"]
  node_auth_routes["Auth routes<br/>[authRoutes.js]"]
  node_auth_controller["Student auth<br/>[authController.js]"]
  node_google_auth["Google sign-in"]
  node_email["Verification email<br/>[emailService.js]"]
  node_admin_routes["Admin routes<br/>[adminRoutes.js]"]
  node_admin_controller["Admin operations<br/>[adminController.js]"]
  node_database[("PostgreSQL<br/>[db.js]")]
  node_image_service["Question media"]
end

node_student(("Student"))
node_guest(("Guest candidate"))
node_admin(("Administrator"))
node_cloudinary[("Cloudinary")]
node_supabase[("Supabase Storage")]

node_student -->|"uses"| node_student_portal
node_guest -->|"practices"| node_guest_exam
node_admin -->|"administers"| node_admin_portal
node_student_portal -->|"maintains session"| node_student_auth
node_admin_portal -->|"maintains session"| node_admin_auth
node_student_auth -->|"uses"| node_auth_api
node_admin_auth -->|"uses"| node_auth_api
node_auth_api -->|"HTTP requests"| node_api_server
node_api_server -->|"mounts"| node_auth_routes
node_api_server -->|"mounts"| node_exam_routes
node_api_server -->|"mounts"| node_admin_routes
node_auth_routes -->|"routes to"| node_auth_controller
node_auth_routes -->|"routes to"| node_google_auth
node_auth_controller -->|"reads and writes"| node_database
node_auth_controller -->|"sends verification"| node_email
node_google_auth -->|"provisions account"| node_database
node_admin_routes -->|"routes to"| node_admin_controller
node_admin_controller -->|"reads and writes"| node_database
node_exam_routes -->|"routes exam actions"| node_exam_manage
node_exam_routes -->|"routes student attempts"| node_attempts
node_exam_routes -->|"routes guest attempts"| node_guest_attempts
node_exam_routes -->|"routes result reads"| node_results
node_exam_manage -->|"reads and writes"| node_database
node_exam_manage -->|"removes media"| node_image_service
node_question_manage -->|"uses media service"| node_image_service
node_attempts -->|"grades attempts"| node_grading
node_guest_attempts -->|"grades attempts"| node_grading
node_results -->|"uses grading logic"| node_grading
node_grading -->|"updates scores"| node_database
node_performance -->|"delegates metrics"| node_performance_service
node_performance_service -->|"queries performance data"| node_database
node_student_insights -->|"requests analysis"| node_performance
node_admin_insights -->|"requests analysis"| node_performance
node_guest_exam -->|"stores session result"| node_guest_storage
node_image_service -->|"uploads and deletes"| node_cloudinary
node_image_service -->|"stores and signs URLs"| node_supabase

click node_student_portal "https://github.com/happymite/testbuddy/tree/main/frontend/src/pages"
click node_guest_exam "https://github.com/happymite/testbuddy/blob/main/frontend/src/pages/guestTakeExam.jsx"
click node_admin_portal "https://github.com/happymite/testbuddy/tree/main/frontend/src/pages/admin"
click node_student_auth "https://github.com/happymite/testbuddy/blob/main/frontend/src/context/AuthContext.jsx"
click node_admin_auth "https://github.com/happymite/testbuddy/blob/main/frontend/src/context/AdminAuthContext.jsx"
click node_auth_api "https://github.com/happymite/testbuddy/tree/main/frontend/src/api"
click node_api_server "https://github.com/happymite/testbuddy/blob/main/backend/app.js"
click node_auth_routes "https://github.com/happymite/testbuddy/blob/main/backend/routes/authRoutes.js"
click node_auth_controller "https://github.com/happymite/testbuddy/blob/main/backend/controllers/authController.js"
click node_google_auth "https://github.com/happymite/testbuddy/blob/main/backend/controllers/googleAuthController.js"
click node_email "https://github.com/happymite/testbuddy/blob/main/backend/services/emailService.js"
click node_admin_routes "https://github.com/happymite/testbuddy/blob/main/backend/routes/adminRoutes.js"
click node_admin_controller "https://github.com/happymite/testbuddy/blob/main/backend/controllers/adminController.js"
click node_exam_routes "https://github.com/happymite/testbuddy/blob/main/backend/routes/examRoutes.js"
click node_exam_manage "https://github.com/happymite/testbuddy/blob/main/backend/controllers/examController.js"
click node_question_manage "https://github.com/happymite/testbuddy/blob/main/backend/controllers/questionController.js"
click node_attempts "https://github.com/happymite/testbuddy/blob/main/backend/controllers/attemptController.js"
click node_guest_attempts "https://github.com/happymite/testbuddy/blob/main/backend/controllers/guestAttemptController.js"
click node_grading "https://github.com/happymite/testbuddy/blob/main/backend/services/gradingService.js"
click node_results "https://github.com/happymite/testbuddy/blob/main/backend/controllers/resultController.js"
click node_performance "https://github.com/happymite/testbuddy/blob/main/backend/controllers/performanceController.js"
click node_performance_service "https://github.com/happymite/testbuddy/blob/main/backend/services/performanceService.js"
click node_student_insights "https://github.com/happymite/testbuddy/blob/main/frontend/src/pages/performance/PerformanceAnalysis.jsx"
click node_admin_insights "https://github.com/happymite/testbuddy/blob/main/frontend/src/pages/admin/AdminPerformance.jsx"
click node_database "https://github.com/happymite/testbuddy/blob/main/backend/config/db.js"
click node_image_service "https://github.com/happymite/testbuddy/blob/main/backend/services/questionImageService.js"
click node_guest_storage "https://github.com/happymite/testbuddy/blob/main/frontend/src/utils/guestSessionStorage.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_student_portal,node_guest_exam,node_admin_portal,node_guest_storage toneBlue
class node_exam_routes,node_exam_manage,node_question_manage,node_attempts,node_guest_attempts,node_grading,node_results,node_cloudinary,node_supabase toneAmber
class node_performance,node_performance_service,node_student_insights,node_admin_insights toneMint
class node_student_auth,node_admin_auth,node_auth_api,node_api_server,node_auth_routes,node_auth_controller,node_google_auth,node_email,node_admin_routes,node_admin_controller,node_database,node_image_service toneRose
class node_student,node_guest,node_admin toneIndigo
```

## Components

### User portals

- [Student portal](https://github.com/happymite/testbuddy/tree/main/frontend/src/pages): `frontend/src/pages`
- [Guest practice](https://github.com/happymite/testbuddy/blob/main/frontend/src/pages/guestTakeExam.jsx): `frontend/src/pages/guestTakeExam.jsx`
- [Admin console](https://github.com/happymite/testbuddy/tree/main/frontend/src/pages/admin): `frontend/src/pages/admin`
- [Guest session storage](https://github.com/happymite/testbuddy/blob/main/frontend/src/utils/guestSessionStorage.js): `frontend/src/utils/guestSessionStorage.js`

### Exam lifecycle

- [Exam routes](https://github.com/happymite/testbuddy/blob/main/backend/routes/examRoutes.js): `backend/routes/examRoutes.js`
- [Exam management](https://github.com/happymite/testbuddy/blob/main/backend/controllers/examController.js): `backend/controllers/examController.js`
- [Question management](https://github.com/happymite/testbuddy/blob/main/backend/controllers/questionController.js): `backend/controllers/questionController.js`
- [Attempt handling](https://github.com/happymite/testbuddy/blob/main/backend/controllers/attemptController.js): `backend/controllers/attemptController.js`
- [Guest attempts](https://github.com/happymite/testbuddy/blob/main/backend/controllers/guestAttemptController.js): `backend/controllers/guestAttemptController.js`
- [Grading engine](https://github.com/happymite/testbuddy/blob/main/backend/services/gradingService.js): `backend/services/gradingService.js`
- [Results](https://github.com/happymite/testbuddy/blob/main/backend/controllers/resultController.js): `backend/controllers/resultController.js`

### Results and insights

- [Performance analysis](https://github.com/happymite/testbuddy/blob/main/backend/controllers/performanceController.js): `backend/controllers/performanceController.js`
- [Performance metrics](https://github.com/happymite/testbuddy/blob/main/backend/services/performanceService.js): `backend/services/performanceService.js`
- [Student insights](https://github.com/happymite/testbuddy/blob/main/frontend/src/pages/performance/PerformanceAnalysis.jsx): `frontend/src/pages/performance/PerformanceAnalysis.jsx`
- [Admin insights](https://github.com/happymite/testbuddy/blob/main/frontend/src/pages/admin/AdminPerformance.jsx): `frontend/src/pages/admin/AdminPerformance.jsx`

### Identity and services

- [Student identity](https://github.com/happymite/testbuddy/blob/main/frontend/src/context/AuthContext.jsx): `frontend/src/context/AuthContext.jsx`
- [Admin identity](https://github.com/happymite/testbuddy/blob/main/frontend/src/context/AdminAuthContext.jsx): `frontend/src/context/AdminAuthContext.jsx`
- [Auth API](https://github.com/happymite/testbuddy/tree/main/frontend/src/api): `frontend/src/api`
- [API routing](https://github.com/happymite/testbuddy/blob/main/backend/app.js): `backend/app.js`
- [Auth routes](https://github.com/happymite/testbuddy/blob/main/backend/routes/authRoutes.js): `backend/routes/authRoutes.js`
- [Student auth](https://github.com/happymite/testbuddy/blob/main/backend/controllers/authController.js): `backend/controllers/authController.js`
- [Google sign-in](https://github.com/happymite/testbuddy/blob/main/backend/controllers/googleAuthController.js): `backend/controllers/googleAuthController.js`
- [Verification email](https://github.com/happymite/testbuddy/blob/main/backend/services/emailService.js): `backend/services/emailService.js`
- [Admin routes](https://github.com/happymite/testbuddy/blob/main/backend/routes/adminRoutes.js): `backend/routes/adminRoutes.js`
- [Admin operations](https://github.com/happymite/testbuddy/blob/main/backend/controllers/adminController.js): `backend/controllers/adminController.js`
- [PostgreSQL](https://github.com/happymite/testbuddy/blob/main/backend/config/db.js): `backend/config/db.js`
- [Question media](https://github.com/happymite/testbuddy/blob/main/backend/services/questionImageService.js): `backend/services/questionImageService.js`

### Other components

- **Student**
- **Guest candidate**
- **Administrator**
- **Cloudinary**
- **Supabase Storage**

## Connections

- Student → Student portal: uses
- Guest candidate → Guest practice: practices
- Administrator → Admin console: administers
- Student portal → Student identity: maintains session (evidence: `frontend/src/context/AuthContext.jsx`)
- Admin console → Admin identity: maintains session (evidence: `frontend/src/context/AdminAuthContext.jsx`)
- Student identity → Auth API: uses (evidence: `frontend/src/context/AuthContext.jsx`)
- Admin identity → Auth API: uses (evidence: `frontend/src/context/AdminAuthContext.jsx`)
- Auth API → API routing: HTTP requests
- API routing → Auth routes: mounts (evidence: `backend/app.js`)
- API routing → Exam routes: mounts (evidence: `backend/app.js`)
- API routing → Admin routes: mounts (evidence: `backend/app.js`)
- Auth routes → Student auth: routes to (evidence: `backend/routes/authRoutes.js`)
- Auth routes → Google sign-in: routes to (evidence: `backend/routes/authRoutes.js`)
- Student auth → PostgreSQL: reads and writes (evidence: `backend/controllers/authController.js`)
- Student auth → Verification email: sends verification (evidence: `backend/controllers/authController.js`)
- Google sign-in → PostgreSQL: provisions account (evidence: `backend/controllers/googleAuthController.js`)
- Admin routes → Admin operations: routes to (evidence: `backend/routes/adminRoutes.js`)
- Admin operations → PostgreSQL: reads and writes (evidence: `backend/controllers/adminController.js`)
- Exam routes → Exam management: routes exam actions (evidence: `backend/routes/examRoutes.js`)
- Exam routes → Attempt handling: routes student attempts (evidence: `backend/routes/examRoutes.js`)
- Exam routes → Guest attempts: routes guest attempts (evidence: `backend/routes/examRoutes.js`)
- Exam routes → Results: routes result reads (evidence: `backend/routes/examRoutes.js`)
- Exam management → PostgreSQL: reads and writes (evidence: `backend/controllers/examController.js`)
- Exam management → Question media: removes media (evidence: `backend/controllers/examController.js`)
- Question management → Question media: uses media service (evidence: `backend/controllers/questionController.js`)
- Attempt handling → Grading engine: grades attempts (evidence: `backend/controllers/attemptController.js`)
- Guest attempts → Grading engine: grades attempts (evidence: `backend/controllers/guestAttemptController.js`)
- Results → Grading engine: uses grading logic (evidence: `backend/controllers/resultController.js`)
- Grading engine → PostgreSQL: updates scores (evidence: `backend/services/gradingService.js`)
- Performance analysis → Performance metrics: delegates metrics (evidence: `backend/controllers/performanceController.js`)
- Performance metrics → PostgreSQL: queries performance data (evidence: `backend/services/performanceService.js`)
- Student insights → Performance analysis: requests analysis
- Admin insights → Performance analysis: requests analysis
- Guest practice → Guest session storage: stores session result (evidence: `frontend/src/pages/guestTakeExam.jsx`)
- Question media → Cloudinary: uploads and deletes (evidence: `backend/services/questionImageService.js`)
- Question media → Supabase Storage: stores and signs URLs (evidence: `backend/services/questionImageService.js`)
