@ossy/users
v3.8.0
Published
User domain - aggregate, events, and validators for the Ossy user model
Downloads
3,274
Readme
@ossy/users
User domain package for the Ossy platform — event-sourced user entities, workspace membership, and user-scoped API token actions.
What this package provides
| Primitive | File | Id / export |
|---|---|---|
| Schema | user.schema.js | @ossy/users/schema/user |
| Schema ids | schema-ids.js | UserSchema |
| Aggregate | user.aggregate.js | User (kind: 'entity', SchemaId) |
| Events | users.events.js | UsersEvents.Created, SignInVerified, NameUpdated, … |
| Queries | users.queries.js | UsersQueries |
| Startup | users.startup.js | Bot user bootstrap |
Client exports (@ossy/users) surface action metadata for the SDK. Server exports (@ossy/users/server) include the aggregate, events, queries, and validators.
Actions
| Action | Access | Task |
|--------|--------|------|
| @ossy/users/actions/update-details | authenticated | @ossy/users/tasks/update-details |
| @ossy/users/actions/request-email-change | authenticated | @ossy/users/tasks/request-email-change |
| @ossy/users/actions/confirm-email-change | public | @ossy/users/tasks/confirm-email-change |
| @ossy/users/actions/edit-profile-details | authenticated | client-only (profile editor) |
| @ossy/users/actions/save-profile-details | authenticated | client-only (profile form submit) |
| @ossy/users/actions/get-current-user-history | authenticated | @ossy/users/tasks/get-current-user-history |
| @ossy/users/actions/join-workspace | authenticated | @ossy/users/tasks/join-workspace |
| @ossy/users/actions/leave-workspace | authenticated | @ossy/users/tasks/leave-workspace |
| @ossy/users/actions/get-api-tokens | authenticated | @ossy/users/tasks/get-api-tokens |
| @ossy/users/actions/create-api-token | authenticated | @ossy/users/tasks/create-api-token |
| @ossy/users/actions/invalidate-api-token | authenticated | @ossy/users/tasks/invalidate-api-token |
API token tasks delegate to @ossy/tokens (TokenEvents.Created / revoke flows).
User schema (ADR 0006)
| Schema | Id | Fields |
|---|---|---|
| User | @ossy/users/schema/user | email, firstName, lastName |
Event model (ADR 0008)
User entity events use the universal envelope: type (schema id), resourceId, event (lifecycle name), payload, createdBy.
| Event | Effect |
|---|---|
| Created | New user (type: 'User' or 'Bot') |
| SignInVerified | Sets verifiedAt on first verification |
| NameUpdated | Updates firstName / lastName |
| EmailChangeRequested | Sets pendingEmail (verification mail sent to the new address) |
| EmailUpdated | Sets email, clears pendingEmail (old address is notified) |
| WorkspaceJoined | Adds workspace id to workspaces[] |
| WorkspaceLeft | Removes workspace id from workspaces[] |
Email change is a two-step flow: authenticated request-email-change appends EmailChangeRequested and emails a confirmation link; public confirm-email-change (GET /api/v0/users/confirm-email-change?token=… / page /verify-email-change) appends EmailUpdated. If the new address is already used by another account, request returns { ok: true } without events or mail. Mail is sent only via the email integration; if it is missing after the aggregate update, the task still returns { ok: true } and logs a warning so verification / old-address notices are not dropped silently.
UsersEvents.SignedUp was renamed to UsersEvents.Created to match the ADR 0008 lifecycle name.
Server usage
import { Aggregate } from '@ossy/event-store'
import { User, UsersEvents, UserSchema } from '@ossy/users/server'
const created = UsersEvents.Created({ email, firstName, lastName })
const user = await Aggregate.Of(User, created).then(Aggregate.View())
UserSchema.user
// => '@ossy/users/schema/user'Forms & flows
| Primitive | Id |
|---|---|
| Form | @ossy/users/form/update-profile-details |
| Schema | @ossy/users/schema/update-profile-details |
| Flow | @ossy/users/flows/update-email |
update-email.flow.js composes the sign-up flow, edits email on @profile, confirms via @ossy/users/emails/verify-email-change, asserts return to profile, and checks [data-user-email="$email"] for the new address.
Testing
npm test -w @ossy/users
npm run test:integration -w @ossy/usersUnit coverage lives in package tests; users.integration.spec.js exercises actions against @ossy/platform. Product e2e: npm run test:e2e:flows in @ossy/app-test (includes update-email when built into the manifest).
