Implements comprehensive scheduled sync system using node-cron with full admin interface for configuration and monitoring. Features: - Configurable sync schedules with cron expressions - Enable/disable schedules without deletion - Manual trigger for testing - Status monitoring (last run, next run, success/failure) - Error tracking and display - Incremental and full sync support - Multiple concurrent schedules - Admin UI with schedule management Components: 1. Sync Scheduler Service (lib/services/sync-scheduler.ts) - node-cron integration for scheduling - Database-backed schedule configuration - Automatic initialization on startup - Prevents concurrent runs of same schedule - Calculates next run times - Tracks execution status and errors 2. Database Schema (sync_schedules table) - Schedule configuration storage - Execution history tracking - Last run status and errors - Next run calculation 3. API Endpoints - GET /api/sync/schedules - List all schedules - POST /api/sync/schedules - Create schedule - GET /api/sync/schedules/[id] - Get schedule - PATCH /api/sync/schedules/[id] - Update schedule - DELETE /api/sync/schedules/[id] - Delete schedule - POST /api/sync/schedules/[id]/trigger - Manual trigger 4. Admin UI (components/admin/SyncScheduler.tsx) - View all schedules with status - Create/edit/delete schedules - Enable/disable toggle - Manual trigger button - Cron expression presets - Real-time status updates - Error message display - Next run countdown 5. Default Schedules (created on first startup, disabled) - Daily Incremental: 2 AM daily (0 2 * * *) - Weekly Full: 3 AM Sunday (0 3 * * 0) Admin Interface: - New 'Schedules' tab in sync page - Schedule cards with status badges - Enable/disable with play/pause button - Manual trigger with clock button - Edit dialog with cron presets - Create dialog for new schedules - Real-time status (running, next run, last run) - Success/failure indicators - Error message alerts Cron Features: - Full cron expression support - Validation before saving - Common presets (daily, weekly, hourly) - Next run time calculation - Automatic schedule restart on config change Monitoring: - Last run timestamp - Next run countdown (e.g., 'in 2h 15m') - Success/failure status with icons - Error messages for failed syncs - Running indicator (animated badge) - Schedule validity check Dependencies: - node-cron: ^3.0.3 - @types/node-cron: ^3.0.11 UI Components: - Alert component added (components/ui/alert.tsx) - Integrated into sync page tabs - Responsive design Documentation: - Complete guide (docs/SCHEDULED_SYNCS.md) - Cron expression reference - Best practices - Troubleshooting guide - API reference - Database schema Use Cases: 1. Daily incremental sync for recent changes 2. Weekly full sync for data integrity 3. Custom schedules for specific needs 4. Off-peak hour automation 5. Backup for webhook failures Benefits: - No manual intervention required - Consistent data freshness - Flexible scheduling - Easy monitoring - Error tracking - Manual override available Next Steps: 1. Restart application to initialize scheduler 2. Navigate to Admin → Sync → Schedules tab 3. Enable default schedules or create custom ones 4. Monitor first runs for success 5. Adjust schedules as needed Files Added/Modified: - lib/services/sync-scheduler.ts (new) - app/api/sync/schedules/route.ts (new) - app/api/sync/schedules/[id]/route.ts (new) - app/api/sync/schedules/[id]/trigger/route.ts (new) - components/admin/SyncScheduler.tsx (new) - components/ui/alert.tsx (new) - app/admin/sync/page.tsx (modified - added Schedules tab) - docs/SCHEDULED_SYNCS.md (new) - package.json (node-cron added)
94 lines
2.2 KiB
TypeScript
94 lines
2.2 KiB
TypeScript
/**
|
|
* Sync Schedule API (single schedule)
|
|
* Manage individual sync schedules
|
|
*/
|
|
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
import { syncScheduler } from '@/lib/services/sync-scheduler';
|
|
|
|
/**
|
|
* GET /api/sync/schedules/[id]
|
|
* Get a specific schedule
|
|
*/
|
|
export async function GET(
|
|
request: NextRequest,
|
|
{ params }: { params: { id: string } }
|
|
) {
|
|
try {
|
|
const schedule = await syncScheduler.getSchedule(params.id);
|
|
|
|
if (!schedule) {
|
|
return NextResponse.json(
|
|
{ error: 'Schedule not found' },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
schedule,
|
|
});
|
|
} catch (error) {
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
console.error('[SCHEDULE API] Error fetching schedule:', errorMessage);
|
|
|
|
return NextResponse.json(
|
|
{ error: 'Failed to fetch schedule', details: errorMessage },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PATCH /api/sync/schedules/[id]
|
|
* Update a schedule
|
|
*/
|
|
export async function PATCH(
|
|
request: NextRequest,
|
|
{ params }: { params: { id: string } }
|
|
) {
|
|
try {
|
|
const body = await request.json();
|
|
|
|
const schedule = await syncScheduler.updateSchedule(params.id, body);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
schedule,
|
|
});
|
|
} catch (error) {
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
console.error('[SCHEDULE API] Error updating schedule:', errorMessage);
|
|
|
|
return NextResponse.json(
|
|
{ error: 'Failed to update schedule', details: errorMessage },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* DELETE /api/sync/schedules/[id]
|
|
* Delete a schedule
|
|
*/
|
|
export async function DELETE(
|
|
request: NextRequest,
|
|
{ params }: { params: { id: string } }
|
|
) {
|
|
try {
|
|
await syncScheduler.deleteSchedule(params.id);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: 'Schedule deleted',
|
|
});
|
|
} catch (error) {
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
console.error('[SCHEDULE API] Error deleting schedule:', errorMessage);
|
|
|
|
return NextResponse.json(
|
|
{ error: 'Failed to delete schedule', details: errorMessage },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|