diff --git a/2.Design/ROADMAP-M0-M1.md b/2.Design/ROADMAP-M0-M1.md index a9ef962..4ff32ad 100644 --- a/2.Design/ROADMAP-M0-M1.md +++ b/2.Design/ROADMAP-M0-M1.md @@ -647,4 +647,16 @@ - `backend/tests/test_email_signup.py`(9 例):真走 SMTP(monkeypatch 记账)、dev echo 不发信、 注册即登录、码用完不能重放、错码/过期、试错上限、邮箱占用、发码节流、弱密码、注册关闭时两条接口都回 2017。 - e2e `web/e2e/register.mjs`:登录页进注册页 → 拿码(dev echo)→ 注册 → 落进首页 → 退出用「邮箱 + 密码」登回来 → - 同一个邮箱再发码回 `2019`。 + 同一个邮箱再发码回 `2019`。7 项全绿。 +- `pytest` 139 passed、`ruff check` / `format --check` 全绿、`tsc --noEmit` 0、`vite build` 通过; + 回归 `account.mjs`(14 项)、`knowledge.mjs`、`login-email-smtp.mjs`(15 项,含真发一封测试信)全绿。 + +### 10.6 上线情况(2026-11-03,commit b5170ad) + +- 生产 `/auth/methods` → `{"password":true,"email_password":true,"sms_code":false,"email_register":true}`。 +- 已注册的邮箱再发码回 `2019`;未注册的地址 `POST /auth/email/code` 返回 `sent:true`(真走了 126 的 SMTP)。 +- 生产登录页出现「用邮箱注册」,注册页渲染正常、控制台零报错(`web/e2e/prod-register-check.mjs`, + 截图 `web/e2e/artifacts/prod-register.png`)。 +- 生产 env **不带** `EMAIL_CODE_DEV_ECHO`:码只发到邮箱,页面不回显。 +- 踩到的坑:dev 库要先 `alembic upgrade head` 到 0011,否则注册接口报 + `column "email_verified_at" of relation "app_user" does not exist` 直接 500——迁移写好不等于跑过。 diff --git a/2.Design/screens/prod-register.png b/2.Design/screens/prod-register.png new file mode 100644 index 0000000..56cf560 Binary files /dev/null and b/2.Design/screens/prod-register.png differ diff --git a/web/e2e/prod-register-check.mjs b/web/e2e/prod-register-check.mjs new file mode 100644 index 0000000..1569418 --- /dev/null +++ b/web/e2e/prod-register-check.mjs @@ -0,0 +1,35 @@ +/** + * 生产上确认注册页真的开出来了(截图留证)。 + * + * 只读:填一个邮箱、看页面长什么样,不点「获取验证码」——那会真的发信, + * 而且生产没有 dev echo,码只能到收件人邮箱里。 + */ +import { chromium } from "playwright-core"; + +const WEB = process.env.WEB ?? "http://192.168.8.188:8200"; +const OUT = "e2e/artifacts"; + +const browser = await chromium.launch({ + executablePath: + process.env.CHROME ?? + `${process.env.LOCALAPPDATA}/ms-playwright/chromium-1223/chrome-win64/chrome.exe`, +}); +const page = await browser.newPage({ viewport: { width: 1440, height: 960 } }); +const errors = []; +page.on("console", (m) => m.type() === "error" && errors.push(m.text())); +page.on("pageerror", (e) => errors.push(String(e))); + +await page.goto(`${WEB}/login`); +await page.waitForSelector("#account"); +const hasLink = (await page.getByRole("link", { name: "用邮箱注册" }).count()) > 0; +console.log(`登录页有注册入口:${hasLink}`); + +await page.getByRole("link", { name: "用邮箱注册" }).click(); +await page.waitForURL("**/register"); +await page.waitForSelector("#email"); +await page.locator("#email").fill("someone@example.com"); +await page.screenshot({ path: `${OUT}/prod-register.png` }); + +console.log(`控制台报错:${errors.length}`); +await browser.close(); +process.exit(hasLink && errors.length === 0 ? 0 : 1);