现象
Zendesk / Intercom / Freshdesk 标配:未注册客户输入 工单号 + 邮箱 → OTP 验证 → 查看工单。
当前 #1294 spec 的 anonymousEntry.routes 只能表达两种:
- 全公开 view(任何人可看,如 KB)
- 全匿名 mutation action(如提交工单)
缺少第三种「凭证校验后的私有 view」。
复现
- 客户用一次性邮件提了工单,没留账号
- 想查进度,记不住 magic-link 邮件
- 期望:访问
/portal/helpdesk/lookup → 输 ticket_number + email → 收 OTP → 看工单
- spec 表达不出来
Workaround
用 action(mutation)模拟读取,违反语义;或者要求用户必须注册。
分阶段建议
M2:PortalAnonymousRouteSchema 新增 discriminator kind: 'lookup':
{
kind: 'lookup',
path: '/lookup',
viewRef: 'helpdesk_ticket.detail',
keyFields: ['ticket_number', 'customer_email'],
challenge: { method: 'email_otp', ttl: '10min' } | { method: 'magic_link' },
rateLimit: { rule: '3/hour/ip' },
captcha: true,
}
运行时:匹配 keyFields → 用 record 上的 email 字段发 OTP → 验证通过颁发短期 token → 渲染 viewRef。
验收
- helpdesk portal 声明 lookup route,三次错误尝试后被 rate-limit 拦截
- OTP 验证通过后,只能看到匹配的那一条记录,不能枚举其它工单(即使 viewRef 是 list)
关联
现象
Zendesk / Intercom / Freshdesk 标配:未注册客户输入 工单号 + 邮箱 → OTP 验证 → 查看工单。
当前 #1294 spec 的
anonymousEntry.routes只能表达两种:缺少第三种「凭证校验后的私有 view」。
复现
/portal/helpdesk/lookup→ 输ticket_number + email→ 收 OTP → 看工单Workaround
用 action(mutation)模拟读取,违反语义;或者要求用户必须注册。
分阶段建议
M2:
PortalAnonymousRouteSchema新增 discriminatorkind: 'lookup':运行时:匹配 keyFields → 用 record 上的 email 字段发 OTP → 验证通过颁发短期 token → 渲染 viewRef。
验收
关联