Skip to main content

Collections: User vs Member vs Profile

Quick reference for how users, people, member, and profile relate. Most data lives under person (people). The engineers collection has been removed; all person/staff data is in people.


1. users (Firestore collection)

What it is: App accounts — who can sign in and what role they have in the app. Linked to a person by email; optional personId is written when resolved (so the user “owns” that person record).

AspectDetail
Doc IDFirebase Auth UID (request.auth.uid)
PurposeAuth + RBAC; link to one person (by email → personId)
Typical fieldsemail, displayName, role, team, personId (optional), disabled, createdAt, updatedAt
RoleApp role: core_team | product_team | tech_lead | engineer | viewer
Used byLogin, sidebar, RbacRouteGuard, Users page; /api/me resolves and stores personId from people by email

Not: A staff directory. A “user” is an app identity with permission to edit their own person (name, email, department, etc.).


2. people (Firestore collection)

What it is: Canonical list of persons/staff in the org — the source of truth for “who is this human” (name, email, job role, teams, external accounts).

AspectDetail
Doc IDVelocity ID (e.g. vel_a1b2c3d4e5f6) — see PEOPLE_COLLECTION.md
PurposeStaff directory, project allocations (tech lead, owner, team allocations), Jira/Bitbucket links
Typical fieldsdisplayName, email, role (job title, e.g. SWE1), teamIds, externalAccounts, active, etc.
Used byTeam “All members” list, engineer list/detail APIs (backed by people + engineerMetrics), project dropdowns, /api/me (email → personId)

Link to users: By email. A users doc and a people doc can represent the same person; we match them via users.email = people.email to get personId (e.g. in /api/me and engineer-scoped access).


3. engineers — removed

The engineers collection has been deleted from the app. All person/staff data lives in people. List and detail APIs (GET /api/engineers, GET /api/engineers/[id]) read from people (and engineerMetrics for stats). Slack work-arrangement and link APIs use people (e.g. by slackUserId or by person ID).


4. Member (concept, not a collection)

What it is: A person (from people) in a membership context.

  • Team member: teams docs have memberIds: string[] → those IDs are people doc IDs.
  • Project allocation: projects.teamAllocations[].assignments[].memberId → again people doc IDs.

So “member” = “this person is a member of this team / allocated to this project”. The data lives in people and in teams / projects, not in a separate “members” collection.


5. Profile (concept / page, not a collection)

What it is: The view of one person’s data; profile data lives under person (people). The user has permission to edit their own person (name, email, department, etc.).

  • Route: /profile (My Profile).
  • Data source: One person from people, loaded via GET /api/engineers/[personId] (reads people + engineerMetrics) and GET /api/people/[personId] for editable fields.
  • Edit: “Edit profile” calls PUT /api/people/[personId] with auth; only the linked user can edit their own person (core_team can edit any).
  • Who sees it: Anyone with access to /profile; for engineer role it’s the only way to see “their” record (they don’t see the full Team list).

So “profile” = one person’s record; the underlying store is people; the user (matched by email, personId on user) can edit that record.


Summary table

TermCollection?Meaning
UserYes: usersApp account (Auth UID, email, app role, optional personId). Used for login and RBAC. Linked to one person by email; user can edit that person.
PersonYes: peopleMost data lives here. Canonical staff record (Velocity ID, name, email, job role, teams, links). Used for members list, engineer list/detail, project allocations. Profile data lives under person.
MemberNoA person in a team or project (references are people doc IDs in teams.memberIds or projects.teamAllocations).
ProfileNoThe view of one person (from people), e.g. on /profile. User can edit their own person (name, email, department).

Relationship in one line: A user (app account in users) is linked to a person (in people) by email; personId is stored on the user when resolved. That person holds profile data; the user has permission to edit their own person. “Engineer” in the UI is that same person from people. The engineers collection has been removed.