Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ GitHub Actions 工作流目录。
## ✅ 放什么
- CI 验证
- 构建检查
- `e2e.yml` 分别运行快速页面 smoke 与真实本地 Worker/D1/R2 业务回归,并上传浏览器和 Worker 证据
- 发布自动化

## 🚫 不放什么
Expand Down
39 changes: 39 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,42 @@ jobs:
path: apps/web/test-results
if-no-files-found: ignore
retention-days: 7

business-playwright:
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5

- name: Setup pnpm
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10.18.2

- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
with:
node-version: 22
cache: pnpm

- name: Install workspace dependencies
run: pnpm install --frozen-lockfile

- name: Install Playwright Chromium
run: pnpm exec playwright install --with-deps chromium

- name: Run isolated Worker and D1 business E2E
run: pnpm test:e2e:business

- name: Upload business E2E evidence
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: business-playwright-evidence
path: |
apps/web/playwright-report/business
apps/web/test-results/business
if-no-files-found: ignore
retention-days: 7
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Preserved canonical notification events independently from chat-platform request bodies so failed Slack, Discord, Feishu, and WeCom deliveries replay with complete mail and extraction content; added bounded response reading, request timeouts, platform acknowledgement validation, and explicit errors for legacy chat records without replay data (D1 migration 0024).
- Brought the local database schema snapshot up to date with inbound Message-ID, notification channels, and retention/idempotency indexes; added empty-database and existing-delivery migration regression coverage.
- Restored background accessibility during the same render commit that closes a modal, and cleaned up API key clipboard feedback timers on unmount so route transitions do not leave the page inert or trigger delayed updates.

### Added

- Added owner-scoped notification status and replay controls in Webhook/Telegram, administrator notification aggregates, explainable rule dry-runs, and explicit IANA quiet-hours timezones while preserving UTC for existing rules (D1 migration 0026).
- Added durable inbound notification tasks committed with mail metadata, conditional lease-based claiming, bounded exponential retries with Retry-After, stable event IDs, owner-scoped replay, and expiration/deletion cleanup (D1 migration 0025). Minute-level notification recovery runs independently from hourly mail retention cleanup.
- Added isolated real Worker/D1/R2 business E2E with browser registration and mailbox creation, inbound extraction, API key lifecycle, permissions, quotas, Message-ID deduplication, HTML attachments, webhook replay, and controlled outbound retries; added a separate CI job and staging external-service validation checklist.
- Added a next-development roadmap grounded in the current 0.4.0 implementation, prioritizing chat-channel replay fixes, real Worker/D1 business E2E, recoverable notification delivery, outbound status handling, extraction quality evaluation, and first-use guidance with explicit acceptance criteria.

### Changed

- Normalized roadmap and validation-report formatting so the committed documents pass whitespace validation.
- Corrected implementation-versus-verification documentation, backup/restore binding instructions, test coverage descriptions, and unmeasured deployment-time claims on the landing page.
- Rebuilt the landing hero around demonstrating the product instead of describing it: an auto-playing inbox demo (mail arrives → verification code extracted → copied), an interactive extraction playground running the real Worker-side extraction engine client-side on pasted text, open-source/self-host/edge positioning pills, honest CTAs (申请邀请 + 自托管部署 instead of 立即开始 hitting the invite wall), and the rotating headline word now carries the brand accent.
- Landing content honesty: key metrics describe automated tests, separate staging/production environments, Cloudflare edge deployment, and the open-source license; the testimonials section is labeled 场景示例 with workflow scenarios instead of fabricated personas.
- Added a blanket prefers-reduced-motion guard covering all landing-page animations.

## [0.4.0] - 2026-09-06

### Added
Expand Down
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</p>

<p align="center">
<img alt="Version" src="https://img.shields.io/badge/version-0.1.2-111111?style=flat-square" />
<img alt="Version" src="https://img.shields.io/badge/version-0.4.0-111111?style=flat-square" />
<img alt="License" src="https://img.shields.io/badge/license-MIT-ff7a00?style=flat-square" />
<img alt="Node" src="https://img.shields.io/badge/node-22-43853d?style=flat-square" />
<img alt="pnpm" src="https://img.shields.io/badge/pnpm-10.18.2-f69220?style=flat-square" />
Expand All @@ -21,6 +21,18 @@

`WeMail` 是一个基于 pnpm monorepo 的 disposable email 服务,提供临时邮箱、邮件收取、发件控制、API Key、公告、Webhook、Telegram 通知与管理员后台能力。

项目版本以根 [`package.json`](package.json) 为准;切版时使用 `pnpm version:sync` 同步 workspace、共享版本常量与 OpenAPI,并更新本页徽章。

## 能力与验证范围

| 状态 | 说明 | 当前范围 |
| --- | --- | --- |
| 已实现 | 源码中存在接口、业务逻辑或界面 | 收件、提取、通知规则、聊天渠道、发件、权限与管理员设置 |
| 已联调 | 指定环境中的组件协同有可复现测试结果 | `pnpm test:e2e:business` 连接真实本地 Worker/D1/R2 与浏览器,外部供应商为受控适配器;快速 smoke 保留模拟 API,范围见[测试策略](docs/testing-strategy.md) |
| 已上线验收 | 指定 commit、环境与真实服务有验收记录 | 需要按[发布手册](docs/deploy-runbook.md)保存真实 Email Routing、通知平台、Resend 与权限验证证据;本页不代表所有外部链路均已验收 |

`GET /api/users/commercial` 当前返回部署级用量、套餐展示和一个 `default` 组织汇总;独立团队、成员关系与共享邮箱授权仍需后续开发。系统设置中的历史「运维中心」「成熟度总览」「可靠性后台」面板已移除,`/system/operations` 转到系统设置;相关管理员 API 保留。后续交付顺序见[开发计划](docs/plans/2026-10-03-next-development-roadmap.md)。

## 仓库结构

```text
Expand Down Expand Up @@ -100,6 +112,7 @@ pnpm test:shared
pnpm test:worker:integration
pnpm test:web:integration
pnpm test:e2e
pnpm test:e2e:business
```

首次运行 E2E 前安装浏览器:
Expand Down Expand Up @@ -331,6 +344,8 @@ curl -i "$PRODUCTION_API_BASE_URL/api/system/health"

只在 GitHub Actions 不可用或明确需要手动操作时使用。

Actions 的绑定注入不会在本地自动发生。手动部署前按[备份恢复手册的私有配置步骤](docs/backup-restore-runbook.md#22-准备私有-wrangler-配置)准备 `.wrangler/wrangler.recovery.toml`,填入目标环境的真实 D1/KV ID,并核对路由、R2 bucket、Cookie 与 CORS。公开 `wrangler.toml` 继续保留占位值。构建前按目标环境设置 `VITE_API_BASE_URL`;只有已配置同域 `/api/*` Worker 路由时才可省略。

staging:

```bash
Expand All @@ -340,8 +355,8 @@ pnpm typecheck
pnpm lint
pnpm build
cd apps/worker
pnpm exec wrangler d1 migrations apply wemail-staging --env staging --remote
pnpm exec wrangler deploy --env staging
pnpm exec wrangler d1 migrations apply DB --env staging --remote --config .wrangler/wrangler.recovery.toml
pnpm exec wrangler deploy --env staging --config .wrangler/wrangler.recovery.toml
cd ../..
pnpm exec wrangler pages deploy apps/web/dist --project-name=<pages-project-name> --branch=staging
```
Expand All @@ -355,8 +370,8 @@ pnpm typecheck
pnpm lint
pnpm build
cd apps/worker
pnpm exec wrangler d1 migrations apply wemail-production --env production --remote
pnpm exec wrangler deploy --env production
pnpm exec wrangler d1 migrations apply DB --env production --remote --config .wrangler/wrangler.recovery.toml
pnpm exec wrangler deploy --env production --config .wrangler/wrangler.recovery.toml
cd ../..
pnpm exec wrangler pages deploy apps/web/dist --project-name=<pages-project-name>
```
Expand Down Expand Up @@ -395,4 +410,4 @@ D1 migration 如果已经写入生产,不能盲目回滚代码后假设数据

## 致谢

![认可linux.do](https://ld.xh.do/ld-badge.svg)
![认可linux.do](https://ld.xh.do/ld-badge.svg)
7 changes: 7 additions & 0 deletions apps/web/e2e-business/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# 真实本地业务回归

运行 `pnpm test:e2e:business`,无需手动启动服务。测试实际连接生产路由、D1 本地数据库、R2 本地附件存储与浏览器页面,没有 `page.route()` API 替身。外部供应商使用 Worker 测试入口里的受控适配器。

`BUSINESS_TEST_TOKEN` 由 runner 临时生成;邀请码、用户、邮箱和消息都在隔离数据库中。测试结束时删除临时配置与存储,日志/失败截图/trace 保存在已忽略的 `apps/web/test-results/business` 中。

Browser 插件与其 browser skill 未在当前会话中提供,本批次按前端测试技能使用项目既有 Playwright。验证目标为“真实邀请码注册 → 建邮箱 → 收件与多值提取 → API Key 与权限”,同时断言无页面运行时异常并保存收件页截图。
Loading
Loading