Teams — views¶
Responsibilities¶
The views in the Teams app expose the HTTP API for:
- listing all teams in the current org
- listing the current user’s teams
- creating, reading, updating, deactivating, and reactivating teams
- listing members of a specific team
- listing the current user’s teammates across their teams
- listing lightweight team membership pairs for graph-like frontend use
- listing richer team membership rows
- adding users to teams
- updating team membership role
- switching primary team membership
- deactivating and reactivating team memberships
They are responsible for:
- enforcing authentication and current-org scoping
- validating request payloads with serializers
- calling the service layer
- returning API responses
- keeping payload shape stable
They are not responsible for:
- embedding privilege logic inline
- enforcing team/org consistency themselves
- handling membership business rules directly
- performing serializer-independent data assembly when a serializer is available
View modules¶
teams.views.teams¶
Contains views focused on team objects and team lifecycle actions.
teams.views.memberships¶
Contains views focused on team membership visibility and membership management.
teams.views.teams¶
AllTeamsInOrgView¶
Returns all active teams in the current organization.
Permissions
- IsAuthenticated
- HasCurrentOrg
Behavior
- Requires the current user to be privileged in the org
- Privileged org roles:
- owner
- admin
- manager
- Calls:
- teams.services.team.is_privileged_in_org
- teams.services.team.list_all_teams_in_org
- Serializes with:
- TeamListSerializer
Response
- 200 OK with all active teams in the current org
- 403 Forbidden if the user lacks sufficient org privilege
Purpose - Used for admin/manager team overviews - Supports management screens and full-team browsing
TeamCreateView¶
Creates a team in the current organization.
Permissions
- IsAuthenticated
- HasCurrentOrg
Behavior
- Validates input with:
- TeamCreateSerializer
- Calls:
- teams.services.team.validate_team_management
- teams.services.team.create_team
- Serializes with:
- TeamDetailSerializer
Response
- 201 Created with the created team
- 403 Forbidden if the user may not manage teams
- 400 Bad Request if validation fails or the team name is invalid/duplicate
Purpose - Used by team administration UI - Supports controlled team creation inside the current org
TeamDetailView¶
Returns one team in the current organization.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: team_id
Behavior
- Resolves the team with:
- teams.services.team.get_team_in_org
- Serializes with:
- TeamDetailSerializer
Response
- 200 OK with the team detail
- 404 Not Found if the team does not exist in the current org
Purpose - Used for team detail screens - Provides a stable read contract for one team
TeamUpdateView¶
Updates a team in the current organization.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: team_id
Behavior
- Validates input with:
- TeamUpdateSerializer
- Calls:
- teams.services.team.validate_team_management
- teams.services.team.get_team_in_org
- teams.services.team.update_team
- Serializes with:
- TeamDetailSerializer
Response
- 200 OK with the updated team
- 403 Forbidden if the user may not manage teams
- 404 Not Found if the team does not exist
- 400 Bad Request for invalid updates
Purpose - Used by team administration screens - Supports renaming teams and toggling active state
TeamDeactivateView¶
Deactivates a team.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: team_id
Behavior
- Calls:
- teams.services.team.validate_team_management
- teams.services.team.get_team_in_org
- teams.services.team.deactivate_team
- Serializes with:
- TeamDetailSerializer
Response
- 200 OK with the updated team
- 403 Forbidden
- 404 Not Found
Purpose - Provides soft deactivation of teams instead of hard deletion
TeamReactivateView¶
Reactivates a team.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: team_id
Behavior
- Calls:
- teams.services.team.validate_team_management
- teams.services.team.get_team_in_org
- teams.services.team.reactivate_team
- Serializes with:
- TeamDetailSerializer
Response
- 200 OK with the updated team
- 403 Forbidden
- 404 Not Found
Purpose - Restores previously deactivated teams without recreating them
MyTeamsInOrgView¶
Returns the active teams the current user belongs to in the current organization.
Permissions
- IsAuthenticated
- HasCurrentOrg
Behavior
- Calls:
- teams.services.team.list_my_teams_in_org
- Serializes with:
- TeamListSerializer
Response
- 200 OK with the current user’s active teams
Purpose - Used for user-facing “my teams” views - Useful for mobile or worker dashboards
teams.views.memberships¶
TeamMembersByTeamView¶
Returns the active members of a specific team.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: team_id
Behavior
- Resolves the team in the current org:
- teams.services.team.get_team_in_org
- Validates visibility:
- teams.services.membership.validate_team_visibility
- Loads members:
- teams.services.membership.list_team_members
- Serializes with:
- TeamMemberSerializer
Visibility rules - Superusers may view any team - Privileged org users may view any team in the org - Non-privileged users may only view teams they actively belong to
Response
- 200 OK with team members
- 403 Forbidden if the user may not view the team
- 200 OK with [] if the team does not exist or is inactive
Purpose - Used for team member lists and team detail screens
TeamMembershipCreateView¶
Adds a user to a team.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: team_id
Behavior
- Validates input with:
- TeamMembershipCreateSerializer
- Calls:
- teams.services.membership.validate_team_membership_management
- teams.services.team.get_team_in_org
- teams.services.membership.get_user_for_team_membership
- teams.services.membership.add_user_to_team
- Serializes with:
- TeamMembershipListSerializer
Response
- 201 Created with the created or updated membership
- 403 Forbidden if the user may not manage memberships
- 404 Not Found if the team does not exist
- 400 Bad Request for invalid membership requests
Purpose - Used by team management UI to add users to teams - Enforces that the user must already belong to the team’s org via service logic
MyTeamMembersInOrgView¶
Returns the users who share at least one team with the current user in the current org.
Permissions
- IsAuthenticated
- HasCurrentOrg
Behavior
- Calls:
- teams.services.membership.list_my_team_member_options
- Serializes with:
- TeamMemberOptionSerializer
Response
- 200 OK with distinct teammate options
Purpose - Used for teammate selection and collaboration UI - Useful for planning and assignment screens
TeamMembershipPairsInOrgView¶
Returns lightweight team_id / user_id membership pairs visible to the current user.
Permissions
- IsAuthenticated
- HasCurrentOrg
Behavior
- Calls:
- teams.services.membership.list_visible_membership_pairs_in_org
- Serializes with:
- TeamMembershipPairSerializer
Visibility rules - Privileged users see all active memberships in the org - Non-privileged users see only memberships belonging to teams they are in
Response
- 200 OK with a compact pair list
Purpose - Useful for frontend graph structures - Reduces payload size where nested membership detail is unnecessary
TeamMembershipsInOrgView¶
Returns richer visible membership rows for the current user in the current org.
Permissions
- IsAuthenticated
- HasCurrentOrg
Behavior
- Calls:
- teams.services.membership.list_visible_memberships_in_org
- Serializes with:
- TeamMembershipListSerializer
Visibility rules - Privileged users see all active memberships in the org - Non-privileged users see only memberships for their own teams
Response
- 200 OK with richer membership rows
Purpose
- Used where the frontend needs more than just team_id / user_id
- Supports team membership admin displays and richer list rendering
TeamMembershipRoleUpdateView¶
Updates the role of a team membership.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: membership_id
Behavior
- Validates input with:
- TeamMembershipRoleUpdateSerializer
- Calls:
- teams.services.membership.validate_team_membership_management
- teams.services.membership.get_membership_by_id_in_org
- teams.services.membership.update_team_membership_role
- Serializes with:
- TeamMembershipListSerializer
Response
- 200 OK with updated membership
- 403 Forbidden
- 404 Not Found
- 400 Bad Request
Purpose - Used for membership administration and team-role assignment
TeamMembershipPrimaryUpdateView¶
Sets a membership as the primary team membership for its user.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: membership_id
Behavior
- Validates input with:
- TeamMembershipPrimaryUpdateSerializer
- Calls:
- teams.services.membership.validate_team_membership_management
- teams.services.membership.get_membership_by_id_in_org
- teams.services.membership.set_primary_team_membership
- Serializes with:
- TeamMembershipListSerializer
Response
- 200 OK with updated membership
- 403 Forbidden
- 404 Not Found
- 400 Bad Request
Purpose - Provides an explicit primary-team switching endpoint - Centralizes primary team invariant handling in the service layer
TeamMembershipDeactivateView¶
Deactivates a team membership.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: membership_id
Behavior
- Calls:
- teams.services.membership.validate_team_membership_management
- teams.services.membership.get_membership_by_id_in_org
- teams.services.membership.deactivate_team_membership
- Serializes with:
- TeamMembershipListSerializer
Response
- 200 OK with updated membership
- 403 Forbidden
- 404 Not Found
- 400 Bad Request
Purpose - Soft-removes a user from a team while preserving membership history
TeamMembershipReactivateView¶
Reactivates a team membership.
Permissions
- IsAuthenticated
- HasCurrentOrg
Inputs
- URL parameter: membership_id
Behavior
- Calls:
- teams.services.membership.validate_team_membership_management
- teams.services.membership.get_membership_by_id_in_org
- teams.services.membership.reactivate_team_membership
- Serializes with:
- TeamMembershipListSerializer
Response
- 200 OK with updated membership
- 403 Forbidden
- 404 Not Found
- 400 Bad Request
Purpose - Restores an inactive team membership without creating a new row
View relationships¶
flowchart TD
AllTeamsInOrgView --> is_privileged_in_org
AllTeamsInOrgView --> list_all_teams_in_org
AllTeamsInOrgView --> TeamListSerializer
TeamCreateView --> validate_team_management
TeamCreateView --> create_team
TeamCreateView --> TeamDetailSerializer
TeamDetailView --> get_team_in_org
TeamDetailView --> TeamDetailSerializer
TeamUpdateView --> validate_team_management
TeamUpdateView --> get_team_in_org
TeamUpdateView --> update_team
TeamUpdateView --> TeamDetailSerializer
TeamDeactivateView --> validate_team_management
TeamDeactivateView --> get_team_in_org
TeamDeactivateView --> deactivate_team
TeamDeactivateView --> TeamDetailSerializer
TeamReactivateView --> validate_team_management
TeamReactivateView --> get_team_in_org
TeamReactivateView --> reactivate_team
TeamReactivateView --> TeamDetailSerializer
MyTeamsInOrgView --> list_my_teams_in_org
MyTeamsInOrgView --> TeamListSerializer
TeamMembersByTeamView --> get_team_in_org
TeamMembersByTeamView --> validate_team_visibility
TeamMembersByTeamView --> list_team_members
TeamMembersByTeamView --> TeamMemberSerializer
TeamMembershipCreateView --> validate_team_membership_management
TeamMembershipCreateView --> get_team_in_org
TeamMembershipCreateView --> get_user_for_team_membership
TeamMembershipCreateView --> add_user_to_team
TeamMembershipCreateView --> TeamMembershipListSerializer
MyTeamMembersInOrgView --> list_my_team_member_options
MyTeamMembersInOrgView --> TeamMemberOptionSerializer
TeamMembershipPairsInOrgView --> list_visible_membership_pairs_in_org
TeamMembershipPairsInOrgView --> TeamMembershipPairSerializer
TeamMembershipsInOrgView --> list_visible_memberships_in_org
TeamMembershipsInOrgView --> TeamMembershipListSerializer
TeamMembershipRoleUpdateView --> validate_team_membership_management
TeamMembershipRoleUpdateView --> get_membership_by_id_in_org
TeamMembershipRoleUpdateView --> update_team_membership_role
TeamMembershipRoleUpdateView --> TeamMembershipListSerializer
TeamMembershipPrimaryUpdateView --> validate_team_membership_management
TeamMembershipPrimaryUpdateView --> get_membership_by_id_in_org
TeamMembershipPrimaryUpdateView --> set_primary_team_membership
TeamMembershipPrimaryUpdateView --> TeamMembershipListSerializer
TeamMembershipDeactivateView --> validate_team_membership_management
TeamMembershipDeactivateView --> get_membership_by_id_in_org
TeamMembershipDeactivateView --> deactivate_team_membership
TeamMembershipDeactivateView --> TeamMembershipListSerializer
TeamMembershipReactivateView --> validate_team_membership_management
TeamMembershipReactivateView --> get_membership_by_id_in_org
TeamMembershipReactivateView --> reactivate_team_membership
TeamMembershipReactivateView --> TeamMembershipListSerializer
Typical request flow¶
sequenceDiagram
participant Client
participant View
participant Serializer
participant Service
participant Model
Client->>View: request with auth + org context
View->>Serializer: validate payload when needed
Serializer-->>View: validated data
View->>Service: apply business/visibility logic
Service->>Model: query or update teams / memberships
Model-->>Service: results
Service-->>View: domain objects
View->>Serializer: serialize result
Serializer-->>View: response payload
View-->>Client: HTTP response
¶
sequenceDiagram
participant Client
participant View
participant Serializer
participant Service
participant Model
Client->>View: request with auth + org context
View->>Serializer: validate payload when needed
Serializer-->>View: validated data
View->>Service: apply business/visibility logic
Service->>Model: query or update teams / memberships
Model-->>Service: results
Service-->>View: domain objects
View->>Serializer: serialize result
Serializer-->>View: response payload
View-->>Client: HTTP responseKey design notes¶
1. Current-org scoping is mandatory¶
All team endpoints are scoped to the current organization.
This is enforced through:
- HasCurrentOrg
- team and membership resolution within request.org
This prevents cross-org visibility and mutation.
2. Views stay thin¶
The views do not contain: - direct org privilege branching logic for management - primary-team logic - org-membership prerequisite checks - membership mutation rules
That logic lives in:
- teams.services.team
- teams.services.membership
This keeps view code easy to test and maintain.
3. Visibility differs by privilege¶
There are two broad visibility modes: - privileged org users see all team/membership data in the org - regular users only see teams and memberships they are part of
The views delegate that rule to services instead of implementing it inline.
4. Management actions are explicit¶
The app now has explicit endpoints for: - team creation - team update - team deactivation/reactivation - membership creation - membership role updates - primary team switching - membership deactivation/reactivation
This makes the API easier to reason about than overloading generic PATCH behavior.
5. Two membership list endpoints intentionally exist¶
The app exposes both: - compact membership pairs - richer membership rows
This is useful because different frontend screens have different payload needs.
Compact¶
- smaller
- better for mapping and graph-like joins
Rich¶
- better for display-heavy screens and admin flows
6. Team member output is now serializer-backed¶
TeamMembersByTeamView no longer builds an inline payload manually.
Using TeamMemberSerializer:
- improves consistency
- makes testing easier
- keeps payload shape explicit in the serializer layer
Endpoint summary¶
Team endpoints¶
AllTeamsInOrgViewTeamCreateViewTeamDetailViewTeamUpdateViewTeamDeactivateViewTeamReactivateViewMyTeamsInOrgView
Membership / visibility endpoints¶
TeamMembersByTeamViewTeamMembershipCreateViewMyTeamMembersInOrgViewTeamMembershipPairsInOrgViewTeamMembershipsInOrgViewTeamMembershipRoleUpdateViewTeamMembershipPrimaryUpdateViewTeamMembershipDeactivateViewTeamMembershipReactivateView