领域事件和命令
默认模板的 Reaction 中已经注册的 Event、Command 及其处理方式。
一次业务变化会先生成 Event,再由 Event 创建一个或多个 Command。Reaction 只处理已经注册到 src/core/reaction/events/index.ts 和 src/core/reaction/commands/index.ts 中的定义。
Event
EventInput
Prop
Type
已注册的 Event
| Event | type | 输入要点 | 生成的 Command |
|---|---|---|---|
UserSignupEvent | user_signed_up | Subject、来源,可选角色和注册邮件 | grant_role、send_email |
UserEmailVerifiedEvent | user_email_verified | 用户 Subject、verifiedEmail、emailHash、verifiedAt、purpose | 账号邮箱验证成功且邮箱命中管理员名单时,生成 grant_role |
PaymentSucceededEvent | payment_succeeded | Subject、来源,可选角色和权益 | grant_role、grant_entitlement |
SubscriptionCreatedEvent | subscription_created | Subject、订阅来源,可选角色和权益 | grant_role、grant_entitlement |
SubscriptionUpdatedEvent | subscription_updated | Subject、订阅来源,可选的完整角色和权益配置 | 先撤销该来源已有内容,再按新配置重新授予 |
SubscriptionEndedEvent | subscription_ended | Subject、订阅来源,可选角色和权益 | revoke_role、revoke_entitlement |
UserEmailUpdatedEvent | user_email_updated | 用户 Subject、邮箱摘要、可选的旧邮箱通知数据 | 同步支付服务商邮箱,并按需向旧邮箱发送安全提醒 |
UserTwoFactorSecurityChangedEvent | user_two_factor_security_changed | 用户、邮箱、姓名、语言、发生时间和安全设置地址 | send_email |
EntitlementCycleDueEvent | entitlement_cycle_due | 可选的下一条周期权益记录 | process_due_entitlement_cycles |
DataCleanupEvent | data_cleanup | olderThan | purge_stale_data |
NotificationRequestedEvent | notification_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
| Command | type | 模式 | 用途 |
|---|---|---|---|
GrantRoleCommand | grant_role | sync | 按来源为 Subject 授予角色 |
RevokeRoleCommand | revoke_role | sync | 按来源撤销角色或静态能力 |
GrantEntitlementCommand | grant_entitlement | sync | 按来源为 Subject 授予权益 |
RevokeEntitlementCommand | revoke_entitlement | sync | 按来源撤销权益或动态能力 |
SendEmailCommand | send_email | async | 渲染已注册邮件模板并发送邮件 |
SendNotificationCommand | send_notification | async | 使用配置的通知渠道发送消息 |
CreateUserNotificationCommand | create_user_notification | async | 创建已发布的站内通知,Command ID 同时作为通知 ID |
SyncPaymentCustomerEmailCommand | sync_payment_customer_email | async | 把用户最新的已验证邮箱同步到支付服务商 Customer |
ProcessDueEntitlementCyclesCommand | process_due_entitlement_cycles | async | 处理到期的周期权益并安排下一次执行 |
PurgeStaleDataCommand | purge_stale_data | async | 清理超过指定时间的数据 |
所有 Command 的模板默认版本都是 1,最大尝试次数都是 3。每个 Command 定义可以另行设置这两个值;Event 创建 Command 时,也可以只修改本次执行的 maxAttempts。
sync Command 会在 Event 执行过程中立即处理;async Command 会交给 ASYNC_POLICY_TASK_QUEUE。无论使用哪种模式,执行记录都会写入 command_execution。
执行状态
EventExecutionStatus
| 值 | 含义 |
|---|---|
processing | 没有触发终止条件,并且仍有 Command 等待执行 |
completed | 没有 Command 处于等待、业务失败或异常状态 |
partial_failed | continueOnFailure 为 true,全部 Command 已结束,其中至少一个返回业务失败 |
failed | continueOnFailure 为 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 不会识别该定义。