T1 Electrical SolutionsT1 Platform Docs
Platform

Auth and Roles

Authentication surfaces, firewalls, roles, and scope checks.

Auth and Roles

Authentication is Auth0-based, but the app uses different Symfony firewalls for browser portals and API traffic.

Firewalls

Defined in app/config/packages/security.yaml:

FirewallPatternAuthenticatorProviderNotes
api_docs^/api/docsnonenonePublic API docs.
api_v2_docs^/api/v2/docsnonenonePublic API v2 docs.
portal`^/(supervisorpayrollfinanceelectrician
admin`^/(adminloginauthxero
api^/apiAuth0AuthenticatorUserProviderStateless JWT API.
mainfallbackdefault lazyUserProviderFallback for non-API routes.

Access control

Important rules:

  • /login, /logout, /admin/logout, and /auth/callback are public.
  • /api/docs and /api/v2/docs are public and must be listed before /api.
  • /xero, portals, and debug routes require full authentication.
  • /api requires ROLE_USER.
  • /admin/clients/{id}/projects allows ROLE_ADMIN and ROLE_CLIENT_ADMIN.
  • /admin generally requires ROLE_ADMIN.

Role and scope model

The code uses both broad user type and client/project relationships.

  • UserType decides the broad persona.
  • ClientMembershipRole decides client-scoped responsibilities.
  • Project.clientSupervisors identifies users who can review work for a project.
  • Client.clientAdmins and PortalClientScopeService identify client-admin scope.
  • Project assigned electricians/users identify who can submit work.

Timesheet edit policy

TimesheetEditPolicy centralizes which roles can edit which timesheet fields:

ActorAllowed edits
Platform AdminAny field.
Electrician ownerAny field only while the timesheet is draft or rejected.
SupervisorJob code, cost code, status, signature, and location fields, only before sign-off. Status transition is restricted to accepted or rejected from submitted/accepted.
Client AdminJob code and cost code only, and only before approval.
PayrollNo direct timesheet editing through this policy.

Changes are logged by TimesheetChangeLogger as one TimesheetChangeLog row per changed field path, grouped by a change-set UUID.

On this page