Add timesheet sync: pull actual hours, daily cron, per-cell source indicators

- fetchTimesheetShifts: hits /api/v2/shifts, subtracts breaks, carries PENDING/APPROVED status
- syncJobs.js: shared runRotaSync/runTimesheetSync logic used by routes and cron
- Rota sync now skips dates already marked source='timesheet'
- POST /api/workforce/sync-timesheets: on-demand pull of last 7 days actual hours
- Daily 6am cron: rota sync then timesheet sync, each logged independently
- upsertWorkforceShifts now writes source per row (workforce or timesheet)
- Frontend: Pull timesheets button alongside Sync rota button
- Clock icon on timesheet cells — amber for PENDING, green for APPROVED
- Both buttons disabled while either sync is in progress

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-22 18:25:02 +00:00
parent 109a4ea194
commit 9bfd14a082
16 changed files with 1129 additions and 212 deletions

View file

@ -120,6 +120,10 @@ export function syncWorkforce(): Promise<{ ok: boolean; from: string; to: string
return request('/workforce/sync', { method: 'POST' })
}
export function syncTimesheets(): Promise<{ ok: boolean; from: string; to: string; dates_synced: number }> {
return request('/workforce/sync-timesheets', { method: 'POST' })
}
export function getWorkforceShifts(start: string, end: string): Promise<Record<string, WfDayData>> {
return request(`/workforce/shifts?start=${start}&end=${end}`)
}