Teams¶
Purpose¶
The Teams app manages how users are grouped within an organization for operational execution.
It provides: - A structured way to group users into teams - A clear distinction between org-level roles and team-level roles - A foundation for workforce coordination (planning, assignments, reporting)
This app sits between: - Orgs (who belongs to the company) - Accounts (who the user is) - Operational apps (who does the work)
Without Teams, the system would lack: - scoped collaboration units - visibility boundaries within an org - assignment-ready workforce groupings
Key concepts¶
1. Organization vs Team¶
- Organization (Org) = tenant / company boundary
- Team = operational subgroup inside an org
A user:
- belongs to an org via OrgMembership
- belongs to one or more teams via TeamMembership
2. TeamMembership¶
This is the core model of the app.
It defines: - which user is in which team - what role they have in that team - whether the membership is active - whether the team is the user’s primary team
3. Org role vs Team role¶
There are two independent permission layers:
Org role (from Orgs app)¶
- owner
- admin
- manager
- engineer
- viewer
Used for: - global visibility and control within the org
Team role¶
- lead
- member
Used for: - local team responsibility and structure
4. Primary team¶
Each user can have one primary team:
- enforced at DB level (UniqueConstraint)
- used for:
- default assignments
- planning logic
- reporting grouping
5. Visibility model¶
Team visibility depends on:
- Privileged org users
-
can see all teams and memberships in the org
-
Non-privileged users
- can only see:
- teams they belong to
- users in those teams
This is enforced in the service layer.
6. Membership graph¶
Teams form a many-to-many graph: - one user → many teams - one team → many users
The app exposes both: - rich membership objects - compact (team_id, user_id) pairs
to support different frontend needs.
Entry points¶
URLs¶
Defined in teams/urls.py
Main endpoints:
- teams/all/ → all teams (privileged)
- teams/my/ → my teams
- teams/my/members/ → my teammates
- teams/<team_id>/members/ → members of a team
- teams/memberships/pairs/ → compact graph data
- teams/memberships/ → richer membership rows
All endpoints:
- require authentication
- are scoped to the current org (HasCurrentOrg)
Admin¶
Django admin is implicitly available for:
- Team
- TeamMembership
Used for: - debugging - manual data correction - back-office management
Tasks¶
No Celery/background tasks currently exist in this app.
Potential future tasks: - team sync from external systems - bulk membership imports - notifications on team changes
Signals¶
No explicit signals are currently defined.
Potential future signals: - auto-assign default team on org join - enforce primary team defaults - propagate team changes to planning systems
Dependencies¶
Depends on:¶
- Orgs app
OrganizationOrgMembership- Accounts app
Usermodel- Core
HasCurrentOrgpermission
Used by:¶
- Planning / scheduling
- team-based assignments
- Service reports
- grouping engineers by team
- Inventory / logistics
- team-based equipment allocation
- Workforce management
- availability and capacity per team
Operational notes¶
Known pitfalls¶
1. Org vs Team confusion¶
A user being in an org does not mean: - they are in any team
Always ensure:
- OrgMembership exists before
- creating a TeamMembership
2. Primary team constraint¶
Only one is_primary=True per user.
Violating this: - raises a DB constraint error
Always use service functions when: - switching primary teams
3. Visibility bugs are high risk¶
Incorrect visibility logic can cause: - data leaks across teams - incorrect workforce displays
All visibility must go through:
- service layer (teams.services.membership)
4. Cross-org safety¶
Never allow: - team access across orgs - membership queries without org filtering
Always filter by:
- team__org
- or request.org
5. Role expansion impact¶
If you expand team roles: - update: - serializers - services - tests - ensure backward compatibility
Performance considerations¶
1. Membership-heavy queries¶
Queries like: - “all memberships in org” - “all teammates”
can become large.
Mitigations:
- .only("team_id", "user_id") for lightweight endpoints
- .select_related("user") for richer endpoints
- .distinct() where necessary
2. N+1 query risks¶
When returning user data:
- always use select_related("user")
Avoid: - per-row user lookups
3. Large organizations¶
In large orgs:
- teams/memberships/ can grow quickly
Consider future improvements: - pagination - filtering (by team, role, active) - caching
4. Graph endpoints are optimized¶
The endpoint:
- teams/memberships/pairs/
exists specifically to: - minimize payload size - support frontend graph reconstruction efficiently
5. Sorting cost¶
Sorting by:
- first_name
- last_name
- email
is acceptable for moderate sizes but may need indexing or pagination at scale.
Summary¶
The Teams app is the operational grouping layer of the system.
It provides: - structured workforce grouping - controlled visibility within orgs - a bridge between identity (Accounts) and tenancy (Orgs)
It is a critical foundation for: - planning - execution - reporting
and is designed to scale as: - teams grow - roles expand - cross-team workflows increase