s-m-r-t
Open the s-m-r-t source on GitHub Switch to dark color scheme
← All packages
Foundation v0.57.40

@happyvertical/smrt-profiles

People, organizations, identities, metadata, and reciprocal or directional relationships.

Source ↗

What it gives you

People, organizations, identities, metadata, and reciprocal or directional relationships.

  1. 01Profiles remain separate from authentication records
  2. 02Reciprocal and directional relationship types
  3. 03Time-bounded relationship terms and contextual third parties
  4. 04Organization-to-organization links on the same Profile rows
  5. 05Ordered web links and a public-figure flag on the profile

Attach identities without exposing credentials

Profiles can carry OIDC and Nostr identities, one-time magic-link records, and API keys. Nostr keypairs are encrypted; API-key material is SHA-256 hashed and shown only at creation. resolveIdentity and the createProfileFromOidc and createProfileFromNostr helpers keep canonical-person and email reservation checks in one place.

Keep extensible metadata and audit evidence controlled

ProfileMetafield supplies the validation schema for ProfileMetadata, whose collection supports add, get, batchGet, and batchUpdate. ProfileAsset is the owned-asset join. AuditLog is a sensitive model with no generated read routes. It records actor, action, reason, before and after changes, resource, source, and delegated identity. createAuditWriter, the consumer-authorized readAuditTrail, and the bounded pruneAuditTrail are its access paths; its super-admin bypass is an explicit policy choice.

Links and public figures

ProfileLink stores ordered web links with a platform, a validated http or https url, an optional label, and a sort order. Write them through replaceForProfile and reorder on the collection, or setLinks and getLinks on the profile; each is one transaction. Profile.isPublic records that a person is a public figure and nothing more; consumers decide visibility.

Relate two organizations

Organization is a Profile subtype, so an organization relates to another the way a person does. Create a supplier type with getOrCreateBySlug, then call addRelationship on the mill with the shop and the supplier slug. A directional type writes that one row. A reciprocal type with a handler also writes the inverse, and the shipped handlers are friend, spouse, partner, colleague, and sibling. Read the link from either side with getRelationships, date it with addTerm, and name a third profile as its context.

Profile relationships →

A relationship is not a tenant link and not a permission

ProfileRelationship carries one tenantId, and the Tenant record in smrt-users has no profile field. A tenant-to-tenant partnership is something an application builds on top, for example one Organization profile per tenant. Permission resolution never reads a relationship, so relating two profiles changes nothing about access.

Decide where data belongs →