W06 — Employee Self-Attendance (Full Matrix)
Decision date: 2026-08-30
Approver: requesting user (explicit plan approval W06 Full Matrix option 3 + implement)
Status: IMMUTABLE W06 IMPLEMENTATION CONTRACT
Scope: Entitled employee check-in/out with approved location/face policy, own history, auditable correction, period lock
Package: Optional Supported PKG-ATTEND-W06 / SC-ATTEND+ (scola_hr_attendance)
Amends: 07-release-test-matrix.md §3 row W06 + §7.3
Does not: durable offline sync (W06.1), physical RFID device CRUD (W20), W09 payslip auto-post, parent notification
Canonical flow
User linked to active employee + SC-ATTEND+ entitled
→ resolve policy (location/face/liveness/anti-spoof)
→ check-in (optional GPS + face evidence) → open attendance
→ check-out → closed attendance + derived late/duration
→ own history
→ optional correction request (draft→submitted) → HR approve/reject
→ period lock denies further punch/correction for that period
Decisions
| # |
Contract |
| 1 |
Track = W06 Employee Self-Attendance, module scola_hr_attendance (not a new module). |
| 2 |
Model SSOT = scola.employee.attendance (+ hr.attendance bridge fields where present). |
| 3 |
Identity: user must link to exactly one active employee in active company; unlinked = deny. |
| 4 |
Schedule/shift: punch does not require assigned shift; if work calendar exists, late/early may derive from it; otherwise timestamps only. |
| 5 |
Device (W06): no enrolled hardware device; approved client = browser/PWA session of entitled user. Hardware RFID = W20 only. |
| 6 |
Location: company attendance_require_location (default true); geofence attendance_max_distance; GPS accuracy attendance_gps_max_accuracy; anti-spoof block/flag. |
| 7 |
Face: company attendance_require_face (default true) + attendance_require_liveness (default true); threshold face_match_threshold; templates only via entitled enroll. |
| 8 |
Fallback REC: block = reject with no partial record; flag = allow + spoof_flags; no silent bypass. |
| 9 |
Offline / IDM: online-required; idempotency via client_request_id on check-in/out/correction submit; double-tap returns same effect; durable offline queue = non-claim W06.1. |
| 10 |
State machine: absent → checked_in → checked_out; correction types missed_checkin, missed_checkout, wrong_time. |
| 11 |
Correction SoD: employee submit (draft→submitted); approve/reject only hr.attendance.edit; no silent HR overwrite without correction + audit. |
| 12 |
Period lock: locked period denies self punch and correction submit/approve; unlock only hr.attendance.config. |
| 13 |
Privacy DEC-009: self history omits face embedding/raw template; full GPS only for entitled operator; retention note in settings. |
| 14 |
XMD: writes employee attendance only; never creates W05 student attendance; RFID bridge only when scola_smart_attendance enabled + explicit. |
| 15 |
Capabilities: self punch = hr.attendance.view + hr.attendance_personal.view; correction approve = hr.attendance.edit; lock = hr.attendance.config. |
| 16 |
Feature flag = scola_hr_attendance; commercial SKU = SC-ATTEND+. |
State machine
| Action |
From |
To |
Actor |
| check-in |
absent |
checked_in |
linked employee self |
| check-out |
checked_in |
checked_out |
linked employee self |
| correction submit |
draft |
submitted |
employee self |
| correction approve |
submitted |
approved (applies attendance) |
HR hr.attendance.edit |
| correction reject |
submitted |
rejected |
HR hr.attendance.edit |
| lock period |
unlocked |
locked |
hr.attendance.config |
| unlock period |
locked |
unlocked |
hr.attendance.config |
Staff / self API (canonical)
| Route |
Auth |
Capability |
POST /api/v1/attendance/check-in |
user |
hr.attendance.view |
POST /api/v1/attendance/check-out |
user |
hr.attendance.view |
POST /api/v1/attendance/self/policy |
user |
hr.attendance_personal.view |
POST /api/v1/attendance/self/history |
user |
hr.attendance_personal.view |
POST /api/v1/attendance/self/corrections/* |
user |
hr.attendance_personal.view (own) |
POST /api/v1/attendance/hr-admin/corrections/* |
user |
hr.attendance.edit |
POST /api/v1/attendance/lock-period |
user |
hr.attendance.config |
POST /api/v1/attendance/unlock-period |
user |
hr.attendance.config |
FE surfaces
| Path |
Auth |
Status |
/employee/self-attendance |
hr.attendance.view + flag |
OPTIONAL_GATED |
/hr/attendance/* |
HR capabilities + flag |
OPTIONAL_GATED |
Certification
- RT-W06-POS-01 … RT-W06-UIA-01 (11 cases) full matrix
- RT-PROFILE-TIMEZONE-01 W06 fixed-clock straddle (WIB minimum)
Non-claims
Durable offline sync (W06.1), physical device enrollment / RFID ingest (W20), W06→W09 automatic payslip posting, DPO legal retention text beyond in-app notice.