Files
Arkie-Library-Frontend/docs/backend-requirements-wallet-favorites.md
TerryM ed04e1fb7e fix: TokenPocket mobile deep-link login, desktop empty-state, toast above modal
- Mobile TokenPocket now opens the tpoutside:// sign deep link and returns to
  the original browser to finish login (no wallet in-app browser); desktop
  keeps the QR. Fixes mobile login + logout being trapped in TP's browser.
- Desktop without an injected wallet shows a clear message instead of a dead
  button; TokenPocket login card is always available as a working path.
- Raise toast z-index above the login modal so feedback is visible.
- Add native TokenPocket-login strings across 7 locales.
- Document that the live backend lacks favorites + TokenPocket routes (404),
  the real blocker for those features in production.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 04:00:30 +08:00

162 lines
8.6 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.
# 后端需求与核对文档:钱包登录 + 收藏
> 面向后端(`Arkie-Library-Backend`)。
> 本文是在前端审计「登录 + 收藏」bug 与 UI 重设计时,对后端现有实现的逐条核对,以及由此产生的后端待办。
>
> **核心结论:后端目前几乎已经满足前端全部需求。本次重设计与 bug 修复基本是纯前端工作。后端真正需要新增的只有少量「可选项」,外加几处需要确认的契约。请不要把已完成的功能再派一遍。**
日期2026-06-022026-06-02 更新:新增 §0.5 部署阻塞)
相关分支:`terry-wallet-login`
---
## 0.5 🔴 关键阻塞:线上后端是旧版本,收藏与 TokenPocket 端点未部署
> 源码(`Arkie-Library-Backend`)里这些端点都有;但**当前线上 / dev 代理指向的后端**`https://ark-library.com/apnew`)是**旧构建**,下列路由全部 404。
> **前端已就绪,但收藏与 TokenPocket 扫码登录在生产上无法工作,直到后端把含这些路由的版本部署上线。** 这正是用户实测「收藏用不了、扫码登录用不了」的根因。
curl 实证(经 vite dev 代理打到线上后端2026-06-02
| 端点 | 方法 | 实测状态 | 结论 |
|---|---|---|---|
| `/api/auth/wallet/nonce` | POST | **200** | ✅ 已部署 |
| `/api/auth/wallet/verify` | POST | **400**(入参错误)| ✅ 已部署 |
| `/api/auth/wallet/me` | GET | **401**(需鉴权)| ✅ 已部署 |
| `/api/auth/wallet/tp-login-request` | POST | **404** | ❌ 未部署 |
| `/api/auth/wallet/tp-result` | GET | **404** | ❌ 未部署 |
| `/api/auth/wallet/tp-callback` | POST | **404** | ❌ 未部署 |
| `/api/me/favorites` | GET | **404**(应为 401| ❌ 未部署 |
| `/api/me/favorites/ids` | GET | **404** | ❌ 未部署 |
| `/api/me/favorites/{id}` | POST | **404** | ❌ 未部署 |
**后端动作(必做,按优先级最高):**
1. 部署包含 favorites`internal/handlers/favorites.go`+ TokenPocket`internal/handlers/wallet_tp.go`)路由的后端版本(`cmd/server/main.go` 已注册这些路由)。
2. 为 TokenPocket 登录设置 `PUBLIC_BASE_URL``buildTokenPocketSignURL` 需要它生成回调 URL否则 tp-login-request 会 500
3. 确保 `wallet_tp_login_requests` / `user_favorites` 等表已迁移(`EnsureWalletAuthSchema` 会建表)。
> 复测命令:`curl -s -o /dev/null -w "%{http_code}" -X POST https://ark-library.com/apnew/api/auth/wallet/tp-login-request -d '{}'` 应返回 200且 body 的 `qrUrl` 形如 `tpoutside://pull.activity?param=...`)。
---
## 0. 一句话给后端
> 钱包认证、TokenPocket 扫码、收藏列表/筛选/分页/可用性,**都已实现且符合前端契约**。
> 下面 §1 是「已完成、勿动」的核对§2 是「真正可能要后端做的事」§3 是「前端会改但与后端无关,别误接」。
---
## 1. 已实现并符合前端契约(✅ 无需改动)
逐条核对自后端源码(`internal/handlers/wallet_auth.go``wallet_tp.go``favorites.go``public.go``cmd/server/main.go`)。
### 1.1 钱包认证
| 端点 | 状态 | 说明 |
|---|---|---|
| `POST /api/auth/wallet/nonce` | ✅ | 返回 `{nonce, message}`message 含一次性码,写入 `wallet_auth_nonces`TTL 15 分钟 |
| `POST /api/auth/wallet/verify` | ✅ | EIP-191 `personal_sign` 验签恢复地址,签发 JWT |
| `GET /api/auth/wallet/me` | ✅ | Bearer JWT → `{wallet, role:"user"}` |
关键事实(对前端 bug 很重要):
- **验签完全链无关。** `recoverPersonalSign` 只做 EIP-191 文本哈希恢复,不校验任何 chainId。签名消息文案是
`"ARK Database — wallet sign-in … Sign this message to log in. No transaction or gas fee."`**不引用任何链**。
→ 因此前端登录时强制切到 BNB 链(`ensureBnbChain`)是**多余的**,删除它**不影响后端**。这是一项纯前端修复。
- JWTHS256**有效期 30 天**`SignUserWallet(..., 30*24h)`),无状态。
- nonce 用后即删,过期自动清理。
### 1.2 TokenPocket 扫码登录
| 端点 | 状态 |
|---|---|
| `POST /api/auth/wallet/tp-login-request` | ✅ 生成 actionId/nonce/message/qrUrl`wallet_tp_login_requests` |
| `POST /api/auth/wallet/tp-callback` | ✅ 钱包回调写入签名,校验 `callbackToken` |
| `GET /api/auth/wallet/tp-result?actionId=` | ✅ 轮询返回 `pending/completed/expired/failed` |
→ 前端把扫码从「手机端」挪到「桌面端」只是 UI 位置调整,**后端无需改动**。
### 1.3 收藏
| 端点 | 状态 | 支持的能力 |
|---|---|---|
| `GET /api/me/favorites` | ✅ | `q`title/description/body_text/tag ILIKE`category`(slug)、`sort`(`favorited_at`/`published_at`/`hot`)、`includeUnavailable`(默认 true)、`page`/`limit`(≤100)、返回 `total`、tags、`favoriteCount``availability` |
| `GET /api/me/favorites/ids?resourceIds=` | ✅ | 批量查询收藏状态 |
| `POST /api/me/favorites/{id}` | ✅ | 加收藏,返回 `{ok,resourceId,favorited,favoriteCount}` |
| `DELETE /api/me/favorites/{id}` | ✅ | 取消收藏,`favorite_count` 不低于 `favorite_base_count` |
关键事实:
- **下架资源可用性已支持。** `scanFavoriteItem` 会把 `status!='published' 或 is_public=false` 的资源标为
`availability:"unavailable"`,且默认 `includeUnavailable=true` 仍返回。→ 前端「不可用资源卡片」逻辑后端已就绪。
- `sort=hot` 定义 = `download_count + favorite_count + share_count` 降序。
- 鉴权失败统一返回 **401**
---
## 2. 真正可能需要后端做的事
按优先级。除 2.1 外多为**可选/按产品决定**。
### 2.1 【需确认】CORS 允许前端源 + Authorization 头
前端通过 `apiBase``/api/me/favorites`,并带 `Authorization: Bearer <jwt>`
若前端与 API 不同源,需确认 CORS 允许:
- 来源:前端正式域名(及预览/本地开发源)
- 方法:`GET, POST, DELETE`
- 请求头:`Authorization, Content-Type`
**动作**:确认现有 CORS 配置覆盖以上;若 `apiBase` 同源则可忽略。
### 2.2 【可选】服务端登出 / Token 失效
现状JWT 无状态,前端「断开连接」只清本地 localStorage旧 token 在 30 天内仍有效。
若产品需要「真正的远程登出 / 失效被盗 token」后端需引入二选一
- token 版本号(用户级 `token_version`,签发与校验时比对);或
- token 黑名单jti 撤销表)
**默认建议**:第一版**不做**,保持无状态。仅在有安全需求时再做。
### 2.3 【可选】缩短或可配置 JWT 有效期
现为固定 30 天。若希望更安全或可配置,可将 TTL 提为环境变量(如 `USER_JWT_TTL`)。
**默认建议**30 天对「只验证地址、无资产操作」的场景可接受,可暂不动。
### 2.4 【按产品决定】MetaMask / imToken 扫码兜底WalletConnect/Reown
如果前端最终保留 WalletConnect 扫码路径:**后端无需任何改动**——`/verify` 接受任何 `personal_sign` 签名,与连接方式无关。
此项列出只为说明「即便前端接了 WalletConnect也不产生后端工作」。
### 2.5 【可选打磨】收藏列表 `q` 搜索性能
当前 `q` 用多列 `ILIKE '%..%'`,数据量大时无法走索引。量级变大后可考虑 `pg_trgm` 或全文索引。
**默认建议**:当前数据量下不必做,记录备查。
---
## 3. 前端会改、但与后端无关(请勿误派给后端)
这些是本次 bug/重设计的主体,**全部在前端完成,不涉及后端**
1. 删除登录时强制切 BNB 链(`ensureBnbChain`)—— 验签链无关(见 §1.1)。
2. 桌面登录弹窗简化为「使用浏览器钱包登录」单一主操作;扫码降级为「其他方式」。
3. 扫码从手机端挪到桌面端。
4. 手机端「打开钱包 App」死路修复反馈、未安装兜底
5. 移除/收敛未被登录流程使用的 RainbowKit/WalletConnect 装配(纯前端依赖与体积问题)。
6. 全站「我的收藏」入口缺失(导航 / 手机菜单 / 钱包下拉加入口)。
7. 收藏按钮状态视觉、收藏页筛选区移动端密度、空/错误状态打磨。
8. token 过期时前端自动登出并引导重新登录(消费后端已返回的 401无需后端改
---
## 4. 给后端的「确认清单」
- [ ] §2.1 CORS 是否已允许前端源 + `Authorization` 头?(唯一可能的必做项)
- [ ] 是否需要 §2.2 服务端登出/撤销?(默认否)
- [ ] 是否需要 §2.3 可配置 JWT TTL默认否维持 30 天)
- [ ] 知悉§3 全部为前端工作,无需后端介入。