Guides
HR
Role-based kiosk for HR management — independent of hospital department.
The HR Manager logs in at hr.manager@hospital.com / admin123 and lands on a stripped kiosk shell pinned to the /hr page. There is no sidebar — the HR module is the entire surface — and a single “Human Resources” tab in the top bar reminds the manager what they’re operating. Notifications and the user pill are kept; everything clinical is hidden.
The HR kiosk is not a department-bound shell like ICU / Maternity / Lab. Anyone with users.role = 'hr' lands here regardless of users.department, so HR can use whatever departmental string the org prefers (“HR”, “Human Resources”, “People Ops”).
This guide is split into two parts:
- Part A — Business is for the HR Manager who logs in. It explains what each tab is for, the day-flow, common pitfalls, and how the kiosk shows alerts.
- Part B — Technical is for anyone wiring or extending the HR module: backend tables, RBAC, routes, and what files to touch when adding a new tab.
Part A — Business
What you own end-to-end
You are responsible for everything about a hospital employee’s lifecycle except the day-to-day clinical work itself:
| Domain | What you do |
|---|---|
| Configure | One-time and rarely-changed setup that drives every other tab — company identity (legal name, working week, EOS formula), branches, job grades / pay bands, shift templates, public-holiday calendar, leave policies per grade, overtime multipliers, allowance / deduction catalogs. |
| Hire | Job postings, applicant tracking, interview scheduling, hiring decision, onboarding checklist (12 default tasks per new hire). |
| Employ | Employee directory, contracts, documents, manager assignment / org-chart, branch + grade assignment, shifts, leave, attendance, payroll, doctor revenue shares. |
| Comply | Clinical credentialing (medical / nursing licenses, DEA, board certs, malpractice — with renewal alerts), mandatory training (BLS, ACLS, fire safety, infection control, HIPAA), occupational health (HBV, MMR, Tdap, flu, COVID-19, TB screening). |
| Develop | Annual / quarterly performance reviews with KPIs and goals; manage promotions, transfers, raises (job-history tab). |
| Discipline | Verbal warning → written warning → PIP → suspension → termination, with full document trail for legal. |
| Money | Monthly payroll (with allowance / deduction catalog), doctor revenue shares, employee loans / salary advances, annual leave-balance ledger. |
| Exit | Resignations, terminations, exit interviews, eligibility-for-rehire flag, asset returns, final settlement. |
Screen layout
┌────────────────────────────────────────────────────────────────────┐
│ ▢ Mando · HR Human Resources 🔔 Hala (HR) ⏻ │ ← top bar (kiosk)
├────────────────────────────────────────────────────────────────────┤
│ HR banner: 215 employees · 198 active · 7 pending leaves · 5 │
│ credentials expiring · 3 trainings due │
│ [+ <Tab Action>] │
├────────────────────────────────────────────────────────────────────┤
│ ⚠ 5 license/credential(s) expiring in the next 60 days... │
│ ⚠ 3 training certification(s) expiring soon... │
├────────────────────────────────────────────────────────────────────┤
│ OVERVIEW [Dashboard] │
│ PEOPLE [Employees] [Org Chart] [Recruitment] [Onboarding 4] │
│ [Exit] │
│ TIME [Leave 7] [Attendance] [Shifts] [Leave Balances] │
│ [Time-off Calendar] [Birthdays] │
│ COMPLIANCE [Credentialing 5] [Training 3] [Occ. Health] │
│ [Reviews] [Disciplinary 1] [Contracts] [Documents] │
│ FINANCE [Payroll] [Doctor Shares] [Loans] [Reports] │
│ LIFECYCLE [Job History] [Assets] │
│ CONFIG [Company Setup] │
├────────────────────────────────────────────────────────────────────┤
│ │
│ ─── current tab content ─── │
│ │
└────────────────────────────────────────────────────────────────────┘
The badges next to tab names ([Onboarding 4], [Leave 7], etc.) are live counts that pull from the dashboard endpoint — they tick down as items get cleared.
Day flow (typical)
- Open with the Dashboard. The headcount/expiry strip across the top tells you what needs attention before you do anything else: pending leaves, expiring credentials, expiring training, open disciplinary actions, onboarding tasks still pending. Three banners on top (red / amber) repeat the most urgent of these so you can’t miss them.
- Clear the inbox: pending leaves. Open the Leave tab → approve / reject any pending requests. The dashboard count drops live.
- Renewal sweep: Credentialing & Training. Anything with a yellow/red “Days Left” column needs HR to start the renewal conversation now. Click Edit, push the expiry date out once the renewal is in hand, and flip the status if needed.
- Onboarding follow-up. Anyone with un-ticked tasks shows up in the Onboarding tab; check the boxes as IT / Facilities / Training confirm completion. Each card shows a per-employee progress bar.
- Time-off Calendar. When clinical managers ask “who’s off in week 18?”, the calendar tab is the one-screen answer.
- Payroll / Loans. Around the 25th–28th: open the Payroll tab for the current month, generate or edit rows, then Export to Accounting once approved. Active loans deduct automatically through the regular payroll deductions field.
- Reviews & job-history. When a promotion or raise is approved, record it in Job History — that one action also updates the employee’s current position / department / salary, so the directory stays in sync.
Each tab, in one paragraph
- Dashboard — KPIs, top-10 by department + position bar charts, upcoming birthdays + work anniversaries (next 30 days). One-screen overview.
- Employees — directory; search by name / employee no / email; filter by department, role, branch, or grade. The employee form now carries optional Branch and Job Grade dropdowns (populated from Configuration); pick them so the directory groups people correctly and so payroll can default the salary band. Clicking + Employee still offers the 12-task onboarding checklist seeder.
- Org Chart — auto-built from
manager_id. Set each employee’s manager and the tree appears automatically with three depth-color tiers. - Recruitment — applicant funnel: open → screening → interview → offered → hired/rejected/closed.
- Onboarding — per-employee checklist with progress bar; tick off tasks as they’re done.
- Exit — resignation / termination ledger. Setting a last working day automatically marks the employee as
terminated. - Leave / Attendance / Shifts — request → approve workflow, daily attendance records, shift schedule library. The shift form now has a Shift Template dropdown at the top — pick one (Morning / Afternoon / Night, defined under Configuration) and the name + start + end auto-fill so you only type once per template.
- Leave Balances — annual entitlement vs used per (employee, year, type), with a usage bar that turns amber at 80% and red at 100%.
- Time-off Calendar — month view with each leave coloured by type (annual blue, sick red, personal amber, maternity pink, unpaid grey), with pending leaves rendered semi-transparent.
- Birthdays — split view of upcoming birthdays + work anniversaries (next 30 days only).
- Credentialing — clinical licenses with their issuing authority and expiry. Critical for regulatory inspection.
- Training — BLS, ACLS, fire safety, infection control, HIPAA, etc. Each row is colour-tagged by type for quick scan.
- Occupational Health (Vaccinations) — HBV series, MMR, Tdap, flu, COVID-19, TB screening with
resultand lot numbers. - Reviews — annual / quarterly review record with 1-5 star rating, KPI score, strengths, areas to improve, goals, status.
- Disciplinary — formal action trail (verbal → written → PIP → suspension → termination) with reason, action date, and outcome.
- Contracts / Documents — employee contracts + uploaded documents (ID, certificates, etc) with expiry alerts.
- Payroll / Doctor Shares — monthly compute, export to Accounting. The payroll form now has Allowance Type and Deduction Type pickers (catalogs from Configuration); selecting an allowance prefills Bonus with its default amount, selecting a deduction prefills Deductions. You can still override either number after the prefill.
- Loans — salary advances + employee loans, with automatic monthly deduction tracking.
- Reports — date-range attendance summary (present / absent / late / half-day rollup).
- Job History — promotion / transfer / raise log. Every entry also pushes through to the employee record so the directory stays accurate.
- Assets — physical items issued (badge, locker, scrubs, laptop, parking permit, vehicle); ensure all return on exit.
- Company Setup (under the Configuration section) — the one-time setup tab. Sub-sections in the left rail: Company Identity, Workforce Defaults, Branches, Job Grades, Shift Templates, Public Holidays, Leave Policies, Overtime Rules, Allowance Types, Deduction Types. See the next subsection for what each is for and when to touch it.
Configuration — the one-time setup tab
Configuration is where you tell the system how this company runs people: the legal name on every payslip, which days are weekends, which grades pay what, when the public holidays are, what allowances and deductions exist. You set these once at go-live, revise occasionally, and the rest of the kiosk reads from them. Everything in this tab is shared with Finance where it makes sense (legal name, working week, base currency).
| Sub-section | What it controls | When you touch it |
|---|---|---|
| Company Identity | Legal name, trade name, commercial registration #, employer #, logo, address, phone/email/website. Shared with Finance. | At go-live. Edit if the company rebrands or changes registration. |
| Workforce Defaults | Working week start (Sunday / Monday / Saturday), working days/week, working hours/day, default probation days, default notice days, end-of-service formula. | At go-live. Edit if labour law changes or a new entity gets a different work week. |
| Branches | Hospital sites / locations with their own address and manager. Each employee can be assigned a branch. | When you open a new site or shut one down. |
| Job Grades | Pay bands: code, level, min / mid / max salary, currency. Each employee can be assigned a grade so payroll knows the band. | When the comp committee rebases the salary structure (annual review). |
| Shift Templates | Named shifts (Morning 07:00–15:00, Afternoon 15:00–23:00, Night 23:00–07:00) with break minutes. | At go-live. Add a template per recurring shift pattern. The Shifts tab picks from this list. |
| Public Holidays | Calendar per year. Paid / Unpaid, Recurring (yearly) / One-off. | Once per year, ahead of the new calendar year. |
| Leave Policies | Per-grade entitlement: Annual, Sick, Maternity, Paternity, Hajj, Bereavement, Unpaid. Days/year, carryover max, min service months, paid flag. | At go-live. Edit when policy changes. |
| Overtime Rules | Multipliers per day type (Weekday ×1.5, Weekend ×2.0, Holiday ×2.5) and minimum-hours threshold. Seeded with industry defaults. | At go-live. Adjust to match the local labour ministry. |
| Allowance Types | Catalog: Housing, Transport, Phone, Meal, etc. Default amount, percent-of-basic, taxable flag. | At go-live. Add a new allowance whenever the comp policy adds one. The Payroll tab lets you pick from this list. |
| Deduction Types | Catalog: Loan, Advance, Fine, Tardiness, etc. Default amount, recoverable flag. | At go-live. Same idea — payroll picks from this list. |
The order on the left rail is the suggested go-live order: identity → workforce defaults → branches → grades → shifts → holidays → policies → rules → catalogs. Each step is independent — you can add branches before shift templates if you prefer — but later items often reference earlier ones (a leave policy can target a grade, so define grades first).
Notification triggers (HR-relevant)
- Pending leave → counter on the Leave tab; clears when you approve / reject.
- Expiring credential → red banner above the tab list when any active credential is within its alert window (default 60 days).
- Expiring training → amber banner ditto.
- Expiring contract → amber banner ditto.
- Disciplinary follow-up → counter on the Disciplinary tab badge for any action with
status='open'. - Onboarding pending → counter on the Onboarding tab badge for any unchecked task across any employee.
Common pitfalls
- Ignoring the alert window on credentials. A clinical license is meaningless to a regulator the day after it expires. The default 60-day alert is generous; some jurisdictions require longer. Override
alert_daysper credential when you know the issuing authority’s renewal lead time is longer than 60. - Forgetting to set the manager. Without
manager_id, the Org Chart tab is empty. Backfill by editing each employee and picking their manager. - Setting last-working-day on a future date and assuming the employee is still active. Recording an exit with
last_working_dayset immediately marks the employeeterminatedeven if the date is in the future. If you want to keep the employee active until that date arrives, leavelast_working_dayblank until the day-of and then update. - Editing the employee’s salary directly to record a raise. This loses history. Use Job History → + Promotion / Change instead — it captures from-salary, to-salary, effective date AND updates the employee record.
- Recording leave used outside the Leave tab. Leave Balances tab tracks entitled vs used; you have to bump the
usednumber manually since leave_requests and leave_balances are not auto-linked yet (see Part B follow-ups).
Part B — Technical
Identity & RBAC
Backend role string: hr (middleware.RoleHR).
Path-based RBAC in backend/internal/middleware/roles.go:
RoleHR: {
"hr": {"GET", "POST", "PUT", "DELETE"},
"doctors": {"GET"},
"departments": {"GET"},
"patients": {"GET"},
"records": {"GET"},
"patient-journey": {"GET"},
"notifications": {"GET", "POST", "PUT"},
"chat": {"GET", "POST", "PUT"},
}
Note that hr is the path prefix (/api/hr/*), so all 14+ HR sub-resources (employees, credentials, trainings, etc.) inherit the same permission row. There is no clinical-write permission and no ward / lab / radiology / MAR / pharmacy / cashier / accounts access.
Frontend RoleNavigation in frontend/src/services/role-permissions.js mirrors that RBAC: clinical: ['notifications', 'chat'], administration: ['hr'], everything else empty.
Kiosk shell wiring
Three lines in frontend/src/components/app-root.js:
// 1. WARD_CONFIG entry — kept here so any code that walks WARD_CONFIG
// treats HR as a kiosk identifier; the depts list is informational.
hr: {
route: 'hr',
brand: 'Mando · HR',
tabLabel: 'Human Resources',
depts: ['hr', 'human resources', 'people operations', 'people ops'],
}
// 2. wardForUser short-circuits on role==='hr', skipping the dept lookup.
if (user.role === 'hr') return 'hr';
// 3. renderWardPage routes to the existing <hr-page>.
case 'hr': return html`<hr-page></hr-page>`;
The reason HR is role-based and not department-based is to keep the kiosk independent of HR’s users.department value — different deployments type that field as “HR”, “Human Resources”, “People Ops”, etc., and we shouldn’t depend on the spelling.
Seed user
backend/internal/database/database.go runs ensureHRManager() on every boot:
hr.manager@hospital.com, passwordadmin123, rolehr, departmentHR, full nameHala Mansour (HR Manager).- Idempotent —
ON CONFLICT (email) DO NOTHINGso re-runs are safe.
Database (deep HR additions)
Already-existing HR tables (employees / leave_requests / attendance / employee_contracts / employee_documents / shift_schedules / recruitment / payroll / doctor_shares) gained these new neighbours in database.go:
| Table | Purpose | Key columns |
|---|---|---|
employee_credentials | Clinical licenses | credential_type, credential_no, issuing_authority, expiry_date, alert_days |
employee_trainings | Hospital training (BLS/ACLS/fire/infection/HIPAA) | training_name, training_type, valid_until, certificate_no, score |
employee_vaccinations | Occ-health record | vaccine_name, dose_number, administered_date, next_due_date, lot_number, result |
performance_reviews | Annual/Q reviews | period, rating(1-5), kpi_score, strengths, improvements, goals, status |
disciplinary_actions | Verbal→written→PIP→suspension→termination | action_type, incident_date, action_date, reason, follow_up_date, status |
onboarding_tasks | Per-hire checklist | task_name, category, due_date, completed, completed_date, completed_by |
employee_loans | Advances / loans | loan_type, principal, monthly_deduction, balance, interest_rate, status |
leave_balances | Entitled vs used per (emp, year, type) | year, leave_type, entitled, used, balance |
job_history | Promotion/transfer/raise log | change_type, effective_date, from/to position+department+salary |
exit_records | Resignation/termination | exit_type, last_working_day, eligible_rehire, clearance_complete, final_settlement |
employee_assets | Issued items (badge, locker, laptop) | asset_name, asset_type, serial_no, issued_date, returned_date, status |
Plus a manager_id INTEGER column added to employees for the org-chart, with covering indexes.
Company-configuration tables (shared with Finance)
| Table | Purpose | Key columns |
|---|---|---|
company_settings | Singleton row (id=1). Identity + workforce defaults + fiscal anchors (Finance reads the same row). | legal_name, trade_name, commercial_reg_no, employer_no, tax_id, vat_number, working_week_start, working_days_per_week, working_hours_per_day, fiscal_year_start_month, period_type, base_currency, probation_days_default, notice_days_default, eos_formula, period_lock_days |
org_branches | Branches / sites | code (UNIQUE), name, address, city, country, phone, manager_id, active |
job_grades | Pay bands | code (UNIQUE), name, level, min_salary, mid_salary, max_salary, currency, active |
shift_templates | Named shifts | code (UNIQUE), name, start_time, end_time, break_minutes, night_shift, active |
public_holidays | Calendar | year, holiday_date, name, is_paid, recurring |
leave_policies | Per-grade entitlement | grade_id (nullable = all grades), leave_type, days_per_year, carryover_max, min_service_months, paid, active |
overtime_rules | Multipliers | day_type (UNIQUE: weekday/weekend/holiday), multiplier, min_hours, active |
allowance_types | Allowance catalog | code (UNIQUE), name, default_amount, percent_of_basic, taxable, active |
deduction_types | Deduction catalog | code (UNIQUE), name, recoverable, default_amount, active |
Three columns also wired into existing HR tables to point at the catalogs:
employees.branch_idandemployees.grade_id(nullable, indexed) — assignmentshift_schedules.shift_template_id(nullable) — picker on the shift form auto-fills name + start + endpayroll.allowance_type_idandpayroll.deduction_type_id(nullable) — picker on the payroll form prefills Bonus / Deductions
Seed functions in database.go:
ensureCompanySettings()— inserts the singleton (id=1) on first boot.ensureOvertimeRulesSeed()— seeds weekday ×1.5, weekend ×2.0, holiday ×2.5.
The other catalogs (branches, grades, shifts, holidays, policies, allowances, deductions) start empty — HR adds rows from the kiosk at go-live.
API surface
All under /api/hr/*, mounted by cmd/server/main.go after the existing HR block:
GET /api/hr/dashboard ← aggregated KPIs for the landing tab
GET /api/hr/calendar?from=&to= ← time-off calendar window
GET/POST/PUT/DELETE /api/hr/credentials
GET/POST/PUT/DELETE /api/hr/trainings
GET/POST/DELETE /api/hr/vaccinations
GET/POST/PUT/DELETE /api/hr/reviews
GET/POST/PUT/DELETE /api/hr/disciplinary
GET/POST/PUT/DELETE /api/hr/onboarding
POST /api/hr/onboarding/seed?employee_id=X ← seed 12 default tasks
GET/POST/PUT/DELETE /api/hr/loans
GET/POST/DELETE /api/hr/leave-balances ← POST upserts
GET/POST/DELETE /api/hr/job-history
GET/POST/PUT/DELETE /api/hr/exit
GET/POST/PUT/DELETE /api/hr/employee-assets
Plus the shared /api/config/* block (HR uses the HR-owned half; Finance uses the Finance-owned half from the same prefix):
GET/PUT /api/config/company ← singleton
GET/POST/PUT/DELETE /api/config/branches
GET/POST/PUT/DELETE /api/config/job-grades
GET/POST/PUT/DELETE /api/config/shift-templates
GET/POST/PUT/DELETE /api/config/holidays?year=
GET/POST/PUT/DELETE /api/config/leave-policies
GET/POST/PUT/DELETE /api/config/overtime-rules
GET/POST/PUT/DELETE /api/config/allowance-types
GET/POST/PUT/DELETE /api/config/deduction-types
Handlers live in backend/internal/handlers/hr_extended.go (HR domain) and backend/internal/handlers/config_hr.go (HR-owned config). They follow the same patterns as the existing HR handlers (List joins on employees, Create / Update / Delete on the table directly, days-to-expiry computed in Go).
The dashboard endpoint runs ~12 small COUNT/group-by queries and computes upcoming birthdays + work anniversaries in Go (parses YYYY-MM-DD dates, projects them onto the current/next year, filters to the next-30-day window). Cheap enough to call on every tab open.
Configuration panel (shared component)
Configuration is rendered by configuration-panel.js, a single Lit component embedded by both kiosks via:
case 'config': return html`<configuration-panel mode="hr"></configuration-panel>`;
The component reads a mode attribute ("hr" or "finance") and shows only the sub-sections that mode owns. HR mode shows the nine HR sub-sections; Finance mode shows the seven Finance sub-sections. The component does its own data loading, modal handling, and CRUD against the /api/config/* endpoints — the kiosk pages just embed it.
Per-mode accent colour is threaded through CSS custom properties (--accent, --accent-tint) — purple in HR mode, green in Finance mode — so the configuration UI inherits the kiosk’s identity.
How catalogs are consumed by other tabs
The HR kiosk loads all five catalogs (branches, grades, shiftTemplates, allowances, deductions) once on connectedCallback() via a _loadCatalogs() helper. They live as cfgBranches, cfgGrades, etc. on the page state and feed the modals:
| Modal | Catalog used | Behaviour |
|---|---|---|
| Employee | cfgBranches, cfgGrades | Two dropdowns under Manager. Saved as employees.branch_id / grade_id. |
| Shift | cfgShiftTemplates | Top-of-form dropdown. _onShiftTemplatePick event handler auto-fills name + start + end fields. Saved as shift_schedules.shift_template_id (backend re-applies the same fields server-side as a safety net). |
| Payroll | cfgAllowances, cfgDeductions | Two dropdowns above the amount fields. _onAllowancePick / _onDeductionPick prefill Bonus / Deductions with the catalog’s default_amount. Saved as payroll.allowance_type_id / deduction_type_id. |
If HR hasn’t populated the catalogs yet, the dropdowns show only the — None — option and the existing manual-entry path still works — none of these are required fields.
Frontend page structure
frontend/src/pages/hr-page.js is one page with 24 tabs grouped into 7 sections (Overview / People / Time / Compliance / Finance / Lifecycle / Configuration). Each tab is one render method; data is loaded lazily on switchTab(t) so the initial load only fetches employees + dashboard + the five config catalogs.
Tab badges (the small numbers in pills) come from the dashboard payload — they update on every tab change and after every mutation that affects the count (approve leave → dashboard refresh → “Leave 7” → “Leave 6”; tick onboarding task → dashboard refresh → “Onboarding 4” → “Onboarding 3”).
Where to add a new tab
- Add a table in
database.go(in themigrate()statements list, plus an alter for any new index). - Add the model struct in
backend/internal/models/models.go. - Add List / Create / Update / Delete handlers in
backend/internal/handlers/hr_extended.go. - Wire routes in
backend/cmd/server/main.gounder the HR block. - Add API methods in
frontend/src/services/api.js. - Add a tab id to one of the
TAB_GROUPSarrays inhr-page.js. - Add a
casetoswitchTab()to load the slice. - Add a
casetorenderTab()to render it. - Add a render method.
- Add a modal block in
renderModal()if it has create/edit forms.
Build verification
# backend
cd backend && go build ./...
# frontend
cd frontend && npx vite build
Both should complete without errors. Frontend build size is currently ~1.78 MB / 296 kB gzip — the Configuration panel and HR catalog wiring added ~80 kB raw / ~10 kB gzip on top of the deep-HR baseline, mostly form HTML.
Follow-ups (NOT done)
These were considered but out of scope for the kiosk-build pass:
- Auto-link
leave_requests→leave_balances. Approving a leave should decrement the matching balance row automatically using theleave_policiesentitlement for the employee’s grade. Today the manager has to bump theusedfield manually after approving — the policy catalog exists but the accrual job doesn’t read from it yet. - Holidays-aware working-days computation. Payroll’s
working_daysis typed manually; withpublic_holidaysandcompany_settings.working_days_per_weeknow configured, this can be computed automatically per month. - Overtime auto-compute.
overtime_rulesandshift_templatesexist; the next step is using them to convert raw clock-in/clock-out attendance intoovertime_hours× multiplier on the payroll row. - Department-aware backend RBAC. Today RoleHR has
/api/hr/*global access. Larger orgs may need per-department HR scoping (you only see your department’s employees). This is a row-level filter on the queries plus adepartmentscolumn on the user record. - File upload for documents / certificates. Today document records store a path/URL in a free-text field. A real upload endpoint with object storage backing would let HR drop PDFs into the chart directly.
- Performance review workflow notifications. Reviewer → reviewee → manager acknowledgement chain isn’t wired to notifications yet; status moves through
draft → submitted → acknowledged → finalizedmanually. - Self-service portal. Employees can’t log into see their own payslips, request leave, or check their leave balance. That would be a
role=employeeview of a per-employee subset of the HR API. - Loan auto-deduction in payroll. Today payroll deductions are typed manually (or prefilled from a deduction-type catalog choice). A monthly cron that pulls from
employee_loans WHERE status='active'and pre-fills the deduction would close the manual loop. - Credential-expiry inter-departmental notifications. When a doctor’s medical license is within 14 days of expiring, the ICU / OR / ER manager should also be paged so they can pull the doctor off the schedule. Today only the HR alert bar surfaces it.
- Audit log for HR mutations. Disciplinary actions, terminations, salary changes are all “high-trust” operations — a write trail (who clicked, when, what changed) is desirable for legal and would mirror the existing audit-log infrastructure used elsewhere.
- Probation / contract-end automation. Today an expiring contract just shows in the alert bar. A workflow that auto-creates a “renew or terminate” decision item, routed to the line manager, would close the loop.
- Org-chart drag-and-drop. The chart renders today but reassigning a manager still requires editing the employee form.