Files
lunarfront-app/planning/19_Domain_Personnel.md
Ryan Moon 5f8726ee4e Add planning documents for Forte music store platform
17 domain design docs covering architecture, accounts, inventory,
rentals, lessons, repairs, POS, payments, batch repairs, delivery,
billing, accounting, deployment, licensing, installer, and backend
tech architecture. Plus implementation roadmap (doc 18) and
personnel management (doc 19).

Key design decisions documented:
- company/location model (multi-tenant + multi-location)
- member entity (renamed from student to support multiple adults)
- Stripe vs Global Payments billing ownership differences
- User/location/terminal licensing model
- Valkey 8 instead of Redis
2026-03-27 14:51:23 -05:00

264 lines
10 KiB
Markdown

Forte — Music Store 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)