diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index 2f5350ab..4e68d707 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -1979,7 +1979,7 @@ "deleteRole": "Delete Role", "roleName": "Role Name", "roleDescription": "Description", - "roleNamePlaceholder": "e.g., Front Desk", + "roleNamePlaceholder": "e.g., Support Staff", "roleDescriptionPlaceholder": "Brief description of this role's responsibilities", "permissions": "Permissions", "menuAccess": "Menu Access", diff --git a/frontend/src/pages/help/HelpSettingsStaffRoles.tsx b/frontend/src/pages/help/HelpSettingsStaffRoles.tsx index 0f5f7a8c..ba7806f4 100644 --- a/frontend/src/pages/help/HelpSettingsStaffRoles.tsx +++ b/frontend/src/pages/help/HelpSettingsStaffRoles.tsx @@ -84,28 +84,28 @@ const HelpSettingsStaffRoles: React.FC = () => {
-

Full Access Staff

+

Manager

- Access to all menu items and all dangerous permissions. Best for managers and supervisors. -

-
-
-
- -

Limited Staff

-
-

- Access to Scheduler, Customers, and Messages only. No dangerous permissions. Best for general staff. + Full access to all features and settings. Best for supervisors and team leads.

-

Front Desk

+

Support Staff

- Access to Scheduler, Services, Customers, and Messages. No delete permissions. Best for reception. + Customer-facing operations including scheduling, customers, tickets, messages, and payments. +

+
+
+
+ +

Staff

+
+

+ Basic access to own schedule and availability. Best for general staff members.

@@ -406,7 +406,7 @@ const HelpSettingsStaffRoles: React.FC = () => {

Start with Default Roles

- Use the built-in roles (Full Access, Limited, Front Desk) as templates when creating custom roles + Use the built-in roles (Manager, Support Staff, Staff) as templates when creating custom roles

diff --git a/smoothschedule/smoothschedule/identity/users/migrations/0016_rename_default_staff_roles.py b/smoothschedule/smoothschedule/identity/users/migrations/0016_rename_default_staff_roles.py new file mode 100644 index 00000000..18b7057a --- /dev/null +++ b/smoothschedule/smoothschedule/identity/users/migrations/0016_rename_default_staff_roles.py @@ -0,0 +1,72 @@ +""" +Migration to rename default staff roles to more intuitive names. + +Renames: +- "Full Access Staff" -> "Manager" +- "Front Desk" -> "Support Staff" +- "Limited Staff" -> "Staff" +""" + +from django.db import migrations + + +ROLE_RENAMES = { + 'Full Access Staff': 'Manager', + 'Front Desk': 'Support Staff', + 'Limited Staff': 'Staff', +} + +ROLE_DESCRIPTIONS = { + 'Manager': 'Full access to all features and settings', + 'Support Staff': 'Customer-facing operations and scheduling', + 'Staff': 'Basic access to own schedule and availability', +} + + +def rename_staff_roles(apps, schema_editor): + """Rename default staff roles to new names.""" + StaffRole = apps.get_model('users', 'StaffRole') + + for old_name, new_name in ROLE_RENAMES.items(): + StaffRole.objects.filter( + name=old_name, + is_default=True + ).update( + name=new_name, + description=ROLE_DESCRIPTIONS.get(new_name, '') + ) + + +def reverse_migration(apps, schema_editor): + """Reverse: rename roles back to original names.""" + StaffRole = apps.get_model('users', 'StaffRole') + + reverse_renames = {v: k for k, v in ROLE_RENAMES.items()} + original_descriptions = { + 'Full Access Staff': 'Complete access to all features (similar to manager)', + 'Front Desk': 'Access to scheduling, customers, and basic operations', + 'Limited Staff': 'Basic access to own schedule only', + } + + for new_name, old_name in reverse_renames.items(): + StaffRole.objects.filter( + name=new_name, + is_default=True + ).update( + name=old_name, + description=original_descriptions.get(old_name, '') + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0015_update_staff_invitation_role_choices'), + ] + + operations = [ + migrations.RunPython( + rename_staff_roles, + reverse_code=reverse_migration, + ), + ] diff --git a/smoothschedule/smoothschedule/identity/users/models.py b/smoothschedule/smoothschedule/identity/users/models.py index fd010710..d88b4855 100644 --- a/smoothschedule/smoothschedule/identity/users/models.py +++ b/smoothschedule/smoothschedule/identity/users/models.py @@ -26,7 +26,7 @@ class User(AbstractUser): # Tenant-level roles (access within single tenant) TENANT_OWNER = 'TENANT_OWNER', _('Tenant Owner') - # TENANT_MANAGER removed - use TENANT_STAFF with "Full Access Staff" role instead + # TENANT_MANAGER removed - use TENANT_STAFF with "Manager" role instead TENANT_STAFF = 'TENANT_STAFF', _('Tenant Staff') # Customer role (end users of the tenant) diff --git a/smoothschedule/smoothschedule/identity/users/staff_permissions.py b/smoothschedule/smoothschedule/identity/users/staff_permissions.py index f3bfc3c5..e2aba148 100644 --- a/smoothschedule/smoothschedule/identity/users/staff_permissions.py +++ b/smoothschedule/smoothschedule/identity/users/staff_permissions.py @@ -261,12 +261,12 @@ def get_default_permissions_for_role(role_name: str) -> dict: # Default role configurations # These are created for each tenant during migration and on new tenant creation DEFAULT_ROLES = { - 'Full Access Staff': { - 'description': 'Complete access to all features (similar to manager)', + 'Manager': { + 'description': 'Full access to all features and settings', 'permissions': {k: True for k in ALL_PERMISSIONS.keys()}, }, - 'Front Desk': { - 'description': 'Access to scheduling, customers, and basic operations', + 'Support Staff': { + 'description': 'Customer-facing operations and scheduling', 'permissions': { 'can_access_dashboard': True, 'can_access_scheduler': True, @@ -274,11 +274,13 @@ DEFAULT_ROLES = { 'can_access_my_availability': True, 'can_access_customers': True, 'can_access_tickets': True, + 'can_access_messages': True, + 'can_access_payments': True, 'can_cancel_appointments': True, }, }, - 'Limited Staff': { - 'description': 'Basic access to own schedule only', + 'Staff': { + 'description': 'Basic access to own schedule and availability', 'permissions': { 'can_access_dashboard': True, 'can_access_my_schedule': True, diff --git a/smoothschedule/smoothschedule/identity/users/tests/test_staff_roles.py b/smoothschedule/smoothschedule/identity/users/tests/test_staff_roles.py index 350a49f2..17e6234a 100644 --- a/smoothschedule/smoothschedule/identity/users/tests/test_staff_roles.py +++ b/smoothschedule/smoothschedule/identity/users/tests/test_staff_roles.py @@ -285,27 +285,27 @@ class TestDefaultRoles: """Default roles are defined""" from smoothschedule.identity.users.staff_permissions import DEFAULT_ROLES - assert 'Full Access Staff' in DEFAULT_ROLES - assert 'Front Desk' in DEFAULT_ROLES - assert 'Limited Staff' in DEFAULT_ROLES + assert 'Manager' in DEFAULT_ROLES + assert 'Support Staff' in DEFAULT_ROLES + assert 'Staff' in DEFAULT_ROLES - def test_full_access_has_all_permissions(self): - """Full Access Staff has all permissions enabled""" + def test_manager_has_all_permissions(self): + """Manager has all permissions enabled""" from smoothschedule.identity.users.staff_permissions import DEFAULT_ROLES, ALL_PERMISSIONS - full_access = DEFAULT_ROLES['Full Access Staff'] - permissions = full_access['permissions'] + manager = DEFAULT_ROLES['Manager'] + permissions = manager['permissions'] for key in ALL_PERMISSIONS.keys(): assert key in permissions, f"Missing permission: {key}" assert permissions[key] is True, f"Permission not enabled: {key}" - def test_limited_staff_has_basic_permissions(self): - """Limited Staff has only basic permissions""" + def test_staff_has_basic_permissions(self): + """Staff has only basic permissions""" from smoothschedule.identity.users.staff_permissions import DEFAULT_ROLES - limited = DEFAULT_ROLES['Limited Staff'] - permissions = limited['permissions'] + staff = DEFAULT_ROLES['Staff'] + permissions = staff['permissions'] # Should have basic permissions assert permissions.get('can_access_dashboard') is True diff --git a/smoothschedule/smoothschedule/scheduling/schedule/management/commands/reseed_demo.py b/smoothschedule/smoothschedule/scheduling/schedule/management/commands/reseed_demo.py index 5951aaf3..adfd918d 100644 --- a/smoothschedule/smoothschedule/scheduling/schedule/management/commands/reseed_demo.py +++ b/smoothschedule/smoothschedule/scheduling/schedule/management/commands/reseed_demo.py @@ -274,18 +274,18 @@ class Command(BaseCommand): if created: manager.set_password("test123") manager.save() - # Assign Full Access Staff role - full_access_role = StaffRole.objects.filter( + # Assign Manager role + manager_role = StaffRole.objects.filter( tenant=tenant, - name="Full Access Staff" + name="Manager" ).first() - if full_access_role and manager.staff_role != full_access_role: - manager.staff_role = full_access_role + if manager_role and manager.staff_role != manager_role: + manager.staff_role = manager_role manager.save(update_fields=['staff_role']) users["manager"] = manager if not self.quiet: status = self.style.SUCCESS("CREATED") if created else self.style.WARNING("EXISTS") - self.stdout.write(f" {status} {manager.email} (Full Access Staff)") + self.stdout.write(f" {status} {manager.email} (Manager)") # Staff members (stylists and spa therapists) staff_data = [ @@ -716,17 +716,17 @@ class Command(BaseCommand): """Assign staff roles to demo staff members.""" staff_users = tenant_users.get("staff", []) - # Role assignments: first gets Full Access, some get Front Desk, rest get Limited + # Role assignments: mix of Manager, Support Staff, and Staff roles role_assignments = { - 0: "Full Access Staff", # Sophia - 1: "Front Desk", # Emma - 2: "Limited Staff", # Olivia - 3: "Front Desk", # Isabella - 4: "Limited Staff", # Mia + 0: "Manager", # Sophia - Senior Stylist gets manager role + 1: "Support Staff", # Emma - handles front desk duties + 2: "Staff", # Olivia - basic access + 3: "Support Staff", # Isabella - handles customers + 4: "Staff", # Mia - basic access } for i, user in enumerate(staff_users): - role_name = role_assignments.get(i, "Limited Staff") + role_name = role_assignments.get(i, "Staff") try: # Get tenant from user if user.tenant: diff --git a/smoothschedule/smoothschedule/scheduling/schedule/management/commands/seed_data.py b/smoothschedule/smoothschedule/scheduling/schedule/management/commands/seed_data.py index 63d8a938..5312c522 100644 --- a/smoothschedule/smoothschedule/scheduling/schedule/management/commands/seed_data.py +++ b/smoothschedule/smoothschedule/scheduling/schedule/management/commands/seed_data.py @@ -259,7 +259,7 @@ class Command(BaseCommand): "last_name": "Manager", "tenant": tenant, "phone": "555-100-0002", - "_assign_full_access": True, # Flag to assign Full Access Staff role + "_assign_manager_role": True, # Flag to assign Manager role }, { "username": "staff@demo.com", @@ -277,7 +277,7 @@ class Command(BaseCommand): manager_user = None # Track manager user separately for user_data in tenant_users: password = user_data.pop("password") - assign_full_access = user_data.pop("_assign_full_access", False) + assign_manager_role = user_data.pop("_assign_manager_role", False) user, created = User.objects.get_or_create( username=user_data["username"], defaults=user_data, @@ -289,14 +289,14 @@ class Command(BaseCommand): else: status = self.style.WARNING("EXISTS") - # Assign Full Access Staff role if flagged - if assign_full_access: - full_access_role = StaffRole.objects.filter( + # Assign Manager role if flagged + if assign_manager_role: + manager_role = StaffRole.objects.filter( tenant=tenant, - name="Full Access Staff" + name="Manager" ).first() - if full_access_role and user.staff_role != full_access_role: - user.staff_role = full_access_role + if manager_role and user.staff_role != manager_role: + user.staff_role = manager_role user.save(update_fields=['staff_role']) manager_user = user # Track for resource creation