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:
parent
109a4ea194
commit
9bfd14a082
16 changed files with 1129 additions and 212 deletions
|
|
@ -1,10 +1,12 @@
|
|||
import Fastify from 'fastify'
|
||||
import cookie from '@fastify/cookie'
|
||||
import cors from '@fastify/cors'
|
||||
import cron from 'node-cron'
|
||||
import { initDb } from './db.js'
|
||||
import { bookingRoutes } from './routes/bookings.js'
|
||||
import { configRoutes } from './routes/config.js'
|
||||
import { workforceRoutes } from './routes/workforce.js'
|
||||
import { runRotaSync, runTimesheetSync } from './lib/syncJobs.js'
|
||||
|
||||
const app = Fastify({ logger: true, trustProxy: true })
|
||||
const startedAt = Date.now()
|
||||
|
|
@ -25,3 +27,20 @@ try {
|
|||
app.log.error(err)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Daily 6am: rota sync (today-7 → today+28) then timesheet sync (last 7 days)
|
||||
cron.schedule('0 6 * * *', async () => {
|
||||
app.log.info('cron: starting daily workforce sync')
|
||||
try {
|
||||
const r = await runRotaSync()
|
||||
app.log.info({ dates_synced: r.dates_synced }, 'cron: rota sync complete')
|
||||
} catch (err) {
|
||||
app.log.error({ err: err.message }, 'cron: rota sync failed')
|
||||
}
|
||||
try {
|
||||
const r = await runTimesheetSync()
|
||||
app.log.info({ dates_synced: r.dates_synced }, 'cron: timesheet sync complete')
|
||||
} catch (err) {
|
||||
app.log.error({ err: err.message }, 'cron: timesheet sync failed')
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue