/** * Lifecycle status of an {@link AccessRequest} — the "request access / join the * waitlist" identity primitive that captures a prospective user from a public * form before they become a real `User`. * * Operators triage `REQUESTED` records, then either decline them or approve and * **graduate** them into a `User` (optionally attached to a tenant). * * State machine: * ``` * REQUESTED ──approve──> APPROVED ──graduate──> GRADUATED * │ │ * ├──decline──> DECLINED ┘ (decline also valid from APPROVED) * └──cancel───> CANCELED * ``` * * @example * ```typescript * if (request.status === AccessRequestStatus.APPROVED) { * await service.graduateAccessRequest(request.id, { by: operatorId }); * } * ``` * * @see {@link UserStatus} for the account-level status set when a request graduates */ export declare enum AccessRequestStatus { /** Open request awaiting operator triage (the default on creation) */ REQUESTED = "requested", /** Operator approved the request; ready to graduate into a User */ APPROVED = "approved", /** Operator declined the request */ DECLINED = "declined", /** Request was graduated into a real User (terminal) */ GRADUATED = "graduated", /** Request was canceled before a decision (terminal) */ CANCELED = "canceled" } /** * Shared AI usage tracking types for SMRT. * * These types are intentionally provider-agnostic so SMRT can normalize * telemetry emitted by the underlying AI SDK into a stable internal shape. */ /** * Normalized token usage information for an AI call. */ export declare interface AiTokenUsage { /** Number of input tokens consumed by the request */ promptTokens?: number; /** Number of output tokens produced by the response */ completionTokens?: number; /** Total tokens consumed across the call */ totalTokens?: number; } /** * Grouping dimensions supported by summary helpers. */ export declare type AiUsageGroupBy = 'provider' | 'model' | 'class' | 'tenant' | 'operation' | 'day'; /** * Callback interface for handling normalized AI usage events. */ export declare interface AiUsageHandler { /** * Handle a normalized AI usage event. */ handle(event: SmrtAiUsageEvent): Promise; } /** * Options for listing raw AI usage records from persistence. */ export declare interface AiUsageListOptions { /** Only include records on or after this timestamp */ since?: Date; /** Only include records before or at this timestamp */ until?: Date; /** Filter by provider */ provider?: string; /** Filter by model */ model?: string; /** Filter by operation */ operation?: string; /** Filter by SMRT class name */ className?: string; /** Filter by tenant ID */ tenantId?: string | null; /** Maximum number of rows to return */ limit?: number; /** Number of rows to skip */ offset?: number; /** Sort order */ orderBy?: 'timestamp DESC' | 'timestamp ASC'; } /** * In-memory snapshot returned by the collector. */ export declare interface AiUsageSnapshot { /** Usage aggregated by "provider:model" */ byModel: Record; /** Usage aggregated by "className:operation" */ byClass: Record; /** Total number of calls observed by the collector */ totalCalls: number; /** Collector start time in epoch milliseconds */ startTime: number; } /** * Aggregated statistics bucket for AI usage reporting. */ export declare interface AiUsageStats { /** Number of calls represented in the bucket */ callCount: number; /** Sum of prompt/input tokens */ promptTokens: number; /** Sum of completion/output tokens */ completionTokens: number; /** Sum of total tokens */ totalTokens: number; /** Sum of durations in milliseconds */ totalDuration: number; /** Sum of estimated costs in USD */ estimatedCost: number; /** Timestamp of the most recent event in epoch milliseconds */ lastUsed: number; } /** * Options for summarized AI usage queries. */ export declare interface AiUsageSummaryOptions extends Omit { /** Dimension to group summary buckets by */ groupBy?: AiUsageGroupBy; } /** One typed predicate. `in` and `notIn` require a non-empty value array. */ export declare interface DataQueryCondition { kind: 'condition'; field: DataQueryFieldId; operator: DataQueryFilterOperator; value: DataQueryScalar | DataQueryScalar[]; } export declare interface DataQueryConsistency { /** Prefer the adapter's most recently available data. */ mode: DataQueryConsistencyMode; /** Optional RFC 3339 instant requested by a time-travel capable adapter. */ asOf?: string; } /** Read consistency requested by a caller; adapters decide whether they support it. */ export declare type DataQueryConsistencyMode = 'eventual' | 'snapshot'; /** Cursor values are opaque to callers and bound to a normalized query. */ export declare interface DataQueryCursorPage { kind: 'cursor'; after?: string; limit: number; } /** A bounded request for one declared facet. */ export declare interface DataQueryFacetRequest { field: DataQueryFieldId; limit: number; } export declare interface DataQueryFacetResult { field: DataQueryFieldId; values: DataQueryFacetValue[]; truncated: boolean; } /** A bounded facet value/count pair. */ export declare interface DataQueryFacetValue { value: DataQueryScalar; count: number; } /** An explicitly declared query field and its capability allowlist. */ export declare interface DataQueryFieldDescriptor { id: DataQueryFieldId; type: 'string' | 'number' | 'boolean' | 'datetime' | 'json'; projectable?: boolean; sortable?: boolean; facetable?: boolean; filterOperators?: DataQueryFilterOperator[]; } /** A stable, adapter-defined field identifier. It is never a property path. */ export declare type DataQueryFieldId = string; /** Bounded, recursive filter expression with explicit boolean semantics. */ export declare type DataQueryFilter = DataQueryCondition | { kind: 'all' | 'any'; filters: DataQueryFilter[]; } | { kind: 'not'; filter: DataQueryFilter; }; /** Operators map to an adapter's allowlisted, typed predicate implementation. */ export declare type DataQueryFilterOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'notIn' | 'like'; /** Freshness metadata is declarative; it does not grant access to a snapshot. */ export declare interface DataQueryFreshness { state: 'fresh' | 'stale' | 'unknown'; asOf?: string; } /** Offset pagination is explicit so callers cannot smuggle arbitrary bounds. */ export declare interface DataQueryOffsetPage { kind: 'offset'; offset: number; limit: number; } export declare type DataQueryPage = DataQueryOffsetPage | DataQueryCursorPage; /** * Canonical data-query request. * * A request id correlates transport logs and results only; it is intentionally * excluded from the semantic query fingerprint. The query does not contain * authority, raw database expressions, property paths, functions, or a * transport-specific filter object. */ export declare interface DataQueryRequest { version: 1; requestId: string; mode: 'rows' | 'count' | 'facets'; projection?: DataQueryFieldId[]; filter?: DataQueryFilter; sort?: DataQuerySort[]; page?: DataQueryPage; consistency?: DataQueryConsistency; facets?: DataQueryFacetRequest[]; } /** * Normalized adapter result. `queryFingerprint` identifies the semantic query * (not the request id or page cursor), while pagination state stays explicit. */ export declare interface DataQueryResult { version: 1; requestId: string; queryFingerprint: string; identityField: DataQueryFieldId; rows: DataQueryRow[]; page?: { kind: 'offset'; limit: number; offset: number; hasMore: boolean; } | { kind: 'cursor'; limit: number; nextCursor?: string; hasMore: boolean; }; total: DataQueryTotal; facets?: DataQueryFacetResult[]; freshness: DataQueryFreshness; warnings: string[]; truncated: boolean; } /** Rows use JSON-safe values; adapters must project only declared fields. */ export declare type DataQueryRow = Record; /** * Transport-neutral, bounded data-query contract (#2444). * * This module intentionally has no runtime code. The core package owns * normalization, policy enforcement, canonical fingerprints, and result * validation; browser, REST, MCP, WebMCP, ContentList, and report adapters * share these serializable shapes without importing a server runtime. * * Authority is deliberately absent. A query can name only adapter-declared * field ids and operators; tenant, principal, SQL, relationship paths, and * execution details belong to the authenticated adapter, never this envelope. */ /** JSON scalar values accepted in predicates, facets, and normalized rows. */ export declare type DataQueryScalar = string | number | boolean | null; /** * Per-adapter execution policy. It is trusted adapter configuration, never * client input, and therefore carries the field allowlists the normalizer * applies to requests and returned rows. */ export declare interface DataQuerySchema { version: 1; identityField: DataQueryFieldId; fields: DataQueryFieldDescriptor[]; defaultPageLimit?: number; maxPageLimit?: number; maxResultBytes?: number; defaultSort?: DataQuerySort[]; supports?: { cursorPagination?: boolean; consistency?: boolean; facets?: boolean; }; } /** Deterministic sort precedence; earlier terms take precedence. */ export declare interface DataQuerySort { field: DataQueryFieldId; direction: DataQuerySortDirection; } export declare type DataQuerySortDirection = 'asc' | 'desc'; /** How a returned total was obtained, including the absence of a total. */ export declare type DataQueryTotal = { kind: 'exact'; value: number; asOf?: string; } | { kind: 'estimated'; value: number; asOf?: string; } | { kind: 'unavailable'; reason?: string; }; /** Per-object configuration controlling domain-knowledge generation and exposure. */ export declare interface DomainKnowledgeConfig { enabled?: boolean; api?: { /** * Generate HTTP knowledge routes. Disabled by default; prefer CLI/MCP for * agent workflows unless this is a guarded dev/admin endpoint. */ enabled?: boolean; basePath?: string; includeDocs?: boolean; includePrompts?: boolean; /** * Require dev mode or admin locals for HTTP knowledge access. Setting this * to false makes the route public and should only be used when sanitized * anonymous schema/surface metadata is acceptable. */ requireAdmin?: boolean; }; includeDocs?: boolean; includePrompts?: boolean; tags?: string[]; summary?: string; risks?: string[]; } /** A field retained in the curated agent-facing object shape. */ export declare interface DomainKnowledgeField { name: string; type: string; required?: boolean; related?: string; columnType?: string; default?: unknown; constraints?: DomainKnowledgeFieldConstraints; readonly?: boolean; transient?: boolean; } /** Validation constraints retained in the curated agent-facing field shape. */ export declare interface DomainKnowledgeFieldConstraints { min?: number; max?: number; minLength?: number; maxLength?: number; pattern?: string; } /** Result of a domain-knowledge freshness check (stale references, error/warning counts). */ export declare interface DomainKnowledgeFreshnessResult { ok: boolean; checkedAt: string; artifactPath?: string; issueCount: number; errorCount: number; warningCount: number; issues: Array<{ severity: 'error' | 'warning'; code: string; message: string; file?: string; packageName?: string; }>; } /** The package-level domain-knowledge artifact (`smrt-knowledge.json`) — the agent/developer contract. */ export declare interface DomainKnowledgeManifest { schemaVersion: 1; /** True when generation removed sensitive fields before projecting objects. */ sensitiveFieldsExcluded?: true; generatedAt: string; packageName?: string; packageVersion?: string; sourceManifestPath?: string; agentDocPath?: string; sourceHashes: Record; exports: string[]; dependencies: Record; smrtDependencies: string[]; sdkDependencies: string[]; tags: string[]; summary?: string; risks: string[]; objects: DomainKnowledgeObject[]; surfaces: DomainKnowledgeSurface[]; prompts: Array<{ filePath: string; key?: string; }>; relationshipsV2: { foreignKeyFields: number; crossPackageRefFields: number; junctionCollections: number; hierarchicalObjects: number; polymorphicAssociations: number; uuidColumns: number; }; agentDoc?: string; /** Sibling module docs linked from `AGENTS.md`; omitted when the package links none. */ moduleDocs?: DomainKnowledgeModuleDoc[]; } /** Additive structured signature; `methods: string[]` remains the compatibility surface. */ export declare interface DomainKnowledgeMethodSignature { name: string; async?: boolean; static?: boolean; params?: string[]; returns?: string; } /** * A sibling module doc linked from a package's `AGENTS.md` (#2108). * * Oversized package docs are split by module into `packages//agents/.md` * rather than nested `AGENTS.md` files, because instruction chains are additive. * The link in `AGENTS.md` is the registration: the knowledge tooling resolves it * so the moved prose — which is curated and not regenerable from the manifest — * stays reachable from agent context. */ export declare interface DomainKnowledgeModuleDoc { /** Path relative to the package root, e.g. `agents/commissions.md`. */ path: string; /** Module name derived from the file's basename, e.g. `commissions`. */ module: string; content: string; } /** One object's entry in the domain-knowledge manifest (fields, relationships, surfaces). */ export declare interface DomainKnowledgeObject { name: string; qualifiedName?: string; collection: string; tableName?: string; packageName?: string; extends?: string; visibility?: string; fields: DomainKnowledgeField[]; relationships: DomainKnowledgeField[]; methods: string[]; methodSignatures?: DomainKnowledgeMethodSignature[]; tenant?: DomainKnowledgeTenant; tableStrategy?: 'cti' | 'sti'; conflictColumns?: string[]; surfaces: DomainKnowledgeSurface[]; relationshipFeatures: string[]; tags: string[]; summary?: string; risks: string[]; } /** A single generated surface (one api/cli/mcp/ai operation) exposed by an object. */ export declare interface DomainKnowledgeSurface { kind: DomainKnowledgeSurfaceKind; name: string; operation: string; path?: string; method?: string; description?: string; objectName?: string; } /** Kind of generated surface a knowledge entry describes (REST/CLI/MCP/AI). */ export declare type DomainKnowledgeSurfaceKind = 'api' | 'cli' | 'mcp' | 'ai'; /** Normalized tenancy facts from `@smrt({ tenantScoped })`. */ export declare interface DomainKnowledgeTenant { scoped: boolean; mode?: 'required' | 'optional'; field?: string; } /** User↔Tenant↔Role junction. Runtime class: `@happyvertical/smrt-users:Membership`. */ export declare interface Membership extends SmrtEntityFields { userId?: string; tenantId?: string; roleId?: string; status: MembershipStatus; } /** * Status of a user's membership within a specific tenant. * * A user may hold memberships in multiple tenants simultaneously, each with an * independent `MembershipStatus`. * * @example * ```typescript * const active = memberships.filter(m => m.status === MembershipStatus.ACTIVE); * ``` * * @see {@link UserStatus} for the global account-level status * @see {@link TenantStatus} for the status of the tenant itself */ export declare enum MembershipStatus { /** Active membership */ ACTIVE = "active", /** Inactive membership */ INACTIVE = "inactive", /** Pending invitation acceptance */ PENDING = "pending" } /** * Generic component type for SMRT module UI slots. * * Intentionally opaque — defined as a loose function signature rather than * `import('svelte').ComponentType` to avoid pulling Svelte (and its DOM types) * into server-side Node.js builds. The actual Svelte component constructor * is assignable to this type at runtime. * * @typeParam Props - The props interface the component accepts; defaults to `unknown`. * * @example * ```typescript * import InvoiceCard from './InvoiceCard.svelte'; * // InvoiceCard is assignable to ModuleComponentType * registry.register('@happyvertical/smrt-commerce', 'invoice-card', InvoiceCard); * ``` * * @see {@link ModuleUIBaseProps} for the base props all slot components receive * @see {@link ModuleUIRegistryInterface} for storing and retrieving components */ export declare type ModuleComponentType = (...args: any[]) => any; /** * Base props contract for all SMRT module UI slot components. * * Every component registered against a `ModuleUISlot` should accept at least * these props. Individual slot components may extend this interface with * slot-specific required props. * * @typeParam TData - Shape of the primary data object(s) the component renders. * @typeParam TConfig - Shape of the optional configuration/settings object. * * @example * ```typescript * interface InvoiceCardProps extends ModuleUIBaseProps { * showLineItems?: boolean; * } * ``` * * @see {@link ModuleComponentType} for the component type that accepts these props * @see {@link ModuleUISlot} for the slot declaration that names the `propsInterface` */ export declare interface ModuleUIBaseProps { /** Primary data object(s) the component operates on */ data?: TData; /** Configuration/settings */ config?: TConfig; /** Callback for data changes */ onChange?: (data: TData) => void | Promise; /** Callback for saving */ onSave?: (data: TData) => Promise; /** Whether component is read-only */ readonly?: boolean; /** CSS class for styling */ class?: string; /** Loading state */ loading?: boolean; } /** * Registry interface for mapping SMRT module slots to Svelte components. * * Implemented by `ModuleUIRegistry` in `@happyvertical/smrt-ui`. Consumers * call `register()` once per slot at Svelte package initialisation time and * `get()` when rendering to retrieve the correct component. * * @example * ```typescript * // Registration (in packages/commerce/src/svelte/index.ts) * ModuleUIRegistry.registerModule(COMMERCE_MODULE_META); * ModuleUIRegistry.register('@happyvertical/smrt-commerce', 'invoice-card', InvoiceCard); * * // Retrieval (in a host Svelte app) * const InvoiceCard = ModuleUIRegistry.get('@happyvertical/smrt-commerce', 'invoice-card'); * ``` * * @see {@link SmrtModuleMeta} for the module metadata structure passed to `registerModule()` * @see {@link ModuleUISlot} for the slot identifiers used as `slotId` * @see {@link ModuleComponentType} for the component type stored in the registry */ export declare interface ModuleUIRegistryInterface { /** Register a component for a module's slot */ register(moduleName: string, slotId: string, component: ModuleComponentType): void; /** Get a component for a module's slot */ get(moduleName: string, slotId: string): ModuleComponentType | undefined; /** Check if component is registered */ has(moduleName: string, slotId: string): boolean; /** Get all registered slot IDs for a module */ getSlots(moduleName: string): string[]; /** Get all registered module names */ getModules(): string[]; /** Get module metadata */ getModuleMeta(moduleName: string): SmrtModuleMeta | undefined; /** Register module metadata */ registerModule(meta: SmrtModuleMeta): void; /** Unregister for testing */ unregister(moduleName: string, slotId: string): boolean; /** Clear all for testing */ clear(): void; } /** * Module type definitions for SMRT Framework * * These types allow SMRT modules to declare their capabilities, * including models, collections, and optional Svelte UI components. * * @example Module with UI components * ```typescript * // In core module: packages/commerce/src/ui.ts * import type { SmrtModuleMeta, ModuleUISlot } from '@happyvertical/smrt-types'; * * export const COMMERCE_UI_SLOTS: Record = { * 'invoice-card': { id: 'invoice-card', label: 'Invoice Card', category: 'display' }, * }; * * export const COMMERCE_MODULE_META: SmrtModuleMeta = { * name: '@happyvertical/smrt-commerce', * displayName: 'Commerce', * uiSlots: COMMERCE_UI_SLOTS, * }; * * // In svelte subpath: packages/commerce/src/svelte/index.ts * import { ModuleUIRegistry } from '@happyvertical/smrt-ui/registry'; * import { COMMERCE_MODULE_META } from '../ui.js'; * import InvoiceCard from './components/InvoiceCard.svelte'; * * ModuleUIRegistry.registerModule(COMMERCE_MODULE_META); * ModuleUIRegistry.register('@happyvertical/smrt-commerce', 'invoice-card', InvoiceCard); * ``` */ /** * UI slot definition for a SMRT module. * * Modules declare the slots they support in their `SmrtModuleMeta`. Svelte UI * packages then implement those slots by registering components against the * same `id` via `ModuleUIRegistryInterface.register()`. * * @example * ```typescript * const slot: ModuleUISlot = { * id: 'invoice-card', * label: 'Invoice Card', * description: 'Compact card view for a single invoice', * category: 'display', * order: 10, * }; * ``` * * @see {@link SmrtModuleMeta} for how slots are declared on a module * @see {@link ModuleUIRegistryInterface} for registering component implementations */ export declare interface ModuleUISlot { /** Unique identifier (e.g., 'invoice-card', 'customer-form') */ id: string; /** Human-readable label */ label: string; /** Description of the component's purpose */ description?: string; /** Icon identifier (lucide icon names) */ icon?: string; /** Display order (lower first) */ order?: number; /** Component category for grouping */ category?: 'display' | 'form' | 'admin' | 'list' | 'detail' | 'action' | 'dashboard' | 'navigation'; /** Required props interface name (for documentation) */ propsInterface?: string; } /** * Effect applied by a user-level permission override. * * Overrides target a specific user + permission combination and always win * over role-based grants. `DENY` overrides are checked before `GRANT` in * the 4-level permission cascade. * * @example * ```typescript * await override.create({ * userId, * permission: 'billing.view', * effect: OverrideEffect.DENY, * }); * ``` * * @see {@link TenantPermissionEffect} for the tenant-level equivalent that supports inheritance */ export declare enum OverrideEffect { /** Grant the permission */ GRANT = "grant", /** Deny the permission */ DENY = "deny" } /** RBAC role. Runtime class: `@happyvertical/smrt-users:Role`. */ export declare interface Role extends SmrtEntityFields { /** `null` → system role available to every tenant. */ tenantId?: string | null; name: string; description: string; isSystem: boolean; /** * Opt-in hierarchical inheritance: when `true`, an ACTIVE membership holding * this role also resolves permissions in descendant tenants where the user * has no direct membership. Default `false` (authority is exact-tenant only). */ inheritsToDescendants: boolean; } /** * Status of an authenticated session. * * Sessions transition from `ACTIVE` to either `EXPIRED` (time-based) or * `REVOKED` (explicit action by the user or an administrator). * * @example * ```typescript * if (session.status !== SessionStatus.ACTIVE) { * redirect(302, '/login'); * } * ``` * * @see {@link UserStatus} for the account-level status checked before session creation */ export declare enum SessionStatus { /** Active session */ ACTIVE = "active", /** Expired session (past expiresAt) */ EXPIRED = "expired", /** Revoked by user or admin */ REVOKED = "revoked" } /** * Signal emitted during SMRT method execution. * * Signals provide automatic observability into method execution, * enabling logging, metrics, pub/sub updates, and other integrations * without requiring manual instrumentation. * * @example * ```typescript * // Logging adapter * const loggingAdapter: SignalAdapter = { * async handle(signal: Signal) { * const label = `${signal.className}.${signal.method} [${signal.id}]`; * if (signal.type === 'start') console.log(`→ ${label}`); * if (signal.type === 'end') console.log(`✓ ${label} (${signal.duration}ms)`); * if (signal.type === 'error') console.error(`✗ ${label}`, signal.error); * }, * }; * ``` * * @see {@link SignalType} for the lifecycle stage values * @see {@link SignalAdapter} for implementing a consumer */ export declare interface Signal { /** * Unique identifier for this specific execution * Generated once per method invocation */ id: string; /** * ID of the SMRT object instance */ objectId: string; /** * Name of the SMRT class */ className: string; /** * Name of the method being executed */ method: string; /** * Signal type indicating lifecycle stage: * - 'start': Method execution started * - 'step': Manual step within method (optional) * - 'end': Method execution completed successfully * - 'error': Method execution failed */ type: SignalType; /** * Optional step label for manual progress tracking * Developers can emit custom steps within methods using bus.emit() */ step?: string; /** * Sanitized method arguments (sensitive data removed) * Objects with @sensitive JSDoc tags are excluded */ args?: unknown[]; /** * Method result (only present on 'end' signals) */ result?: unknown; /** * Error that was thrown (only present on 'error' signals) */ error?: Error; /** * Method execution duration in milliseconds * Only present on 'end' and 'error' signals */ duration?: number; /** * Timestamp when signal was emitted */ timestamp: Date; /** * Optional additional context * Can include tracing IDs, user context, request metadata, etc. */ metadata?: Record; } /** * Adapter interface for consuming signals from the SMRT signaling system. * * Adapters process signals for specific purposes: * - **Logging**: write to console, file, or a logging service * - **Metrics**: track execution counts, durations, and error rates * - **Pub/Sub**: broadcast real-time updates to connected clients * - **Tracing**: forward spans to a distributed tracing system (e.g., OpenTelemetry) * * Adapters are fire-and-forget — errors thrown inside `handle()` are caught * by the SignalBus and do not interrupt the main execution flow. * * @example * ```typescript * class MetricsAdapter implements SignalAdapter { * async handle(signal: Signal): Promise { * if (signal.type === 'end') { * metrics.histogram('smrt.method.duration', signal.duration ?? 0, { * class: signal.className, * method: signal.method, * }); * } * } * } * ``` * * @see {@link Signal} for the payload each adapter receives * @see {@link SignalType} for the lifecycle stages */ export declare interface SignalAdapter { /** * Handle a signal event * * @param signal - The signal to process * @returns Promise that resolves when signal is handled * * @remarks * This method should not throw - errors are caught by the SignalBus. * Implementations should handle their own error logging/recovery. */ handle(signal: Signal): Promise; } /** * Universal Signaling System Types * * This module defines the core types for the SMRT signaling system, * which provides automatic method tracking and event distribution * for logging, metrics, pub/sub, and other observability needs. */ /** * Lifecycle stage of a signal emitted during SMRT method execution. * * - `'start'` — emitted when a tracked method begins executing * - `'step'` — emitted manually within a method for progress tracking * - `'end'` — emitted when a method completes successfully * - `'error'` — emitted when a method throws an unhandled exception * * @example * ```typescript * adapter.handle = async (signal: Signal) => { * if (signal.type === 'error') { * logger.error(`${signal.className}.${signal.method} failed`, signal.error); * } * }; * ``` * * @see {@link Signal} for the full signal payload shape * @see {@link SignalAdapter} for consuming signals */ export declare type SignalType = 'start' | 'step' | 'end' | 'error'; /** * Stable usage event shape emitted inside SMRT after every AI call. */ export declare interface SmrtAiUsageEvent { /** AI provider identifier (e.g. "openai", "anthropic") */ provider: string; /** Model identifier used for the call */ model: string; /** High-level operation name (e.g. "chat", "embed", "stream") */ operation: string; /** Token usage reported by the provider, when available */ usage?: AiTokenUsage; /** Wall-clock duration in milliseconds */ duration: number; /** Event timestamp */ timestamp: Date; /** Optional provider- or application-specific tags */ tags?: Record; /** SMRT class responsible for the call */ className?: string; /** Tenant identifier when available */ tenantId?: string | null; /** Best-effort estimated cost in USD */ estimatedCost?: number; } /** * Persisted AI usage record returned from query helpers. */ export declare interface SmrtAiUsageRecord extends SmrtAiUsageEvent { /** Persistent record identifier */ id: string; } /** * Fields every persisted SMRT entity exposes — a subset of `SmrtObject`'s public * surface. `id`/`slug` are `null`/`undefined` before the first persist, matching * the base getters. */ export declare interface SmrtEntityFields { /** UUID, assigned on first persist. */ id: string | null | undefined; /** URL-safe slug, when the model maintains one. */ slug: string | null | undefined; /** Creation timestamp; `null`/`undefined` before first persist. */ created_at: Date | null | undefined; /** Last-update timestamp; `null`/`undefined` before first persist. */ updated_at: Date | null | undefined; } /** * Metadata declaration for a SMRT module. * * Each module exports a `SmrtModuleMeta` constant describing its package * identity, the UI slots it declares, and the model/collection classes it * provides. The UI registry uses this to resolve component lookups at runtime. * * @example * ```typescript * export const COMMERCE_MODULE_META: SmrtModuleMeta = { * name: '@happyvertical/smrt-commerce', * displayName: 'Commerce', * description: 'Invoicing, contracts, and fulfillment', * models: ['Customer', 'Invoice', 'Contract'], * uiSlots: { * 'invoice-card': { id: 'invoice-card', label: 'Invoice Card', category: 'display' }, * }, * }; * ``` * * @see {@link ModuleUISlot} for the shape of each declared slot * @see {@link ModuleUIRegistryInterface} for registering and retrieving module components */ export declare interface SmrtModuleMeta { /** Package name (e.g., '@happyvertical/smrt-commerce') */ name: string; /** Human-readable display name */ displayName: string; /** Module description */ description?: string; /** Module version */ version?: string; /** UI slots this module declares */ uiSlots?: Record; /** Model classes this module provides */ models?: string[]; /** Collection classes this module provides */ collections?: string[]; /** Peer dependencies for UI (e.g., ['@happyvertical/smrt-profiles']) */ uiDependencies?: string[]; } /** * Package-owned route definition. * * @typeParam TData - Data shape the route component expects. * @typeParam TLoadInput - Input accepted by the optional `load` helper. * @typeParam TProps - Component props shape. Defaults to `{ data?: TData }`. */ export declare interface SmrtRouteDefinition { /** Stable route identifier, namespaced by package. */ id: string; /** Human-readable page title. */ title: string; /** Optional description for docs and tooling. */ description?: string; /** Canonical path the package recommends by default. */ defaultPath: string; /** Page component exported by the package. */ component: ModuleComponentType; /** Optional reusable load helper for app-owned route files. */ load?: (input: TLoadInput) => Promise | TData; /** Which SvelteKit route file the `load` helper belongs in. */ loadKind?: SmrtRouteLoadKind; /** Optional navigation metadata. */ nav?: SmrtRouteNavigationMeta; /** Optional tags for docs, hosts, or filtering. */ tags?: string[]; } /** * Route load function category. * * `page` maps naturally to SvelteKit's `+page.ts`, while `page-server` maps to * `+page.server.ts`. */ export declare type SmrtRouteLoadKind = 'page' | 'page-server'; /** * Package-owned route module. * * Consumers import one of these from `@happyvertical/smrt-/routes`, then * mount the exported components and loaders inside their own app route tree. * */ export declare interface SmrtRouteModule { /** Package name, usually `@happyvertical/smrt-`. */ packageName: string; /** Human-readable module name. */ displayName: string; /** Optional module description. */ description?: string; /** * Route definitions keyed by package-local name. * * A heterogeneous registry: each entry is a `SmrtRouteDefinition` with its * own `TData`/`TLoadInput`/`TProps`. `TLoadInput` sits in a contravariant * position (`load?: (input: TLoadInput) => …`), so a concrete route * (`SmrtRouteDefinition`) is NOT assignable to * `SmrtRouteDefinition` — narrowing the params to * `unknown` would reject every real route registration. Like * {@link ModuleComponentType}, this is an irreducible registry `any`. */ routes: Record>; } /** * Resolved navigation entry for a mounted route. */ export declare interface SmrtRouteNavigationItem { /** Stable route identifier. */ routeId: string; /** Link href as mounted by the consuming app. */ href: string; /** Label shown in the app navigation. */ label: string; /** Optional description for menu UI. */ description?: string; /** Optional icon identifier. */ icon?: string; /** Display order (lower first). */ order?: number; /** Optional grouping key for larger menus. */ group?: string; } /** * Navigation metadata for a package route. */ export declare interface SmrtRouteNavigationMeta { /** Label shown in app navigation. */ label: string; /** Optional route description for menus or docs. */ description?: string; /** Optional icon identifier. */ icon?: string; /** Display order (lower first). */ order?: number; /** Optional grouping key for larger menus. */ group?: string; } /** Hierarchical tenant. Runtime class: `@happyvertical/smrt-users:Tenant`. */ export declare interface Tenant extends SmrtEntityFields { name: string; status: TenantStatus; description: string; parentTenantId?: string | null; hierarchyLevel: number; hierarchyPath: string; cascadePermissions: boolean; inheritPermissions: boolean; } /** * Effect of a tenant-level permission setting in a hierarchical tenant tree. * * Unlike `OverrideEffect`, tenant-level effects support `INHERIT` — the default * behaviour where a child tenant walks up to its parent to resolve the permission. * `DENY` blocks inheritance, preventing child tenants from acquiring the permission * even if a grandparent grants it. * * @example * ```typescript * // Sub-tenant explicitly blocks billing access regardless of parent settings * await tenantPermission.create({ * tenantId: subTenantId, * permission: 'billing.manage', * effect: TenantPermissionEffect.DENY, * }); * ``` * * @see {@link OverrideEffect} for user-level overrides (no inheritance step) * @see {@link TenantStatus} for the tenant lifecycle status */ export declare enum TenantPermissionEffect { /** Inherit from parent tenant (default behavior) */ INHERIT = "inherit", /** Explicitly grant at this tenant level */ GRANT = "grant", /** Explicitly deny at this tenant level (blocks inheritance) */ DENY = "deny" } /** * Lifecycle status of a tenant (organization) within the platform. * * @example * ```typescript * if (tenant.status === TenantStatus.ARCHIVED) { * return; // skip soft-deleted tenants * } * ``` * * @see {@link MembershipStatus} for a user's membership status within a tenant * @see {@link TenantPermissionEffect} for permission inheritance across tenant hierarchies */ export declare enum TenantStatus { /** Active tenant */ ACTIVE = "active", /** Inactive tenant */ INACTIVE = "inactive", /** Suspended tenant */ SUSPENDED = "suspended", /** Archived tenant (soft-deleted) */ ARCHIVED = "archived" } /** Auth identity record. Runtime class: `@happyvertical/smrt-users:User`. */ export declare interface User extends SmrtEntityFields { /** Plain-string reference to the owning `Profile` (not a DB foreign key). */ profileId: string; /** Lower-cased email; globally unique. */ email: string; status: UserStatus; lastLoginAt: Date | null; } /** * User-related type definitions * * These enums and types are exported from smrt-types to allow * browser-safe packages (like smrt-svelte) to import them without * pulling in server-side dependencies from smrt-users. */ /** * Lifecycle status of a user account. * * @example * ```typescript * if (user.status === UserStatus.SUSPENDED) { * throw new ForbiddenError('Account is suspended'); * } * ``` * * @see {@link MembershipStatus} for a user's status within a specific tenant * @see {@link SessionStatus} for the status of an active session */ export declare enum UserStatus { /** Active user account */ ACTIVE = "active", /** Inactive user account */ INACTIVE = "inactive", /** Suspended user account */ SUSPENDED = "suspended", /** Pending email verification */ PENDING = "pending" } export { }