实现创作者主页与关注粉丝功能
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 6m35s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 5m10s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 4m29s
Project CI / Frontend tests (pull_request) Failing after 55s
Project CI / Backend tests (pull_request) Successful in 8m13s
Project CI / AI game creator shell web tests (pull_request) Successful in 5m37s
Project CI / Repository checks (pull_request) Successful in 7m5s
Project CI / Native shell tests (pull_request) Successful in 9m2s

新增创作者公开主页、第四导航入口、详情作者跳转及关注按钮
实现关注与粉丝列表、取消后重新关注、回关及移除粉丝交互
新增私有关注关系表、类型契约、受信过程和站内查询写入接口
按作者过滤公开游戏并保持既有四十八项读取边界
复用共享用户行、关注按钮及游戏卡,接入移动布局和页面深链
补充定向测试、隔离数据库及浏览器验收脚本并归并工程验证文档
This commit is contained in:
2026-10-05 11:43:05 +01:00
parent 25f858667e
commit e32823d389
101 changed files with 10035 additions and 5491 deletions
+2 -3
View File
@@ -21,9 +21,8 @@
- [当前产品与工程约束](./【项目基线】当前产品与工程约束-2026-05-15.md):现役入口、账号钱包、UI 和后端分层。
- [平台入口与玩法链路](./【玩法创作】平台入口与玩法链路-2026-05-15.md):平台壳、图片画布、游戏分发与在线游玩合同;网站游戏评分与评价已实现并通过本地验证,待用户验收,未部署。
- [网站游戏评分与评价里程碑](./project-memory/plans/【里程碑】网站游戏评分与评价-2026-09-30.md):唯一评价、编辑预填、4000 字符、公共分页与平均分/人数的验收边界与本地证据。
- [创作者主页与关注粉丝合同](./【玩法创作】平台入口与玩法链路-2026-05-15.md#创作者主页与关注粉丝合同)、[关系与公开查询里程碑](./project-memory/plans/【里程碑】创作者关系与公开查询-2026-10-05.md)和[主页与交互里程碑](./project-memory/plans/【里程碑】创作者主页与关系交互-2026-10-05.md):产品规则已确认,未实现;第四项默认进入自己主页,他人的关注/粉丝列表统一只读并支持主页跳转。
- [创作者主页与关注粉丝工程设计](./technical/【技术方案】创作者主页与关注粉丝工程设计-2026-10-05.md):待实现的分层落点、关系表/DTO、授权、关系列表分页、组件状态、深链与验证边界;游戏列表沿用最多 48 项限制,不做额外分页改造。
- [创作者关系与公开查询实施计划](./project-memory/plans/【实施计划】创作者关系与公开查询-2026-10-05.md):首阶段开发计划已就绪,明确契约、事务、facade/HTTP、隔离运行时验收顺序与回滚边界;未开始业务实现。
- [创作者主页与关注粉丝合同](./【玩法创作】平台入口与玩法链路-2026-05-15.md#创作者主页与关注粉丝合同):前后端已实现并通过工程验证,用户已确认提交交付,未部署。第四项默认进入自己主页,他人的关注/粉丝列表统一只读并支持主页跳转。
- [创作者主页与关注粉丝工程设计](./technical/【技术方案】创作者主页与关注粉丝工程设计-2026-10-05.md):分层落点、关系表/DTO、授权、关系列表分页、组件状态、深链与验证边界;游戏列表沿用最多 48 项限制,不做额外分页改造。
- [后台游戏评价管理合同](./【玩法创作】平台入口与玩法链路-2026-05-15.md#后台游戏评价管理合同):查找、分页、隐藏/恢复/删除、必填原因、统计与个人状态联动;已实现并通过本地验证,待用户验收,未部署。
- [后台游戏评价管理里程碑](./project-memory/plans/【里程碑】后台游戏评价管理-2026-10-01.md)与[实施计划](./project-memory/plans/【实施计划】后台游戏评价管理-2026-10-01.md):单里程碑范围、接口/schema 边界及验收要求;本地证据已回写主规范。
- [游戏广场评分展示合同](./【玩法创作】平台入口与玩法链路-2026-05-15.md#游戏广场评分展示合同)、[里程碑](./project-memory/plans/【里程碑】游戏广场评分展示-2026-10-01.md)与[实施计划](./project-memory/plans/【实施计划】游戏广场评分展示-2026-10-01.md):已实现并通过本地定向验证,待用户验收,未部署;公开列表/详情携带真实摘要,卡片显示一位小数均分与人数,复用有效评价统计。
@@ -1,128 +0,0 @@
# 创作者关系与公开查询实施计划
| 字段 | 值 |
| --- | --- |
| Version | 1.0 |
| Status | ready(计划已形成,尚未开始实现) |
| Date | 2026-10-05 |
| Owner | 接手本里程碑的开发者或 Agent |
| Milestone | [创作者关系与公开查询](./【里程碑】创作者关系与公开查询-2026-10-05.md) |
| Parent Spec | [创作者主页与关注粉丝合同](../../【玩法创作】平台入口与玩法链路-2026-05-15.md#创作者主页与关注粉丝合同) |
| Engineering | [创作者主页与关注粉丝工程设计](../../technical/【技术方案】创作者主页与关注粉丝工程设计-2026-10-05.md) |
## 交付结果与优先级
交付可由真实 API 读写、由 SpacetimeDB 持久化的关注关系、公开主页摘要、关注/粉丝分页列表和作者公开游戏查询;以权限、双向关系、幂等、计数、只读列表及游戏过滤的运行时证据验收。
必须项:契约与纯规则 → 表与事务 → facade 与 HTTP → 定向测试与隔离环境回读。风险项:服务身份、关系方向、认证快照同步、账号不存在时的统计、生成绑定、作者过滤与 48 项截取顺序。可选的计数缓存、性能专项优化和界面优化不进入本里程碑。
开始实施时用约 15 分钟核对分支、最新源文件、工具链和开发环境。按下述四个检查点推进,每个检查点至少输出一次结果;单个阻塞调查超过 30 分钟时记录具体限制并优先完成其余独立必需项,不因调查扩展产品范围。时间盒用于控制调查,不削减验收要求。
## 修改边界
| 层 | 允许修改的范围 |
| --- | --- |
| 共享契约 | 新增 `server-rs/crates/shared-contracts/src/creator.rs`、`packages/shared/src/contracts/creator.ts` 及导出;对应序列化/契约测试 |
| 领域规则 | `server-rs/crates/module-auth/src/` 新增关系子模块及导出,承载方向、用户对键和输入规则;不依赖数据库或 HTTP |
| 数据与事务 | `server-rs/crates/spacetime-module/src/` 新增 creator 模块、注册入口、`migration.rs`;必要的 `game_distribution.rs` 可选作者过滤 |
| 数据访问 | `server-rs/crates/spacetime-client/src/` 新增 creator facade/mapper、注册入口、内部输入与绑定;game-distribution 输入追加可选作者参数 |
| HTTP | `server-rs/crates/api-server/src/modules/creator.rs`、`modules.rs`、`app.rs`;现有 game-distribution query 与调用透传;对应路由/权限测试 |
| 生成物和文档 | 仓库脚本生成的绑定、现有 schema/DDD/契约守卫所需登记、后端表目录、主规范中的实现证据及本里程碑验收记录 |
本阶段不修改主站页面、导航、共享 UI、前端服务调用层、nginx/Pingora 路由、AGC 客户端、后台管理、external v1 或正式游戏运行态。这些页面接入工作属于下一里程碑。既有游戏广场与“我的游戏”继续最多读取 48 项;只增加作者查询能力,不增加游戏分页,不重构两张既有列表。
## 实现顺序与检查点
### 检查点一:冻结契约与纯规则
1. 对照主规范的八项接口合同和工程设计 DTO,增加 Rust/TS 同名模型与导出;保留现有响应信封和错误映射。
2. 在关系领域子模块明确关注、取消关注、移除粉丝三种命令的方向及自关注拒绝规则。用用户 ID 字节长度前缀生成有向用户对键,覆盖中文、多字节和易拼接碰撞 ID。
3. 校验列表 limit、游标结构、长度边界和排序键,具体长度常量按项目既有输入上限约定固定并写入定向测试;游标绑定主人和列表类型,不承担授权。
4. 增加共享契约序列化测试:字段名、null、时间格式与响应信封内的数据形状;记录本阶段实际测试名称,避免过滤条件零匹配。
退出判据:DTO 与产品合同一致,方向/唯一键/参数规则测试通过;接口中没有可由普通调用者指定的操作者身份。
### 检查点二:表、事务和绑定
1. 新增私有 `user_follow` 表及双方向索引,字段按工程设计;不修改账号/游戏主键,不新增账号状态或计数表。
2. 新增事务写路径,先校验受信 API 服务身份,再检查认证操作者和目标账号存在性。关注只建立出边;取消只删除出边;移除粉丝只删除入边。重复相同写操作不重复插行、扣数或改既有时间。
3. 新增主页、关系和双向列表读取:每次请求内部一次事务读出所需事实,账号不存在时按合同返回/过滤。只有访问者等于列表主人时生成逐行关系;游客、他人关注列表与他人粉丝列表仅读取列表本身和公开资料。
4. 关系列表先过滤不存在的对端,再统计和分页;按既定时间/主键顺序读取 limit+1。头像昵称直接投影当前账号资料,不保存副本。
5. game-distribution 查询追加可选作者 ID,按作者与现役公开可见性过滤后排序、截取最多 48 项;不传作者保持当前返回语义,`nextCursor` 仍为 null。
6. 同步 `migration.rs`、后端数据契约的表目录及必要守卫登记,运行仓库绑定生成和 schema 检查。确认认证全量快照更新不包含或清空新关系表。
退出判据:模块可编译、生成物一致、schema 门禁通过;无破坏性 schema 变更。事务的真实执行在检查点四验证,host 测试不能替代。
### 检查点三:facade 与 HTTP 接入
1. 在 `spacetime-client` 增加 typed 输入、结果、mapper 和调用方法,复用现有连接及服务身份,不建立第二条数据访问链。
2. 注册 creator 路由,复用现有认证校验、状态码与响应信封;操作者取认证上下文。公开主页无访问者字段,关系 GET 和三个写入口需要登录。
3. 列表有效认证只用于判断主人身份;认证无效返回 401,无凭据按游客读取。带认证列表与关系接口设置 `private, no-store`。不允许客户端参数强制他人列表返回逐行关系。
4. 透传游戏查询的可选 `authorId`,显式空值返回 400。回归旧查询,确认没有新增游戏分页或更改原有过滤行为。
5. 添加路由与 facade 测试:401/403/404/400、幂等回执、输入伪造、公开字段白名单、缓存响应头,以及他人两类列表不触发额外访问者关系投影。
退出判据:API 与 DTO 一致,授权和列表只读分支测试通过;本阶段仍不开始前端接线。
### 检查点四:隔离运行时验证与证据
1. 核实实际开发栈状态和隔离数据库目标,按现有运维脚本构建/发布 module 并启动 API;不使用生产库,不使用删库或 `spacetime --root-dir`。
2. 以 A/B/C 三个测试账号执行关注、取消、重新关注、互关与移除粉丝;验证 A 移除 B 粉丝后 `A → B` 保留、`B → A` 消失,并从数据库与 API 回读计数。
3. 验证游客、失效凭据、自操作拒绝、第三方越权及普通身份直接调用 procedure 被拒。测试身份凭据不打印到日志、不写入提交。
4. 用超过 50 条且含同时间关系的夹具验证分页,覆盖主人/类型不匹配游标、空列表和已不存在对端。验证认证快照刷新后关系仍保留。
5. 作者游戏夹具混合多个作者、超过 48 个目标作者游戏及非公开/下架/删除作品,确认过滤先于截取且最多 48 项;旧目录查询结果口径保持一致。
6. 覆盖相同请求重复、相反动作并发和写入结果未知后的回读;最终结果按事务提交顺序解释,不承诺跨请求冻结快照。
退出判据:逐条填写下方证据矩阵;环境缺失的项写明原因,不以通过的单测代替未完成运行时证据。完成后停止,待本里程碑验收再制定页面阶段实施计划。
## 验证命令
以下均为后续工程实现时执行,本次文档任务不构建或发布数据库。`creator` 为新增测试的功能分组,需检查实际匹配数量;相关 game-distribution 模块回归单独运行。
```bash
cargo test --locked --manifest-path server-rs/Cargo.toml -p module-auth creator
cargo test --locked --manifest-path server-rs/Cargo.toml -p shared-contracts creator
cargo test --locked --manifest-path server-rs/Cargo.toml -p spacetime-client creator
cargo test --locked --manifest-path server-rs/Cargo.toml -p api-server creator
cargo test --locked --manifest-path server-rs/Cargo.toml -p api-server game_distribution
cargo test --locked --manifest-path server-rs/Cargo.toml -p spacetime-module creator
cargo test --locked --manifest-path server-rs/Cargo.toml -p spacetime-module game_distribution
cargo check --locked --manifest-path server-rs/Cargo.toml -p spacetime-module
npm run spacetime:generate
npm run check:generated-bindings
npm run check:server-rs-ddd
npm run check:game-distribution-dto-parity
npm run typecheck
npm run dev:api-server
```
绑定生成需在依赖新绑定的 facade 编译前执行,schema/DDD 门禁在生成后执行;以上清单不是要求按行机械运行。`dev:api-server` 是持续服务命令,启动后根据 `.app/dev-stack.json` 中的实际地址检查 `/healthz` 并执行接口 smoke,不把默认端口当作运行时真相。Rust 格式检查使用当前仓库约定;新增 TS 契约测试按实际文件定向执行,不为占位断言创建无效测试。
文档和代码交付均运行:
```bash
npm run check:encoding
npm run check:doc-index
git diff --check
```
## 风险与回滚点
- Schema 发布前:可以回退本里程碑代码和生成物;不覆盖他人改动,不修改已有表字段顺序/类型。若出现破坏性迁移需求,先更新主规范和迁移计划,再确认实施。
- Schema 发布后:保留关系表和已写数据,业务回退使用保留新表兼容 schema 的版本;不通过删除数据库或关系表恢复旧版本。后端和对应 bindings 同步,先确认兼容再重启服务。
- 认证投影:关系表独立于账号快照,回归同步账号资料不会删除关系;缺失账号过滤与计数同口径。
- 范围控制:读时精确计数先复用索引;发现规模风险只记录证据,不自行增加缓存、后台任务或账号状态。游戏目录现有 48 项限制保持不变。
- 交付边界:本计划只授权范围内的开发验证,不等同于生产部署;本次只补文档并本地提交,不推送远程。
## 验收证据矩阵
| 对照项 | 验证方式 | 当前结果 |
| --- | --- | --- |
| 唯一键、方向、自关注与幂等 | 领域测试 + API/数据库回读 | 未实施 |
| 认证与第三方越权 | HTTP 负向用例 + 普通身份调用 procedure | 未实施 |
| 他人两类列表只读、无访问者关系查询 | 路由/投影定向测试 + API 响应 | 未实施 |
| 公开字段、计数、分页、账号存在性 | 契约测试 + 多页隔离夹具 | 未实施 |
| 作者游戏过滤与原有 48 项边界 | game-distribution 回归 + API 夹具 | 未实施 |
| Schema、迁移、绑定及认证快照兼容 | 生成检查、DDD 门禁 + 实际运行时回读 | 未实施 |
| 重复/并发写与结果未知 | 事务集成用例与写后查询 | 未实施 |
实际实现时补充命令结果、证据位置和未验证原因。本里程碑与页面阶段全部验收后,将持久结论融合回主规范并删除已完成临时计划。
@@ -1,40 +0,0 @@
# 创作者主页与关系交互
| 字段 | 值 |
| --- | --- |
| Version | 1.0 |
| Status | ready(产品规则已确认,实施仍依赖前阶段验收) |
| Date | 2026-10-05 |
| Parent Spec | [创作者主页与关注粉丝合同](../../【玩法创作】平台入口与玩法链路-2026-05-15.md#创作者主页与关注粉丝合同) |
## 目标与范围
在既有主站接入第四项创作者主页、游戏详情作者链接和关注按钮、公开主页与游戏列表、关注和粉丝列表及本人管理操作。
复用公共游戏卡、账号资料、登录能力、确认弹窗与页面导航;通用关注表现和用户行抽到共享组件,后端副作用与正式关系由业务层持有。不包含主页装修、资料编辑新系统和关注消息通知。
## 前置条件
- [创作者关系与公开查询](./【里程碑】创作者关系与公开查询-2026-10-05.md)已验收。
- 主规范的产品规则已确认;开始编码前单独落地本阶段实施计划。
## 验收标准
- [ ] 桌面第四项进入自己主页,第五项为“我的”;移动入口为“游戏 / 创作者主页 / 我的”。
- [ ] 游戏详情可进入自己或他人主页,关注按钮与作者链接互不误触。
- [ ] 主页显示真实计数和公开游戏,点击进入现有详情;本人无自关注按钮。
- [ ] 公开关注/粉丝列表支持分页;只有本人有移除粉丝动作。
- [ ] 他人的关注、粉丝列表均仅展示资料和主页链接,无关系操作按钮,不补查或比对访问者关系;预置关注缓存不改变只读表现,自己的列表仍可管理关系。
- [ ] 自己/他人的关注/粉丝四类列表,游客和登录用户均可点击列表用户头像或昵称进入其创作者主页,覆盖本人及无公开游戏用户;返回恢复来源列表和分页/滚动位置,关系操作按钮不误触跳转。
- [ ] 取消关注后可在当前行重新关注;刷新后的正式列表正确。
- [ ] 粉丝列表回关/取消回关和移除粉丝分别改变正确方向。
- [ ] 移除粉丝需二次确认,取消弹窗不发写请求;取消关注直接执行,不弹确认。
- [ ] 登录、退出、账号切换、请求迟到和网络失败不污染关系状态。
- [ ] 主页/详情/列表往返状态一致,深链刷新和返回位置正确。
- [ ] 375px 移动和桌面布局、长昵称、空态/错误态、键盘和触摸操作可用。
## 证据与停止点
前端定向 Vitest、`npm run typecheck`、`npm run check:encoding`、`npm run check:doc-index` 和 `git diff --check`;真实浏览器配合三个测试账号完成关系闭环,验证公开与私有游戏隔离。
提交最终逐条证据,等待验收;通过后将持久结论更新到主规范和相关共享记忆,删除已完成临时计划。本里程碑不授权自动生产部署。当前无实现或浏览器证据。
@@ -1,37 +0,0 @@
# 创作者关系与公开查询
| 字段 | 值 |
| --- | --- |
| Version | 1.0 |
| Status | ready(产品规则已确认,未实现) |
| Date | 2026-10-05 |
| Parent Spec | [创作者主页与关注粉丝合同](../../【玩法创作】平台入口与玩法链路-2026-05-15.md#创作者主页与关注粉丝合同) |
## 目标与范围
为公开创作者主页提供真实用户资料、关注/粉丝计数、分页关系列表、访问者关系和作者公开游戏筛选,并支持认证用户关注、取消关注和移除自己粉丝。
不包含页面接入、消息通知、推荐、拉黑、既有游戏列表分页改造和生产部署。不新增独立创作者身份,公开游戏沿用现有可见性口径及最多 48 项限制。
## 前置条件
- 主规范的产品规则已确认;账号公开性按现有账号存在性判断,不新增账号状态体系。
- 对应[实施计划](./【实施计划】创作者关系与公开查询-2026-10-05.md)已补齐,覆盖 schema、DTO、事务、API、测试及回滚边界;开工时按计划核验当前代码和隔离开发环境。
## 验收标准
- [ ] 用户对唯一、不能自关注、重复写入与删除幂等。
- [ ] 关注和粉丝方向正确,移除粉丝不取消本人对对方的关注。
- [ ] 第三方不能代替他人写出边或删除入边。
- [ ] 游客可读公开资料和列表,认证关系不混入共享公共缓存。
- [ ] 他人的关注、粉丝列表即使带有效认证也只返回公开行,relationship 为 null;不额外查询访问者与各行用户之间的关系,自己的列表所需关系查询继续有效。
- [ ] 分页、计数、失效账号过滤一致,响应不泄露私有账号字段。
- [ ] 作者游戏筛选发生在最多 48 项截取前,过滤未公开、下架和删除作品;不增加游戏分页,未传作者的广场请求保持原有行为。
- [ ] schema、迁移、表目录、生成绑定与共享 DTO 同步。
- [ ] 正常、重复、并发和权限负向用例通过真实 API/SpacetimeDB 验证。
## 证据与停止点
领域/契约定向测试、schema 与 DDD 边界检查、编码/文档检查;通过 `npm run dev:api-server` 启动并验证 `/healthz` 后,以三个测试账号验证本人/对方/第三方关系。新增测试数据仅写隔离开发环境。
提供主规范逐条证据矩阵及未验证项;通过验收后才进入页面里程碑。当前产品规则已确认,无实现或运行时证据。
@@ -2,12 +2,13 @@
## 2026-10-05 创作者主页与关注粉丝的产品边界
- 已确认但未实现:桌面第四项“创作者主页”默认进入当前账号主页,“我的”移到第五项;他人的关注/粉丝列表公开可查看,自己或他人的两类列表均可点击用户进入其创作者主页。
- 产品已确认:桌面第四项“创作者主页”默认进入当前账号主页,“我的”移到第五项;他人的关注/粉丝列表公开可查看,自己或他人的两类列表均可点击用户进入其创作者主页。
- 关注为单向关系,取消回关与移除粉丝分别影响不同方向;只有本人可移除自己的粉丝,自己不能关注自己。
- 他人的关注、粉丝列表统一只读:保留头像/昵称进入用户主页,不显示任何关系操作按钮;前后端均不额外检测访问者与列表用户的关注关系,已有缓存也不用于显示关系动作。
- 已确认:移动端入口为“游戏 / 创作者主页 / 我的”;自己的主页也只展示公开游戏;自己的关注列表取消后当前行暂留以便重新关注;移除粉丝二次确认,取消关注不弹确认。
- 用户明确本次不额外改造游戏目录分页:既有游戏广场和“我的游戏”保持现状,作者主页按作者过滤后沿用最多 48 项限制。新关注/粉丝列表的分页仍按主规范设计。
- 行为真相见[创作者主页与关注粉丝合同](../../【玩法创作】平台入口与玩法链路-2026-05-15.md#创作者主页与关注粉丝合同),工程落点见[工程设计](../../technical/【技术方案】创作者主页与关注粉丝工程设计-2026-10-05.md)。当前仅完成文档,不代表功能上线。
- 关系纯规则放在 `module-auth::creator`,现有认证服务通过 `services` feature 隔离宿主依赖,数据库 WASM 只使用纯规则。私有 `user_follow` 不参与认证快照替换;只通过受信服务过程读写,HTTP 操作者取认证身份。
- 行为真相见[创作者主页与关注粉丝合同](../../【玩法创作】平台入口与玩法链路-2026-05-15.md#创作者主页与关注粉丝合同),工程落点见[工程设计](../../technical/【技术方案】创作者主页与关注粉丝工程设计-2026-10-05.md)。后端已完成隔离验证并由用户验收通过;页面工程验证通过,用户已要求提交并推送;证据归并工程设计,已完成临时计划删除,未上线。
## 2026-10-03 首页自动建项与 AI 项目命名解耦(Issue 599)
@@ -3,20 +3,20 @@
| 字段 | 值 |
| --- | --- |
| Version | 1.0 |
| Status | ready(产品规则已确认,业务未实现、未部署) |
| Status | implemented(工程验证通过,用户已确认提交交付,未部署) |
| Date | 2026-10-05 |
| Parent Spec | [创作者主页与关注粉丝合同](../【玩法创作】平台入口与玩法链路-2026-05-15.md#创作者主页与关注粉丝合同) |
本文明确主站创作者主页、关注关系和列表操作的工程边界,供后续按里程碑实施。产品行为以父规范为准;本次只提交文档,不改业务代码或数据库。
本文明确主站创作者主页、关注关系和列表操作的工程边界。产品行为以父规范为准;后端实现及隔离验证已由用户验收通过,前端已完成工程验证,用户已要求提交并推送。
## 当前实现与修改边界
| 层 | 现有入口与拟修改范围 |
| 层 | 现有入口与修改范围 |
| --- | --- |
| 主站导航 | `src/components/platform-entry/PlatformEntryActiveFlowShell.tsx`、`platformEntryActiveTypes.ts`、`src/routing/activeAppPageRoutes.ts`;增加创作者主页与关系列表 stage,保持既有创作/项目/游戏/我的入口 |
| 详情与公共 UI | `src/components/game-distribution/GameDetailPage.tsx`、`packages/shared/src/components/GameDetailDisplay/`;扩展作者区域插槽,公共关注按钮和用户行放共享组件 |
| 新页面与访问层 | 在 `src/components/creator/`、`src/services/creatorClient.ts` 增加主页、关系列表和 HTTP 访问;复用现有认证、响应解包、错误处理和游戏卡表现 |
| DTO | `server-rs/crates/shared-contracts/src/creator.rs`、`packages/shared/src/contracts/creator.ts`(拟新增);分别在现有导出入口注册 |
| 新页面与访问层 | 在 `src/components/creator/`、`src/services/creatorProfileClient.ts` 增加主页、关系列表和 HTTP 访问;复用现有认证、响应解包、错误处理和游戏卡表现 |
| DTO | `server-rs/crates/shared-contracts/src/creator.rs`、`packages/shared/src/contracts/creator.ts`;分别在现有导出入口注册 |
| 领域 | `module-auth` 内新增纯关系规则子模块;不新增账号系统,不把 HTTP、数据库和 UI 状态放入领域规则 |
| 持久化 | `spacetime-module` 新增关系模块,复用 `auth/tables.rs` 中的用户身份;同步模块注册、`migration.rs`、表目录和生成绑定 |
| Facade | `spacetime-client` 新增 creator typed facade 与 mapper,复用现有连接和受信服务身份 |
@@ -30,7 +30,7 @@
## 关系模型和授权
拟新增私有表 `user_follow`:
私有表 `user_follow`:
| 字段 | 类型与约束 |
| --- | --- |
@@ -41,6 +41,8 @@
同一用户对最多一行,双方不得相同。删除后重新关注视为新的建立时间。不另存关系计数、昵称、头像或互关布尔值;读时按对应方向索引计算,并以 `user_account` 当前存在性过滤对端。当前账号表和公开查询没有独立的封禁/公开状态,不能凭空增加状态字段。
`module-auth` 的现有认证服务通过默认启用的 `services` feature 保持原有导出;API 和 facade 显式启用该 feature。数据库仅依赖关闭默认 feature 的纯关系模块,避免将短信、网络和宿主运行时依赖引入 WASM。用户 ID 上限为 256 UTF-8 字节,游标上限为 4096 字节;空值、控制字符及超长输入拒绝,游标未知字段和非规范时间戳拒绝。
写入沿用项目受信 API 服务身份调用 procedure 的模式:HTTP 从已验证 access token 派生操作者 ID,procedure 先校验调用服务身份,再在事务内检查操作者、目标和方向。普通客户端不能直接传入任意操作者绕过认证。新表不进入认证全量快照替换流程,登录或刷新账号资料不能清空关系。
关注只插入 `actor → target`;取消只删除同一方向;移除粉丝只删除 `follower → actor`。事务回执返回 actor 相对目标的最新关系,不把移除粉丝误报为 actor 已取消关注。用户不再存在时不暴露其资料,计数和列表同步排除;本次不增加账号注销或清理任务。
@@ -109,13 +111,16 @@ type CreatorRelationshipResponse = {
- 进入页面、返回和重新聚焦时回读;旧请求通过请求序号/取消机制隔离。认证变化清除私有关系缓存和旧页请求,不让上个账号响应覆盖新账号。
- 新主页路由接入页面标题、导航高亮、返回兜底和滚动位置恢复。移动点击区域至少 44px;加载、错误、空态分别呈现,不因关系失败阻断公开游戏阅读。
- 顶层访问层登记到 `vite.config.ts` 的现役模块白名单及 ESLint 范围,开发代理显式转发 `/api/creators`。页面深链同步三份 nginx 模板与 Pingora 路由清单。
- 浏览器历史条目仅保存 URL、访问者、已加载页数和滚动位置,不持久化关系列表或暂留行;新导航清除继承的恢复标记。同一舞台切换用户、页签以及返回时,应用重读 URL 并重新渲染。
## 兼容、验证和交付
新关系表从空数据开始;同步迁移登记、后端表目录和 Rust 生成绑定。新增 procedure 与 facade 同步发布,不手改生成文件;游戏查询新增的 authorId 是可选能力,旧 HTTP 请求继续有效。后端部署先于新前端,回滚前端不删除关系数据;回滚后端必须保留新表的兼容 schema,禁止删库回退。
实施顺序和验收边界分别见[关系与公开查询里程碑](../project-memory/plans/【里程碑】创作者关系与公开查询-2026-10-05.md)、[主页与关系交互里程碑](../project-memory/plans/【里程碑】创作者主页与关系交互-2026-10-05.md)。首阶段[实施计划](../project-memory/plans/【实施计划】创作者关系与公开查询-2026-10-05.md)已就绪;前阶段验收通过后再制定下一阶段的单里程碑实施计划并进入实现。
后端已由用户验收通过;页面工程验证完成后,用户要求提交并推送。已将持久结论和验证证据归并到主规范及本文,删除已完成的临时里程碑和实施计划。
实施时按范围执行以下命令;本次文档提交只执行最后三项:
按范围执行以下命令,后端与前端证据见本文对应章节;本文保留逐项验收对照:
```bash
cargo test --locked --manifest-path server-rs/Cargo.toml -p module-auth creator
@@ -135,4 +140,43 @@ git diff --check
`creator` 测试组为实施时新增的定向分组,届时核对实际匹配数量,零匹配不算通过;补充共享 DTO/UI 和 facade 的对应测试。host 单测不替代 SpacetimeDB 事务验证,运行时通过 `npm run dev:api-server` 启动并验证实际开发地址 `/healthz`,使用隔离开发库的 A/B/C 三账号完成权限、重复写入、双向关系与未知结果回读。
浏览器覆盖桌面与 375px 移动,四类列表跳转、返回位置、自己的空游戏主页、互关后移除粉丝和登录切换。他人的关注、粉丝两类列表夹具均包含访问者已关注、未关注及访问者本人,断言一律无关系操作,后端响应 relationship 为 null 且不调用访问者关系投影,前端无补查/写请求;预置关系缓存也不得改变只读表现,点击用户进入主页仍可正常操作。游戏边界夹具应包含超过 48 项及其他作者作品,证明作者过滤在截取前,广场原有上限保持不变;关系列表用超过 50 项和同时间关系验证分页。所有执行结果回填里程碑证据,本次不宣称实现或运行时验收完成。
浏览器覆盖桌面与 375px 移动,四类列表跳转、返回位置、自己的空游戏主页、互关后移除粉丝和登录切换。他人的关注、粉丝两类列表夹具均包含访问者已关注、未关注及访问者本人,断言一律无关系操作,后端响应 relationship 为 null 且不调用访问者关系投影,前端无补查/写请求;预置关系缓存也不得改变只读表现,点击用户进入主页仍可正常操作。游戏边界夹具包含超过 48 项及其他作者作品,证明作者过滤在截取前,广场原有上限保持不变;关系列表用超过 50 项和同时间关系验证分页。后端可重复运行 `python3 scripts/test-creator-runtime.py --database creator-hub-validation`;执行结果保留在以下证据矩阵中。
## 后端验证证据
用户已验收通过关系与公开查询实现,并授权进入页面阶段。
| 对照项 | 验证方式 | 当前结果 |
| --- | --- | --- |
| 唯一键、方向、自关注与幂等 | 领域测试 + API/数据库回读 | 5 条纯规则测试通过;认证模块完整 45 条通过;运行时重复关注保持原时间、重关更新时间,移除粉丝只删入边 |
| 认证与第三方越权 | HTTP 负向用例 + 普通身份调用 procedure | 新增 HTTP 4 条通过;隔离 A/B/C 与普通数据库身份验证 400/401/403/404 和操作者归属 |
| 他人两类列表只读、无访问者关系查询 | 路由/投影定向测试 + API 响应 | 模块 1 条测试断言关系查询闭包不执行;facade 2 条通过;游客/他人两类列表运行时 relationship 均为 null,本人列表正常返回 |
| 公开字段、计数、分页、账号存在性 | 契约测试 + 多页隔离夹具 | DTO 2 条通过;58 个测试账号、55 个同时间双向关系、失效对端夹具,多页去重与 total/计数一致;错主人/类型游标返回 400 |
| 作者游戏过滤与原有 48 项边界 | game-distribution 回归 + API 夹具 | API 44 条与模块 4 条回归通过;55 个目标作者、55 个更晚其它作者、6 个非公开或无有效版本夹具,作者查询与旧广场各返回正确的 48 项 |
| Schema、迁移、绑定及认证快照兼容 | 生成检查、DDD 门禁 + 实际运行时回读 | WASM 构建和 CLI 生成通过;schema、DDD、生成绑定、38 组 DTO 对照通过;登录刷新前后关系导出相同 |
| 重复/并发写与结果未知 | 事务集成用例与写后查询 | 8 个同向并发只产生一行,相反动作并发后 API 与数据库一致;丢弃写回执后读取正式关系再执行后续意图 |
2026-10-05 通过仓库启动器启动 `creator-hub-validation`,CLI/standalone 为 2.8.3(固定 commit 核对通过),API `/healthz` 返回 200。可复核运行时证据由 `scripts/test-creator-runtime.py` 的四组 PASS 断言产生,不依赖 host 测试模拟事务。类型、编码、文档索引及 diff 检查通过;本地依赖缺失已按原锁文件恢复,不改依赖版本。
后端证据边界:不包含生产发布;浏览器与前端交互另见下方前端证据。未知结果用例覆盖丢弃回执后的回读,不冒充真实网络故障注入。游戏夹具只验证公开目录投影,不写对象存储或测试游戏运行态。
## 前端验证证据
2026-10-05 工程验证通过,用户确认提交并推送;未部署生产。
| 合同条款 | 自动化和实际运行证据 |
| --- | --- |
| 桌面第四入口、移动三入口、标题和深链 | 导航/路由/标题 Vitest;三份 nginx SPA 检查及 Pingora 对照通过;实际浏览器直达与刷新 `/creators`、`/creators/connections`;游客直接访问他人关注/粉丝列表后,返回均落到所属作者主页 |
| 本人和他人主页、详情作者和公开游戏 | 主页测试覆盖裸路由登录、显式目标登录后保持、自己无关注按钮、空游戏及独立错误;已关注状态显示“已关注”,可访问名称为“取消关注”;真实 API 页面显示该作者 48 项,详情作者可返回自己主页 |
| 四类列表及他人只读 | 前端测试覆盖四类用户链接、预置关系缓存不改变他人只读;实际浏览器验证他人两类列表无按钮、无 relationship 补查请求 |
| 暂留、回关及移除方向 | 前端测试和真实浏览器验证取消后原行重新关注、刷新去行、粉丝回关/取消回关、移除确认及取消弹窗;移除后实际 API 确认自己的出边仍在 |
| 返回、分页与滚动 | 实际加载 40 行,进入用户主页后返回,重新读取两页并恢复滚动;历史条目只保存位置与页数,新导航不继承暂留行 |
| 失效、单飞和身份切换 | 状态测试覆盖重复点击、旧读覆盖保护、退出再登录同账号时丢弃旧写、未知结果只回读、仍未知禁写、回读恢复;页面测试覆盖切账号/目标的迟到响应 |
| 桌面和 375px 移动 | Chromium 实际验收无横向溢出、移动三入口、键盘 Enter 进入主页、访客关注仅唤起登录;窄屏按钮移至资料下方,共享组件测试覆盖长昵称和独立交互 |
定向 Vitest 共 12 个文件、126 项通过;覆盖 creator 页面/状态/访问层、游戏访问层及三个游戏页面、导航、路由、标题、Vite 接入和共享 UI。当前 Node 原生 webstorage 与旧 jsdom 环境冲突,使用 `NODE_OPTIONS=--no-experimental-webstorage npm run test -- ...` 执行;不修改业务存储策略。`npm run typecheck`、`npm run build:raw`、定向 ESLint、Rust 格式检查、编码检查(5319 文件)、文档索引(245 份)及 `git diff --check` 均通过。
可重复浏览器脚本为 `scripts/test-creator-web.cjs`:先运行隔离后端脚本、再用仓库 `dev:web` 启动同库并把 `RUST_SERVER_TARGET` 指向该隔离 API;脚本从 `.app/dev-stack.json` 读取实际端口,仅接受 `creator-hub-validation` 和 loopback。通过 `CREATOR_PLAYWRIGHT_DIR` 指向临时 Playwright 安装,`PLAYWRIGHT_BROWSERS_PATH` 指向临时浏览器目录。截图输出到临时目录,不提交登录信息、数据库或构建产物。
验证边界:浏览器使用真实 API/SpacetimeDB;超时、旧请求与账号切换由可控前端测试覆盖,没有声称做真实断网注入。游戏夹具无发行包,不验证游玩加载;未部署生产,未用真实用户数据。本次交付按用户指令提交并推送,生产部署另行执行。
@@ -257,6 +257,12 @@ Responses 的终态载荷既是工具调用的恢复源,也是正文的恢复
## SpacetimeDB 表目录
### `user_follow`
- 私有关注关系表:`relationship_id` 为有向用户对主键,`follower_user_id`、`followee_user_id` 分别建立索引,`created_at` 记录首次建立时间。
- 关注建立出边,取消删除出边,移除粉丝仅删除入边;重复写入不改变原时间。受信 API 身份调用事务过程,操作者来源于 HTTP 认证。
- 独立于认证投影同步,不随账号快照清空;计数和列表均排除不存在的对端。他人列表不计算访问者关系。详见[创作者工程设计](./technical/【技术方案】创作者主页与关注粉丝工程设计-2026-10-05.md)。
下列 `###` 标题是 schema guard 的机器可读表目录。新增、删除或改名表时必须同步这里。
### `ai_result_reference`
@@ -556,7 +556,7 @@
| 字段 | 值 |
| --- | --- |
| Version | 1.0 |
| Status | ready(产品规则与首阶段实施计划已就绪,未实现) |
| Status | implemented(工程验证通过,用户已确认提交交付,未部署) |
| Date | 2026-10-05 |
| 范围 | 主站导航、公开创作者主页、游戏详情作者入口、关注关系与列表管理 |
@@ -564,7 +564,7 @@
让用户从游戏详情进入任意作者主页、查看作者公开游戏、关注或取消关注,并在自己的列表管理关注和粉丝。验收以真实账号关系、计数、公开游戏过滤及跨页回读一致为准。
2026-10-05 源码核验:`PlatformEntryActiveFlowShell` 的桌面导航实际为“创作 / 项目 / 游戏 / 我的”,移动端为“游戏 / 我的”;`activeAppPageRoutes` 已包含游戏列表、详情、游玩与作者管理路由。本文前部旧三入口说明不作为本提案的导航基线。现有 `GameDetailPage` 使用共享 `GameDetailDisplay`,作者身份已有稳定 `author.id`,昵称缺失时经公开用户接口查询;现有 schema 尚无关注关系表。
2026-10-05 实现状态:桌面导航为“创作 / 项目 / 游戏 / 创作者主页 / 我的”,移动端为“游戏 / 创作者主页 / 我的”;`activeAppPageRoutes` 已接入创作者主页和关系列表。`GameDetailPage` 通过共享 `GameDetailDisplay` 的作者插槽提供主页链接和独立关注按钮。私有关注关系表、查询/写入 API 以及页面交互已实现;后端已由用户验收,前端工程验证通过,用户已要求提交并推送。本文前部旧入口说明不作为本专题的导航基线。
必须项为入口、主页、双向列表查看、关注/取消关注/重新关注、本人移除粉丝、公开游戏列表及详情跳转。风险项为关系方向、越权、公开/私有游戏隔离、并发请求与关系列表分页回读。私信、关注动态、通知、拉黑、推荐榜单、主页装修、关系隐私设置和既有游戏目录分页改造不纳入首版。
@@ -627,7 +627,7 @@
| `DELETE /api/creators/me/followers/{followerId}` | 当前登录用户移除自己的粉丝,幂等 |
| 扩展 `GET /api/game-distribution/games?authorId=<userId>` | 服务端精确作者过滤,复用公开游戏可见性与卡片契约 |
以上为待实现合同,尚不是可调用 API。关注/粉丝列表默认 20、上限 50,按关系建立时间与稳定身份倒序,返回 `items/nextCursor/total`;游标绑定主人和列表类型,非法/错域游标返回 400。增删期间重新加载可能改变页内成员,前端按用户 ID 去重,重新关注产生新的建立时间。此分页规则仅用于新关系列表;游戏列表继续最多读取 48 项,不实现分页。
以上接口已在本地隔离环境实现并验证,未部署。关注/粉丝列表默认 20、上限 50,按关系建立时间与稳定身份倒序,返回 `items/nextCursor/total`;游标绑定主人和列表类型,非法/错域游标返回 400。增删期间重新加载可能改变页内成员,前端按用户 ID 去重,重新关注产生新的建立时间。此分页规则仅用于新关系列表;游戏列表继续最多读取 48 项,不实现分页。
关系写入成功返回 200 与当前访问者关系;重复删除不存在的关系仍成功。不合法输入或关注自己返回 400,未认证 401,越权 403,目标不存在或不可公开 404。本人读取自己的关系列表时以有效认证批量附带各行关系;游客和他人的关注、粉丝列表该字段为 null,后者即使已登录也不计算逐行关系。带关系的响应禁用共享缓存,认证失效时清除访问者关系并按游客重新读取。
@@ -638,7 +638,7 @@
1. 关系与公开查询:先交付真实持久化、权限、幂等、双向查询、准确计数、公开资料和作者游戏筛选;通过 API 与数据库运行时验收后进入页面接入。
2. 页面与交互:接入导航、主页、列表、详情作者链接、共享关注控件和移除弹窗,完成真实账号桌面/移动端闭环验收。
每阶段先评审里程碑,再编写该阶段的单独实施计划;本次只交付规划,不进入业务实现。每阶段完成后给出证据并等待验收,不以单元测试替代真实运行时验证。
每阶段先评审里程碑,再编写该阶段的单独实施计划。后端阶段已完成工程实现及隔离验证并由用户验收通过,页面阶段的工程与真实浏览器验证已通过,用户已确认提交交付;证据保留在工程设计,已完成的临时计划删除,不以单元测试替代真实运行时验证。
| 验收条款 | 证据要求 |
| --- | --- |
@@ -657,8 +657,8 @@
- 已确认:第四项默认进入自己主页;他人关注和粉丝列表公开可查看;自己或他人的关注/粉丝列表均可点击任意用户进入其创作者主页;他人的关注、粉丝列表统一只读,无关系操作且不检测访问者与列表用户的关系;本次不额外改造游戏目录分页,保持既有广场和“我的游戏”行为。
- 已确认:移动端采用“游戏 / 创作者主页 / 我的”;自己的主页也只列公开游戏;自己的关注列表取消后当前行暂留以便重新关注;移除粉丝二次确认,取消关注不弹确认。
- 产品待定项已收口,接口命名、路由和关系列表分页按本文及工程设计落地。[关系与公开查询实施计划](./project-memory/plans/【实施计划】创作者关系与公开查询-2026-10-05.md)已补齐;前阶段验收后再制定页面阶段实施计划。本次只修改文档,不提前编写业务代码。
- 产品待定项已收口,接口命名、路由和关系列表分页按本文及工程设计落地。[工程设计](./technical/【技术方案】创作者主页与关注粉丝工程设计-2026-10-05.md#后端验证证据)已记录后端验证证据;用户已验收通过,页面按独立实施计划推进。
- 源码核验:现有公开用户查询按账号存在性返回资料,`user_account` 没有独立封禁/公开状态字段。首版复用该存在性口径,关系计数和列表一致排除不存在的账号,不在本功能内增加账号状态体系。
- 本次证据只覆盖源码调研和规划文档检查;业务、数据库迁移与浏览器验收均未执行。
- 后端证据:领域、DTO、facade、HTTP 定向测试、WASM 构建与绑定生成、schema/DDD/类型/编码/文档检查通过;隔离运行时脚本覆盖双向关系、权限、同时间分页、计数、账号快照、并发和作者游戏过滤。浏览器及生产部署未执行。
工程落点、DTO、事务与验证命令见[创作者主页与关注粉丝工程设计](./technical/【技术方案】创作者主页与关注粉丝工程设计-2026-10-05.md)。本节是行为主规范,工程设计不另立产品规则。