
# Service Library - `attendanceManagement`

This document provides a complete reference of the custom code library for the `attendanceManagement` service. It includes all library functions, edge functions with their REST endpoints, templates, and assets.


## Library Functions

Library functions are reusable modules available to all business APIs and other custom code within the service via `require("lib/<moduleName>")`.


### `calculateLateness.js`

```js
module.exports = function calculateLateness(shift, checkInTime) {
  if (!shift || !shift.startTime || !checkInTime) return {isLate: false, lateByMinutes: 0};
  const shiftStart = new Date(shift.shiftDate + 'T' + shift.startTime);
  const checkIn = new Date(checkInTime);
  const diffMs = checkIn - shiftStart;
  const lateByMinutes = Math.max(Math.round(diffMs / 60000), 0);
  return {
    isLate: diffMs > 0,
    lateByMinutes: diffMs > 0 ? lateByMinutes : 0
  };
};
```


### `calculateLeftEarly.js`

```js
module.exports = function calculateLeftEarly(shiftEndTime, checkOutTime) {
  if (!shiftEndTime || !checkOutTime) return {leftEarly: false};
  // parse to Date objects assuming checkOutTime has full ISO string
  const shiftEnd = new Date(shiftEndTime);
  const checkOut = new Date(checkOutTime);
  return { leftEarly: checkOut < shiftEnd };
};
```


### `cronMarkAbsentees.js`

```js
module.exports = async function cronMarkAbsentees(context) {
  /**
   * This cron will:
   * 1. For today's date, for all shifts, fetch all assigned users (assignedUserIds)
   * 2. For each (user, shift) pair: check if an attendanceRecord exists
   * 3. If not, create attendanceRecord with status = 'absent', set shiftId/userId
   */
  const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
  const { fetchRemoteListByMQuery, createAttendanceRecord, getAttendanceRecordByQuery } = require('serviceCommon');
  // 1. Fetch all shifts for today, active only
  const shifts = await fetchRemoteListByMQuery('scheduleManagement:shift', { shiftDate: today, isActive: true }, 0, 9999);
  for (const shift of shifts) {
    // resolve all assigned userIds
    const assignedUserIds = shift.assignedUserIds || [];
    for (const userId of assignedUserIds) {
      // Check if attendanceRecord exists
      const existing = await getAttendanceRecordByQuery({ userId, shiftId: shift.id, isActive: true });
      if (!existing) {
        await createAttendanceRecord({ userId, shiftId: shift.id, status: 'absent' }, context);
        // optionally: publish notification event for absentee here
      }
    }
  }
};
```





## Edge Functions

Edge functions are custom HTTP endpoint handlers that run outside the standard Business API pipeline. Each edge function is paired with an Edge Controller that defines its REST endpoint.


### `triggerCronMarkAbsentees.js`


**Edge Controller:**
- **Path:** `/cron/mark-absentees`
- **Method:** `GET`
- **Login Required:** Yes


```js
module.exports = async (request) => {
  const { cronMarkAbsentees } = LIB;
  await cronMarkAbsentees(request);
  return { status: 200, message: 'Processed absentee auto-marking' };
};
```





## Edge Controllers Summary

| Function Name | Method | Path | Login Required |
|--------------|--------|------|----------------|
| `triggerCronMarkAbsentees` | `GET` | `/cron/mark-absentees` | Yes |









---

*This document was generated from the service library configuration and should be kept in sync with design changes.*
