# eHandyHire API Documentation

Base URL: `http://localhost:4000/api`

All responses follow this format:
```json
{
  "success": true,
  "data": {},
  "message": "optional message",
  "meta": { "page": 1, "limit": 20, "total": 100, "totalPages": 5 }
}
```

## Authentication

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| POST | `/auth/register` | Register customer or worker | No |
| POST | `/auth/login` | Login with email/phone + password | No |
| POST | `/auth/google` | Sign in / register with Google ID token | No |
| POST | `/auth/google/profile` | Verify Google token & return profile (no account create) | No |
| POST | `/auth/refresh` | Refresh access token | Cookie/Body |
| POST | `/auth/logout` | Logout and invalidate refresh token | Yes |
| GET | `/auth/me` | Get current user profile | Yes |

### Google Sign-In Body
```json
{
  "idToken": "google-identity-services-credential"
}
```
Links an existing account by `googleId` or email, or creates a new **CUSTOMER** account.

### Register Body
```json
{
  "email": "user@example.com",
  "phone": "+639171234567",
  "password": "Password123!",
  "firstName": "Juan",
  "lastName": "Dela Cruz",
  "role": "CUSTOMER"
}
```

## Categories

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| GET | `/categories` | List all categories | Optional |
| GET | `/categories/:slug` | Get category by slug | No |

## Workers

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| GET | `/workers` | List workers with filters | Optional |
| GET | `/workers/:id` | Get worker profile | No |

### Query Parameters
- `search` - Search by name, skill
- `categoryId` / `categorySlug` - Filter by category
- `location` - Filter by service area
- `verified=true` - Verified workers only
- `sort` - `rating`, `reviews`, `experience`
- `page`, `limit` - Pagination

## Jobs

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| GET | `/jobs` | List jobs | Optional |
| GET | `/jobs/:id` | Get job details | Optional |
| POST | `/jobs` | Create job (customer, requires login) | Customer |
| POST | `/jobs/:id/images` | Upload job images | Customer |
| POST | `/jobs/:id/progress` | Job lifecycle action (`start`, `mark_complete`, `confirm_complete`, `cancel`) | Customer/Worker |
| PATCH | `/jobs/:id/status` | Update job status (admin override) | Admin |
| GET | `/jobs/my/list` | Get my jobs (`?status=ACCEPTED,IN_PROGRESS` supported) | Yes |

## Quotations

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| POST | `/quotations` | Submit quotation | Worker |
| PATCH | `/quotations/:id/accept` | Accept quotation | Customer |
| PATCH | `/quotations/:id/reject` | Reject quotation | Customer |
| GET | `/quotations/job/:jobId` | Get job quotations | Yes |

## Messages

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| GET | `/messages` | List conversations | Yes |
| GET | `/messages/:id/messages` | Get conversation messages | Yes |
| POST | `/messages` | Send message | Yes |
| PATCH | `/messages/:conversationId/read` | Mark as read | Yes |

## Notifications

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| GET | `/notifications` | List notifications | Yes |
| GET | `/notifications/unread-count` | Get unread count | Yes |
| PATCH | `/notifications/:id/read` | Mark as read | Yes |
| PATCH | `/notifications/read-all` | Mark all as read | Yes |

## Reviews

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| POST | `/reviews` | Submit review | Customer |
| GET | `/reviews/worker/:workerId` | Get worker reviews | No |

## Verifications

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| POST | `/verifications` | Upload verification doc | Worker |
| GET | `/verifications/my` | Get my documents | Worker |
| PATCH | `/verifications/:id/review` | Review document | Admin |
| GET | `/verifications/pending` | List pending docs | Admin |

## Analytics

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| POST | `/analytics/qr-scan` | Track QR code scan | No |
| GET | `/analytics/qr` | QR analytics | Admin |
| GET | `/analytics/dashboard` | Admin dashboard stats | Admin |

## Users

| Method | Endpoint | Description | Auth |
|--------|----------|-------------|------|
| GET | `/users` | List users | Admin |
| PATCH | `/users/:id/status` | Suspend/activate user | Admin |
| PATCH | `/users/profile` | Update profile | Yes |
| PATCH | `/users/worker/profile` | Update worker profile | Worker |
| POST | `/users/worker/portfolio` | Upload portfolio image | Worker |
| GET | `/users/worker/dashboard` | Worker dashboard stats | Worker |
| GET | `/users/customer/dashboard` | Customer dashboard stats | Customer |

## Socket.IO Events

| Event | Direction | Description |
|-------|-----------|-------------|
| `send-message` | Client → Server | Send chat message |
| `receive-message` | Server → Client | Receive chat message |
| `typing` | Bidirectional | Typing indicator |
| `read-receipt` | Bidirectional | Message read receipt |
| `new-job` | Server → Client | New job notification |
| `new-quote` | Server → Client | New quotation notification |
| `job-status-update` | Server → Client | Job status changed |
| `notification` | Server → Client | General notification |
| `join-room` | Client → Server | Join a room |
| `join-conversation` | Client → Server | Join chat room |
| `join-category` | Client → Server | Subscribe to category jobs |

### Connection
```javascript
const socket = io('http://localhost:4000', {
  auth: { token: 'your-jwt-access-token' }
});
```

## Error Codes

| Code | Description |
|------|-------------|
| 400 | Validation error |
| 401 | Authentication required |
| 403 | Insufficient permissions |
| 404 | Resource not found |
| 409 | Conflict (duplicate) |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
