Files
GuJumpgate/docs/多注册流程状态迁移设计.md
T

249 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 多注册流程状态迁移设计
本文是 `docs/多注册流程架构边界.md` 的落地补充,专门解决“现有扁平状态怎么迁到多 flow 架构”这个最容易把旧逻辑拖垮的问题。
## 1. 先说结论
当前项目不能直接在 `DEFAULT_STATE` 上继续堆字段。要支持多个完全不同的注册流程,必须先把“运行态”“持久配置”“共享服务状态”“flow 私有状态”分层,再保留一层 OpenAI 旧步骤兼容视图。
这次迁移的目标不是一步把全部字段搬完,而是先建立新的状态主模型,让旧代码通过 adapter 继续运行。
## 2. 当前源码里的真实问题
### 2.1 `DEFAULT_STATE` 仍然是单流程扁平模型
`background.js` 里的 `DEFAULT_STATE` 目前把这些不同层次的状态混在一起:
- 流程进度:`currentStep``stepStatuses`
- 通用运行态:`automationWindowId``tabRegistry``logs`
- OpenAI OAuth / 平台回调:`oauthUrl``localhostUrl``sub2apiSessionId``codex2apiSessionId`
- OpenAI Plus`plusCheckoutTabId``plusCheckoutUrl``plusBillingAddress`
- OpenAI 接码:`currentPhoneActivation``signupPhoneActivation``reusablePhoneActivation`
- OpenAI LuckMail`currentLuckmailPurchase`
- 共享邮箱运行态:`registrationEmailState`
这会带来两个直接后果:
1. 新 flow 一接进来,就只能继续往全局 state 加字段。
2. 任何 reset / retry / stop 都容易误清理别的业务域状态。
### 2.2 旧步骤数字模型已经渗透到多个模块
当前不只是 `background.js` 依赖 `currentStep / stepStatuses`,下列模块也在按“Step 1~13”理解流程:
- `background/auto-run-controller.js`
- `background/logging-status.js`
- `background/account-run-history.js`
所以新状态模型不能只改 `background.js`,必须给自动运行、日志、账号记录保留兼容出口。
### 2.3 `registrationEmailState` 名字看起来通用,内部却仍带 OpenAI 身份假设
`background/registration-email-state.js` 已经把邮箱运行态单独抽出来了,这是好事;但它的 `preserveAccountIdentity` 现在默认保留的是“手机号身份”,也就是:
- `accountIdentifierType = phone`
- `signupPhoneNumber`
- `signupPhoneActivation`
- `signupPhoneCompletedActivation`
这对 OpenAI 的 `add-email` 分支是对的,但对未来可能出现的“用户名主身份”“邀请码主身份”“钱包地址主身份”并不通用。
## 3. 目标状态分层
建议先建立“概念上的标准状态模型”,物理存储可以分阶段迁移。
```js
chrome.storage.session.runtimeState = {
activeFlowId: 'openai',
activeRunId: 'run_20260512_xxx',
currentNodeId: 'submit-signup-email',
nodeStatuses: {
'open-chatgpt': 'completed',
'submit-signup-email': 'running',
},
shared: {
automationWindowId: 123,
tabRegistry: {},
sourceLastUrls: {},
logs: [],
autoRun: {},
accountArtifacts: {},
},
services: {
mail: {},
proxy: {},
accountPools: {},
},
flows: {
openai: {
auth: {},
platformBinding: {},
plus: {},
phoneVerification: {},
luckmail: {},
identity: {},
},
},
legacyStepCompat: {
currentStep: 2,
stepStatuses: { 1: 'completed', 2: 'running' },
},
};
chrome.storage.local.settings = {
schemaVersion: 2,
shared: {
autoRunDefaults: {},
logging: {},
},
services: {
mailProviders: {},
ipProxy: {},
hotmailPool: {},
mail2925Pool: {},
icloud: {},
customEmailPool: {},
},
flows: {
openai: {
signupMethod: 'email',
phoneVerificationEnabled: false,
plusModeEnabled: false,
plusPaymentMethod: 'paypal',
sub2api: {},
codex2api: {},
luckmail: {},
smsProviders: {},
},
},
};
```
## 4. 四层状态边界
### 4.1 共享运行态 `runtimeState.shared`
只放“运行任何 flow 都需要”的内容:
- `activeFlowId / activeRunId / currentNodeId / nodeStatuses`
- `automationWindowId`
- `tabRegistry`
- `sourceLastUrls`
- `logs`
- 自动运行轮次、暂停、计时器计划
- 账号产物总览,如最终身份、最终邮箱、最终手机号、完成时间
这里不要再放 OpenAI 特有概念,例如 `plusCheckoutTabId``currentPhoneActivation`
### 4.2 共享服务状态 `runtimeState.services`
放“可被多个 flow 复用的服务运行态”,而不是具体网站流程状态:
- 邮箱 provider 当前会话
- 2925 / Hotmail / iCloud / Cloud Mail 等共享邮箱服务上下文
- IP 代理当前应用结果、探测结果、池游标
- 可复用的共享账号池游标
注意:`LuckMail` 目前不进这一层,它仍属于 OpenAI flow 私有能力。
### 4.3 flow 私有运行态 `runtimeState.flows[flowId]`
每个 flow 自己保管自己的业务运行态。当前 OpenAI 至少应拆成:
- `auth``oauthUrl``localhostUrl`
- `platformBinding``sub2api*``codex2api*`
- `plus``plusCheckoutTabId``plusCheckoutUrl``plusBillingAddress`
- `phoneVerification``currentPhoneActivation``signupPhoneActivation``reusablePhoneActivation`
- `luckmail``currentLuckmailPurchase``currentLuckmailMailCursor`
- `identity`:OpenAI 特有的登录方式冻结结果、`step8VerificationTargetEmail`
### 4.4 持久配置 `settings`
持久配置必须按“共享 / 服务 / flow 私有”拆开,不再把所有配置都平铺到同一个 namespace。
特别注意:
- `signupMethod` 先保留在 `flows.openai`,不要急着抽成全局通用枚举。
- `plusModeEnabled``plusPaymentMethod``gopay*``paypal*` 都属于 OpenAI flow 私有配置。
- `phoneVerificationEnabled` 当前也属于 OpenAI flow 私有配置。
## 5. 旧步骤兼容层怎么做
迁移阶段仍要保留 `currentStep / stepStatuses`,但它们不再是主数据,只是 `legacyStepCompat` 的派生视图。
建议规则:
1. 新的 canonical 状态只写 `activeFlowId / currentNodeId / nodeStatuses`
2. OpenAI flow 通过 node-to-step 映射生成 `legacyStepCompat`
3. `getState()` 对旧模块仍返回:
- `currentStep`
- `stepStatuses`
- OpenAI 旧字段镜像
4. `setStepStatus(step, status)` 内部先更新 node,再回写 legacy step 视图
这样可以保证:
- `background/auto-run-controller.js` 先不重写也能跑
- `background/logging-status.js` 先不重写也能继续渲染
- `background/account-run-history.js` 仍能按旧语义落盘
## 6. 账号记录与自动运行的兼容策略
### 6.1 自动运行
`background/auto-run-controller.js` 当前按数字步骤推断进度、失败点和恢复点。迁移阶段要增加一层统一 selector:
- `getActiveRunProgress(state)`
- `getLegacyStepCompat(state)`
- `inferResumeNode(state, flowId)`
第一阶段可以继续让 OpenAI flow 通过旧 step 恢复;第二个 flow 接入时再真正改成 node-based resume。
### 6.2 账号记录
`background/account-run-history.js` 不能只记“失败在第几步”,还要开始记录:
- `activeFlowId`
- `activeRunId`
- `currentNodeId`
- `nodeStatuses` 摘要
- `legacyFailedStep`(仅 OpenAI 兼容)
否则未来多 flow 下,单看 `step7_failed` 已经没有意义。
## 7. 命名约束
仓库里已经存在别的 `flow_id` 语义,用在 GPC / GoPay 远端任务里。为了避免冲突:
- 扩展内部运行态统一使用 `activeFlowId`
- 当前轮标识统一使用 `activeRunId`
- 节点标识统一使用 `currentNodeId`
- 不新增裸字段 `flowId`
`flow_id` 只保留给外部接口 payload 兼容使用。
## 8. 第一阶段迁移顺序
1. 新增状态 selector / patch helper,不改业务步骤行为。
2. 给 OpenAI flow 建立 `flowState.openai` 命名空间,同时保留旧字段镜像。
3. 把日志、自动运行、账号记录改为优先读 selector,不直接拼 `stepStatuses`
4. 把新加字段一律放进 `shared / services / flows.openai`,禁止继续向 `DEFAULT_STATE` 顶层加 OpenAI 字段。
5. 第二个 flow 接入前,再清理旧 step 镜像的写路径。
## 9. 本文对应解决的缺口
本文主要补齐以下缺口:
- `DEFAULT_STATE` 扁平模型没有命名空间
- 旧步骤状态与新 node 状态如何并存
- 自动运行 / 日志 / 账号记录如何不被状态迁移打断
- `registrationEmailState` 当前仍隐含“手机号是唯一可保留主身份”的假设