# 其它约定(长版明细) ## 其它约定 - 校验靠 `valid:"required;maxlen:N"` 标签(`internal/form/*.go`),别在 handler 手写。 - 终止性操作(停用)落独立公开页 `/deactivated`(注册在 `reqUserSignIn` 外);改密码后重登才用 flash + `/login`。 - 只有箱主 `/user` 面板,**无管理员角色、无站方后台,用户要求不要加**:站方动作只走 CLI / 邮件 / 改配置重启。 - git `https://git.shiroko.one/tamakyi/tamabox`(`main`)。**`git push` 能直接推**(本机 Git for Windows 已认证); 「Failed to authenticate user」是临时态。推前 `git log --oneline -3`。`outputs/` 已 gitignore,别整目录 add。 - 打包交付用 tar.gz(排除 `.git`/`.workbuddy`/`outputs`),放项目同级。 ## 测试环境 box-dev-api.337845818.best - 账号 `admin6@admin.com` / `adminadmin`,公开页 `/_/admin6`。 - 登录要过算数验证码:`GET /login` 取 `_csrf`+cookie → `GET /api/captcha/generate` → 算 `a op b` → `POST /login` 带 `g-recaptcha-response=":<答案>"`。默认语言 **ja**,四语言文案要一起加。 - **部署有延迟**;模板是编译期 embed,**只重启不重编不会变**。用户说「已部署但没变化」→ 先抓线上 HTML 比对标记。 - 表单字段:提问 `content`,回答 `answer`。`GET /user/votes` 故意 302;匿名无邮箱提问成功直接 200 渲染。 - 自检:`dev/devcheck-e2e.py`(28 项)、`dev/devcheck-restrict.sh`(基线非 200 就别往下走;`RUN=1` 才真跑)。 - 图片编码三档(头像 512/q78、背景 1920/q80、通用 1600/q80),**EXIF 方向必须先归一**(转 WebP 会丢)。 ## CLI(`TamaBox `) - ⚠️ **两个构建入口必须同步**:根 `go build .`(`tamabox.go`)与 Dockerfile 的 `./cmd/`(`cmd/tamabox.go`), 否则 `No help topic for ''`。 - 现有:`web` `censor` `uid` `ban` `restore` `reports` `restrict` `unrestrict` `hide-public`。 - `restrict --domain|--email --level L1..L4 --days N --reason` / `unrestrict`; `reports --domain|--email [--days]`(证据包)、`--pending`、`--stats --days N`;`hide-public [--only-reported] [--since N]`。 - 本地冒烟:`NEKOBOX_CONFIG_PATH=`;`conf.Init` 强制 `app.external_url`、`server.salt`、`server.xsrf_key` 非空。 - 蜜罐 CLI:`TamaBox honeypot hits|stats|prune`(`--since 24h` / `--show-password` / `--yes`), 注册须在 `cmd/tamabox.go` + 根 `tamabox.go` 两处同步。 - 蜜罐配置:`[security] enable_honeypot` / `honeypot_paths` / `honeypot_retain_days`(默认全关)。 ## 行尾与测试坑(2026-10-21 蜜罐轮) - ⚠️ `internal/route/route.go`、`internal/conf/static.go`、`conf/app.sample.ini` **实际是全 CRLF**; `grep | cat -A` 不显示 `^M` 极易误判 → Python 替换用 `\r\n` 锚点,写后统计 `b'\r\n'` 复核。 - ⚠️ Go 里 `time.Duration(60)` = 60 **纳秒**,测试写裸数字会让封禁/冷却瞬间过期 → 一律 `60 * time.Minute`。 - ⚠️ 测 `IsBanned` → 403 必须注册中间件(`f.Use(autobanMiddleware(ab, hp))`),只注册路由+NotFound 会被绕过。