Skip to main content

Auth Service API

The Auth Service orchestrates user, organization, and session management. All business methods return Result<*, DomainError> values, while certain read helpers still surface plain promises for convenience.

Location: worker/services/auth/service.ts

Dependencies

  • AuthRepository – persistence for users, organizations, and sessions
  • createLogger – structured logging for auditing auth flows
  • Shared domain error helpers – conflict, validation, not-found, and business-logic errors

User Management

createUser(data: CreateUserRequest): Promise<Result<UserEntity, DomainError>> : Validates email uniqueness, logs duplicate attempts, and returns ValidationError("email") when an account already exists.

findOrCreateUser(data: CreateUserRequest): Promise<Result<UserEntity, DomainError>> : Atomically finds or creates a user, retrying after race failures. Returns BusinessLogicError if creation ultimately fails.

getUserByEmail(email: string): Promise<UserEntity | null> getUserById(id: string): Promise<UserEntity | null> : Repository pass-through helpers that still return nullable promises.

updateUser(id: string, data: UpdateUserRequest): Promise<Result<UserEntity, DomainError>> : Ensures the user exists, then applies partial updates. Returns NotFoundError when the user is missing.

listUsers(options?): Promise<Result<UserWithAuth[] | PagedUserResult, DomainError>> : Supports organization-scoped, system-wide, and paged listings. Returns BusinessLogicError for repository issues.

updateUserRole(id: string, role: Role): Promise<Result<UserEntity, DomainError>> : Thin convenience wrapper calling updateUser.

Organization Management

createOrganization(data: CreateOrganizationRequest): Promise<Result<OrganizationEntity, DomainError>> : Ensures slug uniqueness, returning BusinessLogicError (CONFLICT) when a duplicate slug exists.

getOrganizationBySlug(slug: string): Promise<Result<OrganizationEntity, DomainError>> getOrganizationById(id: string): Promise<Result<OrganizationEntity, DomainError>> : Return NotFoundError for missing organizations.

Sessions

createSessionForUser(userId: string): Promise<Result<string, DomainError>> : Generates a seven-day session token and returns the session identifier wrapped in a Result.

validateSession(sessionId: string): Promise<Result<UserWithAuth, DomainError>> : Confirms existence and expiration, returning NotFoundError or BusinessLogicError when invalid.

invalidateSession(sessionId: string): Promise<Result<void, DomainError>> deleteUserSessions(userId: string): Promise<Result<void, DomainError>> : Remove sessions, returning NotFoundError when the session/user has no active tokens.

Error Semantics

  • createValidationError – invalid email formats or duplicate checks
  • createConflictError – duplicate organization slugs or other uniqueness violations
  • createNotFoundError("User"|"Organization"|"Session", id) – lookups that miss
  • toBusinessLogicError(error, message) – unexpected repository or external errors

Logging captures structured breadcrumbs for each operation (createUser:start, createUser:duplicate, etc.), making it easier to trace failures in observability tooling.

Usage Example

const createResult = await services.auth.createUser({
email: "[email protected]",
name: "Admin",
organizationId: "system",
});

const user = createResult.match(
(value) => value,
(error) => {
throw mapDomainErrorToTRPC(error);
},
);

Legacy Notes

  • getUserByEmail and getUserById remain nullable promise helpers to simplify session validation code. Wrap the returned value in Result helpers when exposing outside the service boundary.
  • Session invalidation still returns Result<void, DomainError> but depends on repository constraints—ensure callers unwrap via executeResult.

Last Validated: 2025-11-10 against commit 0342a62e