Skip to content

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
  • Organization
  • OrgMembership
  • Accounts app
  • User model
  • Core
  • HasCurrentOrg permission

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