Objects / User
User
Canonical identity record representing a platform user across lifecycle contexts.
Generated from @oods/foundry 0.10.1
Screens
Every screen below was generated from this object by OODS Foundry 0.10.1, in React and Vue, and shows the calls that made it and its content hash. Each runs as its generated app runs, in this site's brand, Aquex, in the theme you choose, with the sample records this object's own file carries. A value no record gives shows as a neutral one, such as an empty value or "Not recorded"; OODS Foundry invents none.
sha256:970963e87082…Open full size: User detail screen generated by OODS Foundry in Reactsha256:974708009995…Open full size: User detail screen generated by OODS Foundry in Vuesha256:7b515068c105…Open full size: User list screen generated by OODS Foundry in Reactsha256:ad1d827a009d…Open full size: User list screen generated by OODS Foundry in Vuesha256:d2bda633e857…Open full size: User form screen generated by OODS Foundry in Reactsha256:7fffbf99d80d…Open full size: User form screen generated by OODS Foundry in Vuesha256:796761663b91…Open full size: User timeline screen generated by OODS Foundry in Reactsha256:52bcac4abf96…Open full size: User timeline screen generated by OODS Foundry in Vuesha256:b219ce1b0b27…Open full size: User card screen generated by OODS Foundry in Reactsha256:6926a444ef37…Open full size: User card screen generated by OODS Foundry in Vuesha256:5850dd0e7f4e…Open full size: User inline screen generated by OODS Foundry in Reactsha256:8f001ea2a11b…Open full size: User inline screen generated by OODS Foundry in Vuesha256:a5d69bdbcc34…Open full size: User workflow screen generated by OODS Foundry in Reactsha256:80fae8e68de3…Open full size: User workflow screen generated by OODS Foundry in VueThe calls that made the User detail apps, in React and Vue
design_compose {
"object": "User",
"context": "detail",
"preferences": {
"brand": "Aquex",
"theme": "light"
}
}
code_generate {
"schemaRef": "compose-8f0872d4",
"framework": "react",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}
code_generate {
"schemaRef": "compose-8f0872d4",
"framework": "vue",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}The React app's content hash: sha256:970963e8708275d29072ebffbca94cfb65da09b493e2a68fb47224ae0c125448. Its src/ folder: App.tsx, GeneratedUI.tsx, app.css, main.tsx, oods-brand-aquex.css
The Vue app's content hash: sha256:974708009995bab63e5deb3593ab7b7f88fdcf6f20884d0e49a5edc05ca30ca0. Its src/ folder: App.vue, GeneratedUI.vue, app.css, main.ts, oods-brand-aquex.css
The calls that made the User list apps, in React and Vue
design_compose {
"object": "User",
"context": "list",
"preferences": {
"brand": "Aquex",
"theme": "light"
}
}
code_generate {
"schemaRef": "compose-9f9acda5",
"framework": "react",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}
code_generate {
"schemaRef": "compose-9f9acda5",
"framework": "vue",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}The React app's content hash: sha256:7b515068c10523a2e58449e6847db409ea829e89b247d45d216b48607a31746d. Its src/ folder: App.tsx, GeneratedUI.tsx, app.css, main.tsx, oods-brand-aquex.css
The Vue app's content hash: sha256:ad1d827a009d1941034974971276ab53321a6911df909e27c95ed49bc295a2c7. Its src/ folder: App.vue, GeneratedUI.vue, app.css, main.ts, oods-brand-aquex.css
The calls that made the User form apps, in React and Vue
design_compose {
"object": "User",
"context": "form",
"preferences": {
"brand": "Aquex",
"theme": "light"
}
}
code_generate {
"schemaRef": "compose-751e85d0",
"framework": "react",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}
code_generate {
"schemaRef": "compose-751e85d0",
"framework": "vue",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}The React app's content hash: sha256:d2bda633e857e37264c42b9363fe8e8bf9c843bfd571e302680ca2b9d040696e. Its src/ folder: App.tsx, GeneratedUI.tsx, app.css, main.tsx, oods-brand-aquex.css
The Vue app's content hash: sha256:7fffbf99d80d6830392523794b6f5a49e7e2bd4f5800b6ede94135ee71a4066f. Its src/ folder: App.vue, GeneratedUI.vue, app.css, main.ts, oods-brand-aquex.css
What design_compose reported:
OODS-V119No view_extensions found for context "timeline" in object "User". Available contexts: list, detail, form, card
The calls that made the User timeline apps, in React and Vue
design_compose {
"object": "User",
"context": "timeline",
"preferences": {
"brand": "Aquex",
"theme": "light"
}
}
code_generate {
"schemaRef": "compose-8006e53b",
"framework": "react",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}
code_generate {
"schemaRef": "compose-8006e53b",
"framework": "vue",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}The React app's content hash: sha256:796761663b9196afb1e948ccd81eda0cfdd84029bfb825ed445173344f521ba9. Its src/ folder: App.tsx, GeneratedUI.tsx, app.css, main.tsx, oods-brand-aquex.css
The Vue app's content hash: sha256:52bcac4abf96288ae9d532f8c1abadfb146064c2b0321d37a1233f9c524481e9. Its src/ folder: App.vue, GeneratedUI.vue, app.css, main.ts, oods-brand-aquex.css
The calls that made the User card apps, in React and Vue
design_compose {
"object": "User",
"context": "card",
"preferences": {
"brand": "Aquex",
"theme": "light"
}
}
code_generate {
"schemaRef": "compose-bc25e7e3",
"framework": "react",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}
code_generate {
"schemaRef": "compose-bc25e7e3",
"framework": "vue",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}The React app's content hash: sha256:b219ce1b0b274d1ec7ba8d5fe6d1aa7eee366d841c504acb203b28f9869376eb. Its src/ folder: App.tsx, GeneratedUI.tsx, app.css, main.tsx, oods-brand-aquex.css
The Vue app's content hash: sha256:6926a444ef3777826dfe4eb356e695214d5b0360c6c659f755ca93babd9d5687. Its src/ folder: App.vue, GeneratedUI.vue, app.css, main.ts, oods-brand-aquex.css
What design_compose reported:
OODS-V119No view_extensions found for context "inline" in object "User". Available contexts: list, detail, form, card
The calls that made the User inline apps, in React and Vue
design_compose {
"object": "User",
"context": "inline",
"preferences": {
"brand": "Aquex",
"theme": "light"
}
}
code_generate {
"schemaRef": "compose-f606e369",
"framework": "react",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}
code_generate {
"schemaRef": "compose-f606e369",
"framework": "vue",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}The React app's content hash: sha256:5850dd0e7f4e45ffa34caf77fde05c2457844d1bdd3423ef4ec4df07d5fbcd4f. Its src/ folder: App.tsx, GeneratedUI.tsx, app.css, main.tsx, oods-brand-aquex.css
The Vue app's content hash: sha256:8f001ea2a11b3c5c5ce24cb7b39d1d0dc9ba3a9fbf44ba8edca1c9309a92a61d. Its src/ folder: App.vue, GeneratedUI.vue, app.css, main.ts, oods-brand-aquex.css
What design_compose reported:
OODS-V119No view_extensions found for context "timeline" in object "User". Available contexts: list, detail, form, card
The calls that made the User workflow apps, in React and Vue
design_compose {
"object": "User",
"context": "workflow",
"preferences": {
"brand": "Aquex",
"theme": "light"
}
}
code_generate {
"schemaRef": "compose-b291c7ae",
"framework": "react",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}
code_generate {
"schemaRef": "compose-b291c7ae",
"framework": "vue",
"profile": "build",
"options": {
"output": "application",
"brand": "Aquex",
"theme": "light",
"payloadMode": "file"
}
}The React app's content hash: sha256:a5d69bdbcc34bc2d9a8383e4e26bd8519bad4a972ffec562bc1ea872cc98eebe. Its src/ folder: App.tsx, actions.ts, app.css, application.ts, main.tsx, oods-brand-aquex.css, sample-data.ts, screens/, ssr.tsx, store.ts
The Vue app's content hash: sha256:80fae8e68de3f607a183aed2a74f609354046383ef73a1d4833cadabf479ae3c. Its src/ folder: App.vue, actions.ts, app.css, application.ts, main.ts, oods-brand-aquex.css, sample-data.ts, screens/, ssr.ts, store.ts
Fields
| Field | Type | Description |
|---|---|---|
statusrequired | string | Canonical lifecycle state derived from the states parameter. MoreThis is the single source of truth for the entity's current lifecycle position. Consumed by Colorized to resolve visual tokens, and by view extensions to render StatusBadge and StatusTimeline. |
state_history | StateTransition[] | Chronological log of state transitions. MoreEach entry records the before/after states, timestamp, and (when governance is enabled) the actor, reason, and transition metadata. Rendered by StatusTimeline in the detail and timeline views. Entry structure: - from: string (previous state) - to: string (new state) - timestamp: ISO 8601 datetime - actor_id: string (user/system who triggered the transition, optional) - reason: string (human-readable justification, required when requireTransitionReason is true) - transition_metadata: Record<string, unknown> (arbitrary context, optional) |
allowed_transitions | string[] | Materialized list of valid next states from the current status, computed from the
transitionRules parameter. MoreWhen transitionRules is null (open model), this contains all states except the current one. Used by StatusSelector to disable invalid options and by StatusBadge to indicate available paths. |
created_atrequired | datetime | Timestamp recording when the entity was first created. |
updated_at | datetime | Timestamp for the most recent modification, when available. |
last_eventrequired | string | Lifecycle event associated with the most recent timestamp mutation. |
last_event_at | datetime | Timestamp for the lifecycle event captured in last_event. |
tags | string[] | Ordered list of tags assigned to the entity. |
tag_countrequired | number | Computed number of tags assigned to the entity. |
tag_metadata | object[] | Per-tag governance metadata. MoreEach entry corresponds to a tag in the tags array and tracks provenance and usage for taxonomy health monitoring. Entry structure: - tag: string (the tag value, matches entry in tags array) - created_at: ISO 8601 datetime - created_by: string (user ID or "system" for allow-list tags) - usage_count: number (how many entities use this tag, computed) - moderation_status: "approved" | "pending" | "rejected" (when allowTagModeration is true) - canonical_form: string (resolved synonym target, when synonymResolution is enabled) |
address_rolesrequired | string[] | Ordered list of roles that currently have address entries. |
default_address_role | string | Role surfaced in UI contexts when one address must be highlighted. |
addresses | AddressableEntry[] | Collection of { role, address, metadata } entries keyed by role. |
preference_documentrequired | PreferenceDocument | Normalized preference payload captured by PreferenceStore (version, preferences map, metadata). |
preference_metadatarequired | PreferenceMetadata | Tracks schema version, lastUpdated timestamp, migration records, and source. |
preference_versionrequired | string | SemVer mirror of preference_document.version for indexing and analytics. |
preference_namespacesrequired | string[] | Materialized namespace list resolved from parameters/registry for auditing. |
preference_mutations | number | Monotonic counter incremented whenever preferences mutate (invalidates caches). |
role_catalogrequired | AuthzRoleDocument[] | Canonical RBAC roles (R21.2 Part 4.2 TABLE 1). |
permission_catalogrequired | AuthzPermissionDocument[] | Atomic permissions following resource:action notation (TABLE 2). |
role_permissionsrequired | Record<string, string[]> | Junction map for role→permission edges (TABLE 3). |
membership_recordsrequired | AuthzMembershipDocument[] | SaaS membership triple (user_id, organization_id, role_id) with UNIQUE constraint (TABLE 4). |
role_hierarchy_edges | AuthzRoleHierarchyEdge[] | Parent→child adjacency list for hierarchical RBAC (Part 3.1). |
session_roles | string[] | Materialized roles granted within the current session/token exchange. |
channel_catalogrequired | Channel[] | Provider configuration for each channel (SMTP/Twilio/FCM/Webhook). |
template_catalogrequired | Template[] | Localized template definitions with declared variables per R20.1 Part 2.3. |
delivery_policiesrequired | DeliveryPolicy[] | Retry/throttle/quiet-hour policies (R20.1 Part 3 lifecycle). |
messages | Message[] | Atomic message payloads queued for delivery (R20.6 Part 1.2 primitives). |
conversations | Conversation[] | Multi-party threaded conversations with membership metadata (R20.6 Part 3.3). |
message_statuses | MessageStatusEntry[] | Delivery state machine transitions (queued → sent → delivered → failed → retried → read). |
user_idrequired | uuid | Primary identifier used to correlate identity across services. |
namerequired | string | Human-friendly name rendered in headers and list contexts. |
preferred_name | string | Preferred display name surfaced in collaborative tooling. |
description | string | Supporting summary rendered in detail and card contexts. |
primary_emailrequired | Canonical login email address for the user. | |
rolerequired | string (end_user, admin, owner, billing) | Highest privilege role currently granted to the user. |
timezone | string | Preferred timezone applied when rendering timestamps. |
Traits
Each trait adds fields and behaviour. Every object with the trait gets the same.
Relationships
These arrows show declared relationships between object types. They don't join live records.
The object file
The User object definition in YAML: objects/core/User.object.yaml
object:
name: User
version: 1.4.0
domain: core.identity
description: Canonical identity record representing a platform user across lifecycle contexts.
tags:
- universal
- identity
- core
traits:
- name: lifecycle/Stateful
alias: UserLifecycle
parameters:
states:
- invited
- active
- suspended
- deactivated
initialState: active
- name: lifecycle/Timestampable
alias: AuditTrail
parameters:
recordedEvents:
- created
- profile_updated
- status_changed
- role_updated
timezone: UTC
allowNullUpdatedAt: false
- name: behavioral/Taggable
alias: AffinityTags
parameters:
maxTags: 12
allowCustomTags: false
allowedTags:
- admin
- beta_tester
- vip
- suspended
caseSensitive: false
- name: core/Addressable
alias: UserAddresses
parameters:
roles:
- home
- billing
- shipping
defaultRole: home
- name: core/Preferenceable
alias: UserPreferences
parameters:
namespaces:
- theme
- notifications
- display
- privacy
schemaVersion: 2.0.0
registryNamespace: user-preferences
- name: core/Authable
alias: UserAuthz
parameters:
hierarchyDepthLimit: 5
- name: core/Communicable
alias: UserCommunications
schema:
user_id:
type: uuid
required: true
description: Primary identifier used to correlate identity across services.
name:
type: string
required: true
description: Human-friendly name rendered in headers and list contexts.
validation:
minLength: 1
maxLength: 120
preferred_name:
type: string
required: false
description: Preferred display name surfaced in collaborative tooling.
description:
type: string
required: false
description: Supporting summary rendered in detail and card contexts.
validation:
maxLength: 160
primary_email:
type: email
required: true
description: Canonical login email address for the user.
role:
type: string
required: true
default: end_user
description: Highest privilege role currently granted to the user.
validation:
enum:
- end_user
- admin
- owner
- billing
timezone:
type: string
required: false
default: UTC
description: Preferred timezone applied when rendering timestamps.
semantics:
user_id:
semantic_type: identity.user.id
token_mapping: tokenMap(identity.id.primary)
name:
semantic_type: identity.user.name
token_mapping: tokenMap(identity.name.primary)
preferred_name:
semantic_type: identity.user.name_preferred
token_mapping: tokenMap(identity.name.preferred)
# The one-line summary under the user's name in lists.
description:
semantic_type: text.summary
token_mapping: tokenMap(identity.description.summary)
primary_email:
semantic_type: identity.user.email
token_mapping: tokenMap(identity.email.primary)
role:
semantic_type: identity.user.role
token_mapping: tokenMap(identity.role.*)
timezone:
semantic_type: identity.user.timezone
token_mapping: tokenMap(identity.timezone.primary)
tokens:
identity.id.primary: "var(--text-strong)"
identity.name.primary: "var(--text-strong)"
identity.email.primary: "var(--text-subtle)"
identity.role.admin: "var(--status-info)"
identity.timezone.primary: "var(--text-muted)"
identity.description.summary: "var(--text-subtle)"
metadata:
owners:
- identity@oods.systems
- platform@oods.systems
steward: design@oods.systems
maturity: stable
changelog:
- version: 1.4.0
date: "2025-11-20"
description: Composed Authable trait to attach RBAC memberships and entitlement exports.
- version: 1.3.0
date: "2025-11-19"
description: Added Preferenceable trait for schema-governed user preferences (theme, notifications, display, privacy).
- version: 1.2.0
date: "2025-11-18"
description: Added Addressable trait for multi-role user addresses (home, billing, shipping).
- version: 1.1.0
date: "2025-10-18"
description: Simplified composition for view engine integration (Stateful, Timestampable, Taggable).
- version: 1.0.0
date: "2025-10-16"
description: Initial Universal Quintet baseline.
# Eight authored sample users, each a person at one of the sample organizations. A user is created active (the
# lifecycle's initial state), so an invited user is one invited back after leaving; each history ends in the user's
# status, and the last event is the latest recorded change.
samples:
- user_id: 8b2e4d6f-1a3c-4e5b-9d7f-2c4e6a8b0d01
name: Dana Whitfield
preferred_name: Dana
description: Operations director, Northwind Traders
primary_email: dana.whitfield@northwind.example
role: owner
timezone: America/Chicago
tags: [admin]
tag_count: 1
status: active
state_history:
- { title: Joined, from: null, to: active, at: '2026-02-02T15:00:00Z', reason: Created the Northwind Traders workspace }
- { title: Suspended, from: active, to: suspended, at: '2026-05-11T08:20:00Z', reason: Sign-in from an unrecognised device }
- { title: Reactivated, from: suspended, to: active, at: '2026-05-11T09:05:00Z', reason: Identity verified and password reset }
created_at: '2026-02-02T15:00:00Z'
updated_at: '2026-05-11T09:05:00Z'
last_event: status_changed
last_event_at: '2026-05-11T09:05:00Z'
- user_id: 8b2e4d6f-1a3c-4e5b-9d7f-2c4e6a8b0d02
name: Ruth Adeyemi
preferred_name: Ruth
description: Finance manager, Tidewater Co-op
primary_email: ruth.adeyemi@tidewater.example
role: billing
timezone: Pacific/Auckland
tags: [vip]
tag_count: 1
status: active
state_history:
- { title: Joined, from: null, to: active, at: '2024-10-02T21:00:00Z', reason: Invited by the Tidewater account team }
- { title: Deactivated, from: active, to: deactivated, at: '2025-03-14T20:00:00Z', reason: On parental leave }
- { title: Reactivated, from: deactivated, to: active, at: '2025-09-01T20:00:00Z', reason: Returned from leave }
created_at: '2024-10-02T21:00:00Z'
updated_at: '2026-01-12T20:00:00Z'
last_event: role_updated
last_event_at: '2026-01-12T20:00:00Z'
- user_id: 8b2e4d6f-1a3c-4e5b-9d7f-2c4e6a8b0d03
name: Priya Raman
preferred_name: Priya
description: Studio manager, Blue Harbor Studio
primary_email: priya@blueharbor.example
role: admin
timezone: America/Los_Angeles
tags: [admin, beta_tester]
tag_count: 2
status: active
state_history:
- { title: Joined, from: null, to: active, at: '2026-09-19T10:00:00Z', reason: Created the Blue Harbor Studio workspace }
- { title: Suspended, from: active, to: suspended, at: '2026-09-20T02:10:00Z', reason: Card check failed at trial start }
- { title: Reactivated, from: suspended, to: active, at: '2026-09-21T09:00:00Z', reason: Card verified and trial started }
created_at: '2026-09-19T10:00:00Z'
updated_at: '2026-09-21T09:00:00Z'
last_event: status_changed
last_event_at: '2026-09-21T09:00:00Z'
- user_id: 8b2e4d6f-1a3c-4e5b-9d7f-2c4e6a8b0d04
name: Tomas Lindqvist
preferred_name: Tomas
description: Owner, Lindqvist Bakery
primary_email: tomas@lindqvist.example
role: owner
timezone: Europe/Stockholm
tags: []
tag_count: 0
status: active
state_history:
- { title: Joined, from: null, to: active, at: '2026-01-12T08:00:00Z', reason: Created the Lindqvist Bakery workspace }
- { title: Suspended, from: active, to: suspended, at: '2026-05-15T08:05:00Z', reason: Workspace locked after the card expired }
- { title: Reactivated, from: suspended, to: active, at: '2026-05-17T08:00:00Z', reason: New card added }
created_at: '2026-01-12T08:00:00Z'
updated_at: '2026-05-17T08:00:00Z'
last_event: status_changed
last_event_at: '2026-05-17T08:00:00Z'
- user_id: 8b2e4d6f-1a3c-4e5b-9d7f-2c4e6a8b0d05
name: Grace Okafor
preferred_name: Grace
description: Accounts lead, Kestrel Print Co.
primary_email: grace.okafor@kestrelprint.example
role: billing
timezone: Europe/London
tags: [suspended]
tag_count: 1
status: suspended
state_history:
- { title: Joined, from: null, to: active, at: '2026-01-20T10:00:00Z', reason: Created the Kestrel Print Co. workspace }
- { title: Suspended, from: active, to: suspended, at: '2026-09-24T07:45:00Z', reason: Locked after repeated failed sign-ins }
created_at: '2026-01-20T10:00:00Z'
updated_at: '2026-09-24T07:45:00Z'
last_event: status_changed
last_event_at: '2026-09-24T07:45:00Z'
- user_id: 8b2e4d6f-1a3c-4e5b-9d7f-2c4e6a8b0d06
name: Mei Chen
preferred_name: Mei
description: Field coordinator, Tidewater Co-op
primary_email: mei.chen@tidewater.example
role: end_user
timezone: Pacific/Auckland
tags: []
tag_count: 0
status: invited
state_history:
- { title: Joined, from: null, to: active, at: '2025-02-10T01:00:00Z', reason: Added by Ruth Adeyemi }
- { title: Deactivated, from: active, to: deactivated, at: '2025-12-19T03:00:00Z', reason: Left the co-op }
- { title: Invited back, from: deactivated, to: invited, at: '2026-09-23T22:30:00Z', reason: Rejoined the co-op; invitation sent }
created_at: '2025-02-10T01:00:00Z'
updated_at: '2026-09-23T22:30:00Z'
last_event: status_changed
last_event_at: '2026-09-23T22:30:00Z'
- user_id: 8b2e4d6f-1a3c-4e5b-9d7f-2c4e6a8b0d07
name: Jonah Marlow
preferred_name: Jonah
description: Founder, Marlow Yoga
primary_email: jonah@marlowyoga.example
role: owner
timezone: America/Chicago
tags: []
tag_count: 0
status: deactivated
state_history:
- { title: Joined, from: null, to: active, at: '2026-01-05T10:15:00Z', reason: Created the Marlow Yoga workspace }
- { title: Deactivated, from: active, to: deactivated, at: '2026-07-10T09:00:00Z', reason: Studio closed }
created_at: '2026-01-05T10:15:00Z'
updated_at: '2026-07-10T09:00:00Z'
last_event: status_changed
last_event_at: '2026-07-10T09:00:00Z'
- user_id: 8b2e4d6f-1a3c-4e5b-9d7f-2c4e6a8b0d08
name: Arjun Mehta
preferred_name: Arjun
description: E-commerce manager, Summit Outfitters
primary_email: arjun.mehta@summit.example
role: admin
timezone: America/Denver
tags: [admin]
tag_count: 1
status: active
state_history:
- { title: Joined, from: null, to: active, at: '2026-04-23T12:00:00Z', reason: Created the Summit Outfitters workspace }
- { title: Suspended, from: active, to: suspended, at: '2026-06-30T18:00:00Z', reason: Paused while single sign-on was reset }
- { title: Reactivated, from: suspended, to: active, at: '2026-07-01T15:00:00Z', reason: Single sign-on restored }
created_at: '2026-04-23T12:00:00Z'
updated_at: '2026-07-01T15:00:00Z'
last_event: status_changed
last_event_at: '2026-07-01T15:00:00Z'