Files
lunarfront-app/planning/19_Domain_Personnel.md
Ryan Moon 9400828f62 Rename Forte to LunarFront, generalize for any small business
Rebrand from Forte (music-store-specific) to LunarFront (any small business):
- Package namespace @forte/* → @lunarfront/*
- Database forte/forte_test → lunarfront/lunarfront_test
- Docker containers, volumes, connection strings
- UI branding, localStorage keys, test emails
- All documentation and planning docs

Generalize music-specific terminology:
- instrumentDescription → itemDescription
- instrumentCount → itemCount
- instrumentType → itemCategory (on service templates)
- New migration 0027_generalize_terminology for column renames
- Seed data updated with generic examples
- RBAC descriptions updated
2026-03-30 08:51:54 -05:00

264 lines
10 KiB
Markdown

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)