The Staff Management module in NDSS CRM provides a complete human resources and workforce management solution tailored for NDIS and disability care providers. It covers the full employee lifecycle from onboarding through to separation, including qualification tracking, availability management, role assignment, and performance monitoring. The module is built using Next.js and React with TypeScript for the front end, Python services for business logic and reporting, PHP for legacy HR integrations, and PostgreSQL as the primary data store.
The Staff Directory is the central hub for managing all employees within the organisation. It provides a searchable, filterable list of all staff members with key information displayed in a table format. The directory supports server-side pagination, full-text search, and multi-criteria filtering.
| Staff Member | Role | Phone | Employment | Status | Actions | |
|---|---|---|---|---|---|---|
|
MW
Mark Wilson
EMP-0012
|
Support Worker | mark.w@newdawnss.com | 0412 111 222 | Full-time | Active | |
|
SC
Sarah Chen
EMP-0015
|
Clinical Lead | sarah.c@newdawnss.com | 0423 333 444 | Full-time | Active | |
|
JS
Jane Smith
EMP-0003
|
Support Coordinator | jane.s@newdawnss.com | 0434 555 666 | Part-time | Active | |
|
TN
Tom Nguyen
EMP-0021
|
Support Worker | tom.n@newdawnss.com | 0445 777 888 | Casual | On Leave | |
|
LP
Lisa Park
EMP-0028
|
Team Leader | lisa.p@newdawnss.com | 0456 999 000 | Full-time | Active |
| Column | Data Source | Sortable | Description |
|---|---|---|---|
| Staff Member | first_name, last_name, employee_id | Yes | Avatar (initials), full name, internal employee ID |
| Role | role | Yes | Primary role within the organisation |
email | Yes | Work email address | |
| Phone | phone | No | Primary contact phone number |
| Employment | employment_type | Yes | Full-time, Part-time, Casual, or Contract |
| Status | status | Yes | Current employment status |
| Actions | N/A | No | View profile button, actions dropdown |
The staff onboarding form captures all essential information required to create a new employee record. The form is divided into logical sections and includes validation rules to ensure data completeness and accuracy. Upon successful creation, the new staff member receives an automated welcome email with login credentials and onboarding instructions.
| Field | Type | Required | Validation | DB Column |
|---|---|---|---|---|
| First Name | Text | Yes | 1-100 chars, alpha + spaces | first_name VARCHAR(100) |
| Last Name | Text | Yes | 1-100 chars, alpha + spaces | last_name VARCHAR(100) |
| Date of Birth | Date | Yes | Valid past date, must be 16+ | date_of_birth DATE |
| Gender | Select | No | Enum values | gender VARCHAR(30) |
| Employment Type | Select | Yes | full_time, part_time, casual, contract | employment_type VARCHAR(20) |
| Primary Role | Select | Yes | Must match valid system role | role VARCHAR(50) |
| Start Date | Date | Yes | Cannot be more than 90 days in future | start_date DATE |
| Contract End Date | Date | Conditional | Required if employment_type = contract | contract_end_date DATE |
| Pay Rate | Currency | No | Positive decimal, max 2 decimal places | pay_rate DECIMAL(8,2) |
| Weekly Hours | Number | No | 0-60, not required for casual | weekly_hours DECIMAL(4,1) |
| Work Email | Yes | Valid email, unique across org | email VARCHAR(255) UNIQUE | |
| Phone | Text | Yes | Australian phone format | phone VARCHAR(20) |
| Emergency Name | Text | Yes | 1-200 chars | emergency_name VARCHAR(200) |
| Emergency Phone | Text | Yes | Australian phone format | emergency_phone VARCHAR(20) |
When a new staff member is created, the following automated workflow is triggered:
onboarding.# Python Onboarding Service
class StaffOnboardingService:
def onboard_new_staff(self, staff_data: dict) -> dict:
# 1. Create staff record
staff = self.staff_repository.create(staff_data)
# 2. Create auth user account via Supabase / Oracle
auth_user = self.supabase.auth.admin.create_user({
'email': staff_data['email'],
'password': generate_temp_password(),
'user_metadata': {
'staff_id': str(staff.id),
'role': staff_data['role'],
'org_id': str(staff_data['org_id']),
}
})
# 3. Send welcome email
self.email_service.send_welcome_email(
to=staff_data['email'],
name=f"{staff_data['first_name']} {staff_data['last_name']}",
temp_password=auth_user.temp_password,
reset_link=f"{BASE_URL}/auth/reset-password?token={auth_user.reset_token}"
)
# 4. Generate onboarding checklist
self.checklist_service.create_onboarding_checklist(staff.id)
# 5. Assign role permissions
self.permission_service.assign_role(auth_user.id, staff_data['role'])
# 6. Notify stakeholders
self.notification_service.notify_new_staff(staff)
return {'staff_id': str(staff.id), 'user_id': auth_user.id}
The Staff Profile page provides a comprehensive view of all information related to an individual staff member. It uses a tabbed interface with five sections: Overview, Qualifications, Shifts, Availability, and Documents.
| Name | Relationship | Phone | |
|---|---|---|---|
| Jennifer Wilson | Spouse | 0423 222 333 | jennifer.w@email.com |
| Tab | Content | Key Features |
|---|---|---|
| Overview | Personal info, employment details, emergency contacts, quick stats | Edit inline, status management, performance snapshot |
| Qualifications | Certifications, training records, compliance status | Expiry tracking, upload documents, verification status |
| Shifts | Shift history and upcoming shifts | Calendar view, completion stats, timesheet status |
| Availability | Weekly availability schedule, leave records | Recurring availability, exceptions, leave requests |
| Documents | Uploaded files: contracts, ID documents, certificates | Category tags, expiry dates, version control |
Qualification and certification tracking is a critical compliance function in NDIS service delivery. NDSS CRM maintains a comprehensive registry of all required certifications for each staff member, with automated expiry monitoring and alert generation. The system ensures that no staff member can be rostered for shifts if they have expired mandatory certifications.
| Qualification | Issue Date | Expiry Date | Days Remaining | Verification | Status |
|---|---|---|---|---|---|
| First Aid Certificate | 15 Mar 2025 | 15 Mar 2028 | 710 days | Verified | Valid |
| CPR Certificate | 15 Mar 2025 | 15 Mar 2027 | 345 days | Verified | Valid |
| NDIS Worker Screening Check | 01 Jan 2024 | 01 Jan 2029 | 1,002 days | Verified | Valid |
| Working With Children Check | 10 Jun 2023 | 10 Jun 2028 | 797 days | Verified | Valid |
| Manual Handling Certificate | 20 Apr 2024 | 20 Apr 2024 | 16 days | Verified | Expiring Soon |
| Certification | Issuing Body | Validity Period | Mandatory For | Renewal Process |
|---|---|---|---|---|
| First Aid Certificate | Registered Training Organisation (RTO) | 3 years | All support workers | Re-attend training course |
| CPR Certificate | RTO | 12 months | All support workers | Annual refresher course |
| NDIS Worker Screening Check | State/Territory screening authority | 5 years | All NDIS workers | Reapply to screening authority |
| Working With Children Check | State/Territory authority | 5 years | Staff working with minors | Renewal application |
| Manual Handling | RTO | 2 years | Support workers providing physical assistance | Re-attend training |
| Medication Administration | RTO | 3 years | Staff administering medication | Re-attend training and assessment |
| Behaviour Support | RTO | 2 years | Staff working with high-behaviour clients | Re-attend specialised training |
| Driver's Licence | State RTA | Varies | Staff providing transport | Standard licence renewal |
| Days Until Expiry | Alert Type | Recipients | Channel |
|---|---|---|---|
| 90 days | Advance Notice | Staff member | Email, In-app notification |
| 60 days | Reminder | Staff member, HR manager | Email, In-app notification |
| 30 days | Warning | Staff member, HR manager, direct supervisor | Email, SMS, In-app notification |
| 14 days | Urgent Warning | All above + Operations Manager | Email, SMS, In-app, Dashboard alert |
| 7 days | Critical Warning | All above + Admin | All channels |
| 0 days (Expired) | Expired | All above | All channels, rostering block enabled |
# Python Certification Expiry Checker (Scheduled Job)
from datetime import datetime, timedelta
class CertificationExpiryChecker:
ALERT_SCHEDULE = [
(90, 'advance_notice', ['staff']),
(60, 'reminder', ['staff', 'hr_manager']),
(30, 'warning', ['staff', 'hr_manager', 'supervisor']),
(14, 'urgent_warning', ['staff', 'hr_manager', 'supervisor', 'ops_manager']),
(7, 'critical_warning', ['staff', 'hr_manager', 'supervisor', 'ops_manager', 'admin']),
(0, 'expired', ['staff', 'hr_manager', 'supervisor', 'ops_manager', 'admin']),
]
def check_expiring_certifications(self):
today = datetime.now().date()
for days_threshold, alert_type, recipients in self.ALERT_SCHEDULE:
target_date = today + timedelta(days=days_threshold)
expiring = self.db.execute("""
SELECT sq.*, s.first_name, s.last_name, s.email, s.org_id
FROM staff_qualifications sq
JOIN staff s ON sq.staff_id = s.id
WHERE sq.expiry_date = %s
AND sq.status = 'active'
AND NOT EXISTS (
SELECT 1 FROM alert_log al
WHERE al.entity_id = sq.id
AND al.alert_type = %s
)
""", (target_date, alert_type))
for cert in expiring:
self.send_expiry_alert(cert, alert_type, recipients)
# Block rostering if expired
if days_threshold == 0:
self.block_rostering(cert['staff_id'], cert['id'])
When a mandatory certification expires, the system automatically prevents the affected staff member from being assigned to new shifts. Existing scheduled shifts within the next 7 days will trigger an urgent alert to the rostering officer to find a replacement. This enforcement is critical for maintaining NDIS compliance and worker safety standards.
Employment status management controls the operational state of a staff member within NDSS CRM. Status changes affect rostering eligibility, system access, and payroll processing.
| Status | Badge | Description | System Impact |
|---|---|---|---|
| Active | Active | Currently employed and available for rostering | Full system access, can be rostered, payroll active |
| On Leave | On Leave | Temporarily absent (annual leave, sick leave, parental leave) | Cannot be rostered, system access maintained, leave accrual paused |
| Suspended | Suspended | Temporarily suspended pending investigation | Cannot be rostered, system access revoked, payroll varies by circumstance |
| Terminated | Terminated | Employment has ended | All access revoked, removed from rosters, final pay processed |
| Onboarding | Onboarding | New staff member completing onboarding process | Limited system access, cannot be rostered until onboarding complete |
Every status change is recorded in the employment_history table, creating a complete audit trail of the staff member's employment lifecycle.
-- PostgreSQL: employment_history table
CREATE TABLE employment_history (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
staff_id UUID NOT NULL REFERENCES staff(id),
previous_status VARCHAR(20),
new_status VARCHAR(20) NOT NULL,
reason TEXT,
effective_date DATE NOT NULL,
changed_by UUID REFERENCES users(id),
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
Availability Management allows staff members to define their regular working hours and preferred shifts. This information is used by the rostering engine to match staff to shifts efficiently and avoid scheduling conflicts.
| Day | Available | Start Time | End Time | Preferred Hours | Notes |
|---|---|---|---|---|---|
| Monday | 7:00 AM | 5:00 PM | 8 hrs | - | |
| Tuesday | 7:00 AM | 5:00 PM | 8 hrs | - | |
| Wednesday | 7:00 AM | 5:00 PM | 8 hrs | - | |
| Thursday | 7:00 AM | 3:00 PM | 6 hrs | School pickup at 3:30 | |
| Friday | 8:00 AM | 4:00 PM | 8 hrs | - | |
| Saturday | - | - | - | Not available | |
| Sunday | - | - | - | Not available |
Staff members can submit leave requests through the platform. Leave types include:
| Leave Type | Accrual Rate | Approval Required | Impact on Roster |
|---|---|---|---|
| Annual Leave | 4 weeks/year (pro-rata) | Yes (Team Leader or HR) | Automatically blocks rostering for leave period |
| Sick Leave | 10 days/year (pro-rata) | Auto-approved, medical cert for 2+ days | Triggers unallocated shift alert for affected shifts |
| Personal Leave | 2 days/year | Yes (Team Leader) | Blocks rostering |
| Long Service Leave | Per state legislation | Yes (HR + Admin) | Blocks rostering, may require backfill planning |
| Parental Leave | Per legislation | Yes (HR + Admin) | Extended block, triggers succession planning |
| Unpaid Leave | N/A | Yes (HR + Admin) | Blocks rostering, payroll paused |
NDSS CRM uses a Role-Based Access Control (RBAC) system to manage staff permissions. Each staff member is assigned one or more roles, and each role grants a specific set of permissions that determine what the user can see and do within the platform.
| Role | Level | Description | Key Permissions |
|---|---|---|---|
| Super Admin | 1 | Full system access, can manage all settings | All permissions, system configuration |
| Organisation Admin | 2 | Organisation-level administration | All operational permissions, user management |
| Operations Manager | 3 | Manages day-to-day operations | Client/staff/roster/compliance management |
| HR Manager | 3 | Human resources management | Staff management, onboarding, training, leave |
| Finance Officer | 3 | Financial operations | Invoicing, payments, NDIS claims, reports |
| Support Coordinator | 4 | Manages client plans and goals | Client management, care plans, goals, notes |
| Team Leader | 4 | Manages a team of support workers | Team roster, shift approval, team performance |
| Compliance Officer | 4 | Manages compliance and incidents | Incident management, audits, certification oversight |
| Rostering Officer | 4 | Manages shift scheduling | Roster creation, shift allocation, availability |
| Clinical Lead | 4 | Manages clinical services | Care plans, health records, medication management |
| Support Worker | 5 | Front-line service delivery | View assigned shifts, progress notes, timesheets |
// Permission Group Definitions (TypeScript)
export const PERMISSION_GROUPS = {
clients: {
'clients.view': 'View client list and profiles',
'clients.create': 'Create new client records',
'clients.edit': 'Edit existing client records',
'clients.delete': 'Delete/archive client records',
'clients.funding': 'View and manage client funding',
'clients.goals': 'Manage client goals',
'clients.notes': 'Create and view progress notes',
'clients.care_plan': 'Manage care plans',
},
staff: {
'staff.view': 'View staff directory and profiles',
'staff.create': 'Create new staff records',
'staff.edit': 'Edit existing staff records',
'staff.delete': 'Delete/archive staff records',
'staff.qualifications': 'Manage staff qualifications',
'staff.availability': 'View/edit staff availability',
},
rostering: {
'shifts.view': 'View shift schedules',
'shifts.create': 'Create new shifts',
'shifts.edit': 'Edit existing shifts',
'shifts.delete': 'Cancel/delete shifts',
'shifts.allocate': 'Assign staff to shifts',
'timesheets.view': 'View timesheets',
'timesheets.approve': 'Approve timesheets',
},
finance: {
'invoices.view': 'View invoices',
'invoices.create': 'Create invoices',
'invoices.approve': 'Approve invoices',
'claims.view': 'View NDIS claims',
'claims.submit': 'Submit NDIS claims',
'reports.financial': 'Access financial reports',
},
compliance: {
'incidents.view': 'View incidents',
'incidents.create': 'Report incidents',
'incidents.manage': 'Manage and resolve incidents',
'audits.view': 'View audit records',
'audits.manage': 'Manage audits',
},
admin: {
'admin.settings': 'Access admin settings',
'admin.users': 'Manage user accounts',
'admin.roles': 'Manage roles and permissions',
'admin.preview_role': 'Preview other roles',
'admin.audit_log': 'View system audit log',
},
} as const;
The Staff Performance module provides metrics and analytics on individual staff performance, including shift completion rates, client feedback scores, compliance adherence, and timeliness. These metrics are aggregated by a Python analytics service and displayed within the staff profile.
| Metric | Calculation | Target | Data Source |
|---|---|---|---|
| Shift Completion Rate | (Completed shifts / Total assigned shifts) x 100 | > 95% | shifts table |
| Punctuality Rate | (On-time clock-ins / Total clock-ins) x 100 | > 90% | timesheets table |
| Timesheet Compliance | (Timesheets submitted within 24hrs / Total) x 100 | > 95% | timesheets table |
| Progress Note Rate | (Shifts with notes / Completed shifts) x 100 | 100% | progress_notes + shifts |
| Certification Compliance | (Valid certifications / Required certifications) x 100 | 100% | staff_qualifications |
| Client Satisfaction | Average rating from client/guardian feedback forms | > 4.0/5.0 | feedback table |
| Incident Involvement | Number of incidents involving this staff member | Minimise | incidents table |
| Training Completion | (Completed training / Assigned training) x 100 | 100% | training_records |
# Python Performance Analytics Service
class StaffPerformanceService:
def calculate_performance_metrics(self, staff_id: str, period_start: date, period_end: date) -> dict:
# Shift completion rate
total_shifts = self.db.execute_scalar(
"SELECT COUNT(*) FROM shifts WHERE staff_id = %s AND date BETWEEN %s AND %s",
(staff_id, period_start, period_end)
)
completed_shifts = self.db.execute_scalar(
"SELECT COUNT(*) FROM shifts WHERE staff_id = %s AND date BETWEEN %s AND %s AND status = 'completed'",
(staff_id, period_start, period_end)
)
completion_rate = (completed_shifts / total_shifts * 100) if total_shifts > 0 else 0
# Punctuality rate
on_time_count = self.db.execute_scalar("""
SELECT COUNT(*) FROM timesheets t
JOIN shifts s ON t.shift_id = s.id
WHERE t.staff_id = %s AND s.date BETWEEN %s AND %s
AND t.clock_in <= s.start_time + INTERVAL '5 minutes'
""", (staff_id, period_start, period_end))
total_clocked = self.db.execute_scalar(
"SELECT COUNT(*) FROM timesheets WHERE staff_id = %s AND created_at BETWEEN %s AND %s",
(staff_id, period_start, period_end)
)
punctuality_rate = (on_time_count / total_clocked * 100) if total_clocked > 0 else 0
return {
'shift_completion_rate': round(completion_rate, 1),
'punctuality_rate': round(punctuality_rate, 1),
'total_shifts': total_shifts,
'completed_shifts': completed_shifts,
'period': {'start': period_start.isoformat(), 'end': period_end.isoformat()},
}
Staff performance metrics can be exported as part of formal performance review documentation. The Python analytics service generates comprehensive performance reports in PDF format that include all metrics, trend charts, and comparison against organisational benchmarks. These reports can be accessed from the Staff Profile under the Overview tab by administrators and HR managers.