curl --request POST \
--url https://api.example.com/api/sync{
"success": true,
"synced": 123,
"created": 123,
"updated": 123,
"locations": [
{
"locationId": "<string>",
"locationName": "<string>",
"count": 123
}
],
"errors": [
{}
]
}Synchronize reservations from external PMS systems (CoverManager)
curl --request POST \
--url https://api.example.com/api/sync{
"success": true,
"synced": 123,
"created": 123,
"updated": 123,
"locations": [
{
"locationId": "<string>",
"locationName": "<string>",
"count": 123
}
],
"errors": [
{}
]
}POST /api/sync
CRON_SECRET in the Authorization header.
Authorization: Bearer YOUR_CRON_SECRET
curl -X POST https://your-domain.com/api/sync \
-H "Authorization: Bearer YOUR_CRON_SECRET"
{
"success": true,
"synced": 142,
"created": 38,
"updated": 104,
"locations": [
{
"locationId": "location-madrid-centro-uuid",
"locationName": "La Tasca Madrid · Centro",
"count": 67
},
{
"locationId": "location-barcelona-eixample-uuid",
"locationName": "La Tasca Barcelona · Eixample",
"count": 75
}
],
"errors": []
}
{
"error": "Unauthorized"
}
CRON_SECRET.
{
"error": "Sync error message"
}
syncSmartGlobal() function from /lib/services/sync-core.ts:
import { syncSmartGlobal } from '@/lib/services/sync-core';
export async function POST(request: Request) {
// Security Check
const authHeader = request.headers.get('authorization');
const cronSecret = process.env.CRON_SECRET;
if (!cronSecret || authHeader !== `Bearer ${cronSecret}`) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
try {
const result = await syncSmartGlobal();
return NextResponse.json(result);
} catch (e: any) {
return NextResponse.json({ error: e.message }, { status: 500 });
}
}
covermanager_id configuredtotal_visits and total_spendexternal_id (PMS reservation ID):
UPSERT INTO reservations (
external_id,
location_id,
customer_id,
reservation_date,
reservation_time,
party_size,
status,
...
)
VALUES (...)
ON CONFLICT (external_id) DO UPDATE
integration_configs table:
{
"integration_type": "covermanager",
"config": {
"api_key": "your-api-key",
"venue_id": "venue-123",
"base_url": "https://api.covermanager.com/v1"
},
"is_enabled": true
}
GET /api/cron/sync
| CoverManager | Hiro CRM |
|---|---|
booking_id | external_id |
customer_name | customer_name |
customer_email | (matched to customers.email) |
booking_date | reservation_date |
booking_time | reservation_time |
party_size | party_size |
status | status (mapped to enum) |
notes | notes |
| CoverManager | Hiro CRM |
|---|---|
pending | pending |
confirmed | confirmed |
seated | seated |
finished | completed |
cancelled | cancelled |
no_show | no_show |