- Move backoffice functionality into settings page as new tab - Remove standalone backoffice page and sidebar link - Add edit/delete buttons for credentials management - Update credentials service to allow overwriting existing credentials - Add API documentation for system credentials endpoints
574 lines
13 KiB
Markdown
574 lines
13 KiB
Markdown
# 📡 GoHorse Jobs - API Documentation
|
|
|
|
Complete API reference with routes, permissions, and modules.
|
|
|
|
> **Last Updated:** 2026-02-16
|
|
> **Base URL:** `https://api.gohorsejobs.com/api/v1`
|
|
> **Auth:** JWT Bearer Token or HttpOnly Cookie
|
|
|
|
---
|
|
|
|
## 🔐 Authentication
|
|
|
|
### Methods
|
|
1. **Authorization Header:** `Authorization: Bearer <token>`
|
|
2. **Cookie:** `jwt=<token>` (HttpOnly, Secure)
|
|
|
|
### Roles
|
|
| Role | Code | Level | Description |
|
|
|------|------|-------|-------------|
|
|
| **SuperAdmin** | `superadmin` | 0 | Platform administrator |
|
|
| **Admin** | `admin` | 1 | Company administrator |
|
|
| **Recruiter** | `recruiter` | 2 | Job poster |
|
|
| **Candidate** | `candidate` | 3 | Candidate |
|
|
| **Guest** | - | - | No authentication |
|
|
|
|
---
|
|
|
|
## 📋 Module: Authentication
|
|
|
|
### Login
|
|
```http
|
|
POST /api/v1/auth/login
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | Guest | Authenticate user |
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"identifier": "lol",
|
|
"password": "Admin@2025!"
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"token": "eyJhbGciOiJI...",
|
|
"user": { "id": 1, "role": "superadmin", "name": "Dr. Horse Expert" }
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Register Candidate
|
|
```http
|
|
POST /api/v1/auth/register
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | Guest | Register new job seeker |
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"name": "John Doe",
|
|
"email": "john@example.com",
|
|
"password": "SecurePass123!"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🏢 Module: Companies
|
|
|
|
### Create Company
|
|
```http
|
|
POST /api/v1/companies
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | Guest | Register new company |
|
|
|
|
### List Companies
|
|
```http
|
|
GET /api/v1/companies
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Smart | ⚪ Optional | Guest/Admin | Public list or admin full list |
|
|
|
|
### Update Company Status
|
|
```http
|
|
PATCH /api/v1/companies/{id}/status
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | Activate/deactivate company |
|
|
|
|
---
|
|
|
|
## 👥 Module: Users
|
|
|
|
### Get Current User
|
|
```http
|
|
GET /api/v1/users/me
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | Any authenticated | Get current user profile |
|
|
|
|
### List Users
|
|
```http
|
|
GET /api/v1/users
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | List all users |
|
|
|
|
### Create User
|
|
```http
|
|
POST /api/v1/users
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | Create new user |
|
|
|
|
### Update User
|
|
```http
|
|
PATCH /api/v1/users/{id}
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | Any authenticated | Update user profile |
|
|
|
|
### Delete User
|
|
```http
|
|
DELETE /api/v1/users/{id}
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin | Delete user |
|
|
|
|
### List User Roles
|
|
```http
|
|
GET /api/v1/users/roles
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | List available roles |
|
|
|
|
---
|
|
|
|
## 💼 Module: Jobs
|
|
|
|
### List Jobs (Public)
|
|
```http
|
|
GET /api/v1/jobs
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | Guest | Search and filter jobs |
|
|
|
|
**Query Parameters:**
|
|
| Param | Type | Description |
|
|
|-------|------|-------------|
|
|
| `q` | string | Search query (title, description) |
|
|
| `location` | string | Filter by location |
|
|
| `type` | string | Employment type filter |
|
|
| `workMode` | string | `onsite`, `hybrid`, `remote` |
|
|
| `page` | int | Page number (default: 1) |
|
|
| `limit` | int | Items per page (default: 20) |
|
|
|
|
### Get Job by ID
|
|
```http
|
|
GET /api/v1/jobs/{id}
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | Guest | Get job details |
|
|
|
|
### Create Job
|
|
```http
|
|
POST /api/v1/jobs
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public* | ❌ | admin, recruiter | Create new job posting |
|
|
|
|
### Update Job
|
|
```http
|
|
PUT /api/v1/jobs/{id}
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public* | ❌ | admin, recruiter | Update job posting |
|
|
|
|
### Delete Job
|
|
```http
|
|
DELETE /api/v1/jobs/{id}
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public* | ❌ | admin, recruiter | Delete job posting |
|
|
|
|
### List Jobs for Moderation
|
|
```http
|
|
GET /api/v1/jobs/moderation
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | List all jobs for moderation |
|
|
|
|
### Update Job Status
|
|
```http
|
|
PATCH /api/v1/jobs/{id}/status
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | Approve/reject/close job |
|
|
|
|
### Duplicate Job
|
|
```http
|
|
POST /api/v1/jobs/{id}/duplicate
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | Duplicate job posting |
|
|
|
|
---
|
|
|
|
## 📝 Module: Applications
|
|
|
|
### Create Application
|
|
```http
|
|
POST /api/v1/applications
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | Guest/JobSeeker | Apply to a job |
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"job_id": 123,
|
|
"name": "John Doe",
|
|
"email": "john@example.com",
|
|
"phone": "+55 11 99999-9999",
|
|
"message": "I am interested in this position...",
|
|
"resume_url": "https://..."
|
|
}
|
|
```
|
|
|
|
### List Applications
|
|
```http
|
|
GET /api/v1/applications
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | admin, recruiter | List applications |
|
|
|
|
### Get Application by ID
|
|
```http
|
|
GET /api/v1/applications/{id}
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | admin, recruiter | Get application details |
|
|
|
|
### Update Application Status
|
|
```http
|
|
PUT /api/v1/applications/{id}/status
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | admin, recruiter | Update application status |
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"status": "hired",
|
|
"notes": "Approved after final interview"
|
|
}
|
|
```
|
|
|
|
**Status Values:**
|
|
- `pending` - Awaiting review
|
|
- `reviewed` - Seen by recruiter
|
|
- `shortlisted` - Selected for interview
|
|
- `rejected` - Not selected
|
|
- `hired` - Offer accepted
|
|
|
|
---
|
|
|
|
## 🔔 Module: Notifications
|
|
|
|
### List Notifications
|
|
```http
|
|
GET /api/v1/notifications
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | Any authenticated | Get user notifications |
|
|
|
|
---
|
|
|
|
## 🏷️ Module: Tags
|
|
|
|
### List Tags
|
|
```http
|
|
GET /api/v1/tags
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | List all tags |
|
|
|
|
### Create Tag
|
|
```http
|
|
POST /api/v1/tags
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | Create new tag |
|
|
|
|
### Update Tag
|
|
```http
|
|
PATCH /api/v1/tags/{id}
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | Update tag |
|
|
|
|
---
|
|
|
|
## 👤 Module: Candidates
|
|
|
|
### List Candidates
|
|
```http
|
|
GET /api/v1/candidates
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | List all candidates |
|
|
|
|
---
|
|
|
|
## 📊 Module: Audit
|
|
|
|
### List Login Audits
|
|
```http
|
|
GET /api/v1/audit/logins
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | Login audit trail |
|
|
|
|
---
|
|
|
|
## 📦 Module: Storage
|
|
|
|
### Generate Upload URL
|
|
```http
|
|
POST /api/v1/storage/upload-url
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | Any authenticated | Get S3 presigned upload URL |
|
|
|
|
### Generate Download URL
|
|
```http
|
|
POST /api/v1/storage/download-url
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | Any authenticated | Get S3 presigned download URL |
|
|
|
|
### Delete File
|
|
```http
|
|
DELETE /api/v1/storage/files
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | Any authenticated | Delete file from S3 |
|
|
|
|
---
|
|
|
|
## 📚 Module: Documentation
|
|
|
|
### Swagger UI
|
|
```http
|
|
GET /docs/
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Public | ❌ | Guest | Interactive API documentation |
|
|
|
|
---
|
|
|
|
## 🔑 Module: System Credentials
|
|
|
|
Manage encrypted credentials for external services (Stripe, SMTP, Storage, etc.).
|
|
|
|
### List Configured Services
|
|
```http
|
|
GET /api/v1/system/credentials
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | List all configured services (metadata only, no secrets) |
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"services": [
|
|
{
|
|
"service_name": "stripe",
|
|
"updated_at": "2026-02-23T10:30:00Z",
|
|
"updated_by": "admin-uuid",
|
|
"is_configured": true
|
|
},
|
|
{
|
|
"service_name": "smtp",
|
|
"updated_at": "2026-02-22T14:00:00Z",
|
|
"updated_by": "superadmin-uuid",
|
|
"is_configured": true
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Save Credentials
|
|
```http
|
|
POST /api/v1/system/credentials
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | Create or update service credentials |
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"serviceName": "stripe",
|
|
"payload": {
|
|
"secretKey": "sk_live_xxx",
|
|
"webhookSecret": "whsec_xxx",
|
|
"publishableKey": "pk_live_xxx"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"message": "Credentials saved successfully"
|
|
}
|
|
```
|
|
|
|
**Supported Services:**
|
|
| Service Name | Fields |
|
|
|--------------|--------|
|
|
| `stripe` | `secretKey`, `webhookSecret`, `publishableKey` |
|
|
| `smtp` | `host`, `port`, `username`, `password`, `from_email`, `from_name`, `secure` |
|
|
| `storage` | `endpoint`, `region`, `bucket`, `accessKey`, `secretKey` |
|
|
| `cloudflare_config` | `apiToken`, `zoneId` |
|
|
| `firebase` | `serviceAccountJson` (JSON string) |
|
|
| `appwrite` | `endpoint`, `projectId`, `apiKey` |
|
|
| `lavinmq` | `amqpUrl` |
|
|
| `cpanel` | `host`, `username`, `apiToken` |
|
|
|
|
### Delete Credentials
|
|
```http
|
|
DELETE /api/v1/system/credentials/{serviceName}
|
|
```
|
|
| Field | Auth | Roles | Description |
|
|
|-------|------|-------|-------------|
|
|
| Protected | ✅ | superadmin, admin | Delete service credentials |
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
**Security Notes:**
|
|
- Credentials are encrypted with RSA-OAEP-SHA256 before storage
|
|
- Only metadata (service name, timestamps) is returned on list operations
|
|
- Actual secret values cannot be retrieved after saving
|
|
- Updating credentials overwrites the existing configuration
|
|
|
|
---
|
|
|
|
## 🔑 Permission Matrix
|
|
|
|
| Route | Guest | JobSeeker | Recruiter | CompanyAdmin | Admin | SuperAdmin |
|
|
|-------|-------|-----------|-----------|--------------|-------|------------|
|
|
| `POST /auth/login` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
| `POST /auth/register` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
| `GET /jobs` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
| `GET /jobs/{id}` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
| `POST /jobs` | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
|
|
| `POST /applications` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
| `GET /users/me` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
| `GET /users` | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
|
|
| `DELETE /users/{id}` | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
|
| `GET /notifications` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
| `GET /audit/logins` | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
|
|
| `GET /jobs/moderation` | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
|
|
|
|
---
|
|
|
|
## 🆔 ID Formats
|
|
|
|
| Entity | ID Type | Example |
|
|
|--------|---------|---------|
|
|
| Users | INT (SERIAL) | `1`, `42`, `1337` |
|
|
| Companies | INT (SERIAL) | `1`, `15`, `100` |
|
|
| Jobs | INT (SERIAL) | `1`, `500`, `2500` |
|
|
| Notifications | UUID v7 | `019438a1-2b3c-7abc-8123-4567890abcdef` |
|
|
| Tickets | UUID v7 | `019438a2-3c4d-7xyz-9abc-def0123456789` |
|
|
| Payments | UUID v7 | `019438a3-4e5f-7mno-pqrs-tuvwxyz012345` |
|
|
|
|
---
|
|
|
|
## 📝 Error Responses
|
|
|
|
### 400 Bad Request
|
|
```json
|
|
{
|
|
"error": "Invalid request body",
|
|
"details": "Field 'email' is required"
|
|
}
|
|
```
|
|
|
|
### 401 Unauthorized
|
|
```json
|
|
{
|
|
"error": "Unauthorized",
|
|
"message": "Invalid or expired token"
|
|
}
|
|
```
|
|
|
|
### 403 Forbidden
|
|
```json
|
|
{
|
|
"error": "Forbidden",
|
|
"message": "Insufficient permissions"
|
|
}
|
|
```
|
|
|
|
### 404 Not Found
|
|
```json
|
|
{
|
|
"error": "Not Found",
|
|
"message": "Resource not found"
|
|
}
|
|
```
|
|
|
|
### 500 Internal Server Error
|
|
```json
|
|
{
|
|
"error": "Internal Server Error",
|
|
"message": "An unexpected error occurred"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📚 Related Documentation
|
|
|
|
- [Database Schema](DATABASE.md)
|
|
- [Roadmap](ROADMAP.md)
|
|
- [Tasks](TASKS.md)
|