Files
airz-uniapp/docs/积分规则与开发契约.md
T
hujun 2c9d3feab5 feat: 完善登录流程、UI适配及协议文档更新
本次提交包含以下修改:
1. 新增微信登录相关服务及页面逻辑,实现首次微信绑定手机号流程
2. 优化产品匹配卡片 UI,移除不必要状态显示
3. 调整首页 scroll-view 属性及 banner 背景样式
4. 完善积分规则校验逻辑,增加时区及策略格式验证
5. 更新协议草案文档,补充资料清单及功能说明
6. 修复分析结果路由路径,适配新的匹配结果页面
7. 调整品牌 Logo 安卓端字体对齐样式
2026-10-22 11:24:15 +08:00

227 lines
28 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.
# 积分规则与开发契约
## 2026-10-19 正式更新
积分一期已随20261019-photo-points-token-r1于17:40:33上线至111.230.144.231:每日10分,上海每日一次,两个字段及两个索引迁移完成,无历史补发。客户端最新完整策略校验和规则文案仍需用户重新编译发行,正式签到到账/真机未验收。记录见后端database/photo-points-token-release-20261019.md;下方未发布/正式关闭为历史阶段。
## 2026-10-19 一期本地收尾
用户在一期规则建议后要求“继续下一步”,本轮按每日签到10分、上海业务日每日一次、不补签、无连续奖励、积分不过期、不联动会员等级推进;兑换、提现、AI额度抵扣、资料和邀请奖励均关闭。不导入本机体验积分,不补发历史奖励。该决定覆盖下文2026-10-02的“首阶段建议待确认”,不代表正式活动已启用。
- 已补齐积分规则弹窗的业务日、加成、有效期、等级和用途说明;奖励额继续读取服务端,前端没有写死10分。暂停状态明确为“签到已暂停”,保留已配置规则、余额和明细。
- 前端读取规则时校验状态、版本、奖励、时区和完整一期策略。不支持或不一致的策略返回错误,不用一期文案套用未知权益,也不展示部分余额和签到入口。
- 后端新增 `database/points-phase1.env.example` 配置片段,版本 `points-checkin-20261019-v1`,默认关闭;它不由应用自动读取,未修改实际 `.env` 或 `application/extra/points.php`。`false`/`none`使用引号,测试采用框架相同的默认INI解析,避免被解析为空值。未来启用必须先核实积分表、完成配套迁移,再设置明确运行配置。
- 本轮251项后端纯内存检查、190项HTTP输入检查、110项迁移纯检查、98项写保护检查、21个前端规则/页面行为场景,以及原协议30/照片26场景通过。旧写保护测试补齐Token统计新增的只读查询替身,业务守卫保持。未启动数据库、Redis或worker,未重新执行数据库/HTTP持久化检查。
- 实际H5页面在390×844与1280×900检查通过,包含规则弹窗、草稿/暂停/异常规则、签到响应丢失后刷新并用原键确认。49项记录包含各接口鉴权观察;全部接口为浏览器拦截合成响应,不是正式到账或数据库验收。无运行错误和意外外部请求,控制台只有刻意制造的未发布协议404及丢响应网络错误。截图已查看,未见遮挡或横向溢出。
- 使用既有HBuilderX5.26编译器完成微信29页编译,产物仅在仓库外证据目录,不是已上传包。桌面CLI因HBuilderX未打开不可用,改用同一已安装编译器直接构建;Browser插件未提供,使用已有Python Playwright/Chrome,未安装依赖。
证据:`D:/AAdesk/202609/airz-backups/points-phase1-20261019-r1`。正式积分仍关闭、原表迁移未执行、未发布后端/前端或规则、未访问生产、未调用真实模型,真机和正式到账未验证。积分与累计Token额度互相独立;前一轮Token未发布改动完整保留。
下列章节保留前期设计和验收历史;业务规则是否确认以本节为准,历史“前端未发行”仅描述当时积分联调阶段,不否认后续小程序1.1.0已发行记录。积分正式启用须单独安排迁移、配套上线和到账验收;邀请体系及资料奖励不属于本期完成范围。
记录日期:2026-10-02。版本:points-page-20261002-v3。状态:**后端已随5fee3cf部署、积分页面读取与恢复隔离联调通过;业务规则未定稿,正式配置关闭,原表未迁移、前端未发行**。归属既有 POINT-001—004,不新增任务编号。POINT-002/004保持开发中;DEC-POINT/POINT-001仍待确认,POINT-003未实施。
本文件作为积分实施入口;数据库具体增量见[积分数据库方案](D:/AAdesk/202609/airz/database/points-design.md),最新页面状态与证据见[开发进度0.51](开发进度.md)。未获规则确认时不填真实奖励,配置默认false/null;合成联调不代表正式积分可用。
## 0. 最新页面恢复与隔离联调
页面主流程98项/127次积分请求和补充81项/81次积分请求通过,共201次进入本机真实PHP/MySQL、7次受控故障/网络中断。覆盖真实丢响应后原键确认、跨接口一致性、读取失败时确认入口、确定拒绝弃键、坏回执保键、账户切换及迟到401;登录响应只为合成认证,真机、生产迁移与正式发布仍未完成。
未知请求由页面会话范围调整为原userId作用域的恢复命令上下文:只含requestId/expectedDate/expectedRuleVersion,不含Token、余额、流水或填写资料;401、会话过期、退出及账户切换仍清资料缓存和会话,但该键保留至确认或明确拒绝。恢复前核验当前账户,POST仍重新鉴权;不会把原请求迁移到别的会员,也不会在登录/刷新后自动发奖。此恢复例外不改变DEC-POINT业务参数。
共享清理专项35项通过(15真实积分HTTP、2合成密码登录):真实401清掉会话与该账户的其它资料缓存、保留原命令,同账户重新登录后实际重放且无重复到账。专项未实测本机过期/主动退出/完整账户切换交互;它们共用的清理函数已按上述规则实现。三批共214项/223积分请求,临时环境及私密配置已清理,正式发布/原表迁移状态保持。
### 0.1 前序:协议与隔离开发检查
87个真实HTTP请求/1079项检查通过,经过实际ThinkPHP路由、Redis Token鉴权和积分控制器。覆盖匿名/无效/停用/删除/撤销、Cookie/旧Token头拒绝、允许Origin的匿名OPTIONS、JSON/原始query/错误方法、草案/发布/暂停/坏规则、跨日/版本变化、实际丢弃已提交成功响应后的原键确认、本人快照/隐私/旧NULL与0流水、余额边界、坏回执和Redis不可用。
新脚本tests/points_http.php仅取明确私密环境的本机3309连接,创建独立合成数据库、临时ROOT/RUNTIME、随机ENV_PREFIX和Redis DB15随机Token作用域;不读取正式.env,不启动worker或调用模型。成功后自建数据库、Token、临时服务/文件已清理,共享fa_user/fa_user_score_log结构/数据及原Redis队列摘要保持。所有权标记限制目录清理;清理失败返回非0并保留受限目录及安全定位,不能声称资源已移除。
主服务238项、HTTP输入190项纯检查通过。原表23项只读预检通过,仍4增量、14类质量计数各项0,applied=false。迁移新增非NULL历史时间质量计数,正UINT流水ID并入invalidLedgerIntegers;合法NULL历史时间保留,非NULL时间范围0—253402271999,确保上海ISO8601四位年份。首次快照坏主键固定409/POINT_LEDGER_INVALID。当前业务配置保持false/null,页面、原表迁移及部署未完成。
迁移纯110项、独立合成库apply/备份/Windows ACL/恢复89项通过。共享隔离库只复制结构,第一新库合成2会员4流水;apply4增量、重复为0,完整双表schema+NDJSON恢复第二新库并逐列摘要一致。目录3文件ACL及读写probe通过,修正Windows原生绝对路径及父级路径校验,纯路径边界覆盖;两新库、私密INI/备份/probe已清理,源表摘要保持。安全verification保留于C:/Users/JUN/AppData/Local/Temp/airz-points-migration-20261001/apply-20261001-115749-d50a5cd87fd5a84a/verification.json。仅为开发演练,未执行共享原表DDL或生产操作。
### 0.2 历史:0.48后端基础检查
已新增 PointsRules、UserPoints、v1 Points 控制器、五条路由、默认未发布配置、显式迁移脚本及测试。通用后台score/level、通用模型更新与旧User::score均已拒绝写入;新服务直接在账户锁内限定更新score并保存完整流水,不重算level。新会员0分、数据库默认0级及Auth注册1级初始化保持。schema.sql和ScoreLog中文注释已同步目标结构,不能据此声称目标库已经增加字段。
纯检查237项服务、98项写保护、84项迁移通过。隔离MySQL3309随机前缀合成表45项检查通过,包含同键/异键双PHP并发、锁等待跨日和真实流水insert故障回滚;测试表及临时文件已精确清理。原fa_user/fa_user_score_log结构和数据摘要保持。另22项只读迁移入口检查通过,重复预检仍为4增量、13类质量计数均0,applied=false;本轮修复PHP7.4 PDO不追踪原始START事务导致预检commit失败,改PDO事务接口与RR只读快照。
没有迁移原表、运行apply/备份/Windows ACL、调用模型/worker/Redis/HTTP、编译页面或部署。提交结果未知和连接故障由纯替身覆盖,不是实际断网或生产到账证据;页面状态、真实HTTP、迁移应用与恢复仍须后续开发检查。
## 1. 首阶段建议与待确认项
建议先实施 POINT-002 的账户余额、流水、每日签到,再接 POINT-004 对应页面部分。POINT-003 邀请关系和可信奖励独立实施;不因完成签到而标记整个积分模块完成。
| 项目 | 首阶段建议 | 状态与理由 |
| --- | --- | --- |
| 每日签到 | 已登录且状态正常的会员,每个业务日一次,每次 10 分 | **待确认数额**;沿用既有页面建议,不表示已批准真实奖励 |
| 业务日 | 服务端 Asia/Shanghai,00:00 至次日 00:00,不提供补签 | 待确认;设备时间、时区及登录连续天数不作为依据 |
| 连续签到加成 | 不启用,始终固定当期奖励 | 待确认;不需要新增连续签到表 |
| 完善资料奖励 | 首阶段关闭,奖励数额为 null | 必须后续确定完整标准、可信事件和一次性范围;进入档案或编辑资料不发奖 |
| 邀请奖励 | 首阶段关闭,奖励数额为 null | 有效邀请条件、双方奖励、次数和归因期限待定;复制、分享、绑定码不直接发奖 |
| 积分用途 | 首阶段只提供余额与流水,不启用提现、现金兑换、AI 次数抵扣或贷款优惠 | **待确认权益范围**;不能把积分说成授信、信用分、放款条件 |
| 有效期 | 首阶段建议不自动过期 | **待确认**;若需要到期扣减,须先设计到期批次/消费抵扣,不靠定时清零余额实现 |
| 会员等级 | 新签到服务首阶段建议仅变更 score,不新增等级或权益联动 | **待确认**;旧 User::score 会按余额改 level,需要明确兼容处理后实施 |
| 历史体验积分 | 不导入、不补发真实积分 | 本机记录可篡改,匿名也可签到;正式余额只取服务端既有 score |
| 历史服务端数据 | 原 score、流水、日期、备注、业务键保留 | 不按流水合计重建余额、不自动清零、不擅自修复差异 |
首阶段的业务确认应至少覆盖“每天 10 分、上海每日一次、不补签”“资料/邀请奖励关闭”“权益、有效期及等级处理”。在明确确认前,设计状态保持 draft;未来配置的安全默认值必须为未发布、停止新入账,奖励数额不得用页面示例兜底。
## 2. 已核实的源码现状
| 位置 | 当前能力或风险 | 实施处理 |
| --- | --- | --- |
| [积分页面](../packages/account/points/points.uvue) | 已读取服务端余额、规则、任务和本人流水;按服务端日期/规则恢复签到请求 | 关闭配置时继续显示未发布状态,不伪造奖励;原键确认后重新读取当前余额 |
| [账户服务](../packages/account/services/account.uts) | 已有登录、账户变化防护;资料 DTO 无 score/share_code | 积分服务复用会话,不扩充无关资料字段;登录恢复只接受固定 `resumePoints` 白名单 |
| [请求基础](../services/api.uts) | 已保留 Token 变化、401 清理、HTTP 状态和业务 `errorCode` | 页面按确定拒绝与结果未知分别清理或保留原签到键,网络/账本故障不误判未入账 |
| [数据库结构](D:/AAdesk/202609/airz/database/schema.sql) | fa_user.score 为有符号 INT;流水已具业务键、事件唯一及用户时间索引 | 复用余额和流水;目标库实际结构仍须迁移前只读核实 |
| [通用积分方法](D:/AAdesk/202609/airz/application/common/model/User.php) | 旧score()已明确拒绝,通用模型不能更新score/level | 使用UserPoints领域服务,不再吞异常或随积分重算等级 |
| [后台会员模型](D:/AAdesk/202609/airz/application/admin/model/User.php) | 模型事件、后台增改/批量及编辑表单已保护score/level | 积分/等级只读;任意SQL仍不经过模型守卫,新增写方须遵守共同账户锁 |
最初设计依据源码和schema.sql;本轮仅对显式隔离库读取实际结构/数据并在随机合成表检查事务。正式库未连接,隔离原积分表仍缺两个新列和两个索引,不能把合成表或结构文件当作正式迁移证据。
## 3. 规则发布与事件身份
已增加application/extra/points.php,独立于模型调用额度。默认 `enabled=false`,rule_version/check_in_reward/expiry_policy/level_policy/benefits_policy均null;API映射ruleVersion/checkInReward。发布必须提供完整版本、1—1000的规范整数奖励及none/unchanged/none三项策略;这一范围是配置校验上限,不是批准的奖励额。enabled=false且保留完整发布内容表示paused,不删历史回执。损坏/不完整配置固定POINT_RULE_UNAVAILABLE。
规则版本格式为 2—64 位小写 ASCII,`^[a-z][a-z0-9-]{1,63}$`;拟首版名 `points-checkin-20261001-v1`。同一版本永久对应同一奖励额、日期和参与语义;变更必须新版本,不改历史流水。暂停活动不删除成功回执;启用配置编辑后台不属于首阶段,先使用受控部署配置。
每日签到的账本事件固定:
```text
business_type = checkin
business_id = 服务端上海业务日 YYYY-MM-DD
unique = user_id + business_type + business_id
```
事件键不包含规则版本,因此同一天发布新版本也不能重复奖励。新请求只能为当前业务日入账;设备日期和客户端字段不能指定补签。旧已成功请求允许在下一日、规则暂停或新版本发布后返回原回执,但仍要求当前账户有效且拥有该流水。
## 4. 接口源码契约
统一前缀 `/api/v1`,全部要求显式合法Bearer及当前正常会员,不接受Cookie/旧Token头回退。沿用v1 Base的code/msg/data与data.errorCode、Cache-Control: no-store,v1框架错误亦补该缓存头。由认证身份取得userId;未知参数、客户端余额/奖励/业务完成状态/其他用户ID均拒绝。五条精确白名单路径、原键恢复和页面隔离联调已通过开发检查;原表迁移和规则发布仍未完成,不视为线上积分已启用。
签到要求application/json,可带UTF-8 charset;正文由原生JSON解码及领域校验,必须三个唯一字符串字段,重复键和Unicode等价重复键拒绝。原始QUERY_STRING校验唯一解码键、白名单及PHP解析一致;NUL、坏编码、重复和空片段拒绝。原始/有效HTTP方法须与接口方法一致,覆盖头存在即拒绝;错误方法405,未知路由404。Common既有入口在鉴权前处理允许Origin的匿名OPTIONS,不重复实现CORS。
| 方法与路径 | 严格输入 | data 主要字段 |
| --- | --- | --- |
| GET /points | 无业务参数 | balance:int、serverDate、timezone、signedToday、checkInEnabled、ruleVersion:string/null、checkInReward:int/null、balanceState:normal/anomaly |
| GET /points/rules | 无业务参数 | status:draft/published/paused、ruleVersion:string/null、checkInReward:int/null、timezone、publishedRules;未发布规则不显示为已生效 |
| GET /points/ledger | limit 默认20/最大50;后续页 beforeId + snapshotId | items、snapshotId、nextBeforeId;本人流水,ID 字符串 |
| POST /points/check-in | requestId、expectedRuleVersion、expectedDate,必须恰好三个字段 | ledgerId、delta:int、balanceAfter:int、signedDate、ruleVersion、replayed:bool |
| GET /points/tasks | 无业务参数 | 首阶段只返回已发布签到任务;未实施资料/邀请奖励明确 unavailable,reward=null |
流水源码采用与现有消息/内容一致的有界游标,替代旧page/pageSize目标草案;积分 API 已接入页面,但正式原表迁移和规则发布仍未完成。tasks实际返回serverDate/timezone/items,签到任务按已发布规则和今日状态显示,资料/邀请始终unavailable且reward=null。邀请/invitations和/invitations/bind保留后续阶段目标,不返回固定码或假的奖励进度。
### 4.1 签到请求及回执
`requestId` 为 `pts_` 加 32 位小写十六进制,由客户端生成并在同一用户命名空间内作为幂等键;服务端以唯一约束和原请求确认保证不重复入账。正式发布前仍应将生成源替换为跨端可用的安全随机实现。`expectedRuleVersion` 为页面实际读取的已发布版本;`expectedDate` 为同一次读取返回的 serverDate,是操作预期条件,**不是指定奖励日期**。日期须为真实有效的 YYYY-MM-DD,拒绝非法日历日期、空值、数组和宽松类型转换。
示例仅描述获批发布后的协议形状,当前无这样的运行规则:
```json
{
"requestId": "pts_0123456789abcdef0123456789abcdef",
"expectedRuleVersion": "points-checkin-20261001-v1",
"expectedDate": "2026-10-01"
}
```
入账回执与原流水绑定;重放中 `replayed=true`,其余业务字段保持原值。`balanceAfter` 是这笔入账后的历史余额,不是当前余额;页面必须随后重新 GET /points,不能用旧回执覆盖新余额。不同请求键同日重复签到返回明确的 `POINT_ALREADY_SIGNED`,不写第二条零分流水,也不把新的请求键附到原流水。
### 4.2 余额与流水读取
余额、今日签到状态与规则须来自一次一致的读取:先按当前会员事务读取,固定一个服务端业务日,再完成对应状态查询,避免日界/入账途中混合视图。日期和规则必须一起提供,客户端不能用本机时钟补齐。服务不可读时固定失败,不把错误或未知余额转成 0。
流水DTO为ledgerId/delta/balanceBefore/balanceAfter/businessType/businessDate/ruleVersion/createdAt。时间为ISO8601带时区,历史未知时间保留null;日期为上海YYYY-MM-DD。ID为字符串,支持现有无符号INT至4294967295,服务/迁移要求64位PHP。历史未识别事件统一legacy,业务日/版本可null;不返回原memo、原业务标识或请求键。历史真实0分记录如实展示,不因新服务禁止零分占位而删除。
首次列表取得本会员最大 ID 作为 snapshotId,空为字符串 "0";后续固定上界并按 `id<beforeId` 倒序读取,nextBeforeId=null 表示末页。上界/游标须属于当前用户;不存在或他人标识统一 `POINT_SNAPSHOT_INVALID`,不泄露归属。新流水不插入已翻页窗口,刷新重新取得上界。
负余额保留真实读数并标 balanceState=anomaly,停止新签到等待核对,不静默修正。本轮不根据历史流水合计断言账户余额错误;可能存在早期余额或未完整记录的合法调整。
### 4.3 固定错误
| HTTP / errorCode | 含义与页面处理 |
| --- | --- |
| 401 / AUTH_REQUIRED | 登录或账户状态失效;清当前账户状态,固定登录恢复 |
| 503 / AUTH_STORAGE_UNAVAILABLE | Token存储不可用;不当作已退出或业务未入账,保留待确认请求 |
| 405 / METHOD_NOT_ALLOWED | 原始/有效方法不符或使用方法覆盖;不进入账本操作 |
| 422 / POINT_INPUT_INVALID | 请求字段、类型、ID、版本或日期非法;不入账 |
| 409 / POINT_REQUEST_CONFLICT | 成功请求键已用于另一日期/版本;保留原账本,不改意图重试 |
| 409 / POINT_DATE_CHANGED | 未成功的预期日期不是锁后服务端当前日;刷新,用户重新点击才生成新请求 |
| 409 / POINT_RULE_CHANGED | 预期版本与当前有效版本不同;刷新后重新确认 |
| 409 / POINT_ALREADY_SIGNED | 当前日已有签到;刷新状态,不再次显示增加积分 |
| 409 / POINT_SNAPSHOT_INVALID | 流水游标无效;清旧列表并重新查询 |
| 503 / POINT_RULE_UNAVAILABLE | 规则未发布、暂停、损坏或不可读;关闭新签到,不以 10 分兜底 |
| 409 / POINT_BALANCE_INVALID | 负余额、非规范余额或本次加法越过 INT 上限;不更新 |
| 409 / POINT_WRITE_CONFLICT | 确定的1062/1205/1213竞争且本请求事务已回滚;不自动换键,可用原请求重试 |
| 503 / POINT_LEDGER_UNAVAILABLE | 账本查询/写入暂不可用,或提交/回滚结果无法确认;客户端保留原请求确认结果 |
| 409 / POINT_LEDGER_INVALID | 成功回执元数据损坏或业务唯一键与预期记录不符;不覆盖、不伪造回执 |
网络失败和无法确认的 5xx 不表示未入账。异常原文、SQL、内部连接、其他会员信息和凭据均不下发。
## 5. 事务与重放算法
1. 验证恰好三个字段,规范化按固定字段顺序处理,拒绝 GET query 或其他正文参数。以当前认证用户确定账户。
2. 开启事务,锁定 fa_user 当前行,重新核验 status=normal。账户不存在/禁用不能借历史请求重放。
3. 在用户锁之后以当前读查 `(user_id,request_id)` 的已成功流水。命中时核验 `business_type=checkin`、规范日期、规则版本、delta/before/after 算术及请求预期;同意图返回原回执,异意图固定冲突。历史 NULL 元字段不能充当该回执。
4. 未命中时,在取得用户锁后采样一个上海业务日与时间,校验 expectedDate。锁等待跨午夜必须使用锁后日期;不匹配先返回 POINT_DATE_CHANGED。
5. 以当前读检查固定 `checkin + 当日` 事件;已有则返回 POINT_ALREADY_SIGNED,优先于活动暂停或新规则变化。未签到才读取有效发布规则并校验活动启用和 expectedRuleVersion。业务键不因新请求或新规则版本变化。
6. 校验现有余额及奖励的整数边界,计算 after=before+reward,要求 0≤after≤2147483647。只进行正数签到奖励,负数调整与消费另行设计。
7. 同事务更新用户 score、写一条完整积分流水(事件键、请求键、规则版本、before/after/delta)。任一步失败全部回滚,不能吞异常或写零分占位。
8. 提交成功后返回流水冻结回执。确定1062/1205/1213且确认本请求事务已回滚时返回 POINT_WRITE_CONFLICT,不自动换请求键或无界重试;提交/回滚无法确认时返回 POINT_LEDGER_UNAVAILABLE,用原请求键确认。处理框架回滚异常时保留实际业务失败,不暴露原异常。
所有影响入账的数据库读取使用当前读,不能复用在用户锁前形成的 MySQL RR 快照或外层事务旧视图。规则若采用部署配置,必须每次操作读取该进程当前已发布配置;版本与语义不可变。跨实例滚动部署出现版本不一致时,固定规则冲突优先于偷偷改变奖励。
```mermaid
flowchart TD
A[验证登录和三个预期参数] --> B[锁账户并查成功请求]
B -->|同意图命中| C[返回原流水回执]
B -->|未命中| D[锁后日期校验]
D --> E[检查当日事件 再校验规则与积分边界]
E --> F[余额和一条流水同事务提交]
D -->|日期或版本变化| G[固定冲突并刷新]
E -->|已签到| G
```
## 6. 首阶段数据库与写路径
schema.sql及显式迁移脚本已定义可空request_id/rule_version、唯一(user_id,request_id)和ID游标索引(user_id,id);原表未应用,旧流水保持。已有业务唯一和用户时间索引不重复添加;用户时间索引不能直接保证按ID排序。成功流水保存日唯一和请求回执,不建独立签到/请求/连续签到表。具体字段、中文注释与预检见[数据库增量方案](D:/AAdesk/202609/airz/database/points-design.md)。
本轮已盘点并封闭通用后台绝对值编辑、批量、User::score和模型score/level更新;仅新增服务加锁不能防其他旧写方覆盖余额。受控管理员积分调整独立排期,当前只读;任意SQL不经过模型守卫,后续插件/导入必须重新审查。会员删除的既有历史策略本轮保持,可能有孤儿流水;已删除/停用账户不能通过新服务读取或重放。
新服务拒绝外层事务,确保成功意味着本次真正提交;不回滚调用方已有事务。数据库break_reconnect必须严格false,防断线自动重连使单条SQL意外自动提交。事务竞争只在确认本人事务回滚后映射409,未知提交返回503保留原键,不进行自动SQL重试。
后续邀请关系需独立表,受邀人唯一绑定、禁止自邀、邀请码唯一且历史冲突先人工处理。资料奖励以永久任务事件去重,不能按每次资料修订发奖。只有服务端可信业务事件可触发奖励;不能用客户端声称“资料已完成/好友已注册”发奖。
## 7. 页面实施边界
- 登录后恢复积分页需为现有登录白名单增加固定 `resumePoints` 目标,不接受任意回跳 URL。
- 初次/刷新分别处理加载、失败、空流水、未发布规则、已签到;失败清掉不可信旧状态,不显示假的 0 分或成功。
- 发送中锁定签到按钮;请求结果未知时保留原 requestId/date/version 和账户身份,只允许原请求确认。不能因刷新、关闭提示或跨日自动生成另一签到请求。
- 原回执仅确认原业务日;回执后重新读取当前余额和 serverDate。要签到新一天,必须由用户在刷新后明确点击。
- 离页/换账号拒绝迟到响应;未知请求在原userId作用域保留,离页、401、过期、退出和切换账户不会弃键,不能跨账户迁移。只保留三字段恢复命令,其它账户缓存照常清除;重新登录该会员后才能显式确认,仍须服务端鉴权。
- 从 API 的 ruleVersion/reward 显示规则与奖励,不再写死 10、AI2680 或本机积分。未接邀请前不显示“真实个人邀请码”或未发生的邀请奖励。
- 清理体验签到缓存不产生服务器写入;原匿名/本机记录不影响服务器 signedToday。
## 8. 后续开发检查清单与顺序
以下为完整开发检查范围;已覆盖部分见第0节和开发进度0.51。积分读取/签到恢复隔离页面检查已通过,邀请与资料奖励、原表迁移、正式发布及真机仍未完成:
| 检查 | 关键反例 |
| --- | --- |
| 并发入账 | 同日同键/异键双进程;只有一笔奖励和流水,余额正确 |
| 历史重放 | 第一天成功、第二天原键仍原回执;新日期复用成功键拒绝 |
| 日期边界 | 锁等待跨午夜;昨日未执行请求不能在新一天到账;客户端时区/时钟篡改无效 |
| 规则边界 | 规则变化/暂停/未发布;成功旧回执仍可读,未成功新请求拒绝 |
| 原子回滚 | 流水 insert、余额 update、commit 故障;无“加分成功但无流水” |
| 数据边界 | 负数、INT 上限、坏元数据、NULL 历史事件、非规范业务键不被误认 |
| 所有权与隐私 | 匿名/禁用/跨账户、流水游标和自由备注;只本人读写 |
| 老写方 | 后台伪造 score/level、legacy 方法/插件调用;不能覆盖新账本 |
| 页面状态 | 实际响应丢失、原键确认、换账号、登录恢复、加载/空/错、迟到回包 |
| 迁移和恢复 | 原表只读预检;新合成库apply4增量/重复0、完整备份/ACL/第二库恢复、旧数据摘要一致及精确清理已通过 |
当前后端可在规则未定稿时保持默认关闭。页面真实读取、登录恢复及原键确认已完成隔离联调;下一步是确认首阶段业务规则,随后执行正式库只读预检、完整备份、4项增量迁移和线上关闭状态烟测。邀请资格/奖励规则与关系方案留POINT-003,完整POINT-004后续推进。发布参数在确认前保持空值。
正式迁移、上线、真机/多设备、权益运营和真实业务验收后续按实际范围安排,不复用历史生产授权。本轮为源码、纯测试及显式隔离开发检查,不是生产签到到账或积分页面完成证据。