文档
08_归档04_VOZEB任务卡

OceanWay 单体运行时与旧站退役任务包

Task ID:OCEANWAY-RUNTIME-CUTOVER-01 状态:LOCAL_IMPLEMENTATION_CANDIDATE / NOT_PRODUCTION_MIGRATED / NOT_DEPLOYED 当前隔离实现 Base SHA:3daafc09a7aaed090c43d23bca9f535b2da22c77

目标结果

oceanway-vozeb 的 Next.js/React 应用成为唯一 OceanWay 产品和运行时:用户在 oceanway.tech(后续也包括解析到同站的 ocean-way.top)使用同一套登录、Session、 用户、Key、积分/账本、套餐、用量、创作与管理后台。模型执行只通过管理员配置的 new-api 网关,应用不直接管理 new-api 后方的渠道、账号池或模型调度。

旧站与旧 sub2api 只作为一次性只读迁移源。切换后停止旧站登录、Session、账本和业务 写入并关闭服务;新站不保留旧站运行时依赖,也不建立 Retail Portal Session、双登录或 Identity Bridge。

本任务明确取代 VOZEB-RETAIL-NEXT-KEY-MODEL-USAGE-01 中“Retail 是运行时事实源”和 “Retail Portal Session Bridge”的方案。该旧文件只保留为历史决策记录,不能再指导实现。

已确认契约

  1. 新登录只签发 oceanway_session;旧 Session 不迁移、不读取,用户首次进入新站重新 登录。迁移的 bcrypt 密码允许在本项目验证,成功后按现有机制渐进重哈希。
  2. 用户、旧 Key、余额/冻结额、套餐/订阅、订单和用量历史均需迁移;每条源数据必须有 ID Map、状态、Manifest、Checkpoint、Checksum 和例外记录,重复 Apply 不得增加经济 价值或重复数据。
  3. Key 运行时由本项目持有 HMAC 与独立加密密文;列表只显示摘要,当前用户显式请求单 Key 时才可返回完整值,响应 no-store,不得进入日志、URL 或浏览器持久存储。
  4. 金额、积分、额度和历史成本使用 PostgreSQL numeric 与十进制字符串。旧单位到新 积分的映射在正式 Apply 前单独冻结;未冻结时只能保留原精度快照,不能猜测换算。
  5. /models 读取本项目管理员维护的逻辑模型与已就绪绑定;只公开 OceanWay 模型 ID、 能力、参数和积分摘要,不暴露 Channel、Group、上游账号或内部模型映射。
  6. /keys、/models、/usage 最终只调用同源 /api/developer/**,不再调用 /api/retail/portal/**。
  7. VOZEB 只保留 LICENSE、NOTICE、第三方许可证和上游来源等法律记录;用户可见 Logo、 文案、Cookie、元数据、导航、导出文件名和业务契约统一为 OceanWay。
  8. 余额、钱包合计、套餐积分等摘要默认显示两位小数;数据库、迁移、追加式流水、单笔 API 消费与退款保留八位小数。单笔非零金额不得因为小于 0.01 而显示或结算成 0.00。

实现切片

R0:身份与模型运行时(本轮)

  • Cookie 切换为 oceanway_session,登录/注册/退出主动清除旧 Cookie;
  • 新建 /api/developer/models,直接读取本地逻辑模型与 new-api 渠道配置;
  • /models 改用 OceanWay 本地契约;
  • 固定后续 Schema、迁移和退役边界,不连接真实旧库、不部署。

R1:本地 Key 域(本地候选已实现,尚未迁移/部署)

  • 新建正式用户 Key 表、Repository、Service 与 /api/developer/keys;
  • 支持 list/create/reveal/revoke,所有权、HMAC、AES-GCM、限流和 no-store 完整;
  • /keys 移除 Retail adapter。

实现与安全证据见 OCEANWAY-DEVELOPER-KEYS-R1.md。R1 只完成新站自身 Key 运行时, 不代表旧 Key 已导入或真实用户已验证。

R2:本地用量与经济域(用量/Key/公开网关已形成候选)

  • 已建立 /api/developer/usage,以当前 Session 用户查询网页积分流水和已导入的旧站历史 用量;旧站成本使用 LEGACY_CREDIT,不冒充当前积分;
  • /usage 已移除 Retail adapter,旧 /api/retail/portal/** 运行时已退役;
  • 迁移 Apply 可把旧 Key 同时写入正式 Key 表,原值可按新 HMAC 认证和显式取回;
  • 余额 opening entry、显式套餐映射、只读历史订单投影已在隔离 PostgreSQL 合成用户上完成 首次 Apply、重复 Apply 与 fingerprint Verify;原密码登录、Key 列表/取回、余额、套餐和 历史用量 API 已实测通过。
  • 已新增公开 /v1/models 与文本/图片/音频/视频创建入口;旧 Key 可按原值鉴权,调用经后台 逻辑模型映射进入同一积分消费、失败退款和用量归属链路。用户 Key 不会转发到上游;同一 幂等身份不会再次生成或重复扣费。
  • PostgreSQL 积分字段、迁移 opening、消费和退款保留八位小数;界面余额汇总显示两位,个人 中心单笔流水和开发者用量保留最多八位。
  • 仍需冻结非零冻结余额政策、旧非终态订单增量责任,以及公开异步任务轮询/取消契约。

实现与边界证据见 OCEANWAY-DEVELOPER-USAGE-R2.md。

R3:迁移器与生产切换

  • 在合成数据完成 audit → dry-run → apply → verify → repeated-apply;
  • 获得单独授权后只读旧库,冻结源、备份、最终增量、校验和、例外处理;
  • 新站冒烟和账本核对通过后关闭旧站写入与服务,DNS 指向同一 OceanWay 站点;
  • 生产数据访问、导入、部署、DNS 和旧服务关闭均需当次明确授权,不包含在 R0。

今晚切换 Go / No-Go

旧服务在以下全部检查为 GO 前保持在线且可回退;任何一项未知或不一致均为 NO-GO:

检查项GO 条件当前状态
用户身份dry-run 的 password:reset-required=0,或已批准并演练逐用户恢复方案;active/disabled 数量与源一致待真实只读审计
可用余额用户逐条 opening、总额、负余额和八位小数 fingerprint 一致;重复 Apply 不增加余额合成库通过,真实库待审计
冻结余额frozen-balance:nonzero=0,或已明确映射为独立不可用资产且完成解冻/退款流程待真实只读审计
套餐/订阅每个旧 Group 都有显式 plan map;subscription:unmapped=0;重叠订阅逐条保留待映射与真实 dry-run
Key每把有效旧 Key 原值可通过 /v1/models 与代表性生成调用;停用、过期、IP、RPM、并发状态不被放宽;旧 quota/used 逐 Key 核对单位合成库通过,真实 Key 待抽样
用量历史行数、用户归属、Key 归属、Token/成本聚合和 fingerprint 一致,页面可查询合成库通过,真实库待审计
订单所有非终态订单逐条列出责任方;新站不重复履约、退款或接管半条流程待真实 dry-run
模型网关生产 new-api 代表性文本/图片/音频/视频成功,失败精确退款,上游与内部地址不泄露本地夹具通过,真实网关待验收
反向代理VOZEB_PRO_TRUSTED_PROXY_HOPS 与真实代理层数一致,Key IP 规则不能被伪造转发头绕过待生产配置
回滚目标库备份可恢复;旧站保持只读/可恢复;观察窗口内账本差异可定位待 Operations 演练

迁移 dry-run 现在输出完整 classifications,包括密码兼容、账号、冻结/负余额、Key 状态/ 过期、API/网页用量、套餐映射和非终态订单计数。订阅 dry-run 会完整列出未映射数量,Apply 仍对任一未映射订阅失败关闭。

R0 允许修改路径

AGENTS.md
.env.example
docs/oceanway/OCEANWAY-RUNTIME-CUTOVER-01.md
docs/content/docs/progress/todo.mdx
docs/content/docs/progress/pending-test.mdx
CHANGELOG.md
web/src/lib/auth/session.ts
web/src/lib/auth/session.test.ts
web/src/integrations/oceanway/**
web/src/lib/server/developer-model-service.ts
web/src/lib/server/developer-model-service.test.ts
web/src/app/api/developer/models/**
web/src/services/api/developer/**
web/src/app/(user)/models/page.tsx
web/src/app/(user)/models/page.test.tsx

禁止修改 retail-platform、真实旧库、生产环境、DNS、支付、现有创作执行逻辑和管理员 渠道写入逻辑。R0 只复用管理员已经配置的渠道和逻辑模型,不发起真实模型调用。

R0 验收

pnpm --dir web exec vitest run src/lib/auth/session.test.ts src/lib/server/developer-model-service.test.ts src/app/api/developer/models/route.test.ts src/app/'(user)'/models/page.test.tsx --config vitest.config.ts --reporter=dot
pnpm --dir web exec tsc --noEmit --pretty false
pnpm --dir web exec eslint <R0 files> --quiet
pnpm --dir web run build
git diff --check

必须证明:旧 Cookie 不被读取;新登录签发 OceanWay Cookie;模型 API 要求当前 OceanWay Session;只公开可解析的本地逻辑模型;响应不包含渠道、密钥或上游模型;筛选、分页、 音频能力和 no-store 正常。正式迁移与停服不以 R0 自测结果代替。

On this page