ADR 010: Use “User” Not “Member” for the Tenant-Scoped Entity
Status
Accepted
Date
2026-03-10
Context
The original domain model used “Member” as the name for the tenant-scoped person entity (e.g., Member, MemberId, MemberRegistered). This made sense when distinguishing between a Zitadel identity (universal) and a tenant-local person.
However, in practice:
- Every person who uses the platform has a login via Zitadel — they are all “users”
- The codebase already has a
Userentity inCore/Identityfor the authenticated person - Having both
User(auth) andMember(domain) for the same person creates confusion - In REST APIs, “user” is the natural resource name
Decision
Use User as the tenant-scoped entity name, not Member.
- The aggregate is
UserwithUserId - Domain events:
UserRegistered,UserProfileUpdated,UserJoinedOrganization, etc. - The
Userentity holds profile fields directly (no separateMemberProfileVO) - The word “membership” is preserved for relationships:
OrgMembership— a user’s role in an organizationGroupMembership— a user’s role in a groupMembershipStatus— active, inactive, pending
Consequences
- Single concept: One
Userentity per tenant, notUser+Member - Natural API design:
/api/users/{id}, not/api/members/{id} - Clear distinction:
User= the person,Membership= the relationship - UI labels remain configurable: Tenants can still display “Member”, “Participant”, “Attendee” via
tenant.memberLabel— the domain name doesn’t constrain the UI - Docs updated:
docs/domain-model.mdrenamed throughout