Skip to content

Leave Tool

The Leave tool replaces direct Xero/Remote leave submissions with an in-app workflow. Employees submit leave requests, which go through a two-tier approval process (manager → executive). On final approval, the leave is automatically synced to the payroll provider (Xero or Remote), Productive.io, the Tribe Google Calendar, and posted to Slack.

  • Leave balances — Cached from Xero or Remote, shown before submitting a request
  • Two-tier approval — Manager approval then executive approval (with shortcuts for managers and executives)
  • External integrations — Xero LeaveApplication or Remote time-off, Productive booking, Google Calendar event, Slack notification
  • Cancellation — Reverses all external integrations when approved leave is cancelled
  • Pending badge — Sidebar badge showing count of requests awaiting your approval
  • Audit trail — Full history of every action on a request
Employee submits → pending_manager → Manager approves → pending_exec → Executive approves → approved
Manager/Head submits → pending_exec → Executive approves → approved
Executive submits → approved (auto)
  • pending_manager: Approver must be is_manager=1 in a shared squad, or an executive
  • pending_exec: Approver must have access_level = 'executive'
LevelViewSubmit/ApproveManage (retry integrations)
ExecutiveAll requestsYes + auto-approve ownYes
HeadAll requestsYesNo
ManagerOwn + squadYesNo
LeadOwn onlySubmit onlyNo
EmployeeOwn onlySubmit onlyNo

On executive approval (or auto-approval for executives), the following run independently:

  1. Xero — Creates a LeaveApplication via Payroll AU API (Xero employees only)
  2. Remote — Creates a time-off request via Remote API (Remote employees only)
  3. Productive — Creates a time-off booking
  4. Google Calendar — Creates an all-day event on the Tribe calendar
  5. Slack — Posts to #company-leave with leave details

Each integration runs independently — a failure in one doesn’t block the others. Failed integrations are stored and can be retried by executives. Xero and Remote are mutually exclusive based on the employee’s payroll provider mapping.

When Nucleus is first rolled out, every employee will already have approved leave sitting in Xero (annual leave booked ahead, personal leave history). To avoid manual re-entry, an executive can trigger a one-shot backfill via the API:

Terminal window
curl -X POST https://app.nucleus.fast/api/admin/leave/backfill-from-xero \
-H "Content-Type: application/json" \
-d '{}'

The endpoint paginates Xero’s tenant-wide GET /payroll.xro/1.0/LeaveApplications (100 records/page), matches each EmployeeID against Nucleus people, and inserts matched applications as exec_approved rows in leave_requests. Applications belonging to Xero employees not mapped in Nucleus (ex-employees, contractors) are skipped and counted under unmapped_employees in the response. Re-running is safe — already-imported applications dedupe on the partial unique index over xero_leave_application_id. Paging is rate-limited to stay under Xero’s 60/min cap.

There is no UI for this — it’s an admin-run operation invoked rarely (typically once per rollout). For testing or spot-fixes, the endpoint accepts person_id (single person), since (skip dates earlier than YYYY-MM-DD), and dry_run (count without writing). See the API reference.

ComponentPurpose
leave-page.tsxMain page: tabs (My Leave, Pending, All), balance card, form/detail sheets
leave-request-form.tsxSubmit leave: type, dates, hours, notes
leave-request-list.tsxList of requests with status, type, dates
leave-request-detail.tsxFull detail with actions, integration status, history timeline
leave-balances-card.tsxLeave balance grid with refresh button
leave-status-badge.tsxColoured status badge (pending/approved/rejected/cancelled)
leave-integration-status.tsxPer-integration success/failure indicators with retry button
  • ?tab=mine|pending|all — active tab
  • ?id=<leave-request-id> — selected request detail view
TablePurpose
leave_typesCached from Xero PayItems or Remote time-off types (ID, name, is_paid). Remote IDs are prefixed with remote:
leave_balancesPer-user balances cached from Xero or aggregated from Remote approved time-offs (1hr TTL)
leave_requestsCore table: user, type, dates, hours, status, external IDs (xero_leave_application_id, remote_timeoff_id, productive_booking_id, google_calendar_event_id, slack_message_ts), integration errors
leave_request_historyAudit trail: action, actor, comment, timestamp