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).
| Aspect | Detail |
|---|---|
| Doc ID | Firebase Auth UID (request.auth.uid) |
| Purpose | Auth + RBAC; link to one person (by email → personId) |
| Typical fields | email, displayName, role, team, personId (optional), disabled, createdAt, updatedAt |
| Role | App role: core_team | product_team | tech_lead | engineer | viewer |
| Used by | Login, 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).
| Aspect | Detail |
|---|---|
| Doc ID | Velocity ID (e.g. vel_a1b2c3d4e5f6) — see PEOPLE_COLLECTION.md |
| Purpose | Staff directory, project allocations (tech lead, owner, team allocations), Jira/Bitbucket links |
| Typical fields | displayName, email, role (job title, e.g. SWE1), teamIds, externalAccounts, active, etc. |
| Used by | Team “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:
teamsdocs havememberIds: 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 viaGET /api/engineers/[personId](readspeople+engineerMetrics) andGET /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
| Term | Collection? | Meaning |
|---|---|---|
| User | Yes: users | App account (Auth UID, email, app role, optional personId). Used for login and RBAC. Linked to one person by email; user can edit that person. |
| Person | Yes: people | Most 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. |
| Member | No | A person in a team or project (references are people doc IDs in teams.memberIds or projects.teamAllocations). |
| Profile | No | The 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.