Skip to content

Teams — URLs

Responsibilities

The Teams app URL configuration exposes the HTTP routes for:

  • creating, reading, updating, deactivating, and reactivating teams
  • listing all active teams in the current org
  • listing the current user’s teams
  • listing members of a specific team
  • listing the current user’s teammates
  • adding users to teams
  • listing visible team membership pairs
  • listing visible richer team membership rows
  • updating membership role
  • switching primary team membership
  • deactivating and reactivating memberships

It is responsible for:

  • mapping stable route paths to views
  • naming routes for reverse lookups and tests
  • grouping team and membership endpoints coherently

It is not responsible for:

  • authorization logic
  • business rules
  • validation
  • serialization behavior

Those concerns are handled by:

  • permissions
  • services
  • serializers
  • views

Route groups

Team routes

These routes expose team-level creation, discovery, detail, and lifecycle management.

teams/

  • Name
  • teams-create
  • View
  • TeamCreateView
  • Methods
  • POST
  • Purpose
  • Create a new team in the current organization
  • Access
  • Privileged org users only (owner, admin, manager)

teams/all/

  • Name
  • teams-all-in-org
  • View
  • AllTeamsInOrgView
  • Methods
  • GET
  • Purpose
  • Return all active teams in the current organization
  • Access
  • Privileged org users only (owner, admin, manager)

teams/my/

  • Name
  • teams-my-in-org
  • View
  • MyTeamsInOrgView
  • Methods
  • GET
  • Purpose
  • Return the active teams the current user belongs to in the current organization

teams/<int:team_id>/

  • Name
  • teams-detail
  • View
  • TeamDetailView
  • Methods
  • GET
  • Purpose
  • Return details for one team in the current organization
  • Path params
  • team_id

teams/<int:team_id>/update/

  • Name
  • teams-update
  • View
  • TeamUpdateView
  • Methods
  • PATCH
  • Purpose
  • Update one team in the current organization
  • Path params
  • team_id
  • Access
  • Privileged org users only (owner, admin, manager)

teams/<int:team_id>/deactivate/

  • Name
  • teams-deactivate
  • View
  • TeamDeactivateView
  • Methods
  • POST
  • Purpose
  • Deactivate one team in the current organization
  • Path params
  • team_id
  • Access
  • Privileged org users only (owner, admin, manager)

teams/<int:team_id>/reactivate/

  • Name
  • teams-reactivate
  • View
  • TeamReactivateView
  • Methods
  • POST
  • Purpose
  • Reactivate one team in the current organization
  • Path params
  • team_id
  • Access
  • Privileged org users only (owner, admin, manager)

Membership and visibility routes

These routes expose team-member visibility and membership management data.

teams/my/members/

  • Name
  • teams-my-members-in-org
  • View
  • MyTeamMembersInOrgView
  • Methods
  • GET
  • Purpose
  • Return users who share at least one team with the current user in the current org

teams/<int:team_id>/members/

  • Name
  • teams-members-by-team
  • View
  • TeamMembersByTeamView
  • Methods
  • GET
  • Purpose
  • Return active members of a specific team in the current org
  • Path params
  • team_id

Visibility rules - Privileged org users can view any team in the org - Non-privileged users can only view teams they belong to


teams/<int:team_id>/members/add/

  • Name
  • teams-membership-create
  • View
  • TeamMembershipCreateView
  • Methods
  • POST
  • Purpose
  • Add a user to a specific team
  • Path params
  • team_id
  • Access
  • Privileged org users only (owner, admin, manager)

teams/memberships/pairs/

  • Name
  • teams-membership-pairs-in-org
  • View
  • TeamMembershipPairsInOrgView
  • Methods
  • GET
  • Purpose
  • Return compact visible membership pairs (team_id, user_id) in the current org

teams/memberships/

  • Name
  • teams-memberships-in-org
  • View
  • TeamMembershipsInOrgView
  • Methods
  • GET
  • Purpose
  • Return richer visible team membership rows in the current org

teams/memberships/<int:membership_id>/role/

  • Name
  • teams-membership-role-update
  • View
  • TeamMembershipRoleUpdateView
  • Methods
  • PATCH
  • Purpose
  • Change the role of a specific team membership
  • Path params
  • membership_id
  • Access
  • Privileged org users only (owner, admin, manager)

teams/memberships/<int:membership_id>/primary/

  • Name
  • teams-membership-primary-update
  • View
  • TeamMembershipPrimaryUpdateView
  • Methods
  • POST
  • Purpose
  • Set a specific membership as the user’s primary team membership
  • Path params
  • membership_id
  • Access
  • Privileged org users only (owner, admin, manager)

teams/memberships/<int:membership_id>/deactivate/

  • Name
  • teams-membership-deactivate
  • View
  • TeamMembershipDeactivateView
  • Methods
  • POST
  • Purpose
  • Deactivate a specific team membership
  • Path params
  • membership_id
  • Access
  • Privileged org users only (owner, admin, manager)

teams/memberships/<int:membership_id>/reactivate/

  • Name
  • teams-membership-reactivate
  • View
  • TeamMembershipReactivateView
  • Methods
  • POST
  • Purpose
  • Reactivate a specific team membership
  • Path params
  • membership_id
  • Access
  • Privileged org users only (owner, admin, manager)

URL relationships

flowchart TD
    URLConf["teams/urls.py"]

    TeamRoutes["Team routes"]
    MembershipRoutes["Membership routes"]

    URLConf --> TeamRoutes
    URLConf --> MembershipRoutes

    TeamRoutes --> TeamCreateView["TeamCreateView"]
    TeamRoutes --> AllTeamsInOrgView["AllTeamsInOrgView"]
    TeamRoutes --> MyTeamsInOrgView["MyTeamsInOrgView"]
    TeamRoutes --> TeamDetailView["TeamDetailView"]
    TeamRoutes --> TeamUpdateView["TeamUpdateView"]
    TeamRoutes --> TeamDeactivateView["TeamDeactivateView"]
    TeamRoutes --> TeamReactivateView["TeamReactivateView"]

    MembershipRoutes --> MyTeamMembersInOrgView["MyTeamMembersInOrgView"]
    MembershipRoutes --> TeamMembersByTeamView["TeamMembersByTeamView"]
    MembershipRoutes --> TeamMembershipCreateView["TeamMembershipCreateView"]
    MembershipRoutes --> TeamMembershipPairsInOrgView["TeamMembershipPairsInOrgView"]
    MembershipRoutes --> TeamMembershipsInOrgView["TeamMembershipsInOrgView"]
    MembershipRoutes --> TeamMembershipRoleUpdateView["TeamMembershipRoleUpdateView"]
    MembershipRoutes --> TeamMembershipPrimaryUpdateView["TeamMembershipPrimaryUpdateView"]
    MembershipRoutes --> TeamMembershipDeactivateView["TeamMembershipDeactivateView"]
    MembershipRoutes --> TeamMembershipReactivateView["TeamMembershipReactivateView"]

Routing style

The Teams app uses explicit path(...) routes rather than a router.

This is appropriate because:

  • the number of endpoints is still moderate and well-bounded
  • endpoints are not standard CRUD-only resources
  • route names are heavily used in tests
  • several membership routes are action-oriented rather than plain modelset actions

Current-org dependency

All team routes are scoped to the current organization and should be used with request org context already resolved.

That generally means requests include:

  • X-ORG-ID
  • optionally X-ORG-SLUG

And the views rely on:

  • HasCurrentOrg

Without current-org context:

  • requests may fail with 400 or 403
  • or the view may never reach team-level logic

Reverse lookup examples

Team routes

  • reverse("teams-create")
  • reverse("teams-all-in-org")
  • reverse("teams-my-in-org")
  • reverse("teams-detail", kwargs={"team_id": ...})
  • reverse("teams-update", kwargs={"team_id": ...})
  • reverse("teams-deactivate", kwargs={"team_id": ...})
  • reverse("teams-reactivate", kwargs={"team_id": ...})

Membership routes

  • reverse("teams-my-members-in-org")
  • reverse("teams-members-by-team", kwargs={"team_id": ...})
  • reverse("teams-membership-create", kwargs={"team_id": ...})
  • reverse("teams-membership-pairs-in-org")
  • reverse("teams-memberships-in-org")
  • reverse("teams-membership-role-update", kwargs={"membership_id": ...})
  • reverse("teams-membership-primary-update", kwargs={"membership_id": ...})
  • reverse("teams-membership-deactivate", kwargs={"membership_id": ...})
  • reverse("teams-membership-reactivate", kwargs={"membership_id": ...})

URL design notes

1. teams/ prefix is kept stable

All routes are grouped under teams/ for consistency and discoverability.

This keeps the app easy to reason about and prevents route sprawl.


2. Team vs membership routes are separated

There is a natural split between:

  • team management and listing routes
  • membership visibility and management routes

That split mirrors the app structure:

  • views/teams.py
  • views/memberships.py

3. Compact and rich membership endpoints both exist intentionally

The app exposes two membership list styles:

Compact

  • teams/memberships/pairs/

Rich

  • teams/memberships/

This avoids forcing every client to fetch heavier payloads when only graph-style IDs are needed.


4. Team-member visibility is addressed directly

The route:

  • teams/<team_id>/members/

is intentionally explicit and reads naturally from a client perspective.

It also keeps permission logic simple:

  • resolve one team
  • validate visibility
  • return members

5. Management actions are explicit

Rather than hiding important team and membership mutations behind overloaded generic endpoints, the app uses explicit action routes such as:

  • teams/<team_id>/deactivate/
  • teams/memberships/<membership_id>/primary/

This keeps intent clear and improves test readability.