cuatrolabs-ecomm-ms / APPOINTMENTS_API_QUICK_REF.md
MukeshKapoor25's picture
docs(appointments): Add API quick reference and PostgreSQL migration guide
2e76228
# E-commerce Appointments API Quick Reference
## Base URL
```
/appointments
```
## Endpoints
### 1. Book Appointment
```http
POST /appointments/book
```
**Request:**
```json
{
"merchant_id": "5starsaloon",
"appointment_date": "2026-02-10",
"start_time": "14:00",
"services": [
{
"service_id": "service_123",
"service_name": "Hair Cut & Styling",
"duration_minutes": 60,
"price": 500.0,
"staff_id": "staff_456",
"staff_name": "John Doe"
}
],
"customer_name": "Jane Smith",
"customer_phone": "+919876543210",
"customer_email": "jane@example.com",
"notes": "First time customer"
}
```
**Response:**
```json
{
"success": true,
"message": "Appointment booked successfully",
"appointment": {
"appointment_id": "uuid",
"merchant_id": "5starsaloon",
"customer_id": "customer_123",
"status": "booked",
...
}
}
```
---
### 2. Get Appointment
```http
GET /appointments/{appointment_id}
```
**Response:**
```json
{
"appointment_id": "uuid",
"merchant_id": "5starsaloon",
"customer_id": "customer_123",
"customer_name": "Jane Smith",
"customer_phone": "+919876543210",
"appointment_date": "2026-02-10",
"start_time": "14:00",
"end_time": "15:00",
"total_duration": 60,
"services": [...],
"status": "booked",
"total_amount": 500.0,
"currency": "INR"
}
```
---
### 3. List Appointments (Standard with Projection Support)
```http
POST /appointments/list
```
**Request (Full Response):**
```json
{
"merchant_id": "5starsaloon",
"status": "booked",
"from_date": "2026-02-01",
"to_date": "2026-02-28",
"limit": 20,
"offset": 0
}
```
**Request (With Projection - Minimal Response):**
```json
{
"merchant_id": "5starsaloon",
"status": "booked",
"limit": 20,
"offset": 0,
"projection_list": ["appointment_id", "customer_name", "start_time", "status"]
}
```
**Response (Full):**
```json
{
"appointments": [
{
"appointment_id": "uuid",
"merchant_id": "5starsaloon",
"customer_name": "Jane Smith",
...
}
],
"pagination": {
"limit": 20,
"offset": 0,
"total": 5
}
}
```
**Response (With Projection):**
```json
{
"items": [
{
"appointment_id": "uuid",
"customer_name": "Jane Smith",
"start_time": "2026-02-10T14:00:00",
"status": "booked"
}
],
"total": 5,
"pagination": {
"limit": 20,
"offset": 0,
"total": 5
}
}
```
---
### 4. Get Available Slots
```http
POST /appointments/available-slots
```
**Request:**
```json
{
"merchant_id": "5starsaloon",
"appointment_date": "2026-02-10",
"service_duration": 60,
"staff_id": "staff_456"
}
```
**Response:**
```json
{
"merchant_id": "5starsaloon",
"appointment_date": "2026-02-10",
"slots": [
{
"start_time": "09:00",
"end_time": "09:30",
"available": true
},
{
"start_time": "09:30",
"end_time": "10:00",
"available": false
}
],
"business_hours": {
"open": "09:00",
"close": "18:00"
}
}
```
---
### 5. Cancel Appointment
```http
DELETE /appointments/{appointment_id}/cancel
```
**Request:**
```json
{
"cancellation_reason": "Customer requested reschedule"
}
```
**Response:**
```json
{
"success": true,
"message": "Appointment cancelled successfully",
"appointment": {
"appointment_id": "uuid",
"status": "cancelled",
...
}
}
```
---
### 6. Get My Appointments
```http
GET /appointments/customer/my-appointments?limit=20&offset=0
```
**Response:**
```json
{
"appointments": [...],
"pagination": {
"limit": 20,
"offset": 0,
"total": 5
}
}
```
---
## Filter Options for List Endpoint
| Filter | Type | Description |
|--------|------|-------------|
| `merchant_id` | string | Filter by merchant |
| `customer_id` | string | Filter by customer |
| `appointment_date` | date | Filter by specific date |
| `status` | enum | Filter by status (booked, confirmed, cancelled, completed, no_show) |
| `from_date` | date | Filter from date (inclusive) |
| `to_date` | date | Filter to date (inclusive) |
| `limit` | int | Max records (1-100, default: 20) |
| `offset` | int | Records to skip (default: 0) |
| `projection_list` | array | Fields to include (optional) |
---
## Projection List Fields
Available fields for projection:
- `appointment_id`
- `merchant_id`
- `customer_id`
- `customer_name`
- `customer_phone`
- `status`
- `start_time`
- `end_time`
- `notes`
- `created_by`
**Note:** When using `projection_list`, services are NOT included. Use full response to get service details.
---
## Status Values
| Status | Description |
|--------|-------------|
| `booked` | Initial state when customer books |
| `confirmed` | Merchant confirms the booking |
| `cancelled` | Customer or merchant cancels |
| `completed` | Service completed |
| `billed` | Payment processed (POS only) |
| `no_show` | Customer didn't show up |
---
## Error Responses
### 400 Bad Request
```json
{
"detail": "Appointment time must be in the future"
}
```
### 404 Not Found
```json
{
"detail": "Appointment not found"
}
```
### 500 Internal Server Error
```json
{
"detail": "Failed to book appointment"
}
```
---
## Performance Tips
1. **Use Projection List**: Reduce payload size by 50-90%
```json
{
"projection_list": ["appointment_id", "customer_name", "start_time"]
}
```
2. **Limit Results**: Use pagination for large datasets
```json
{
"limit": 10,
"offset": 0
}
```
3. **Filter Wisely**: Use specific filters to reduce query time
```json
{
"merchant_id": "5starsaloon",
"appointment_date": "2026-02-10",
"status": "booked"
}
```
---
## Integration Examples
### React/Next.js
```typescript
// Book appointment
const response = await fetch('/appointments/book', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
merchant_id: '5starsaloon',
appointment_date: '2026-02-10',
start_time: '14:00',
services: [{ service_id: 'svc_123', ... }],
customer_name: 'Jane Smith',
customer_phone: '+919876543210'
})
});
// List with projection
const response = await fetch('/appointments/list', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
merchant_id: '5starsaloon',
limit: 10,
projection_list: ['appointment_id', 'customer_name', 'start_time']
})
});
```
### Python
```python
import requests
# Book appointment
response = requests.post(
'http://localhost:8000/appointments/book',
json={
'merchant_id': '5starsaloon',
'appointment_date': '2026-02-10',
'start_time': '14:00',
'services': [{'service_id': 'svc_123', ...}],
'customer_name': 'Jane Smith',
'customer_phone': '+919876543210'
}
)
# List with projection
response = requests.post(
'http://localhost:8000/appointments/list',
json={
'merchant_id': '5starsaloon',
'limit': 10,
'projection_list': ['appointment_id', 'customer_name', 'start_time']
}
)
```
---
## Notes
- All timestamps are in UTC
- Customer authentication via JWT (TODO: implement)
- Shared database with POS appointments
- Source field automatically set to 'online'
- Booking channel automatically set to 'app'