4.0 KiB
Team Management Integration — Current Implementation
This document describes the current team-management integration in the live codebase.
Source of truth:
apps/api/src/modules/team/team.routes.tsapps/api/src/services/teamService.tsapps/dashboard/src/hooks/useTeam.tsapps/dashboard/src/app/(dashboard)/team/page.tsxapps/dashboard/src/app/reset-password/*
Current Model
Team management is local to RentalDriveGo. It no longer depends on Clerk.
The live flow is:
- an owner invites a staff member from the dashboard
- the API creates a pending
Employee - the API generates a password-reset token
- an email is sent with a reset-password link
- the invited employee sets a password through the dashboard reset-password page
- the employee can then sign in through the standard employee login flow
There is no webhook step in the active implementation.
Backend Integration
The team router is already mounted by the main API app in apps/api/src/app.ts under:
/api/v1/team
The public webhook placeholder under /api/v1/webhooks/clerk is intentionally disabled and should not be used for team onboarding.
Team endpoints
GET /api/v1/teamGET /api/v1/team/statsPOST /api/v1/team/invitePATCH /api/v1/team/:id/rolePOST /api/v1/team/:id/deactivatePOST /api/v1/team/:id/reactivateDELETE /api/v1/team/:id
Auth and authorization
These routes are protected by:
- employee JWT auth
- tenant resolution
- subscription guard
- role checks inside the router and service
Important rules in the current implementation:
- only the
OWNERcan invite, change roles, deactivate/reactivate, or remove team members - invited team members cannot be created with the
OWNERrole - the account owner cannot be deactivated or removed through team endpoints
Invite Email Flow
Invitations are generated in apps/api/src/services/teamService.ts.
Current behavior:
- a pending employee row is created
passwordResetTokenandpasswordResetExpiresAtare populated- the invite email links directly to the dashboard reset-password page
Expected URL shape:
{DASHBOARD_URL}/reset-password?token=...
Relevant environment variables:
DASHBOARD_URL=https://your-host/dashboard
NEXT_PUBLIC_DASHBOARD_URL=https://your-host/dashboard
NEXT_PUBLIC_API_URL=https://your-host/api/v1
Dashboard Integration
The team UI lives here:
apps/dashboard/src/app/(dashboard)/team/page.tsxapps/dashboard/src/hooks/useTeam.tsapps/dashboard/src/components/team/InviteModal.tsxapps/dashboard/src/components/team/EditMemberModal.tsxapps/dashboard/src/components/team/PermissionsMatrix.tsx
The dashboard consumes the team API directly through apiFetch(...).
Dashboard page behavior
- loads members from
/team - loads summary counts from
/team/stats - opens invite/edit flows through local modals
- updates local state after invite, role change, deactivate/reactivate, and removal
Password Setup / Invite Acceptance
The active invite-acceptance mechanism is the dashboard reset-password flow, not a Clerk callback flow.
Relevant pages:
apps/dashboard/src/app/reset-password/page.tsxapps/dashboard/src/app/reset-password/ResetPasswordPageClient.tsx
This means:
- there is no
__clerk_ticket - there is no Clerk redirect callback
- there is no employee activation webhook
Invite completion is simply password setup using the token created by the API.
Request Typing
The request object is extended in the API so team routes can rely on:
req.employeereq.companyreq.companyId
Those values are attached by the company auth and tenant middleware before team handlers run.
What Was Removed
These older integration assumptions are no longer valid:
- Clerk webhooks
- Clerk invitation acceptance
- Clerk
user.createdactivation flow /webhooks/clerkas a required part of team onboarding@clerk/nextjsintegration in the dashboard team flow
If this functionality returns in the future, it should be documented as a new integration rather than assumed from this file.