# Pathshalaa API

A Laravel 11 REST API powering the Pathshalaa educational platform — test series, group/batch management, AI question generation, multi-language support, analytics, and subscriptions.

---

## Requirements

- PHP >= 8.2
- Composer
- MySQL 8.x
- Node.js >= 18

---

## Installation

```bash
git clone <repo-url>
cd pathshalaa_api
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate
```

---

## Environment Variables

Key `.env` variables required:

```env
APP_ENV=production
APP_DEBUG=false
APP_URL=https://your-domain.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=pathshalaa
DB_USERNAME=
DB_PASSWORD=

JWT_SECRET=
QUEUE_CONNECTION=database

# Mail
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=
MAIL_FROM_NAME="Pathshalaa"

# Firebase (push notifications)
FIREBASE_CREDENTIALS=storage/app/firebase/service-account.json

# OpenAI (AI question generation)
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4o-mini
OPENAI_MAX_RETRIES=3
OPENAI_RETRY_DELAY=2
OPENAI_TIMEOUT=60
OPENAI_MAX_TOKENS=2000
OPENAI_TEMPERATURE=0.7

# Razorpay
RAZORPAY_KEY=
RAZORPAY_SECRET=
RAZORPAY_WEBHOOK_SECRET=

# Vimeo
VIMEO_CLIENT_ID=
VIMEO_CLIENT_SECRET=
VIMEO_ACCESS_TOKEN=

# Swagger
L5_SWAGGER_GENERATE_ALWAYS=true

# Google Translate retry settings
GOOGLE_TRANSLATE_MAX_RETRIES=3
GOOGLE_TRANSLATE_RETRY_DELAY=2

# Testing — whitelisted numbers that accept a fixed OTP (comma-separated, leave empty in production)
TEST_MOBILE_NUMBERS=
TEST_OTP=123456
```

---

## Deployment

Run these steps in order after pulling new code:

```bash
git pull origin stag
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:clear && php artisan cache:clear && php artisan route:clear && php artisan view:clear
php artisan config:cache && php artisan route:cache && php artisan view:cache
php artisan queue:restart
```

> Never apply raw SQL directly to the database — always create a migration file.

---

## Queue Worker

Required for notifications and AI question generation:

```bash
# Development
php artisan queue:work --queue=default --tries=3

# Production (via Supervisor)
sudo supervisorctl start pathshalaa-worker:*
```

---

## Cron

```cron
* * * * * php /path/to/project/artisan schedule:run >> /dev/null 2>&1
```

---

## Swagger API Docs

```bash
php artisan l5-swagger:generate
```

Available at: `/api/documentation`

---

## Branches

| Branch | Purpose |
|--------|---------|
| `stag` | Staging — mirrors production |
| `stag.beta` | Active development — merged into `stag` after review |

```bash
# Merge stag.beta into stag
git checkout stag && git pull origin stag
git merge stag.beta
git push origin stag
```

---

## Authentication

- **Method:** Laravel Sanctum (Bearer Token)
- **Header:** `Authorization: Bearer {token}`
- **Roles:** Admin (`role_id=1`), Student (`role_id=2`), Tutor (`role_id=3`), School (`role_id=5`)

---

## API Endpoint Groups

### Authentication
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/user/send-otp` | Send OTP to student mobile |
| POST | `/api/user/verify-otp` | Verify OTP and get token |
| POST | `/api/user/google-login` | Google OAuth login |
| POST | `/api/tutor/login` | Tutor login (email/password) |
| POST | `/api/tutor/send-otp` | Send OTP to tutor mobile |
| POST | `/api/tutor/verify-otp` | Verify tutor OTP |
| POST | `/api/v2/tutor/login` | V2 tutor login (email_password / email_otp / mobile_otp) |
| POST | `/api/v2/tutor/send-otp` | V2 send OTP |
| POST | `/api/v2/tutor/verify-otp` | V2 verify OTP |
| POST | `/api/v2/school/login` | School login |

---

### Group / Batch Management
**Base:** `/api/v2/tutor/groups` — auth required

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/groups` | List batches (paginated, with student/test counts) |
| POST | `/groups` | Create group |
| GET | `/groups/{id}` | Get group details + activity logs |
| PUT | `/groups/{id}` | Update group |
| DELETE | `/groups/{id}` | Delete (blocked if students/tests exist) |
| GET | `/groups/{id}/activity` | View activity log |
| GET | `/groups/{id}/enrollment-status` | Check enrollment code status |
| POST | `/groups/{id}/regenerate-code` | Regenerate enrollment code |

**Notes:**
- Enrollment codes are 10-char alphanumeric, expire in 7 days
- All CRUD is logged to `group_activity_log`
- Authorization: school-based (`school_id` match) or freelance (`group_users` membership)

---

### Test Series Management
**Base:** `/api/v2/tutor/test-series` — auth required

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/test-series` | List all test series |
| POST | `/test-series` | Create |
| GET | `/test-series/{id}` | Get details |
| PUT | `/test-series/{id}` | Update |
| DELETE | `/test-series/{id}` | Delete |
| GET | `/test-series/scheduled` | Get scheduled tests |
| POST | `/test-series/{id}/schedule` | Schedule a test |
| PUT | `/test-series/{id}/schedule` | Update schedule |
| POST | `/test-series/{id}/cancel` | Cancel test |
| POST | `/test-series/{id}/assign-to-groups` | Assign to batches (with variant distribution) |
| GET | `/test-series/{id}/groups` | Get assigned groups |
| POST | `/test-series/{id}/export-docx` | Export to DOCX |
| POST | `/test-series/{id}/export-answer-key` | Export answer key |
| GET | `/test-series/{id}/preview` | Preview questions |

**Test Variants (A/B/C):**
- Parent test: `parent_test_id = null`
- Variants: `parent_test_id = {parent_id}`, `set_variant = A/B/C`
- Auto round-robin distribution across groups to prevent cheating

**Automatic Notifications (on schedule):**
1. Immediate — test scheduled
2. 24-hour reminder
3. 1-hour reminder
4. Test is live

---

### Question Bank
**Base:** `/api/v2/tutor/questions` — auth required

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/question-bank/hierarchy` | Class → Subject → Topic tree (cached 1hr) |
| POST | `/question-bank/clear-cache` | Clear hierarchy cache |
| GET | `/questions` | List with pagination |
| GET | `/questions/search` | Search by keyword |
| GET | `/questions/{id}` | Single question |
| PUT | `/questions/{id}` | Update |
| DELETE | `/questions/{id}` | Soft delete |
| POST | `/questions/{id}/restore` | Restore deleted question |
| GET | `/questions/{id}/history` | Audit trail |

**Notes:** CKEditor HTML and LaTeX preserved. Soft deletes with full restoration.

---

### AI Question Generation
**Base:** `/api/v2/teacher/ai` — auth required

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/generate-batch` | Start async batch generation |
| GET | `/batch/{jobId}` | Poll job status + progress |
| GET | `/batches` | List all generation jobs |
| POST | `/generate` | Single question generation |

**Notes:**
- 1 coin per question, refunded on failure
- Quality validation: structure, content, LaTeX, duplicate detection (>80% Levenshtein similarity)
- 3 auto-retries on failure
- Async via Laravel Queue (database driver)

---

### Syllabus Planner
**Base:** `/api/v2/tutor/syllabus` — auth required

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/syllabus` | Create with auto topic distribution |
| GET | `/syllabus` | List (paginated) |
| GET | `/syllabus/{id}` | Get with all topics |
| PUT | `/syllabus/{id}` | Update (recalculates if dates change) |
| DELETE | `/syllabus/{id}` | Soft delete |
| GET | `/syllabus/{id}/weekly?week=3` | Topics for specific week |
| GET | `/syllabus/{id}/weeks-overview` | All weeks summary |
| GET | `/syllabus/{id}/progress` | Completion %, timeline, overdue topics |
| GET | `/syllabus/{id}/dashboard` | Full dashboard |
| POST | `/syllabus-topics/{id}/complete` | Mark topic complete |
| POST | `/syllabus-topics/{id}/incomplete` | Unmark |
| POST | `/syllabus-topics/bulk-complete` | Bulk mark complete |
| POST | `/syllabus/{id}/generate-weekly-test` | Auto-generate test from completed topics |

---

### Language Translation
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/v2/test/{id}/languages` | Available languages with coverage % |
| POST | `/v2/student/test/{id}/start` | Start test with language selection |
| GET | `/v2/student/test/{id}/questions?language=hi` | Questions in selected language |
| POST | `/v2/test-series/{id}/translate-batch` | Start batch translation job |
| GET | `/v2/translation-jobs/{id}` | Job progress |
| DELETE | `/v2/translation-jobs/{id}` | Cancel job |
| GET | `/v2/translations/dashboard` | Coverage dashboard |
| GET | `/v2/translations/missing?language=hi` | Missing translations |
| POST | `/v2/translations/quality-check` | Quality validation |

**Supported languages:** English, Hindi, Marathi, Tamil, Telugu, Gujarati, Bengali
**Fallback:** Auto-fallback to English if translation missing

---

### Results & Analytics
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/v2/tutor/analytics/batch/{batchId}/test/{testId}` | Score distribution, topic performance, time analysis (cached 1hr) |
| GET | `/v2/tutor/leaderboard/test/{testId}` | Global leaderboard (top 50, cached 30min) |
| GET | `/v2/tutor/leaderboard/batch/{batchId}/test/{testId}` | Batch leaderboard |
| GET | `/v2/tutor/trends/student/{studentId}` | Student trends, consistency score, improvement rate |
| POST | `/v2/tutor/results/export-excel` | Export to Excel |
| GET | `/v2/tutor/results/test/{testId}` | Get test results |

---

### Student Enrollment
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/v2/student/enroll` | Enroll using enrollment code |
| GET | `/v2/school-students` | List students in tutor's batches |
| POST | `/v2/pending-enrollment/store` | Store pending enrollment (for deep links) |

**Deep link:** `pathshalaa://enroll/{code}` — pending enrollment stored 24hrs before expiry

---

### Subscriptions & Payments
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/v2/plans` | Get available subscription plans |
| POST | `/v2/subscriptions/purchase` | Create Razorpay order |
| POST | `/v2/subscriptions/verify` | Verify payment and activate |
| GET | `/v2/subscriptions/my-subscriptions` | User's active subscriptions |

**Plans:** Monthly ₹299 (50 coins) · 6-Month ₹1499 (300 coins) · Yearly ₹2499 (600 coins)

---

## Standard Response Format

```json
{
  "status": true,
  "message": "Success",
  "data": { },
  "pagination": { }
}
```

**HTTP Status Codes:**
| Code | Meaning |
|------|---------|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request |
| 401 | Unauthenticated |
| 402 | Insufficient coins |
| 403 | Forbidden |
| 404 | Not Found |
| 422 | Validation Error |
| 500 | Internal Server Error |

---

## Key Database Tables

| Table | Purpose |
|-------|---------|
| `users` | All users (students, tutors, schools, admins) |
| `groups` | Batches — `name, school_id, enrollment_code, expires_at` |
| `group_users` | Enrollments — `type` (1=teacher, 2=student), `status` |
| `group_test_series` | Test assignment to groups — `variant_assigned` |
| `group_activity_log` | Full audit trail for group operations |
| `testseries` | Tests — `parent_test_id, set_variant, scheduled_at, auto_publish_results` |
| `partner_reg_otp` | OTP records with expiry |
| `question_translations` | Translated questions — `language_code, translation_method` |
| `syllabi` | Syllabus plans — `total_weeks, completion_percentage` |
| `syllabus_topics` | Per-topic schedule — `week_number, is_completed` |
| `ai_question_batches` | AI generation jobs — `status, coins_deducted, questions_generated` |
| `scheduled_notifications` | Queued test notifications — `notification_type, is_sent` |
| `enroll_testseries` | Student test enrollments |
| `pending_enrollments` | Deep-link enrollment queue |
| `coin_transactions` | Coin debit/credit history |
| `firm_detail` | Platform settings (master OTP, limits) |

> **Foreign keys** are currently disabled pending data validation. Run `php artisan groups:validate-relationships` before enabling.

---

## Required Packages

```bash
composer require barryvdh/laravel-dompdf
composer require barryvdh/laravel-snappy
composer require mpdf/mpdf
composer require kreait/firebase-php
composer require darkaonline/l5-swagger
composer require phpoffice/phpword
```

---

## Development Guidelines

- All schema changes **must** be Laravel migration files — never raw SQL on staging/production.
- Use `Schema::hasColumn()` / `Schema::hasTable()` guards in migrations for idempotency.
- Follow PSR-12 coding standards.
- `TEST_MOBILE_NUMBERS` and `TEST_OTP` in `.env` control test bypasses — **leave empty in production**.
- Master OTP (`/api/user/master/otp/*`) requires Sanctum auth token.
