Skip to main content
Version: Next

Reference

Complete technical reference for the Staff Attendance module.


TypeScript types

StaffAttendanceStatus

type StaffAttendanceStatus =
| "present"
| "absent"
| "late"
| "half_day"
| "on_leave"
| "holiday"
| "weekend";

StaffAttendanceMarkingMethod

type StaffAttendanceMarkingMethod =
| "biometric"
| "rfid"
| "face_recognition"
| "app"
| "manual"
| "barcode";

StaffAttendanceLeaveType

type StaffAttendanceLeaveType =
| "annual"
| "sick"
| "maternity"
| "paternity"
| "unpaid"
| "study"
| "compassionate";

StaffAttendanceRecord

interface StaffAttendanceRecord {
id: string;
staffId: string;
schoolId: string;
tenantId: string;
attendanceDate: string; // YYYY-MM-DD
checkInTime?: string | null; // HH:mm
checkOutTime?: string | null; // HH:mm
totalHoursWorked?: number | null;
attendanceStatus: StaffAttendanceStatus;
markingMethod: StaffAttendanceMarkingMethod;
isLate?: boolean | null;
minutesLate?: number | null;
leaveType?: StaffAttendanceLeaveType | null;
leaveRequestId?: string | null;
isRemoteWork?: boolean | null;
overtimeHours?: number | null;
overtimeApproved?: boolean | null;
verifiedBy?: string | null; // UUID of verifier
verifiedAt?: string | null; // ISO datetime
notes?: string | null; // visible to staff member
supervisorNotes?: string | null; // internal only
createdAt: string;
updatedAt: string;
staff?: StaffAttendanceStaffContext | null;
}

StaffAttendanceStatistics

interface StaffAttendanceStatistics {
totalRecords: number;
totalStaff: number;
checkedInStaff: number;
present: number;
absent: number;
late: number;
halfDay: number;
onLeave: number;
latePercentage?: number | null;
absenteeismRate?: number | null;
byDepartment?: StaffAttendanceDepartmentSummary[];
byMarkingMethod?: Record<StaffAttendanceMarkingMethod, number>;
dailySummary?: Array<{
date: string;
present: number;
absent: number;
late: number;
}>;
}

StaffAttendanceKioskStation

interface StaffAttendanceKioskStation {
id: string;
schoolId: string;
name: string;
code: string;
location?: string | null;
allowedMarkingMethods: StaffAttendanceMarkingMethod[];
tokenVersion?: number | null;
tokenExpiresAt?: string | null;
isActive: boolean;
revokedAt?: string | null;
lastUsedAt?: string | null;
createdAt: string;
updatedAt: string;
}

React Query hooks

All hooks are exported from @/lib/api/domains/operations/staff-attendance.

Query hooks

HookSignatureDescription
useStaffAttendanceRecords(schoolId, params?, options?)Paginated list of records
useSearchStaffAttendance(schoolId, params?, options?)Full-text search
useStaffAttendanceRecord(schoolId, staffId, options?)Single record
useStaffAttendanceStatistics(schoolId, params?, options?)Aggregated stats
useStaffAttendanceKioskStations(schoolId, params?, options?)List stations
usePublicStaffAttendanceKioskSession(stationCode, options?)Public kiosk session (no auth)

Mutation hooks

HookSignatureDescription
useCreateStaffAttendance(schoolId)Create a single record
useUpdateStaffAttendance(schoolId)Update an existing record
useDeleteStaffAttendance(schoolId)Delete a record
useVerifyStaffAttendance(schoolId)Mark a record as verified
useBulkCreateStaffAttendance(schoolId)Create many records in one request
useCreateStaffAttendanceKioskStation(schoolId)Create a new station
useUpdateStaffAttendanceKioskStation(schoolId, stationId)Edit station fields
useRotateStaffAttendanceKioskStationToken(schoolId, stationId)Generate a new signed URL
useRevokeStaffAttendanceKioskStation(schoolId, stationId)Revoke station access
useDeleteStaffAttendanceKioskStation(schoolId, stationId)Delete a station

API endpoints

Base path: /api/v1/staff-attendance (scoped per school via schoolId header or query parameter).

Records

MethodPathDescription
GET/List records with optional filters
POST/Create a single record
PUT/{id}Update a record
DELETE/{id}Delete a record
POST/{id}/verifyVerify a record
POST/bulkBulk create records
GET/searchFull-text search
GET/statisticsAggregated statistics

Kiosk stations

MethodPathDescription
GET/kiosk-stationsList stations
POST/kiosk-stationsCreate a station
PUT/kiosk-stations/{id}Update a station
DELETE/kiosk-stations/{id}Delete a station
POST/kiosk-stations/{id}/rotate-tokenRotate the signed URL
POST/kiosk-stations/{id}/revokeRevoke station access

Zod validators

Located at src/lib/validators/domains/operations/staff-attendance.ts.

import {
staffAttendanceStatusSchema,
staffAttendanceMarkingMethodSchema,
staffAttendanceLeaveTypeSchema,
staffAttendanceSortBySchema,
createStaffAttendanceSchema,
updateStaffAttendanceSchema,
bulkCreateStaffAttendanceSchema,
verifyStaffAttendanceSchema,
listStaffAttendanceParamsSchema,
createKioskStationSchema,
updateKioskStationSchema,
} from "@/lib/validators/domains/operations/staff-attendance";

Permissions

ResourceActionGrants
staff_attendanceviewRead attendance records and statistics
staff_attendancecreateCreate and self check-in records
staff_attendancemanageEdit, delete, verify, manage kiosk stations

Use useUserPermissions() in components:

const { canView, canCreate, canEdit } = useUserPermissions();

const showVerifyButton = canEdit("staff_attendance");
const showCreateButton = canCreate("staff_attendance");

Query keys

import { staffAttendanceKeys } from "@/lib/api/domains/operations/staff-attendance";

// Invalidate all records for a school after a mutation
queryClient.invalidateQueries({ queryKey: staffAttendanceKeys.list(schoolId) });

// Invalidate statistics
queryClient.invalidateQueries({ queryKey: staffAttendanceKeys.statistics(schoolId) });

// Invalidate kiosk stations
queryClient.invalidateQueries({ queryKey: staffAttendanceKeys.kioskStations(schoolId) });