Skip to main content

Break Tracking

This guide covers how to record breaks during your shift, including automatic break calculations, break policies, and best practices for accurate time tracking.


Overview​

What is Break Tracking?​

Break tracking ensures accurate working hours calculation:

  1. Break Recording - Log breaks taken during shifts
  2. Automatic Deduction - Breaks deducted from total hours
  3. Policy Compliance - Ensure legal break requirements met
  4. Accurate Payroll - Correct pay calculation

Break Types​

TypeTypical DurationPaid/Unpaid
Lunch Break30-60 minutesUsually unpaid
Tea/Coffee Break10-15 minutesUsually paid
Rest Break20 minutesLegally required
Personal BreakVariableDepends on policy

Recording Breaks​

Method 1: At Clock Out​

The simplest method is recording total break time when clocking out:

  1. Click Clock Out on the Time Clock widget
  2. Enter total break time in minutes
  3. Add notes if needed
  4. Confirm to save
// Clock out with break duration
const response = await fetch(`/api/staff/timesheet/entries/${entryId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
clock_out_time: '2025-01-14T17:30:00Z',
break_duration: 45, // 45 minutes total break
notes: '30 min lunch + 15 min afternoon break'
})
})

Method 2: Start/End Break​

For real-time break tracking:

  1. Click Start Break when taking a break
  2. The timer shows break duration
  3. Click End Break when returning
  4. Break time automatically recorded

Method 3: Edit After Clock Out​

If you forgot to record breaks:

  1. Go to Timesheet → View Entries
  2. Find the relevant entry
  3. Click Edit
  4. Add break duration
  5. Save changes

Break Duration Validation​

Minimum and Maximum Limits​

// Source: src/app/api/staff/timesheet/entries/route.ts:70-78
const breakDurationSchema = z.number()
.min(0, 'Break duration cannot be negative')
.max(480, 'Break duration cannot exceed 8 hours')
.optional()

Validation Rules​

RuleLimitReason
Minimum0 minutesCannot be negative
Maximum480 minutes (8 hours)Cannot exceed shift length
Shift Check< Total shiftBreak must be less than shift

Break vs Shift Validation​

// Ensure break doesn't exceed shift duration
const validateBreakDuration = (
clockIn: string,
clockOut: string,
breakMinutes: number
): boolean => {
const shiftDuration = moment(clockOut).diff(moment(clockIn), 'minutes')

if (breakMinutes >= shiftDuration) {
throw new Error('Break duration cannot exceed shift duration')
}

return true
}

Automatic Break Rules​

Policy-Based Breaks​

Some companies have automatic break policies:

// Automatic break calculation example
const calculateAutoBreak = (shiftHours: number): number => {
// Example policy: 30 min break for shifts over 6 hours
if (shiftHours >= 6) {
return 30 // 30 minutes
}
// 15 min break for shifts 4-6 hours
if (shiftHours >= 4) {
return 15
}
return 0 // No automatic break
}
Shift LengthRequired BreakNotes
< 6 hoursNone requiredAt employer discretion
6+ hours20 minutes minimumUninterrupted rest break
Long shiftsAdditional breaksAs per policy

Break Time Calculation​

How Breaks Affect Total Hours​

// Source: src/app/api/staff/timesheet/entries/route.ts:120-145
// Total hours = Shift duration - Break duration
const calculateWorkingHours = (entry: TimeEntry): number => {
const clockIn = moment.tz(entry.clock_in_time, UK_TIMEZONE)
const clockOut = moment.tz(entry.clock_out_time, UK_TIMEZONE)

// Raw shift duration in hours
const shiftHours = clockOut.diff(clockIn, 'hours', true)

// Break duration in hours
const breakHours = (entry.break_duration || 0) / 60

// Net working hours
const workingHours = shiftHours - breakHours

return Math.round(workingHours * 100) / 100
}

Example Calculations​

ShiftClock InClock OutRaw HoursBreakNet Hours
Morning09:0013:004.000 min4.00
Full Day09:0017:308.5030 min8.00
Long Shift08:0020:0012.0060 min11.00

Break Recording Interface​

Time Clock Widget​

// Break recording component structure
interface BreakRecording {
entryId: string
breakDuration: number // minutes
breakNotes?: string
}

// Display break input
const BreakInput = ({ value, onChange }) => (
<div className="space-y-2">
<label className="text-sm font-medium">Break Duration (minutes)</label>
<input
type="number"
min={0}
max={480}
value={value}
onChange={(e) => onChange(parseInt(e.target.value))}
className="form-input"
placeholder="Enter break time in minutes"
/>
<p className="text-xs text-secondary-text">
Total break time taken during this shift
</p>
</div>
)

Quick Break Presets​

PresetDurationUse Case
No Break0 minShort shifts
Tea Break15 minQuick break
Lunch30 minStandard lunch
Extended Lunch60 minLong lunch break

Multiple Breaks​

Recording Multiple Breaks​

When taking multiple breaks, record the total:

// Example: Recording multiple breaks
const breaks = [
{ type: 'morning tea', duration: 15 },
{ type: 'lunch', duration: 30 },
{ type: 'afternoon tea', duration: 15 }
]

const totalBreakMinutes = breaks.reduce((sum, b) => sum + b.duration, 0)
// Result: 60 minutes total

// Record total in time entry
await updateTimeEntry(entryId, {
break_duration: totalBreakMinutes,
notes: 'Morning tea (15), Lunch (30), Afternoon tea (15)'
})

Break Notes​

Use notes to detail break breakdown:

Good NotesBad Notes
"30 min lunch, 15 min afternoon break""45 min"
"Two 20-minute breaks""breaks"
"Extended lunch - 60 min (approved)"""

Break Policies​

Company Break Policies​

Companies may have specific break policies:

// Break policy configuration
interface BreakPolicy {
minimumShiftForBreak: number // hours
mandatoryBreakDuration: number // minutes
paidBreaks: boolean
maxBreakDuration: number // minutes
autoApplyBreaks: boolean
}

// Example GP Practice policy
const gpPracticeBreakPolicy: BreakPolicy = {
minimumShiftForBreak: 6,
mandatoryBreakDuration: 30,
paidBreaks: false,
maxBreakDuration: 60,
autoApplyBreaks: false
}

Industry-Specific Guidelines​

IndustryTypical Policy
GP Practice30 min unpaid lunch for 6+ hour shifts
RestaurantStaggered breaks during service
DentalBetween patient appointments
OfficeFlexible break timing

Editing Break Records​

Modifying Break Duration​

To edit a previously recorded break:

// Update break duration
const updateBreak = async (entryId: string, newBreakMinutes: number) => {
const response = await fetch(`/api/staff/timesheet/entries/${entryId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
break_duration: newBreakMinutes,
notes: 'Updated break duration'
})
})

return response.json()
}

Edit Restrictions​

Entry StatusCan Edit Break?
Draft✅ Yes
Submitted❌ No - recall first
Approved❌ No - contact manager
Rejected✅ Yes - then resubmit

Break Time Display​

Timesheet View​

ColumnFormatExample
BreakMinutes30 min
BreakHours:Minutes0:30
PercentageOf shift5.9%

Summary Statistics​

// Calculate break statistics for period
const calculateBreakStats = (entries: TimeEntry[]) => {
const totalBreakMinutes = entries.reduce(
(sum, e) => sum + (e.break_duration || 0), 0
)

const averageBreak = totalBreakMinutes / entries.length

return {
totalBreakMinutes,
averageBreakMinutes: Math.round(averageBreak),
totalBreakHours: Math.round(totalBreakMinutes / 60 * 10) / 10
}
}

Best Practices​

For Accurate Break Recording​

  1. Record Immediately - Log breaks as you take them
  2. Be Precise - Round to nearest 5 minutes
  3. Include All Breaks - Tea, lunch, personal
  4. Add Context - Note reason for extended breaks
  5. Review Daily - Check entries before end of day

Break Timing Tips​

TipBenefit
Set break remindersDon't forget to log
Use presetsQuick recording
Check policyEnsure compliance
Track patternsOptimise scheduling

Troubleshooting​

Common Issues​

IssueCauseSolution
"Break exceeds shift"Break longer than shiftReduce break duration
Break not savedForm not submittedClick save/confirm
Wrong break recordedEntry errorEdit the time entry
Break missing from hoursNot includedAdd break duration

Error Messages​

ErrorMeaningAction
"Break duration cannot be negative"Negative value enteredEnter positive number
"Break duration cannot exceed 8 hours"Value too largeCheck break minutes
"Break duration exceeds shift"Break > shift lengthReduce break time
"Entry is submitted"Cannot edit submittedRecall entry first

Compliance Considerations​

RequirementDetails
6+ hour shifts20 minutes uninterrupted break
Young workers30 minutes if shift > 4.5 hours
Workplace rest11 consecutive hours between shifts
Weekly rest24 hours uninterrupted per week

Recording for Compliance​

// Check legal break compliance
const checkBreakCompliance = (entry: TimeEntry): ComplianceResult => {
const shiftHours = calculateShiftHours(entry)
const breakMinutes = entry.break_duration || 0

const warnings = []

// Check 6+ hour shift has 20 min break
if (shiftHours >= 6 && breakMinutes < 20) {
warnings.push('Shifts over 6 hours require minimum 20 minute break')
}

return {
compliant: warnings.length === 0,
warnings
}
}


Source Files:

  • src/app/api/staff/timesheet/entries/route.ts - Time entries API
  • src/lib/validation/timesheet.schemas.ts - Break validation schemas
  • src/components/staff/BreakRecorder.tsx - Break recording component
  • src/lib/utils/time-calculations.ts - Time calculation utilities