Team

Team owns staff invites, role editing, team member management, and the public team directory.

On this page

Where to look

AreaMaintainer reference
Admin route
Implementation referencesrc/app/(dashboard)/admin/team/page.tsx
Public routes
Implementation referencesrc/app/(marketing)/team, src/app/(marketing)/team/[id]
Access server code
Implementation referencesrc/features/team/server/access/actions, queries, services, persistence, schemas
Public directory server code
Implementation referencesrc/features/team/server/public-directory
Access UI
Implementation referencesrc/features/team/ui/access
Public directory UI
Implementation referencesrc/features/team/ui/public-directory
Shared types
Implementation referencesrc/features/team/shared/access, src/features/team/shared/public-directory
Implementation reference3 areas

These Product code locations explain how the documented behavior is implemented. Expand them when you are ready to customize or maintain this area.

Access management

Admin team pages manage staff, invites, custom roles, permissions, and member status through feature-owned server actions.

  • src/app/(dashboard)/admin/team/page.tsx
  • src/features/team/server/access/actions/staff-invites.ts
  • src/features/team/server/access/actions/custom-roles.ts
  • src/features/team/server/access/actions/team-members.ts

Role services and persistence

Custom role, permission, member, and invite services keep RBAC behavior separate from UI.

  • src/features/team/server/access/services/custom-role.ts
  • src/features/team/server/access/services/permissions.ts
  • src/features/team/server/access/persistence/custom-roles.ts
  • src/lib/auth/rbac/features.ts

Public directory

Public team pages use a separate directory domain with its own queries, actions, repository, schemas, and UI.

  • src/app/(marketing)/team/page.tsx
  • src/app/(marketing)/team/[id]/page.tsx
  • src/features/team/server/public-directory/queries.ts
  • src/features/team/server/public-directory/actions.ts
  • src/features/team/ui/public-directory/dashboard.tsx

Reference paths are relative to the Shipflash-Product checkout.

Team access flow

  1. 1

    Gate admin work

    Team management runs behind admin access before invite, role, permission, or member actions execute.

    Relevant Product code
    • src/app/(dashboard)/admin/team/page.tsx
    • src/lib/auth/guards/route.ts
  2. 2

    Validate action payloads

    Invite and role schemas normalize user input before services apply business rules.

    Relevant Product code
    • src/features/team/server/access/schemas/invite.ts
    • src/features/team/server/access/actions/permission-form.ts
  3. 3

    Apply RBAC changes through services

    Role and permission services write through persistence modules and keep navigation feature gates aligned.

    Relevant Product code
    • src/features/team/server/access/services/custom-role.ts
    • src/features/team/server/access/services/permissions.ts
    • src/lib/auth/rbac/nav-config.ts
  4. 4

    Keep public directory separate

    Public team member content uses its own repository and does not grant staff access by itself.

    Relevant Product code
    • src/features/team/server/public-directory/repository.ts
    • src/features/team/server/public-directory/actions.ts

Staff invite action

Use this example as a starting point, then adapt it to your product's rules and configuration.

Invite creation checks write access, validates the form, delegates to a service, and revalidates the admin team route.

ts
export async function createStaffInvite(prevState: InviteState, formData: FormData): Promise<InviteState> {
  const profile = await getActiveProfile();

  const accessCheck = await assertTeamWriteAccess(profile);
  if (!accessCheck.success) return { error: accessCheck.error };

  const rawEmail = formData.get("email")?.toString().toLowerCase().trim();
  const rawAssignedRole = formData.get("assignedRole")?.toString() || null;

  const result = InviteSchema.safeParse({
    email: rawEmail,
    assignedRole: rawAssignedRole,
  });

  if (!result.success) {
    return { error: result.error.errors[0].message };
  }
Source reference
  • src/features/team/server/access/actions/staff-invites.ts

Team rules

  • Use canonical default roles: super_admin and user.
  • Check authorization before role edits, invite actions, and team member changes.
  • Keep public directory content separate from staff access management.
  • Audit important admin changes.