LunarFront — Small Business Management Platform Domain Design: Personnel Management Version 1.0 | Draft # 1. Overview The Personnel domain manages employee records, time clock, time-off requests, and work schedules. This is foundational infrastructure — every other domain references employees (POS operators, technicians, instructors, drivers). This domain provides the employee entity and workforce management tools. Personnel management is a licensed module (MOD-PERSONNEL). Without it, the platform still tracks basic user accounts for login and role-based access. The module adds time clock, scheduling, time-off, and labor reporting. # 2. Core Concepts ## 2.1 Employee An employee is a person who works for the company. They have a user account for system login and an employee record for HR/scheduling purposes. An employee can work at any location within the company — they are not locked to a single location. - Linked to a `user` account for authentication - Has a home location (primary work site) but can clock in at any location - Roles: admin, manager, staff, technician, instructor - An employee can hold multiple roles (e.g. a technician who also teaches lessons) - Pay rate tracked for labor cost calculations (repair labor, lesson instructor pay) - Employment status: active, inactive, terminated ## 2.2 Time Clock Employees clock in and out to track hours worked. Clock entries record which location the employee is working at, supporting multi-location operations. - Clock in/out via desktop app or web UI - Location recorded at clock-in — employee may work at different locations on different days - Break tracking — paid and unpaid breaks - Overtime calculated based on configurable rules (weekly threshold, daily threshold) - Clock entries editable by managers with audit trail ## 2.3 Schedules Work schedules define when employees are expected to work. Schedules are per-location and per-week. - Weekly recurring schedules with override capability for specific dates - Shift-based — start time, end time, location, role - Instructors have dual scheduling: lesson schedule (from Lessons domain) + store shift schedule - Schedule conflicts detected — cannot schedule same employee at two locations simultaneously - Published schedules visible to employees (future: via portal or mobile) ## 2.4 Time Off Employees can request time off. Managers approve or deny. Approved time off blocks scheduling for those dates. - Request types: vacation, sick, personal, unpaid - Accrual tracking — configurable accrual rates per type - Manager approval workflow with notification - Approved time off appears on schedule as blocked - Annual carryover rules configurable per type # 3. Database Schema ## 3.1 employee Column | Type | Notes id | uuid PK | company_id | uuid FK | Tenant scoping user_id | uuid FK | Linked login account — nullable for employees not yet set up with system access first_name | varchar | last_name | varchar | email | varchar | Work email phone | varchar | home_location_id | uuid FK | Primary work location roles | text[] | Array of roles: admin, manager, staff, technician, instructor hire_date | date | termination_date | date | Nullable — set when terminated employment_status | enum | active, inactive, terminated pay_type | enum | hourly, salary, commission, per_lesson pay_rate | numeric(10,2) | Hourly rate or salary amount overtime_eligible | boolean | notes | text | Internal HR notes legacy_id | varchar | AIM employee ID created_at | timestamptz | updated_at | timestamptz | ## 3.2 time_clock_entry Column | Type | Notes id | uuid PK | company_id | uuid FK | employee_id | uuid FK | location_id | uuid FK | Where the employee clocked in clock_in | timestamptz | clock_out | timestamptz | Nullable — null while clocked in break_minutes | integer | Total break time in minutes break_type | enum | paid, unpaid, none total_hours | numeric(6,2) | Computed: clock_out - clock_in - unpaid breaks is_overtime | boolean | Flagged based on overtime rules overtime_hours | numeric(6,2) | Hours beyond overtime threshold edited | boolean | True if entry was modified after clock-out edited_by | uuid FK | Manager who edited edit_reason | text | Required if edited created_at | timestamptz | ## 3.3 schedule Column | Type | Notes id | uuid PK | company_id | uuid FK | employee_id | uuid FK | location_id | uuid FK | schedule_date | date | Specific date for this shift start_time | time | end_time | time | role | varchar | What role for this shift (staff, technician, instructor) is_recurring | boolean | True if generated from a recurring template recurring_template_id | uuid FK | Nullable — links to the template that generated this notes | text | created_by | uuid FK | Manager who created created_at | timestamptz | updated_at | timestamptz | ## 3.4 schedule_recurring_template Weekly recurring schedule patterns. The system generates concrete `schedule` entries from these templates. Column | Type | Notes id | uuid PK | company_id | uuid FK | employee_id | uuid FK | location_id | uuid FK | day_of_week | integer | 0=Sunday through 6=Saturday start_time | time | end_time | time | role | varchar | effective_from | date | When this pattern starts effective_until | date | Nullable — open-ended if null is_active | boolean | created_at | timestamptz | ## 3.5 time_off_request Column | Type | Notes id | uuid PK | company_id | uuid FK | employee_id | uuid FK | request_type | enum | vacation, sick, personal, unpaid start_date | date | end_date | date | total_days | numeric(4,1) | Supports half days status | enum | pending, approved, denied, cancelled reason | text | Employee's reason manager_notes | text | Manager's response reviewed_by | uuid FK | Manager who reviewed reviewed_at | timestamptz | created_at | timestamptz | ## 3.6 time_off_balance Tracks accrued and used time off per employee per type per year. Column | Type | Notes id | uuid PK | company_id | uuid FK | employee_id | uuid FK | year | integer | Calendar year request_type | enum | vacation, sick, personal accrued | numeric(5,1) | Days accrued this year used | numeric(5,1) | Days used this year carried_over | numeric(5,1) | Days carried from previous year available | numeric(5,1) | Computed: accrued + carried_over - used created_at | timestamptz | updated_at | timestamptz | # 4. Overtime Rules Overtime configuration is per-company, stored in company settings. Setting | Default | Notes weekly_overtime_threshold | 40 | Hours per week before overtime kicks in daily_overtime_threshold | null | Nullable — some states require daily overtime (e.g. California = 8 hrs) overtime_multiplier | 1.5 | Pay multiplier for overtime hours double_time_threshold | null | Nullable — hours per day before double time (e.g. California = 12 hrs) double_time_multiplier | 2.0 | Pay multiplier for double time Overtime is calculated at clock-out based on the current week's total hours. If daily thresholds are configured, both daily and weekly are evaluated and the higher overtime amount applies. # 5. Key Workflows ## 5.1 Clock In / Out - Employee opens desktop app or web UI - Selects "Clock In" — system records current time, location, and employee - On clock out, system records end time, calculates total hours and break time - If total weekly hours exceed overtime threshold, overtime flagged - Manager can edit clock entries with required reason — logged in audit trail ## 5.2 Schedule Creation - Manager creates recurring schedule templates for each employee - System generates concrete schedule entries for upcoming weeks - Manager can override specific dates (e.g. swap shifts, add extra coverage) - Instructor lesson schedule slots (from Lessons domain) display alongside store shifts for visibility - Schedule conflicts flagged — same employee at two locations at the same time ## 5.3 Time Off Request - Employee submits request specifying dates, type, and reason - Manager receives notification - Manager approves or denies with optional notes - Approved time off deducts from employee's time_off_balance - Schedule entries for approved dates are flagged or removed - If employee is an instructor, lesson sessions for those dates can be auto-cancelled or flagged for makeup ## 5.4 Pay Period Reporting - Manager selects date range for pay period - System generates report: employee, regular hours, overtime hours, total hours - Export to CSV for payroll processing (platform does not run payroll — exports data for external payroll service) - Includes time-off hours taken by type # 6. Integration with Other Domains Domain | Integration Lessons | Instructors are employees. Lesson schedule_slot.instructor_id references employee. Time off auto-flags affected lesson sessions. Repairs | Technicians are employees. repair_ticket.assigned_technician_id references employee. Labor cost calculated from employee pay_rate. Sales/POS | transaction.processed_by references employee. Drawer sessions linked to employee. Delivery | delivery_event.driver_employee_id references employee. Accounting | Labor costs from repair tickets use employee.pay_rate for margin calculation. Payroll export supports journal entry generation for labor expense. # 7. Business Rules - Employee must have unique email within company - Clock entries cannot overlap — cannot be clocked in at two locations simultaneously - Clock-out required before new clock-in (system auto-clocks out at midnight if forgotten — flagged for manager review) - Time-off requests for past dates require manager approval - Schedule recurring templates auto-generate entries 4 weeks ahead (configurable) - Terminated employees retain all historical records (time clock, schedules, time off) — never deleted - Employee pay_rate changes are effective immediately — historical clock entries retain the rate at time of clock-out - Per-lesson instructors: pay tracked per lesson session attended, not via time clock # 8. Reporting Report | Description Hours summary | Total regular + overtime hours per employee per period Overtime report | Employees who hit overtime threshold — broken out by daily vs weekly Time-off balances | Current accrued, used, and available days per employee per type Schedule coverage | Shifts per location per day — identifies understaffed days Clock edit audit | All manager edits to time clock entries with reasons Labor cost by department | Hours * pay_rate grouped by role (technician, instructor, staff) Attendance | Scheduled vs actual clock-in times — identifies chronic lateness Payroll export | CSV export formatted for common payroll services (QuickBooks Payroll, Gusto, ADP)