Skip to content

Bilal-Lodhi/testgorilla-clone

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

176 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

TestGorilla - Online Testing & Assessment Platform

A production-ready, full-stack assessment platform built with Express.js + PostgreSQL (backend) and Flutter (mobile & web frontend). Designed for recruiters and educators to create, publish, and manage online tests with real-time candidate feedback.


πŸ“‹ Table of Contents


πŸ“Œ Overview

TestGorilla is an enterprise-grade assessment platform that enables organizations to:

  • Create & Manage Tests: Build assessments with multiple question types (MCQ, coding, essays)
  • Live Testing: Candidates take tests in real-time with timer, anti-cheating detection, and response validation
  • Dual-Role Support: Admin panels for test creation/management, candidate interfaces for test taking
  • Real-time Results: Instant feedback for MCQ, manual review workflows for subjective questions
  • Cross-Platform: Works on iOS, Android, Web, and Desktop (built with Flutter)

Current Status: Production-ready backend with full Flutter frontend support


πŸ›  Tech Stack

Backend

Component Technology Version
Runtime Node.js 16+ LTS
Framework Express.js 4.22.1
Database PostgreSQL 12+
Authentication JWT (jsonwebtoken) 9.0.3
Security bcryptjs 2.4.3
CORS cors 2.8.6
Development Nodemon 3.1.14

Frontend

Component Technology Version
Framework Flutter 3.9.2+
UI Framework Material 3 Latest
State Management Provider 6.0.0
HTTP Client http 1.1.0
Storage shared_preferences 2.0.0
Audio audioplayers 5.2.1
Ringtone flutter_ringtone_player 4.0.0+4
Icons cupertino_icons 1.0.8

πŸ“ Project Structure

test-gorilla/
β”œβ”€β”€ backend/                          # Node.js/Express backend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ app.js                   # Express app setup & middleware
β”‚   β”‚   β”œβ”€β”€ server.js                # Entry point & server startup
β”‚   β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”‚   └── db.js                # PostgreSQL pool configuration
β”‚   β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.js              # Authentication endpoints
β”‚   β”‚   β”‚   β”œβ”€β”€ tests.js             # Test CRUD & management
β”‚   β”‚   β”‚   β”œβ”€β”€ questions.js         # Question management
β”‚   β”‚   β”‚   β”œβ”€β”€ attempts.js          # Test attempt & response tracking
β”‚   β”‚   β”‚   β”œβ”€β”€ results.js           # Test results & evaluation
β”‚   β”‚   β”‚   └── health.js            # Health check endpoint
β”‚   β”‚   β”œβ”€β”€ controllers/             # Business logic handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ authController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ testController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ questionController.js
β”‚   β”‚   β”‚   β”œβ”€β”€ attemptController.js
β”‚   β”‚   β”‚   └── resultController.js
β”‚   β”‚   β”œβ”€β”€ services/                # Database & business services
β”‚   β”‚   β”‚   β”œβ”€β”€ authService.js
β”‚   β”‚   β”‚   β”œβ”€β”€ testService.js
β”‚   β”‚   β”‚   β”œβ”€β”€ questionService.js
β”‚   β”‚   β”‚   β”œβ”€β”€ attemptService.js
β”‚   β”‚   β”‚   β”œβ”€β”€ evaluationService.js
β”‚   β”‚   β”‚   └── tokenService.js
β”‚   β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”‚   β”œβ”€β”€ authMiddleware.js    # JWT validation & role checks
β”‚   β”‚   β”‚   β”œβ”€β”€ attemptMiddleware.js # Attempt-specific checks
β”‚   β”‚   β”‚   β”œβ”€β”€ cors.js              # CORS configuration
β”‚   β”‚   β”‚   β”œβ”€β”€ errorHandler.js      # Global error handling
β”‚   β”‚   β”‚   └── requestLogger.js     # Request logging
β”‚   β”‚   └── utils/
β”‚   β”‚       β”œβ”€β”€ logger.js            # Structured logging
β”‚   β”‚       β”œβ”€β”€ jwt.js               # JWT utilities
β”‚   β”‚       └── constants.js         # App constants & enums
β”‚   β”œβ”€β”€ migrations/                  # Database migrations (SQL)
β”‚   β”‚   β”œβ”€β”€ 001_create_users_table.sql
β”‚   β”‚   β”œβ”€β”€ 002_create_tests_table.sql
β”‚   β”‚   β”œβ”€β”€ 003_create_questions.sql
β”‚   β”‚   β”œβ”€β”€ 004_create_attempts.sql
β”‚   β”‚   β”œβ”€β”€ 005_create_results.sql
β”‚   β”‚   β”œβ”€β”€ 006_add_manual_review_support.sql
β”‚   β”‚   └── 007_create_verification_tokens.sql
β”‚   β”œβ”€β”€ package.json                 # npm dependencies & scripts
β”‚   β”œβ”€β”€ .env.example                 # Environment variables template
β”‚   └── seed_users.js                # Database seeding script
β”‚
β”œβ”€β”€ frontend/                        # Flutter cross-platform app
β”‚   └── test_gorilla/
β”‚       β”œβ”€β”€ lib/
β”‚       β”‚   β”œβ”€β”€ main.dart            # App entry point & providers
β”‚       β”‚   β”œβ”€β”€ core/
β”‚       β”‚   β”‚   β”œβ”€β”€ api/
β”‚       β”‚   β”‚   β”‚   └── api_client.dart       # HTTP client & API wrapper
β”‚       β”‚   β”‚   β”œβ”€β”€ config/
β”‚       β”‚   β”‚   β”‚   └── app_config.dart       # App configuration
β”‚       β”‚   β”‚   β”œβ”€β”€ theme/
β”‚       β”‚   β”‚   β”‚   └── app_theme.dart        # Material 3 theme
β”‚       β”‚   β”‚   β”œβ”€β”€ utils/
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ jwt_storage.dart      # JWT token storage
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ tenseconds.mp3        # Timer audio
β”‚       β”‚   β”‚   β”‚   └── constants.dart
β”‚       β”‚   β”‚   └── services/
β”‚       β”‚   β”œβ”€β”€ features/
β”‚       β”‚   β”‚   β”œβ”€β”€ auth/
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ auth_provider.dart    # Auth state management
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ login_screen.dart
β”‚       β”‚   β”‚   β”‚   └── register_screen.dart
β”‚       β”‚   β”‚   β”œβ”€β”€ admin/
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ dashboard_screen.dart # Admin panel
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ test_creation/
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ test_management/
β”‚       β”‚   β”‚   β”‚   └── evaluation/           # Manual evaluation UI
β”‚       β”‚   β”‚   β”œβ”€β”€ candidate/
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ candidate_dashboard_shell.dart
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ available_tests_screen.dart
β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ test_taking/
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ test_screen.dart
β”‚       β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ timer_widget.dart
β”‚       β”‚   β”‚   β”‚   β”‚   └── question_widgets/
β”‚       β”‚   β”‚   β”‚   └── results_screen.dart
β”‚       β”‚   β”‚   β”œβ”€β”€ navigation/
β”‚       β”‚   β”‚   β”‚   └── app_router.dart       # Route management
β”‚       β”‚   β”‚   └── shared/
β”‚       β”‚   β”‚       β”œβ”€β”€ widgets/
β”‚       β”‚   β”‚       └── dialogs/
β”‚       β”‚   β”œβ”€β”€ test/
β”‚       β”‚   β”‚   └── widget_test.dart
β”‚       β”œβ”€β”€ android/                 # Android-specific config
β”‚       β”œβ”€β”€ ios/                     # iOS-specific config
β”‚       β”œβ”€β”€ web/                     # Web-specific config
β”‚       β”œβ”€β”€ pubspec.yaml             # Flutter dependencies
β”‚       └── analysis_options.yaml    # Lint rules
β”‚
└── README.md                        # This file

πŸ“¦ Prerequisites

Minimum Requirements

  • Node.js: v16 LTS or higher (download)
  • PostgreSQL: v12+ (download)
  • Flutter: 3.9.2+ (install)
  • Dart: 3.9.2+ (included with Flutter)
  • npm/yarn: v7+ (comes with Node.js)

Verify Installation

# Check Node.js version
node --version    # Should be v16+

# Check npm version
npm --version     # Should be v7+

# Check PostgreSQL
psql --version    # Should be 12+

# Check Flutter
flutter --version # Should be 3.9.2+

# Check Dart
dart --version    # Should be 3.9.2+

πŸš€ Installation & Setup

Backend Setup

1. Clone & Navigate to Backend

git clone <repository-url>
cd test-gorilla/backend

2. Install Dependencies

npm install

This installs all required packages:

  • express - Web framework
  • pg - PostgreSQL client
  • jsonwebtoken - JWT authentication
  • bcryptjs - Password hashing
  • cors - Cross-origin requests
  • dotenv - Environment variables
  • nodemon - Development hot reload

3. Configure Environment Variables

# Copy the example file
cp .env.example .env

# Edit .env with your settings (see Environment Variables section below)

Quick Start Config:

Security note: Never commit real credentials or secrets to GitHub. Keep actual values only in local .env files and use placeholders in documentation.

# .env
NODE_ENV=development
PORT=5000

# PostgreSQL
DB_HOST=<db-host>
DB_PORT=5432
DB_NAME=<db-name>
DB_USER=<your_db_user>
DB_PASSWORD=<your_db_password>
DB_SSL=false
DB_POOL_MIN=2
DB_POOL_MAX=10

# JWT
JWT_SECRET=<generate-a-long-random-secret>
JWT_EXPIRY=24h

# CORS
CORS_ORIGIN=<allowed-origin-url>

# Logging
LOG_LEVEL=debug

4. Create PostgreSQL Database

# Open PostgreSQL terminal
psql -U postgres

# Inside psql:
CREATE DATABASE testgorilla;
\q

Or use a single command:

createdb -U postgres testgorilla

5. Run Database Migrations

Migrations create the necessary tables and schema:

# Manually run migrations (in order)
psql -U postgres -d testgorilla -f migrations/001_create_users_table.sql
psql -U postgres -d testgorilla -f migrations/002_create_tests_table.sql
psql -U postgres -d testgorilla -f migrations/003_create_questions.sql
psql -U postgres -d testgorilla -f migrations/004_create_attempts.sql
psql -U postgres -d testgorilla -f migrations/005_create_results.sql
psql -U postgres -d testgorilla -f migrations/006_add_manual_review_support.sql
psql -U postgres -d testgorilla -f migrations/007_create_verification_tokens.sql

Or create a migration script and automate this process.

6. (Optional) Seed Test Data

# Add sample users for development
node seed_users.js

7. Start the Backend Server

Development (with hot reload):

npm run dev

Server will be available at: http://localhost:5000

Production:

npm start

Expected Output:

Server started successfully
  environment: development
  port: 5000
  url: http://localhost:5000

Frontend Setup

1. Navigate to Frontend

cd test-gorilla/frontend/test_gorilla

2. Get Flutter Dependencies

flutter pub get

This installs all packages from pubspec.yaml.

3. Configure API Connection

Edit the API base URL in your app configuration:

File: lib/core/config/app_config.dart

class AppConfig {
  // Development
  static const String DEV_API_BASE_URL = 'http://localhost:5000/api/v1';
  
  // Production
  static const String PROD_API_BASE_URL = 'https://api.testgorilla.com/api/v1';
  
  // Use based on environment
  static const String API_BASE_URL = DEV_API_BASE_URL;
}

For Android Emulator:

  • Use http://10.0.2.2:5000/api/v1 (special IP for emulator to reach host)

For iOS Simulator:

  • Use http://localhost:5000/api/v1 or use ngrok for tunneling

For Web:

  • Use http://localhost:5000/api/v1

4. Run on Different Platforms

Run on Android Emulator:

flutter emulators --launch emulator-5554  # Launch emulator first
flutter run -d emulator-5554

Run on iOS Simulator:

flutter run -d iPhone

Run on Web Browser:

flutter run -d chrome

Or for a specific browser:

flutter run -d edge
flutter run -d firefox

Run on Physical Device:

# List connected devices
flutter devices

# Run on specific device
flutter run -d <device-id>

5. Build for Release

Android APK:

flutter build apk --release
# Output: build/app/outputs/flutter-apk/app-release.apk

iOS IPA:

flutter build ios --release
# Output: build/ios/ipa/

Web Release:

flutter build web --release
# Output: build/web/

πŸ”Œ API Documentation

Base URL

http://localhost:5000/api/v1

Authentication Endpoints

All endpoints except /auth/register and /auth/login require JWT token in header.

Register User

POST /auth/register
Content-Type: application/json

{
  "name": "John Doe",
  "email": "john@example.com",
  "password": "SecurePassword123",
  "role": "candidate"  // or "admin"
}

Response:

{
  "success": true,
  "message": "User registered successfully",
  "user": {
    "id": "uuid-123",
    "name": "John Doe",
    "email": "john@example.com",
    "role": "candidate"
  },
  "accessToken": "eyJhbGc...",
  "refreshToken": "eyJhbGc..."
}

Login User

POST /auth/login
Content-Type: application/json

{
  "email": "john@example.com",
  "password": "SecurePassword123"
}

Response:

{
  "success": true,
  "message": "Login successful",
  "user": {
    "id": "uuid-123",
    "name": "John Doe",
    "email": "john@example.com",
    "role": "candidate"
  },
  "accessToken": "eyJhbGc...",
  "refreshToken": "eyJhbGc..."
}

Get Current User

GET /auth/me
Authorization: Bearer <accessToken>

Response:

{
  "success": true,
  "user": {
    "id": "uuid-123",
    "name": "John Doe",
    "email": "john@example.com",
    "role": "candidate",
    "createdAt": "2024-04-20T10:30:00Z"
  }
}

Test Management Endpoints

Create Test (Admin Only)

POST /tests
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "title": "JavaScript Assessment",
  "description": "Test your JavaScript skills",
  "duration_minutes": 60,
  "pass_percentage": 75
}

Get All Tests

GET /tests
Authorization: Bearer <token>

Admin sees: their own created tests Candidate sees: published tests only

Get Test by ID

GET /tests/{testId}
Authorization: Bearer <token>

Update Test (Admin Only)

PUT /tests/{testId}
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "title": "Updated Title",
  "description": "Updated description",
  "duration_minutes": 90
}

Publish Test (Admin Only)

PATCH /tests/{testId}/publish
Authorization: Bearer <adminToken>

Archive Test (Admin Only)

PATCH /tests/{testId}/archive
Authorization: Bearer <adminToken>

Delete Test (Admin Only)

DELETE /tests/{testId}
Authorization: Bearer <adminToken>

Question Management Endpoints

Create Question (Admin Only)

POST /tests/{testId}/questions
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "question_text": "What is the output of this code?",
  "question_type": "mcq",  // mcq, coding, or essay
  "options": [
    { "text": "Option A", "is_correct": true },
    { "text": "Option B", "is_correct": false },
    { "text": "Option C", "is_correct": false }
  ],
  "order_index": 1
}

Get Questions in Test

GET /tests/{testId}/questions
Authorization: Bearer <token>

Update Question (Admin Only)

PUT /tests/{testId}/questions/{questionId}
Authorization: Bearer <adminToken>
Content-Type: application/json

Delete Question (Admin Only)

DELETE /tests/{testId}/questions/{questionId}
Authorization: Bearer <adminToken>

Test Attempt Endpoints

Start Test Attempt (Candidate Only)

POST /tests/{testId}/attempts
Authorization: Bearer <candidateToken>
Content-Type: application/json

{
  "candidate_id": "uuid-456"
}

Response:

{
  "success": true,
  "attempt": {
    "id": "attempt-uuid",
    "test_id": "test-uuid",
    "candidate_id": "candidate-uuid",
    "status": "in_progress",
    "started_at": "2024-04-20T10:30:00Z",
    "time_limit_seconds": 3600,
    "questions": [
      {
        "id": "q-1",
        "text": "Question text...",
        "type": "mcq",
        "options": [...]
      }
    ]
  }
}

Get Attempt Details

GET /attempts/{attemptId}
Authorization: Bearer <token>

Submit Answer to Question

POST /attempts/{attemptId}/responses
Authorization: Bearer <candidateToken>
Content-Type: application/json

{
  "question_id": "q-1",
  "selected_option_id": "option-a",  // For MCQ
  "answer_text": "...",              // For essay
  "code_answer": "..."               // For coding
}

Submit Entire Attempt

POST /attempts/{attemptId}/submit
Authorization: Bearer <candidateToken>

Response:

{
  "success": true,
  "message": "Test submitted successfully",
  "result": {
    "id": "result-uuid",
    "attempt_id": "attempt-uuid",
    "total_questions": 10,
    "correct_answers": 8,
    "score": 80,
    "passing_score": 75,
    "status": "passed"  // or "pending_review" if has essays/coding
  }
}

Results & Evaluation Endpoints

Get Test Results

GET /results?test_id={testId}
Authorization: Bearer <adminToken>

Get Candidate Results

GET /candidates/{candidateId}/results
Authorization: Bearer <token>

Get Pending Evaluations (Admin Only)

GET /attempts/pending-evaluations
Authorization: Bearer <adminToken>

Returns all pending essays and coding question evaluations.

Submit Evaluation (Admin Only)

POST /attempts/{attemptId}/evaluate
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "question_id": "q-1",
  "marks_obtained": 8,
  "marks_total": 10,
  "feedback": "Good solution with proper error handling"
}

Health Check Endpoint

GET /health

Response:

{
  "success": true,
  "status": "API and database are operational",
  "database": "connected",
  "timestamp": "2024-04-20T10:30:00Z"
}

✨ Features

Admin Features

  • βœ… Test Management

    • Create, edit, publish, archive tests
    • Set duration, passing criteria
    • Manage test visibility
  • βœ… Question Management

    • Add MCQ, Coding, Essay questions
    • Set correct answers for MCQ
    • Define evaluation rubrics
  • βœ… Candidate Management

    • View all test takers
    • Track candidate progress
    • Download results in CSV/PDF
  • βœ… Evaluation & Scoring

    • Auto-score MCQ questions
    • Manual review interface for essays/coding
    • Provide feedback to candidates
  • βœ… Analytics Dashboard

    • Pass/fail statistics
    • Time analysis
    • Performance trends

Candidate Features

  • βœ… Test Discovery

    • Browse available tests
    • View test details (duration, questions count)
    • Check previous attempts
  • βœ… Test Taking Experience

    • Real-time timer with audio alerts
    • Question navigation (previous/next)
    • Progress indicator
    • MCQ response selection
    • Essay/Coding text input
  • βœ… Anti-Cheating Measures

    • Tab switch detection
    • Full-screen enforcement
    • Window blur detection
    • Suspicious activity logging
  • βœ… Immediate Feedback

    • Instant MCQ results
    • Overall score display
    • Detailed question review
  • βœ… Results History

    • View all attempt history
    • Compare scores
    • Download certificates (if passed)

πŸ— Architecture & Design

Authentication Flow (JWT)

1. User Registration/Login
   └─> POST /auth/register or /auth/login
       └─> Generate JWT tokens (Access + Refresh)
           └─> Return tokens to client

2. Authenticated Requests
   └─> Client includes: Authorization: Bearer {accessToken}
       └─> Middleware validates JWT signature
           └─> Extract user ID & role
               └─> Proceed with request or reject

3. Token Refresh (Future Implementation)
   └─> Access Token expires β†’ Use Refresh Token
       └─> GET /auth/refresh
           └─> Issue new Access Token pair

JWT Payload:

{
  "id": "user-uuid",
  "email": "user@example.com",
  "role": "admin|candidate|recruiter",
  "iat": 1713607800,
  "exp": 1713694200
}

Role-Based Access Control (RBAC)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   User      β”‚
β”‚  (Role)     β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β”œβ”€β†’ [ADMIN]
       β”‚   β”œβ”€ Create/Edit Tests
       β”‚   β”œβ”€ Manage Questions
       β”‚   β”œβ”€ View All Results
       β”‚   β”œβ”€ Evaluate Essays/Coding
       β”‚   └─ Access Analytics
       β”‚
       β”œβ”€β†’ [CANDIDATE]
       β”‚   β”œβ”€ View Published Tests
       β”‚   β”œβ”€ Take Tests
       β”‚   β”œβ”€ View Own Results
       β”‚   └─ View Own Attempts
       β”‚
       └─→ [RECRUITER]
           β”œβ”€ Create Tests
           β”œβ”€ View Results (own tests)
           └─ Evaluate Submissions

Database Schema Overview

Users Table:

  • id (UUID Primary Key)
  • name, email, password_hash
  • role (admin/candidate/recruiter)
  • created_at, updated_at

Tests Table:

  • id, title, description
  • duration_minutes, pass_percentage
  • created_by (Reference to Users)
  • status (draft/published/archived)
  • created_at, updated_at

Questions Table:

  • id, test_id, question_text, question_type
  • options (JSON array for MCQ)
  • correct_answer (for MCQ/coding)
  • order_index, marks

Attempts Table:

  • id, test_id, candidate_id
  • status (in_progress/submitted/evaluated)
  • started_at, submitted_at
  • time_spent_seconds

Results Table:

  • id, attempt_id, score, status
  • total_questions, correct_answers
  • evaluated_at, created_at

API Request/Response Pattern

Standard Success Response:

{
  "success": true,
  "message": "Operation successful",
  "data": { ... },
  "timestamp": "2024-04-20T10:30:00Z"
}

Standard Error Response:

{
  "success": false,
  "error": "Error message",
  "code": "ERROR_CODE",
  "details": { ... },
  "timestamp": "2024-04-20T10:30:00Z"
}

πŸ‘¨β€πŸ’» Development Guide

Backend Development

Running Tests

npm test

Code Structure

  • Controllers: Handle HTTP request/response
  • Services: Core business logic & database queries
  • Middleware: Request interceptors (auth, logging, error)
  • Routes: Endpoint definitions & routing
  • Utils: Helpers (JWT, logger, constants)

Adding a New Endpoint

  1. Define route in routes/ folder
  2. Create controller method in controllers/ folder
  3. Add business logic in services/ folder
  4. Register route in app.js
  5. Add middleware (auth, validation)

Database Queries

// Using connection pool from config/db.js
const db = require('../config/db');

// Query with parameters (prevent SQL injection)
const result = await db.query(
  'SELECT * FROM users WHERE email = $1',
  [email]
);

// Insert
await db.query(
  'INSERT INTO users (name, email) VALUES ($1, $2)',
  [name, email]
);

Frontend Development

Running App in Debug Mode

flutter run -v  # Verbose output

State Management (Provider)

// Define provider
class TestProvider with ChangeNotifier {
  List<Test> _tests = [];
  
  Future<void> fetchTests() async {
    _tests = await apiClient.getTests();
    notifyListeners();
  }
}

// Use in widget
Consumer<TestProvider>(
  builder: (context, testProvider, child) {
    return ListView(
      children: testProvider.tests.map((test) => ...).toList(),
    );
  },
)

API Client Usage

// lib/core/api/api_client.dart
final apiClient = ApiClient();

// GET request
final tests = await apiClient.get('/tests');

// POST request
final result = await apiClient.post('/tests', {
  'title': 'New Test',
  'duration_minutes': 60
});

Local Storage (JWT Tokens)

// Save token
await JwtStorage.saveToken(token);

// Retrieve token
final token = await JwtStorage.getToken();

// Remove token (logout)
await JwtStorage.deleteToken();

πŸ” Environment Variables

Backend (.env)

# Server
NODE_ENV=development|production
PORT=5000

# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=testgorilla
DB_USER=<your_db_user>
DB_PASSWORD=<secure-password>
DB_POOL_MIN=2
DB_POOL_MAX=10

# JWT Authentication
JWT_SECRET=<generate-a-long-random-secret-min-32-chars>
JWT_EXPIRY=24h
REFRESH_TOKEN_EXPIRY=7d
BCRYPT_SALT_ROUNDS=10

# CORS
CORS_ORIGIN=<allowed-origin-1>,<allowed-origin-2>

# Logging
LOG_LEVEL=debug|info|warn|error

Frontend (lib/core/config/app_config.dart)

class AppConfig {
  // API Configuration
  static const String DEV_API_BASE_URL = 'http://localhost:5000/api/v1';
  static const String PROD_API_BASE_URL = 'https://api.testgorilla.com/api/v1';
  static const String API_BASE_URL = DEV_API_BASE_URL;
  
  // JWT Storage Keys
  static const String JWT_TOKEN_KEY = 'auth_token';
  static const String REFRESH_TOKEN_KEY = 'refresh_token';
}

πŸ› Troubleshooting

Backend Issues

Port Already in Use

# Kill process on port 5000
lsof -ti:5000 | xargs kill -9  # macOS/Linux
netstat -ano | findstr :5000   # Windows

Database Connection Failed

# Verify PostgreSQL is running
psql -U postgres -c "SELECT version();"

# Check .env variables
cat .env | grep DB_

# Reset database
dropdb testgorilla
createdb testgorilla
# Re-run migrations

JWT Token Invalid

  • Ensure JWT_SECRET is set in .env
  • Check token expiry: JWT_EXPIRY=24h
  • Clear browser localStorage and re-login

CORS Errors

Update CORS_ORIGIN in .env:

# Allow multiple origins
CORS_ORIGIN=http://localhost:3000,http://localhost:8080,https://example.com

Frontend Issues

Android Emulator Cannot Reach Backend

Use the special IP for emulator:

static const String DEV_API_BASE_URL = 'http://10.0.2.2:5000/api/v1';

Build Fails - Dependency Issues

flutter clean
flutter pub get
flutter pub upgrade

iOS Pod Installation Fails

cd ios
pod deintegrate
pod install
cd ..
flutter run

HTTP Certificate Validation Error

Update API client to allow self-signed certificates (dev only):

HttpClient httpClient = new HttpClient()
  ..badCertificateCallback = ((certificate, host, port) => true);

πŸ“„ License

MIT License - See LICENSE file for details.


πŸ‘₯ Support & Contribution

For issues, feature requests, or contributions:

  1. Check existing issues
  2. Create detailed bug reports
  3. Submit pull requests with clear descriptions
  4. Follow existing code style and patterns

πŸ“ž Contact

For questions or support, reach out to the development team or check the project wiki for additional documentation.


Last Updated: April 2024
Version: 1.0.0
Status: Production Ready

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors