fix login error
This commit is contained in:
@@ -107,6 +107,24 @@
|
||||
- **启动期「历史数据归一」的既有惯例**:在 `db.Init` 的 `AutoMigrate` 之后追加幂等函数
|
||||
(`backfillFeatureControls` / `reconcileLegacyChatEnabled` / `normalizeChatQuota` / `normalizeHarassmentSetting`),
|
||||
失败仅告警、不阻断启动。新增此类归一照此模式即可。
|
||||
- ⚠️ **事务里复用同一个 `tx` 句柄会串条件**:事务句柄的 `clone == 0`,`tx.Where(A)...; tx.Where(B)...`
|
||||
会把 A 的条件累加到 B 的语句上(实测生成 `DELETE FROM follow_ups WHERE <follow_ups 条件> AND <messages 条件>`
|
||||
→ `字段 conversation_id 不存在 (42703)`)。**每条语句都必须重新取句柄**:`tx.WithContext(ctx).<链式调用>`。
|
||||
(`db.WithContext(ctx)` / `.Session(...)` 返回 clone==1 的新句柄,链式调用才会 clone。)
|
||||
- ⚠️ **软删除 + 唯一索引 = 唯一槽位被永久占用**。User 的 `email`/`domain`、`Conversation.token`、
|
||||
`VoteSubmission` 的复合唯一索引都**不含 deleted_at**,而 gorm 的查重查询默认带 `deleted_at IS NULL` →
|
||||
「查重放行、INSERT 被索引拦下」,表现为 500。**处置分两种语义,别混**:
|
||||
- **停用(可恢复)**:`users.Deactivate` = `purgeUserContent()` 物理删内容 + **软删除用户行**(身份占位)。
|
||||
邮箱/域名继续被占用是有意为之(防他人抢占身份),注册侧必须用 `Unscoped` 识别并给出
|
||||
`ErrDeactivatedEmail` / `ErrDeactivatedDomain`(见 `validate` / `fieldTaken`),**不能**当成普通重复邮箱。
|
||||
站长用 `TamaBox restore --email|--domain [--password] --yes` 恢复。
|
||||
- **封禁(不可恢复)**:`users.BanUserAndCleanup` = `purgeUserContent()` + **物理删除用户行**,邮箱彻底释放。
|
||||
- 级联内容删除一律 `Unscoped()` 物理删除;`voteSubmissions.DeleteByVoteID` 同理(`vote_submissions.go:234`)。
|
||||
**新增「删除后要能重建」的路径时务必 Unscoped;新增「删除后仍占位」的路径时务必让注册侧能识别。**
|
||||
- 唯一键冲突兜底:`isDuplicateKeyError(err)`(`vote_submissions.go`,MySQL 1062 / PG 23505)。
|
||||
注册不需要额外兜底 —— `validate` 已覆盖活跃 + 已停用两种占用。
|
||||
- ⚠️ **`cmd/tamabox.go` 的 `app.Commands` 容易漏注册**:`internal/cmd/ban.go` 曾写好但没注册,
|
||||
`TamaBox ban` 实际不可达。新增 CLI 命令记得同时改这里。
|
||||
|
||||
## 文件工具陷阱(重要)
|
||||
|
||||
@@ -138,3 +156,27 @@
|
||||
- **git 仓库已损坏**(`.git/refs` 缺失、index 截断、对象库近乎空),用户明确要求「不要动 git」。
|
||||
备份/回滚一律用 tar.gz(排除 `.git`、`.workbuddy`),放在项目同级目录:
|
||||
`C:/OtherFiles/Github/TamaBox-v4-mainline-<描述>-<日期>.tar.gz`。
|
||||
|
||||
## 测试环境(box-dev-api.337845818.best)
|
||||
|
||||
- **该域名跑的就是本工作区的构建**(2026-09-15 实测:本地新建的模板/路由/文案能在线访问到),
|
||||
但部署有延迟 —— 需重新构建/重启才会生效。**改完代码要提醒用户重新部署**,不要假定已生效。
|
||||
- 站点默认语言是 **ja**(`shared.App.Lang()`),匿名页断言别写中文文案,用语言无关标记(如 `ratio: 3`)。
|
||||
- 验证码是**数学题**(`conf.Recaptcha.CaptchaType == "math"`),可用脚本自动求解:
|
||||
`GET /api/captcha/generate` 取 `{data:{id,question}}`,把 `a op b =` 算出来,提交 `g-recaptcha-response = "<id>:<答案>"`;
|
||||
表单还需页面里的 `_csrf`(`name="_csrf"` 隐藏域)。
|
||||
- 可复用的端到端巡检脚本:`dev/devcheck-e2e.py`(注册→登录→提问→回答→投票→停用→同邮箱重注册)。
|
||||
- 表单字段名易错:提问是 `content` + `g-recaptcha-response`;回答是 `answer`(不是 content)。
|
||||
`GET /user/votes` **故意** 302 到 `/user/questions#votes`,不是 bug。
|
||||
匿名无邮箱提问成功后**直接 200 渲染提问成功页**(不重定向),也不是 bug。
|
||||
|
||||
## 管理 CLI(`TamaBox <cmd>`)
|
||||
|
||||
- 注册在 `cmd/tamabox.go` 的 `app.Commands`。现有:`web` / `censor` / `uid` / `ban` / `restore`。
|
||||
- `ban --email|--domain [--yes]` → 物理删除用户 + 内容(不可恢复,邮箱释放)。
|
||||
- `restore --email|--domain [--password <新密码>] [--yes]` → 恢复已停用账号(清 deleted_at)。
|
||||
`--password` 必须在恢复之后执行(`UpdatePassword` 走普通作用域,软删除状态下找不到用户)。
|
||||
- 本地冒烟:仓库里**只有 `conf/app.sample.ini`**(真 `app.ini` 不在版本库),
|
||||
用 `NEKOBOX_CONFIG_PATH=<你的 ini>` 指定配置即可;`conf.Init` 强制要求
|
||||
`app.external_url`、`server.salt`、`server.xsrf_key` 三者非空。
|
||||
跑 `TamaBox <cmd>` 会自动 `AutoMigrate`,可直接指向一个临时库做端到端验证(用完 DROP)。
|
||||
|
||||
Reference in New Issue
Block a user