Payroll Sync And Exceptions Workflow
Summary
Payroll sync and exceptions cover the point where reviewed payroll state becomes an outbound sync request. The workflow scopes what will be sent, renders payloads, dispatches sync work, records failures, and exposes exception and sync-run views.
Reader Question
How does payroll decide what can be synchronized and how do operators recover when sync fails?
Surface Or Workflow
Operators use sync actions in time review, sync status panels, exception views, and sync-run history. Engineers enter through sync routes, sync request services, sync dispatch, failure blockers, payload builders, and payroll job tests.
Lifecycle
The workflow computes sync scope and risk, creates a sync request, builds payloads, dispatches the request, records output rows and failures, and projects failures back into exception views. Failures become blockers or diagnostics rather than invisible job errors.
Child Threads
- Payroll Time Review Workflow: produces the reviewed state used by sync.
- Jobs And DAG Execution Foundations: explains run state, retries, and artifacts.
- Integration Provider Boundaries: explains provider side-effect boundaries.
Implementation Boundaries
Sync UI lives under app/web/app/payroll/exceptions and app/web/app/payroll/sync-runs; API sync routes live in app/api/payroll/time_review/routes_sync.py; sync scope, requests, payloads, dispatch, mutations, and failure blockers live under services/payroll/time_review.
Tradeoffs
Payroll sync needs explicit scope and failure state because an incorrect sync is more costly than a paused review. The extra state gives operators a way to repair and retry without guessing which rows were affected.
Visual
The current visual is a graph neighborhood. The intended visual is a sync timeline from reviewed state to scope, payload, dispatch, failure blocker, exception view, and retry.
Source Evidence
docs/engineering/concepts/payroll-sync-and-exceptions.mdapp/web/app/payroll/exceptionsapp/web/app/payroll/sync-runsapp/api/payroll/time_review/routes_sync.pyservices/payroll/time_review/sync_requests.pyservices/payroll/time_review/sync_dispatch.pyservices/payroll/time_review/sync_failure_blockers.pyservices/payroll/time_review/sync_payloads.pytests/payroll/test_time_review_sync_requests.pytests/jobs/test_sync_payroll_error_rows.py