Files
fquiz/memory/2026-05-16.md
T

131 lines
8.9 KiB
Markdown
Raw Normal View History

## Work Log - 发布链路切换国内镜像仓库(2026-05-16)
- 背景:
- 当前 `dev` 分支 GitHub Actions 发布阶段在远端执行 `docker login ghcr.io` / `docker compose pull` 时失败。
- 典型报错为:`Error response from daemon: Get "https://ghcr.io/v2/": EOF`
- 参考仓库 `multica-ck` 已采用“可配置国内镜像仓库 + 账号密码登录”的工作流模式。
- 本次改动:
- `/.github/workflows/main.yml`
- 将工作流默认镜像仓库从固定 `ghcr.io` 改为 `REGISTRY` / `REGISTRY_NAMESPACE` 可配置模式。
- 默认值对齐 `multica-ck``crpi-u265r07n4blchcqo.cn-shanghai.personal.cr.aliyuncs.com/ck-registry`
- 构建推送阶段改为使用 `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` 登录镜像仓库。
- 部署阶段新增镜像仓库凭据校验,并将远端 `docker login ghcr.io` 改为登录 `${REGISTRY}`
- API / Web 镜像构建补充 `pull: true`,降低 runner 侧基底镜像陈旧风险。
- `/deploy/pro-deploy/.env`
- 将默认 `API_IMAGE` / `WEB_IMAGE` 从 GHCR 地址替换为阿里云个人版容器仓库地址,保证非 CI 手工部署默认也不再回落到 GHCR。
- 验证:
- `git diff --check -- .github/workflows/main.yml deploy/pro-deploy/.env` 通过,无空白/格式错误。
- 仓库内已清除工作流与生产部署默认镜像中的 `ghcr.io` 活动引用。
- 本次未直接触发 GitHub Actions 真实发布,远端连通性需在下一次 CI 执行中验证。
- 风险与关注点:
- GitHub 仓库需预先配置 `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` Secrets,否则构建登录阶段会失败。
- 若未来镜像仓库或命名空间变化,只需更新仓库 Variables `REGISTRY` / `REGISTRY_NAMESPACE`,无需再改工作流逻辑。
2026-05-16 15:00:23 +08:00
## Work Log - 登录接口跨域拦截定位与修复(2026-05-16)
- 背景:
- 用户反馈 `http://223.109.142.84:3000/fl` 可打开,但登录时报错。
- 现场前端 bundle 实际将 API 基址写死为 `http://127.0.0.1:8000`,运行时会改写为当前主机 `223.109.142.84:8000`
- 在线 `api` 容器实际运行于另一份部署目录 `/opt/fquiz/deploy/pro-deploy`,其 `API_CORS_ORIGINS` 仅允许 `https://quiz.example.com`
- 本次改动:
- `/opt/git/fquiz/deploy/pro-deploy/.env`
-`NEXT_PUBLIC_API_BASE_URL``https://quiz.example.com/api` 修正为 `https://quiz.example.com`,避免未来重发版后前端把接口拼成 `/api/api/v1/...`
- 在线部署 `/opt/fquiz/deploy/pro-deploy/.env.prod`
-`API_CORS_ORIGINS` 调整为 `https://quiz.example.com,http://223.109.142.84:3000`
- 使用现有镜像强制重建 `api` 容器,使新的 CORS 白名单立即生效。
- 验证:
- `curl -i http://127.0.0.1:8000/health` 返回 `200 OK`
- `curl -i -X OPTIONS http://127.0.0.1:8000/api/v1/auth/login -H 'Origin: http://223.109.142.84:3000' -H 'Access-Control-Request-Method: POST'`
返回 `200 OK`,且响应头包含 `access-control-allow-origin: http://223.109.142.84:3000`
- `curl -i -X POST http://127.0.0.1:8000/api/v1/auth/login -H 'Origin: http://223.109.142.84:3000' -H 'Content-Type: application/json' --data '{"user_id":"admin","password":"wrong-password"}'`
返回 `401 Unauthorized`,同时保留 `access-control-allow-origin: http://223.109.142.84:3000`,说明跨域链路已打通,剩余仅取决于账号密码本身。
- 风险与关注点:
- 在线 `api` 仍配置 `REFRESH_COOKIE_SECURE=true`;若继续通过纯 HTTP IP 访问,刷新 token cookie 可能不会被浏览器持久化。短期内不影响本次“登录预检被拦截”的修复,但后续若要稳定保留登录态,建议切到 HTTPS 域名访问,或在明确接受风险的前提下改为 `false`
## Work Log - 认证刷新超时改为同源反代(2026-05-16)
- 背景:
- 浏览器请求 `POST http://223.109.142.84:8000/api/v1/auth/refresh` 超时,控制台报 `Failed to fetch`
- 容器内访问 `http://223.109.142.84:3000/fl` 正常返回 `200`,但访问 `http://223.109.142.84:8000/health` 仍超时;同时 `http://127.0.0.1:8000/health``api` 容器内正常返回 `200`
- 说明故障不在 `auth/refresh` 业务逻辑,而在“浏览器直连公网 `:8000`”这条访问链路。
- 本次改动:
- `web/src/lib/api.ts`
- 浏览器端在发现构建注入的 API 基址仍为 loopback 且当前页面不在 loopback 主机时,不再改写到 `当前主机:8000`,而是直接回落到 `window.location.origin`
- `deploy/pro-deploy/compose.yml`
- 生产部署新增 `proxy`nginx)服务,占用宿主机 `3000`
- `web` 改为仅在 Compose 内网暴露 `3000`,不再直接占用宿主机端口。
- `deploy/pro-deploy/nginx.conf`
- `/api/*` 反代到 `api:8000`
- `/api/v1/ws` 使用 Upgrade 头反代到 `api:8000`
- 其余页面流量反代到 `web:3000`
- 验证:
- 本地 `nft list ruleset` 显示 Docker 已为宿主机 `3000/8000` 建立映射,但容器内访问公网 `:8000` 超时、访问公网 `:3000` 正常,支持“对外入口应统一走 `3000` 反代”的判断。
- 待同步部署目录并重建 `web/proxy` 容器后,再做浏览器与 `curl` 复测。
- 风险与关注点:
- 当前在线 `REFRESH_COOKIE_SECURE=true`;若继续通过纯 HTTP IP 访问,浏览器可能仍不会持久化 refresh cookie。若部署后出现“登录后刷新即掉线”,需将当前环境的 `REFRESH_COOKIE_SECURE` 调整为 `false` 或切到 HTTPS 入口。
2026-05-16 22:33:53 +08:00
## Work Log - 登录入口迁移到 `/fl/login`2026-05-16
- 背景:
- 当前前端登录页挂在应用根路径;在生产 basePath=`/fl` 下,对外登录地址表现为 `/fl`
- 需求要求将登录路由显式调整为 `/fl/login`,同时保留旧入口兼容跳转。
- 本次改动:
- `web/src/app/login/page.tsx`
- 新增独立登录页,沿用现有登录表单、记住密码和登录态自动跳转逻辑。
- `web/src/app/page.tsx`
- 根页改为重定向到 `/login`,不再直接承载登录表单。
- `web/src/middleware.ts`
-`/login` 标记为公开直达路由,避免被后台 rewrite 到 `/admin/login`
- `web/src/components/auth-provider.tsx`
- 退出登录后统一跳转到 `/login`
- `web/src/app/admin/layout.tsx`
- 未登录态提示中的“前往登录”入口改为 `/login`
- `MEMORY.md`
- 同步更新长期路由口径:`/login` 为规范登录入口,`/` 仅做跳转。
- 验证:
- `npm --prefix web run lint -- src/app/page.tsx src/app/login/page.tsx src/middleware.ts src/components/auth-provider.tsx src/app/admin/layout.tsx`
通过;仅保留既有 `<img>` 使用警告,无新增 lint error。
- 已本地确认 Next.js 16 安装包的 app redirect 渲染链会按 basePath 处理重定向,当前 `redirect("/login")` 口径可用于 `/fl/login` 场景。
- `npm --prefix web run build` 已启动并进入 `next build --webpack`,但在本次会话等待窗口内未返回最终退出码;期间未出现与本次改动相关的编译报错输出。
- 风险与关注点:
- 仓库内仍有多处“返回首页”按钮保留指向 `/`;当前会经过根页跳转到 `/login`,功能不受影响,但若后续希望所有入口都直接落到规范地址,可再统一替换为 `/login`
## Work Log - 菜单旧路由兼容修复(2026-05-16)
- 背景:
- 用户反馈 `/fl/user` 按预期应进入用户页面,但实际返回 404。
- 当前前端真实页面路径为 `/users`,而部分历史菜单 path/手输地址仍可能使用旧别名(如 `/user``/role``/menu`)。
- 本次改动:
- `web/src/lib/app-route-path.ts`
- 新增统一路由规范化 helper,集中维护旧菜单别名到正式公开路由的映射。
- `web/src/middleware.ts`
-`/user``/role``/menu` 等旧地址,以及 `/admin/*` 旧入口,统一先重定向到规范公开路由,再走后台 rewrite。
- `web/src/app/admin/layout.tsx`
- 后台菜单树 path 统一先做规范化,避免菜单点击后高亮丢失或 path 仍指向旧地址。
- `web/src/app/admin/menus/page.tsx`
- 菜单管理页读取菜单列表时展示规范化 path;提交菜单编辑时也会把旧别名收敛到正式地址。
- `MEMORY.md`
- 补充“前端菜单路由兼容口径”,记录规范地址与旧别名自动收敛规则。
- 验证:
- `npm --prefix web run lint -- src/lib/app-route-path.ts src/middleware.ts src/app/admin/layout.tsx src/app/admin/menus/page.tsx`
通过;仅保留既有 `<img>` warning,无新增 lint error。
- `git diff --check -- web/src/lib/app-route-path.ts web/src/middleware.ts web/src/app/admin/layout.tsx web/src/app/admin/menus/page.tsx`
通过。
- 风险与关注点:
- 当前别名映射基于已知历史菜单路径补齐;若库里还存在其他非常规旧 path,仍需按实际反馈继续补别名表。