# Phase 1 — Shift Scheduling Workflow Definition ## 1. Executive Summary The current Shift Scheduling module implements a dual-workflow architecture. Administrators and HR personnel can directly assign schedules using the `AssignScheduleModal` which writes directly to the `employee_shift_schedule` table. Simultaneously, there is a proposed schedule change mechanism allowing users to submit requests via a dashboard popover, which are stored in the `schedule_submissions` table and require manual approval. The recommended future model consolidates this by maintaining the dual-track system but formalizing it: - **Direct Assignment**: Exclusive to HR, Admins, and Managers with explicit `schedules.manage` permission. - **Proposed Changes**: Used by employees (if permitted) or lower-level supervisors to request schedule amendments, flowing through an approval pipeline before becoming final. ## 2. Files Reviewed **Frontend**: - `ShiftSchedulePage.jsx` (Dashboard shell) - `AssignScheduleModal.jsx` (Direct assignment modal with conflict handling) - `LayouSMDashboard.jsx` (Schedule grid view and filter controls) - `ScheduleManagerAPI.js` & `schedule-managerAPI.jsx` (API bindings) **Backend / API**: - `backend/schedule-manager/create-sm.php` (Direct creation & conflict detection) - `backend/schedule-manager/upsert-employee-shift.php` (Update logic) - `backend/schedule-manager/get_employee_schedule.php` (Reads final schedules) - `backend/schedule-manager/approvals/create_submission.php` (Proposed schedule logic) - `backend/schedule-manager/approvals/approve_submission.php` (Approval logic) **Database Tables (Inferred from queries)**: - `employee_shift_schedule` (Final, active schedules) - `schedule_submissions` (Pending/Approved/Rejected requests) - `work_time` (Shift definitions) - `leave_types` & `employee_leaves` (Leave management) ## 3. Existing Architecture The system relies on PHP backend endpoints directly interfacing with MySQL. - **Schedules (`employee_shift_schedule`)**: Contains `employee_id`, `work_time_id`, `effective_date`, `end_date`, `recurrence_type`, `days_of_week`, `priority`. - **Submissions (`schedule_submissions`)**: Contains similar fields but acts as a holding table until approved. - **Conflicts**: Detected actively during `create-sm.php` by comparing date ranges and `start_time/end_time` (including overnight calculations). Conflicts block creation, forcing the frontend to decide whether to replace or keep existing entries. ## 4. Current Workflow **Workflow A (Direct Assignment)** ```text HR/Admin ↓ Select Employee(s) & Shift in AssignScheduleModal ↓ Select Effective Date & Recurrence ↓ Submit to `create-sm.php` ↓ Backend detects conflicts (Overlaps in time/days) ↓ If conflicts: frontend prompts resolution (Keep, Replace) ↓ If clear: INSERT INTO `employee_shift_schedule` ↓ Schedule is Finalized and Active ``` **Workflow B (Proposed Change)** ```text User / Supervisor ↓ Click schedule date in LayouSMDashboard (PopoverEditor) ↓ Propose new shift ↓ Submit to `approvals/create_submission.php` ↓ INSERT INTO `schedule_submissions` (Status: Pending) ↓ Authorized Approver reviews in PendingPanel ↓ Approves via `approve_submission.php` ↓ INSERT INTO `employee_shift_schedule` ↓ Schedule is Finalized ``` ## 5. Problems / Risks - **[High] Multiple-Employee Assignment Loop**: The frontend likely loops over employees sequentially. If one fails or hits a conflict mid-loop, it can lead to partial success and confused state. - **[High] Leave & Holiday Ignorance**: Backend endpoints (`create-sm.php`) do not check against `employee_leaves` or holidays, meaning an admin can accidentally schedule an employee who is on paid leave. - **[Medium] Direct Assignment Bypassing Approvals**: Unclear distinction in the UI on when to use direct vs. proposed. If a manager has both, they might bypass auditing. - **[Medium] Priority System Complexity**: Exposing `priority` (integers) to HR users is confusing. It should be an internal technical detail. - **[Low] Monthly Recurrence**: Rarely used for standard shifts, adds unnecessary form bloat. ## 6. Direct Assignment vs Approval Decision **Recommendation**: Maintain both, but enforce strict boundaries based on RBAC. - **Direct Assignment**: Only for users with `schedules.manage` (HR, Admins). Used for initial onboarding, bulk monthly rollouts, and definitive corrections. - **Approval Workflow**: For operational managers or supervisors who manage the floor but do not have ultimate HR authority. They propose changes (e.g., swapping a shift), and HR/Admins approve. ## 7. Roles & Permissions Matrix | Action | Super Admin | HR Admin | Manager | Employee | | :--- | :--- | :--- | :--- | :--- | | View own schedule | Yes | Yes | Yes | Yes | | View dept schedule | Yes | Yes | Yes | No | | Assign schedule directly | Yes | Yes | No | No | | Bulk assign | Yes | Yes | No | No | | Propose change | Yes | Yes | Yes | Yes | | Approve change | Yes | Yes | No | No | | Delete schedule | Yes | Yes | No | No | ## 8. Schedule State Model - **Active**: The canonical, final schedule. Used by attendance and payroll. - **Pending**: A proposed schedule change awaiting approval. Does not affect payroll. - **Rejected**: A proposed schedule that was declined. Kept for audit. - **Inactive/Deleted**: A previously active schedule that was cancelled or superseded by a new assignment. ## 9. Schedule Business Rules - **Creation**: Requires valid `employee_id`, `work_time_id`, `effective_date`. - **Conflicts**: If an assignment overlaps with an existing `Active` schedule, the system must prompt the user. Recommended UI actions: *Replace Existing*, *Keep Existing (Cancel New)*. The raw `priority` integer should be hidden. - **Leave**: If an employee has approved leave on a given date, the schedule should still technically exist (for historical reference of what they *would* have worked), but the UI should visually flag it as "On Leave". Bulk assignment should warn HR if assigning over existing leaves. - **Holidays**: Schedules exist over holidays. Payroll logic handles the multiplier. UI should overlay a holiday indicator. - **Overnight Shifts**: Supported. The backend correctly handles `end_time < start_time` by adding 24 hours. - **Recurrence**: Keep Daily and Weekly. Monthly should be removed from standard UI to reduce clutter unless explicitly requested. - **Day Off**: Represented by a lack of a schedule (NULL) on a given day within a weekly recurrence, or an explicit "Rest Day" shift depending on company policy. Recommended: Use explicit "Rest Day" shifts to differentiate from "Unscheduled". ## 10. Audit Trail Requirements Every change to `employee_shift_schedule` must record: - `employee_id` - `action` (Create, Update, Delete) - `previous_work_time_id` (if applicable) - `new_work_time_id` - `changed_by` (User ID of the actor) - `timestamp` - `source` (Direct, Bulk, Approved Submission) *Current Gap*: The system relies on `created_at` but lacks a dedicated `schedule_audit_logs` table for tracking *who* deleted or modified a schedule. ## 11. Recommended Canonical Workflow ```mermaid graph TD A[HR/Admin Need to Schedule] --> B{Bulk or Single?} B -->|Single| C[Select Employee & Shift] B -->|Bulk| D[Select Employees & Shift] C --> E[Conflict Check] D --> E E -->|No Conflict| F[Finalize Schedule] E -->|Conflict Detected| G[Prompt Resolution: Replace or Cancel] G -->|Replace| F F --> H[(Save to Database)] I[Manager Needs Change] --> J[Select Cell & Propose Shift] J --> K[(Save to Submissions)] K --> L[HR Reviews Pending List] L -->|Approve| F L -->|Reject| M[Mark Rejected] ``` ## 12. Dashboard Requirements Produced by Phase 1 Phase 2 UI must support: - Visual distinction between "Final" (solid) and "Pending Approval" (striped/faded) schedules. - Warning badges on cells where an employee has an Approved Leave. - Holiday overlay markers on column headers. - Bulk selection toggles for employees to apply a schedule. - Summary metrics: Unscheduled employees, Pending approvals count. ## 13. Backend Changes Potentially Required - **Leave Integration**: Minor adjustment to `read-schedules-range.php` to return overlapping leaves so the UI can render warnings. - **Audit Logging**: New endpoint/logic needed to write to an audit table upon deletion or modification. - **Bulk Assignment**: Business-rule change needed to handle bulk arrays transactionally, returning a unified success/failure report rather than relying on frontend looping. ## 14. Database Changes Potentially Required - Create `schedule_audit_logs` table. - Ensure `schedule_submissions` has `rejected_reason` column. ## 15. Open Decisions - **Question**: Should employees be able to propose their own schedule changes? - **Current Evidence**: `create_submission.php` allows it if the frontend exposes it. - **Recommended Default**: No, restrict to Supervisors/Managers to prevent spam, unless company policy relies on shift-bidding. - **Impact**: UI access controls on the schedule grid. ## 16. Phase 1 Acceptance Checklist - [x] Mapped frontend/backend architecture - [x] Defined current dual-workflow - [x] Resolved Direct Assignment vs Approval rules - [x] Defined Schedule States - [x] Defined Business Rules (Conflicts, Leaves, Holidays, Overnight) - [x] Recommended Audit Trail - [x] Documented in `docs/shift-schedule/phase-1-workflow-definition.md` # Phase 1.1 Validation Corrections The following assumptions from Phase 1 have been validated against the actual codebase: - **Permission Verification:** [CONFIRMED] `schedule_management` is the frontend UI permission controlling visibility of the module. `schedules.manage` is explicitly enforced server-side for direct creations and modifications. - **Submission Access:** [CONFIRMED] Employee schedule change request — NOT CURRENTLY CONFIRMED / OUT OF CURRENT SCOPE. Only users with the `schedule_management` permission can access the UI, effectively restricting submissions to Managers/Supervisors. - **Approval Workflow:** [CONFIRMED] The system uses configurable role-based approver levels (Level 1 and Level 2) via `get_role_approver_levels.php`. Statuses observed are: `pending`, `lvl1_approved`, `applied`, `rejected`. - **Leave Integration:** [CONFIRMED] No backend change required for basic leave visualization. The frontend currently maps approved leaves per employee via `fetchLeavesRange` API over the grid. - **Rest Day Decision:** [OPEN DECISION] Current `work_time_id` is deeply tied to attendance calculations (`work_time_late_deduction`, `getShiftBreaks`). Assigning a fake "Rest Day" `work_time_id` risks attendance anomalies. A safe future data model should rely on an explicit `is_rest_day` flag or null `work_time_id` instead. - **Schedule State Model:** [RECOMMENDED] - **Final Schedule Record:** `ACTIVE`, `INACTIVE` - **Proposed Schedule Change:** `PENDING`, `LVL1_APPROVED`, `APPLIED`, `REJECTED` - **Delete / Historical Editing:** [CONFIRMED] Deleting a schedule issues an `UPDATE employee_shift_schedule SET is_active = 0`, acting as a soft delete instead of a raw SQL DELETE. [RECOMMENDED] The UX should expose "Deactivate" and "Replace", with historical changes requiring elevated privileges and strict audit logging. - **Multiple-Employee Assignment Risk:** [CONFIRMED] `AssignScheduleModal.jsx` sequentially loops over the `selectedEmployees` array via a `for...of` loop, awaiting `createSchedule` for each. Partial successes and overlapping conflict modals are guaranteed to occur if failures happen mid-loop. [RECOMMENDED] A transactional/batch API endpoint must be created for bulk assignments.