领域事件和命令

默认模板的 Reaction 中已经注册的 Event、Command 及其处理方式。

一次业务变化会先生成 Event,再由 Event 创建一个或多个 Command。Reaction 只处理已经注册到 src/core/reaction/events/index.ts 和 src/core/reaction/commands/index.ts 中的定义。

Event

EventInput

Prop

Type

已注册的 Event

Eventtype输入要点生成的 Command
UserSignupEventuser_signed_upSubject、来源,可选角色和注册邮件grant_role、send_email
UserEmailVerifiedEventuser_email_verified用户 Subject、verifiedEmail、emailHash、verifiedAt、purpose账号邮箱验证成功且邮箱命中管理员名单时,生成 grant_role
PaymentSucceededEventpayment_succeededSubject、来源,可选角色和权益grant_role、grant_entitlement
SubscriptionCreatedEventsubscription_createdSubject、订阅来源,可选角色和权益grant_role、grant_entitlement
SubscriptionUpdatedEventsubscription_updatedSubject、订阅来源,可选的完整角色和权益配置先撤销该来源已有内容,再按新配置重新授予
SubscriptionEndedEventsubscription_endedSubject、订阅来源,可选角色和权益revoke_role、revoke_entitlement
UserEmailUpdatedEventuser_email_updated用户 Subject、邮箱摘要、可选的旧邮箱通知数据同步支付服务商邮箱,并按需向旧邮箱发送安全提醒
UserTwoFactorSecurityChangedEventuser_two_factor_security_changed用户、邮箱、姓名、语言、发生时间和安全设置地址send_email
EntitlementCycleDueEvententitlement_cycle_due可选的下一条周期权益记录process_due_entitlement_cycles
DataCleanupEventdata_cleanupolderThanpurge_stale_data
NotificationRequestedEventnotification_requested通知目标和消息send_notification

SubscriptionUpdatedEvent 和 SubscriptionEndedEvent 处理 roles、entitlements 时,要区分字段不存在和空数组。字段不存在时不处理这类数据;空数组则撤销该来源下的全部角色或权益。

UserEmailVerifiedEvent 的 purpose 为 account 或 password_reset。只有本站账号邮箱验证流程会按 adminEmails 的精确匹配结果授予 admin 角色,密码重置验证不会授予,OAuth 提供商返回的邮箱已验证声明也不能代替本站验证。

UserEmailUpdatedEvent 默认设置 continueOnFailure: true。同步支付邮箱和发送安全提醒互不依赖,即使其中一项重试后仍然失败,另一项也会继续执行。

Command

CommandDraft

Prop

Type

key 只用于区分同一 Event 中的不同步骤,不决定执行顺序,也不用作 Event 幂等键或 Command 执行 ID。

已注册的 Command

Commandtype模式用途
GrantRoleCommandgrant_rolesync按来源为 Subject 授予角色
RevokeRoleCommandrevoke_rolesync按来源撤销角色或静态能力
GrantEntitlementCommandgrant_entitlementsync按来源为 Subject 授予权益
RevokeEntitlementCommandrevoke_entitlementsync按来源撤销权益或动态能力
SendEmailCommandsend_emailasync渲染已注册邮件模板并发送邮件
SendNotificationCommandsend_notificationasync使用配置的通知渠道发送消息
CreateUserNotificationCommandcreate_user_notificationasync创建已发布的站内通知,Command ID 同时作为通知 ID
SyncPaymentCustomerEmailCommandsync_payment_customer_emailasync把用户最新的已验证邮箱同步到支付服务商 Customer
ProcessDueEntitlementCyclesCommandprocess_due_entitlement_cyclesasync处理到期的周期权益并安排下一次执行
PurgeStaleDataCommandpurge_stale_dataasync清理超过指定时间的数据

所有 Command 的模板默认版本都是 1,最大尝试次数都是 3。每个 Command 定义可以另行设置这两个值;Event 创建 Command 时,也可以只修改本次执行的 maxAttempts。

sync Command 会在 Event 执行过程中立即处理;async Command 会交给 ASYNC_POLICY_TASK_QUEUE。无论使用哪种模式,执行记录都会写入 command_execution。

执行状态

EventExecutionStatus

值含义
processing没有触发终止条件,并且仍有 Command 等待执行
completed没有 Command 处于等待、业务失败或异常状态
partial_failedcontinueOnFailure 为 true,全部 Command 已结束,其中至少一个返回业务失败
failedcontinueOnFailure 为 false,并且至少一个 Command 返回业务失败
errored至少一个 Command 执行时抛出异常

Event 状态由其 Command 状态计算得出,不单独保存,避免两份状态不一致。

CommandExecutionStatus

pending、succeeded、failed、errored 分别表示等待执行、执行成功、返回业务失败和抛出异常。

注册位置

新增 Event 后必须加入 src/core/reaction/events/index.ts 的 events 数组;新增 Command 后必须加入 src/core/reaction/commands/index.ts 的 commands 数组。只创建文件但不注册,Reaction 不会识别该定义。