文档:完善网站游戏评分与评价方案

新增网站游戏评分与评价主规范及独立里程碑
明确唯一评价、编辑取消、公共分页与平均分人数合同
补齐提交期间冻结输入和迟到读取响应隔离的验收要求
同步文档索引、发行范围说明与共享决策记录
This commit is contained in:
2026-09-30 14:43:58 +08:00
parent 66ff5bf4b7
commit 15c123bc59
5 changed files with 194 additions and 5 deletions
+2 -1
View File
@@ -19,7 +19,8 @@
## 当前产品与平台
- [当前产品与工程约束](./【项目基线】当前产品与工程约束-2026-05-15.md):现役入口、账号钱包、UI 和后端分层。
- [平台入口与玩法链路](./【玩法创作】平台入口与玩法链路-2026-05-15.md):只描述现役平台壳与图片画布编辑器链路。
- [平台入口与玩法链路](./【玩法创作】平台入口与玩法链路-2026-05-15.md):平台壳、图片画布、游戏分发与在线游玩合同;网站游戏评分与评价方案为 proposed,尚未实现。
- [网站游戏评分与评价里程碑](./project-memory/plans/【里程碑】网站游戏评分与评价-2026-09-30.md):唯一评价、编辑预填、4000 字符、公共分页与平均分/人数的待评审验收边界。
- [外部 OpenAPI 与 API Key 接入方案](./【后端架构】外部OpenAPI与APIKey接入方案-2026-06-19.md)
- [外部 MCP 语义工具说明与参数设计](./technical/【技术方案】外部MCP语义工具说明与参数设计-2026-09-23.md):15 个新增语义工具与全部原工具并存,复用现有 External API;包含工具说明、action、参数、幂等和兼容合同。
- [External v1 OpenAPI](./openapi/genarrative-external-v1.openapi.json):公开 HTTP 契约唯一机器可读来源。
@@ -36,7 +36,7 @@
- 正式状态来自后端,素材仍复用平台上传与归属能力;前端和 AGC 不另建公开游戏状态、owner 事实或审核结果。
- 真实发行包具有不可变版本和 SHA-256,AGC dist 归一化为发行根 `index.html`;网页 ZIP 与 AGC 共用一条服务管道。
- 不恢复退役玩法 API、公开作品表或专属 runtime;不把私有项目源码镜像公开。
- 首版不包含原生/Wasm 游戏、任意外网依赖、服务端进程、多人联机、云存档、评论/评分/关注、排行榜、推荐算法和收益结算。
- 本发行里程碑不包含原生/Wasm 游戏、任意外网依赖、服务端进程、多人联机、云存档、评论/评分/关注、排行榜、推荐算法和收益结算。网站评分与评价作为[独立里程碑](./【里程碑】网站游戏评分与评价-2026-09-30.md)推进,不借用本文件的发行验收结论。
- 本文件只协调本业务;不顺带改造图片编辑器、Agent Runtime 执行模型或无关项目数据。
## 阶段 A:真实包、身份与可恢复发行
@@ -0,0 +1,62 @@
# 【里程碑】网站游戏评分与评价
| 字段 | 值 |
| --- | --- |
| Version | 1.0 |
| Status | proposed(待评审,未实现、未验收) |
| Date | 2026-09-30 |
| Parent Spec | [平台入口与玩法链路](../../【玩法创作】平台入口与玩法链路-2026-05-15.md#网站游戏评分与评价合同)中的“网站游戏评分与评价合同”Version 1.0 |
## 目标
在网站公开游戏详情页交付“一用户一游戏一条评分与可选评论 → 查看个人评价 → 编辑与取消/提交 → 公共分页浏览 → 平均分与评分人数更新”的完整行为闭环。
## 范围
- 复用现有平台登录态,游客可浏览公开评价与统计,登录后可保存和修改自己的唯一评价。
- 评分为 1–10 整数且必选,评论可空、最多 4000 Unicode 码点;实时显示字数与上限。
- 已评价默认显示个人记录和编辑按钮,编辑时预填;取消不保存修改,成功提交收起输入模块。
- 公共列表默认每页 20 条,按首次提交时间倒序;包含当前用户和空评论评价,不因编辑改变位置。
- 详情显示平均分与评分人数,无人评分为“暂无评分”;人数不因修改增加,均分覆盖全部评价。
- 评价随游戏身份保留,新版本发布不清空;下架与封禁关闭评价读写,重新公开恢复读取。
- 覆盖并发唯一性、账号切换、失败与重试、移动端和键盘可操作性。
## 不在范围内
- AGC 客户端评价、独立评价页面、游戏广场评分卡片、评论回复/点赞/附件/Markdown。
- 评价删除、评价审核、评分排行/推荐、必须游玩或消费才能评价的门槛。
- 通用评论框架、统计缓存、评分任务或外部 API;不补做游戏发行原里程碑的生产上线验收。
## 依赖与前置条件
- 主规范与本里程碑评审通过,整数评分、分页与取消行为等默认规则已确认;均分/人数已由用户确认纳入范围。
- 当前游戏详情、公开可见性、平台认证、账号公开资料读取与受信服务身份链路在验收环境可用。
- 能建立独立测试账号及公开游戏,运行真实 SpacetimeDB/API 和网站浏览器验收;不得把本地通过当成生产上线。
- 新增评价 schema、共享 DTO 与既有绑定变更在实现前写入本里程碑的单独实施计划,不对现有表进行破坏性修改。
## 验收标准
- [ ] 游客可读公开游戏评价与摘要;未登录不能保存或读取个人评价。
- [ ] 1/10 分和空评论成功,未选/越界/非整数分数与超长评论均被拒。
- [ ] 中文、英文、emoji、空格及换行计数一致,4000/4001 边界、粘贴和中文输入法符合主规范。
- [ ] 已评价先显示自己的记录,编辑预填;取消恢复旧记录,提交中禁用评分选择、评论输入及取消/提交,成功隐藏表单,失败恢复编辑并保留草稿。
- [ ] 首次取消不落库;同一账号/游戏的重复与并发保存只有一条;不能指定他人身份写入。
- [ ] 至少 21 条真实记录验证分页、顺序和总数,自己的评价允许在个人区与公共区各出现一次。
- [ ] 空评论也展示分数并计人数;编辑不增加人数、不改变创建时间或排序位置。
- [ ] 无评价显示“暂无评分”;改分正确更新全部评价均分,改评论不改变均分,分页不影响统计。
- [ ] 切换账号或游戏不残留个人草稿、不接受旧响应覆盖;读取失败不伪装为未评价。
- [ ] 保存成功后此前的个人评价与公共列表读取失效,不覆盖新记录、摘要或列表;快速翻页/重复刷新只接受各区域最新请求的结果,旧请求不改写错误及加载状态。
- [ ] 游戏下架/封禁后读写不可见,恢复公开后仍能读取已有评价,新版本不清空评价。
- [ ] 评价读取或保存故障不阻断既有游戏资料与游玩;桌面/移动/键盘操作均可用。
- [ ] 定向测试、网站类型、DTO、schema/生成绑定、真实 API/SpacetimeDB/browser smoke 及编码/文档索引/diff 检查有可复核结果。
## 证据要求
- 自动化:评分/字数/唯一性与修改规则、统计、分页、页面交互及账号切换定向测试。
- 运行时:真实 SpacetimeDB/API 上的两账号写入、并发首次保存与分页统计;真实浏览器编辑/取消/提交、移动端字数提示与键盘评分。
- 边界:未登录、伪造身份、不可见游戏、4000/4001 字符、0/11/非整数分数、响应丢失与迟到响应。
- 证据按主规范条款逐项记录环境、操作、结果与未验证原因,原游戏发行证据不自动代替本次验收。
## 未验证
当前仅有方案文档,所有实现与运行时验收尚未开始。评审后再创建单里程碑实现计划;功能完成前保持本文件活动状态,完成后将稳定结论回写主规范并清理临时计划。
@@ -1,5 +1,12 @@
# 决策记录
## 2026-09-30 网站游戏评价范围与状态边界
- 已确认需求:网站游戏详情支持每账号每游戏唯一一条 1–10 分评分和可空的评论(最多 4000 字符),可修改自己的评价;个人区默认展示已有评价并提供编辑预填,公共列表分页且不排除自己。
- 已确认扩展:详情显示真实平均分与评分人数,空评论计人数,修改不增加人数;当前先由后端评价记录计算,不增加统计缓存。
- 状态:本次仅保存 proposed 方案,尚未实现或验收;整数评分、默认每页 20 条、创建时间排序、取消行为与游戏维度保留按主规范评审默认值推进。原发行 Version 0.2 的排除项不再被解释为永久禁止新增用户评价。
- 权威入口:[平台入口与玩法链路](../../【玩法创作】平台入口与玩法链路-2026-05-15.md#网站游戏评分与评价合同);执行验收使用[独立里程碑](../plans/【里程碑】网站游戏评分与评价-2026-09-30.md),不得把既有发行或本次文档检查当作评价功能上线证据。
## 2026-09-30 release 渠道移除产品名与包名后缀
- 决策:`release` 渠道的正式产品名统一为 `陶泥儿`,Windows NSIS、macOS DMG / updater 归档等由 Tauri `productName` 派生的包名不再包含 `Release` 文本;`identifier=world.genarrative.ai-game-creator.release` 与 `release-win` 更新分区保持不变。
@@ -1,8 +1,8 @@
# 平台入口与玩法链路
> 更新时间:`2026-09-23`
> 更新时间:`2026-09-30`
>
> 本文只描述现役主站平台壳、图片画布编辑器和对应后端契约。未出现在现役路由树、shared-contracts 或 SpacetimeDB module / bindings 中的入口与数据对象不属于本文范围。
> 本文描述现役主站平台壳、图片画布编辑器和游戏分发合同;拟新增能力在各节单独标明状态。“网站游戏评分与评价合同”是待实现方案,不代表现役能力。当前实现以路由树、shared-contracts 和 SpacetimeDB module / bindings 为准。
## 现役平台入口
@@ -64,7 +64,7 @@
交付“AGC 一键提交游戏 / 网页上传游戏 ZIP → 后端收取真实发行包 → 校验与人工审核 → 主站发现、详情、游客在线游玩 → 更新与下架”的完整闭环。验收必须使用真实上传、真实存储、真实审核状态和隔离发行域名;静态演示卡片、metadata-only 请求或前端本地发布状态不能作为完成证据。
首版支持可以离线运行的静态 Web 游戏:HTML、JavaScript、CSS、JSON 与图片、字体、音视频。AGC 首先支持现有 npm/Vite Web 工程;网页入口允许上传符合相同包合同的 ZIP,不以游戏引擎名称限制普通静态产物。Godot/Cocos 工程源码、原生可执行文件、Wasm、服务端进程、外部 API、多人联机、云存档和跨版本存档迁移不在首版内。暂不做评分、评论、关注、榜单、推荐算法、交易和创作者收入。
首版支持可以离线运行的静态 Web 游戏:HTML、JavaScript、CSS、JSON 与图片、字体、音视频。AGC 首先支持现有 npm/Vite Web 工程;网页入口允许上传符合相同包合同的 ZIP,不以游戏引擎名称限制普通静态产物。Godot/Cocos 工程源码、原生可执行文件、Wasm、服务端进程、外部 API、多人联机、云存档和跨版本存档迁移不在首版内。本发行合同 Version 0.2 不包含用户评分与评论,其扩展范围见下文“网站游戏评分与评价合同”;关注、榜单、推荐算法、交易和创作者收入仍不在范围内。
### 入口与产品体验
@@ -176,3 +176,122 @@
3. 是否接受首版离线静态包、无 Wasm/外网/持久存档的范围,以及建议包额度、7 天失败包保留和 60 秒缓存撤销窗口;公开/撤销版本及审核记录保留周期待定。
4. 是否接受平台同源路径发行(`/games/<gameId>/` + `sandbox="allow-scripts"` 的不透明来源隔离)替代独立发行域名:选择该方案后独立域名、通配 DNS/TLS 与 CDN 不再是上线门禁,存储区域与运营责任仍需确定。
5. 本节已提供页面行为、发行状态、真实上传、幂等/CAS 和 API 草案,足以评审完整业务;尚不足以直接实现持久化和部署,必须在对应里程碑评审前冻结表/索引/服务身份、额度/清理、最终响应 DTO 与发行基础设施配置。未经评审不建立 `ready` 实施计划,不把 proposed 标记为 accepted。
## 网站游戏评分与评价合同
| 字段 | 值 |
| --- | --- |
| Version | 1.0 |
| Status | proposed(方案待评审,未实现、未验收) |
| Date | 2026-09-30 |
| 入口 | 网站 `/games/detail?id=<gameId>` |
| 交付目标 | 登录用户对同一游戏保存并修改唯一一条评分与可选评论;所有访客分页浏览评价,并查看真实平均分与评分人数 |
| 里程碑 | [网站游戏评分与评价](./project-memory/plans/【里程碑】网站游戏评分与评价-2026-09-30.md) |
### 范围与默认规则
- 本次只扩展网站游戏详情页、现有游戏分发后端与共享契约;复用平台账号,评分与评论合并为一条“评价”。
- 用户已明确要求:评分范围 1–10、评论可空且最多 4000 字符、可修改自己的评价、每用户每游戏最多一条、个人评价展示与编辑预填、公共列表分页且包含自己的评价。
- 用户已确认加入详情页平均分和评分人数:无人评分显示“暂无评分”,空评论计入评分人数,修改不增加人数,当前规模先由后端读取评价记录计算。
- 本方案采用以下评审默认值:评分只接受整数;每页默认 20 条;按首次提交时间倒序;取消首次填写清空草稿,取消编辑恢复原评价;评价跟随游戏身份,不随发行版本更新清空。
- 登录用户均可评价,包括游戏作者;不增加必须先游玩、消费或具有发布权限的条件。评价权限不复用 `game-distribution:publish` 发布灰度。
- 本次不增加 AGC 客户端评价界面、独立评价页面、游戏目录评分展示、评论回复/点赞/图片/Markdown、评价删除、评价审核或推荐排行;不新建通用评论框架、评分缓存或独立统计任务。
### 评分、评论与统计口径
1. 评分必选,取值为整数 1–10;首次填写时不预选分数,不能仅提交文字而不评分。
2. 评论为空字符串或未提供时均允许提交。纯空白评论保存为空字符串;普通评论保留首尾空格与换行。
3. 输入与提交前统一把 `CRLF` / `CR` 换行为 `LF`,再按 Unicode 码点计数;空格、换行同样计入上限。前端与后端计数一致,不按 UTF-8 字节或 UTF-16 单元计数;组合 emoji 可能含多个码点。
4. 长度校验先于纯空白归一化,4000 字符允许,4001 字符拒绝;不静默截断后保存。输入框旁始终显示 `当前字数/4000`,超限显示可读错误并阻止提交;中文输入法与粘贴同样按该口径处理。
5. 每个评价对应一个已认证账号和一个稳定 `gameId`,不绑定 `versionId`。分数与评论一起原子保存;修改已有记录,`createdAt` 不变,有内容变化时更新 `updatedAt`。
6. 平均分等于所有有效评价分数之和除以评价人数,包含作者、当前用户和只评分的记录;每账号最多计一次。后端返回保留一位小数的平均分,页面显示如“8.2/10 · 26 人评分”。
7. 无评价时 `ratingCount=0`、`averageScore=null`,显示“暂无评分”;不能显示“0 分”或虚构默认分。修改评分重新计算平均分,人数保持不变;修改文字不改变均分。
8. 平均分与人数来自后端对该游戏评价的权威读取,不能由当前分页或前端累计计算。本次不持久化总分、人数或均分,不增加缓存及重算任务。
### 页面布局与交互
游戏详情保留“立即玩”和现有资料,在游戏介绍后增加“我的评价”“全部评价”两个区块;平均分与人数显示在详情资料区,并在评价区域共用同一份后端摘要。
| 状态 | 我的评价区域 | 操作结果 |
| --- | --- | --- |
| 未登录 | 显示“登录后评价”入口,不展示可提交表单 | 使用现有平台登录入口;公共列表和评分摘要仍可浏览 |
| 读取自己的评价中 | 显示加载状态 | 确认不存在已有评价前,不提前展示首次填写表单 |
| 已登录且没有评价 | 展示 1–10 分选择、可选评论输入框、字数统计、取消/提交按钮 | 首次输入的评分和文字仅为当前页面草稿 |
| 已登录且已有评价 | 展示自己的分数、评论、修改时间及“编辑评价”按钮,隐藏输入模块 | 空评论仍展示分数,正文不填造提示内容 |
| 编辑已有评价 | 展示输入模块,完整预填分数与评论 | 个人展示区域暂由编辑表单替代,公共列表仍保留该评价 |
| 提交中 | 保留表单及内容,显示提交状态并禁用评分选择、评论输入及取消/提交 | 冻结本次提交内容,防止重复点击和后续输入被成功响应收起表单时丢失;失败后恢复编辑,不把在途请求解释为已保存 |
| 提交成功 | 用后端权威记录显示自己的评价,隐藏输入模块 | 刷新平均分、人数与公共列表 |
| 读取或提交失败 | 给出错误与重试入口 | 读取失败不伪装成“没有评价”;提交失败保留草稿,不覆盖原评价 |
- 首次填写点击取消:清空评分与文字,保留首次填写表单,不产生后端写入;编辑点击取消:丢弃草稿,恢复上次成功读取/保存的个人评价。
- 首次提交成功后公共列表回到第一页;修改成功后刷新当前页,保留页码。提交响应中的个人记录与统计摘要先更新,分页读取失败单独提示重试,不回滚已成功保存的评价。
- 保存成功后,使此前发出的个人评价与公共列表读取失效;迟到响应不得覆盖已保存的个人记录、评分摘要或刷新后的列表。同一游戏内快速翻页或重复刷新时,各读取区域只接受其最新请求的结果,旧请求的成功、错误和加载结束均不得覆盖当前状态。
- 刷新页面重新读取后端保存结果,不自动保存或恢复未提交草稿;退出登录、切换账号或切换游戏时清空个人评价、草稿与旧错误,旧请求的迟到响应不得写入新上下文。
- 评论纯文本展示并保留换行,不执行 HTML、不解析 Markdown。移动端评分控件可换行,评论与按钮不被底部导航遮挡;控件支持键盘选择并提供可访问名称。
- 评分摘要、公共列表和个人评价分别承接加载/失败;评价区域故障不阻断已有游戏资料和游玩动作。摘要加载失败显示重试状态,不能误显示“暂无评分”。
- 优先复用共享动作按钮、状态提示、空态、输入与分页表现;存在跨页面重复时再抽取共享表现组件,领域规则仍留在后端。
### 公共评价列表与分页
- 游客和登录用户都能读取公开游戏的评价;列表展示作者公开昵称/头像、分数、评论、首次提交时间,编辑后标明修改时间。
- 只评分的评价仍进入列表与总数,不制造“无评论”正文;**不排除当前用户**。自己的评价可以在个人区域与公共列表各出现一次,公共列表内部只能出现一条。
- 使用服务端页码分页,`page` 从 1 开始,`pageSize` 默认 20、允许 1–50;页面提供上一页、下一页、当前页及总页数。前端不能一次取全后自行分页。
- 默认按 `createdAt` 倒序,同时间按稳定评价标识倒序;编辑不改变排序位置,不新增排序/筛选选项。
- 无记录时第一页返回空列表、`total=0`、`totalPages=0`,页面显示真实空态并禁用翻页;超出末页返回空列表,不把不存在的页作为服务端错误。
- 分页与统计在单次读取的一致快照中返回;不同翻页请求之间允许反映新提交,不承诺跨请求冻结整份评价集合。
### 数据、身份与持久化边界
新增游戏评价私有表,保存以下必要字段;实际 Rust 表定义与绑定在实现计划中确定:
| 逻辑字段 | 约束 |
| --- | --- |
| `reviewId` | 稳定唯一标识;通过 `gameId + userId` 的无歧义组合标识保证每对游戏/账号只占一个主键 |
| `gameId` | 已存在的稳定游戏身份;建立按游戏查询索引 |
| `userId` | 仅来自平台认证主体,不接受请求指定或转移归属 |
| `score` | 整数 1–10 |
| `comment` | 归一化后的纯文本,最多 4000 Unicode 码点,可为空 |
| `createdAt` | 首次保存时间,修改时不变 |
| `updatedAt` | 最近一次实际内容修改时间 |
- 游戏必须与当前公开详情采用相同可见性判定,存在已公开可玩版本;未公开、作者下架或管理员封禁时,评价公开读取、个人读取和提交均返回 404。已有评价保留,游戏重新公开后可继续读取和编辑。
- `api-server` 先认证并取得用户 ID;SpacetimeDB 入口继续校验现有受信运行服务身份。数据库上下文中的调用者是 API 服务身份,不能把它误当成网页用户。
- 在同一数据库事务里检查游戏可见性并按唯一主键创建或更新;不得用 HTTP 层“先查是否存在,再生成随机 ID 新建”保证唯一性。并发首次提交、双击与重试最终都只有一条记录。
- 对同一条评价的并发修改采用后提交成功的事务覆盖,避免为该低风险编辑引入新版本锁或操作账本;重复提交相同内容返回已有记录,不变更人数和创建时间,也不制造修改时间。
- 公共作者资料由现有账号公开投影取得,不能由评论请求伪造昵称或头像;私有表不直接对浏览器订阅公开。日志不记录评论正文、Token 或私有账号字段。
- 新增表,不删除、改名、重排或修改现有游戏/版本字段;同步迁移登记、表目录、生成绑定与 schema 检查。现有评价数据不存在,无需旧数据回填;已有游戏无评价时自然返回空列表与“暂无评分”。
- 旧客户端和现有游戏目录、详情 DTO 不需要增加必填字段;评分摘要由新增评价接口提供。本次不扩展 `/api/external/v1`,不改外部 OpenAPI。
- 规则与校验进入 `module-game-distribution`,表与事务进入 `spacetime-module`,读取经 `spacetime-client` facade,HTTP/鉴权进入现有 `api-server` 分发路由,DTO 同步 `shared-contracts` / `packages/shared`;网站只持有展示和编辑草稿。
### HTTP 与 DTO 草案
以下接口均为**待实现**,路径以 `/api/game-distribution` 为前缀,返回沿用平台 `ok/data/error/meta` envelope。用户评价与既有后台游戏发行“审核”是不同对象,`/admin/api/game-distribution/reviews` 继续只表示发行审核队列。
| 方法与路径 | 身份 | 请求与成功响应 |
| --- | --- | --- |
| `GET /games/{gameId}/reviews?page=1&pageSize=20` | 游客可读 | `data={reviews,page,pageSize,total,totalPages,ratingSummary}`;公共作者资料随每条评价返回 |
| `GET /games/{gameId}/my-review` | 登录用户 | `data={review}`;未评价为 `review:null`,不返回 404 |
| `PUT /games/{gameId}/my-review` | 登录用户 | `{score,comment}`;`comment` 可省略,按空字符串保存;首次保存与修改均返回 `200`、`data={review,ratingSummary}` |
- `review` 字段:`id`、`gameId`、`author:{id,name,avatarUrl}`、`score`、`comment`、`createdAt`、`updatedAt`;`avatarUrl` 可为空。个人与公共评价使用同一展示形状,时间为统一 UTC 格式。
- `ratingSummary={averageScore:number|null,ratingCount:number}`;公共列表 `total` 等于 `ratingCount`。`totalPages` 由总数与实际 `pageSize` 得出;均分与人数覆盖该游戏全部评价,不只覆盖当前页。
- PUT 是“保存我的唯一评价”,不能指定目标用户或改他人记录;首次创建和更新不拆成不同接口,不接收任意 `reviewId` 定位写入。
- `400` 表示 JSON/字段类型、非整数分数或分页参数错误;`401` 表示未登录/认证失效;`404` 表示游戏不可公开访问;`422` 表示整数评分越界或评论超长;复用现有限流的 `429` 及可读 `5xx` 失败。
- 网络中断或响应丢失时保存结果可能未知,前端不能宣布“已提交”或删除原评价;保留草稿并可通过个人读取核对结果后重试。PUT 重试不会追加第二条记录。
- 公共与个人响应均不缓存过期的评价/评分摘要,使用 `Cache-Control: no-store`;不混入发布灰度或扩大现有发行沙箱权限。
### 验收标准与证据
| 条款 | 必须获得的证据 |
| --- | --- |
| 首次评分与可选评论 | 1 分、10 分和空评论成功;未选择评分、0/11/非整数被拒,后端没有无效写入 |
| 字数与输入 | 中文、英文、emoji、空格与换行按统一口径计数;4000 成功、4001 拒绝,字数提示实时可见,粘贴/中文输入法不绕过上限 |
| 唯一与并发 | 同一用户同游戏的双击、重试与并发首次保存后仍只有一条;不同用户、不同游戏各自独立 |
| 修改与取消 | 已评价先显示个人卡片;编辑完整预填,取消保留旧值,提交更新同一记录;提交中评分、评论和操作按钮均禁用,失败恢复编辑且不丢草稿;首次取消不落库 |
| 公共分页与重复展示 | 至少 21 条真实评价验证翻页/总数/顺序/空态;自己的评价在个人区和所属公共页各出现一次;空评论评价可见,编辑不换位 |
| 均分与人数 | 无记录为 `null/0`;仅评分计人数;改分只改变均分、不加人数;改评论不改变均分;统计基于所有页 |
| 身份与可见性 | 匿名读成功、写/读个人为 401;伪造用户不能修改他人;下架与封禁后读写 404、恢复公开后记录仍在 |
| 生命周期与故障 | 切换账号/游戏后旧响应不覆盖新状态;保存成功后旧读取不覆盖新记录与摘要,快速翻页/刷新只接受各区域最新读取结果;个人读取失败不误展首次表单,摘要失败不误显示无评分;评价失败不阻断游玩 |
| 页面与工程 | 桌面/移动真实浏览器可操作,评分可键盘选择;相关前后端定向测试、网站类型检查、真实 SpacetimeDB/API smoke、DTO/schema/绑定、编码/文档索引/diff 检查 |
本节仅完成方案文档,所有实现、测试、真实数据库与浏览器验收证据均待补。完整行为作为一个独立里程碑交付;评审通过后再创建仅覆盖该里程碑的实现计划,不把文档编写视为功能验收。