Leave Tool
Overview
Section titled “Overview”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.
Features
Section titled “Features”- 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
Approval Flow
Section titled “Approval Flow”Employee submits → pending_manager → Manager approves → pending_exec → Executive approves → approvedManager/Head submits → pending_exec → Executive approves → approvedExecutive submits → approved (auto)- pending_manager: Approver must be
is_manager=1in a shared squad, or an executive - pending_exec: Approver must have
access_level = 'executive'
Permissions
Section titled “Permissions”| Level | View | Submit/Approve | Manage (retry integrations) |
|---|---|---|---|
| Executive | All requests | Yes + auto-approve own | Yes |
| Head | All requests | Yes | No |
| Manager | Own + squad | Yes | No |
| Lead | Own only | Submit only | No |
| Employee | Own only | Submit only | No |
Post-Approval Integrations
Section titled “Post-Approval Integrations”On executive approval (or auto-approval for executives), the following run independently:
- Xero — Creates a LeaveApplication via Payroll AU API (Xero employees only)
- Remote — Creates a time-off request via Remote API (Remote employees only)
- Productive — Creates a time-off booking
- Google Calendar — Creates an all-day event on the Tribe calendar
- 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.
Rolling Out / Backfilling from Xero
Section titled “Rolling Out / Backfilling from Xero”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:
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.
Components
Section titled “Components”| Component | Purpose |
|---|---|
leave-page.tsx | Main page: tabs (My Leave, Pending, All), balance card, form/detail sheets |
leave-request-form.tsx | Submit leave: type, dates, hours, notes |
leave-request-list.tsx | List of requests with status, type, dates |
leave-request-detail.tsx | Full detail with actions, integration status, history timeline |
leave-balances-card.tsx | Leave balance grid with refresh button |
leave-status-badge.tsx | Coloured status badge (pending/approved/rejected/cancelled) |
leave-integration-status.tsx | Per-integration success/failure indicators with retry button |
URL State
Section titled “URL State”?tab=mine|pending|all— active tab?id=<leave-request-id>— selected request detail view
Data Model
Section titled “Data Model”| Table | Purpose |
|---|---|
leave_types | Cached from Xero PayItems or Remote time-off types (ID, name, is_paid). Remote IDs are prefixed with remote: |
leave_balances | Per-user balances cached from Xero or aggregated from Remote approved time-offs (1hr TTL) |
leave_requests | Core 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_history | Audit trail: action, actor, comment, timestamp |