Constructs a new instance of the UserInfo class, optionally initializing it with the provided metadata and initial data. If newGlobalRoles are provided, the user roles will be set up to validate against those roles instead of fetching them from the metadata provider.
Timestamp when the user record was created
Timestamp when the user record was last updated
Unique email address for the user. This field must be unique across all users in the system
Employee's email address
Employee's concatenated first and last name
Foreign key reference to the Employee entity
Name of the employee's supervisor
Email address of the employee's supervisor
Employee's job title
Concatenated first and last name
User's first name or given name
Unique identifier for the user
Whether this user account is currently active and can log in
User's last name or surname
Foreign key reference to the Entities table
ID of the specific record this user is linked to
Type of record this user is linked to (None, Employee, Contact, etc.)
Name of the user that is used in various places in UIs/etc, can be anything including FirstLast, Email, a Handle, etc
User's professional title or salutation
User account type (User, Owner)
Per-request acting context for an API-key session. Set server-side in the API-key auth path from an authenticated identity, ON A CLONED UserInfo (the resolved userRecord may be the shared UserCache instance — stamping it in place leaks one session's scope to every concurrent session of the same user). Consumed by API-key row filters via the {{Acting*}} tokens. Same getter/setter (non-enumerable accessor) rationale as TenantContext — not a DB/GraphQL field, and it must NEVER be exposed via a resolver.
Row-filter bindings for the API key this session authenticated with, resolved per request from the key's scope rules and stamped on the CLONED per-request UserInfo. Consumed by EntityInfo.GetEffectiveRowFilterWhereClause, which AND-composes each matching binding's filter with role RLS — outside the role-RLS exemption. Plain data on purpose: MJCore cannot depend on the APIKeys packages, so the bridge is this carrier. Never a DB/GraphQL field; never exposed to or settable by a client.
True when this request resolves to the shared Anonymous magic-link principal whose roles are synthesized in memory per-session (never persisted, so anonymous sessions can't accrete privileges across links). The server reads this to serve the synthesized UserRoles for the session's own user row instead of the DB query (which returns empty for the role-less shared principal by design). Same getter/setter (non-enumerable) rationale as TenantContext/MagicLinkScope — it is not a database/GraphQL field.
Per-session resource scope for a magic-link share. Set at request time from the
verified session token's claims (the link's ResourceType/ResourceID). Consumed by
RLS filters via the {{ScopeResourceID}} / {{ScopeResourceType}} tokens in
RowLevelSecurityFilterInfo.MarkupFilterText, so a resource-share link can
be scoped to exactly one resource (and its FK-reachable dependents) without the
granted role being broad. Same getter/setter (non-enumerable) rationale as
TenantContext — it is not a database/GraphQL field.
Returning-visitor context for a public web-widget guest session. Set at request time from the verified session token's claims (the widget mint embeds the resolved VisitorKey / prior conversation / resolved identity). Consumed when a conversation is created server-side (the voice path) so it carries the same returning-visitor anchor + resolved identity the text path stamps client-side. Same getter/setter (non-enumerable) rationale as MagicLinkScope — not a DB/GraphQL field.
Tenant context for multi-tenant data isolation. Set at request time by server middleware when multi-tenancy is enabled. When undefined, no tenant filtering is applied.
Uses a getter/setter so that Object.keys() does not enumerate it —
the GraphQLDataProvider builds CurrentUser queries from Object.keys(new UserInfo()),
and TenantContext is not a database/GraphQL field.
Widget-instance identity for a public web-widget guest session. Set at request time from the
verified session token's mj_widget_id claim. Read by the privileged agent-dispatch path to
resolve the authoritative pinned agent for this guest (never trusting a client-supplied agent
id). Same getter/setter (non-enumerable) rationale as MagicLinkScope — not a DB/GraphQL field.
ProtectedcopyCopies initialization data from a plain object to the class instance. Only copies properties that already exist on the class to prevent creating new fields. Special handling for DefaultValue fields to extract actual values from SQL Server syntax.
The initialization data object
Default JSON serialization for BaseInfo subclasses.
Emits all non-underscored direct field declarations. For _-prefixed private backing fields
(the MJ pattern for collection storage — e.g. _Fields, _RelatedEntities, _OrganicKeys),
emits the value of the corresponding same-named public getter instead. Purely computed getters
without a backing field (display-name formatters, derived flags) are intentionally skipped —
they can throw when source fields are null and don't belong on the wire anyway.
A _-backed getter that throws is omitted from the output rather than aborting the whole
serialization. That omission is safe ONLY because such getters are recomputable: the backing
field is a lazy cache over other serialized state (e.g. QueryInfo.CategoryPath over CategoryID),
so the value is rebuilt on the next access after a warm boot. Do not add a _-backed getter
whose value cannot be recomputed from the serialized fields — a throw would silently drop it.
Nested BaseInfo instances and arrays of them unwrap automatically via JSON.stringify's native toJSON() protocol.
Subclasses may override to emit a filtered subset or custom shape (see EntityFieldValueInfo).
A list of all users who have or had access to the system. Contains user profile information, authentication details, and role assignments.