customware-email
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCustomer Email
客户邮件
<purpose>
Implement one coherent Customware email capability for a Customware-generated app. The capability receives customer replies through the provisioned Postmark inbound webhook and sends customer-facing messages through the same development Postmark server's HTTPS API.
The task provides the project-specific addresses. The two managed server ENV values provide the credentials. This skill provides the implementation method, durable behavior, and verification contract.
</purpose>
Build toward the existing app. Reuse its Hono routes, Drizzle schema, SQLite database, logging, error, andpatterns. A small, native integration is easier to reason about and safer than a second email framework.Result
<purpose>
为Customware生成的应用实现一套连贯的Customware邮件功能。该功能通过预配置的Postmark入站webhook接收客户回复,并通过同一开发环境Postmark服务器的HTTPS API发送面向客户的消息。
任务会提供项目专属地址。两个受管理的服务器环境变量提供凭证。本技能提供实现方法、持久化行为和验证约定。
</purpose>
基于现有应用构建。复用其Hono路由、Drizzle schema、SQLite数据库、日志、错误处理和模式。原生轻量集成比引入第二个邮件框架更易理解且更安全。Result
Read first
必读内容
Read these references before editing source files:
- references/common-architecture.md — task inputs, platform boundaries, credentials, stack, and shared integration shape.
- references/inbound.md — the fixed webhook, authentication, durable receipt, deduplication, and recovery contract.
- references/outbound.md — direct Postmark API sending, message shape, sender/reply routing, and failure handling.
- references/common-quality.md — validation, safe logging, migration, tests, and final verification.
Read the inbound and outbound references even when the task initially sounds one-sided. Replies make the two directions one feature: inbound mail must be able to reach the app, and outbound mail must route replies back to the same virtual address.
<read_order>
Before implementation, also read the target repository's , the complete Builder task, relevant project docs, and the existing database/route/service contracts. Treat the target repository as authoritative when a framework detail differs from an example here.
AGENTS.md</read_order>
在编辑源文件前,请阅读以下参考文档:
- references/common-architecture.md — 任务输入、平台边界、凭证、技术栈和共享集成架构。
- references/inbound.md — 固定webhook、认证、持久化收件、去重和恢复约定。
- references/outbound.md — 直接调用Postmark API发送邮件、消息格式、发件人/回复路由和故障处理。
- references/common-quality.md — 验证、安全日志、迁移、测试和最终验证。
即使任务最初看似只涉及单向功能,也要阅读入站和出站参考文档。回复功能让双向邮件成为一个整体:入站邮件必须能抵达应用,出站邮件必须将回复路由回同一个虚拟地址。
<read_order>
在实现前,还需阅读目标仓库的、完整的Builder任务、相关项目文档以及现有数据库/路由/服务约定。当框架细节与本文示例存在差异时,以目标仓库的内容为准。
AGENTS.md</read_order>
Fixed platform contract
固定平台约定
| Concern | Required decision |
|---|---|
| Postmark server | Use the one development server already provisioned for this project. The app does not create, delete, or configure it. |
| Inbound route | |
| Inbound authentication | HTTP Basic Auth, username |
| Server credentials | Read |
| Inbound address | Use the exact virtual address supplied in the task. Do not create an ENV for it. |
| Outbound sender | Use the exact task-provided sender, currently |
| Outbound stream | Postmark's existing Default Transactional stream ( |
| Transport | Direct HTTPS requests to Postmark's Email API from server code. |
| SMTP | Do not enable or use SMTP. |
| Customware gateway | Do not add a Customware send endpoint, proxy, or email gateway. |
| Production | Implement the development capability described by the task. Do not add production-server, publish, or environment-branching behavior. |
<address_source_of_truth>
The task description is the source of truth for the virtual inbound address and outbound From address. Keep each value in one server-owned constant/module so it cannot drift between the sender, reply routing, and reviewer-visible code. Never replace either value with a placeholder, a guessed address, or a new ENV.
</address_source_of_truth>
| 关注点 | 必填决策 |
|---|---|
| Postmark服务器 | 使用已为该项目预配置的开发服务器。应用不得创建、删除或配置该服务器。 |
| 入站路由 | |
| 入站认证 | HTTP Basic Auth,用户名 |
| 服务器凭证 | 仅在服务器端读取 |
| 入站地址 | 使用任务中提供的精确虚拟地址。请勿为其创建环境变量。 |
| 出站发件人 | 使用任务提供的精确发件人地址,当前为 |
| 出站流 | Postmark现有的默认事务流( |
| 传输方式 | 从服务器代码直接向Postmark的Email API发送HTTPS请求。 |
| SMTP | 请勿启用或使用SMTP。 |
| Customware网关 | 请勿添加Customware发送端点、代理或邮件网关。 |
| 生产环境 | 实现任务描述的开发环境功能。请勿添加生产服务器、发布或环境分支相关行为。 |
<address_source_of_truth>
任务描述是虚拟入站地址和出站发件人地址的唯一可信来源。将每个地址保存在一个服务器专属的常量/模块中,避免发件人、回复路由和评审可见代码之间的地址不一致。切勿用占位符、猜测地址或新环境变量替换任一地址。
</address_source_of_truth>
Non-negotiables
不可协商规则
- Keep both Postmark credentials server-only. Never place them in browser code, , HTML, JSON responses, task output, logs, or client state.
VITE_* - Treat and
.envas inaccessible. Do not inspect them with file commands. A runtime check may use.env.*without printing environment values.node --env-file=.env ... - Register the inbound route before static serving and the SPA fallback.
- Persist an inbound delivery before acknowledging it. The 200 response means the raw delivery is safe to recover, not that application processing finished.
- Enforce uniqueness in the database. Do not implement deduplication as read-then-insert.
MessageID - Make inbound processing recoverable after a crash or restart; an in-memory callback cannot be the only record of work.
- Return the contract statuses in the inbound reference. Never return to Postmark for this receiver.
403 - Send outbound mail only from server code with and
X-Postmark-Server-Token.MessageStream: "outbound" - Use the task's virtual inbound address as , so a customer reply comes back through the existing webhook.
ReplyTo - Keep message content and credentials out of logs. Log only safe operational identifiers and error categories.
- Reuse existing contracts and error/result conventions. Avoid duplicate validation, speculative abstractions, compatibility branches, or a second persistence framework.
- 确保两个Postmark凭证仅在服务器端使用。绝不能将其放入浏览器代码、变量、HTML、JSON响应、任务输出、日志或客户端状态中。
VITE_* - 视和
.env为不可访问文件。请勿用文件命令查看其内容。运行时检查可使用.env.*但不得打印环境变量值。node --env-file=.env ... - 在静态服务和SPA回退之前注册入站路由。
- 在确认收件前先持久化入站邮件。返回200响应仅表示原始邮件已安全保存,不代表应用处理已完成。
- 在数据库中强制唯一性。请勿将去重实现为先读取再插入的逻辑。
MessageID - 确保入站处理在崩溃或重启后可恢复;内存回调不能作为工作记录的唯一方式。
- 入站请求返回参考文档中约定的状态码。绝不能向Postmark的该接收器返回。
403 - 仅从服务器代码发送出站邮件,且需携带和
X-Postmark-Server-Token。MessageStream: "outbound" - 将任务提供的虚拟入站地址设为,确保客户回复能通过现有webhook返回。
ReplyTo - 请勿在日志中记录消息内容和凭证。仅记录安全的操作标识符和错误类别。
- 复用现有约定和错误/结果处理规范。避免重复验证、推测性抽象、兼容性分支或引入第二个持久化框架。
Implementation workflow
实现流程
1. Establish the task contract
1. 确认任务约定
- Read the task completely.
- Extract the exact virtual inbound address and outbound From address.
- Confirm the task names and that the Postmark server has already been provisioned.
customware-email - Stop with a clear result if either address or either managed credential contract is unavailable. Do not invent values.
action_required
- 完整阅读任务内容。
- 提取精确的虚拟入站地址和出站发件人地址。
- 确认任务指定了技能,且Postmark服务器已预配置完成。
customware-email - 如果任一地址或任一受管理凭证约定不可用,立即返回明确的结果。请勿自行编造值。
action_required
2. Inspect the generated app
2. 检查生成的应用
Locate the Hono entrypoint, route registration order, static/fallback handlers, Drizzle schema and migrations, query/service conventions, environment helper, logging boundary, and existing /Zod patterns. Identify where the app's customer workflows should consume an accepted email and where its existing business actions produce outbound messages.
Result定位Hono入口点、路由注册顺序、静态/回退处理器、Drizzle schema和迁移脚本、查询/服务规范、环境变量助手、日志边界以及现有的/Zod模式。确定应用的客户工作流应在何处处理已接收的邮件,以及现有业务操作应在何处生成出站消息。
Result3. Build the shared server foundation
3. 构建共享服务器基础
Create one small server-owned email configuration module for the task-provided addresses and the two managed ENV reads. Keep provider calls behind a focused Postmark client/adapter that follows the app's existing result and error patterns. Do not let browser requests choose the server token, From address, ReplyTo address, stream, or Postmark URL.
创建一个小型的服务器专属邮件配置模块,用于存储任务提供的地址和两个受管理环境变量的读取逻辑。将Postmark调用封装在一个符合应用现有结果和错误模式的专用Postmark客户端/适配器之后。禁止浏览器请求选择服务器令牌、发件人地址、回复地址、流或Postmark URL。
4. Implement inbound and outbound
4. 实现入站和出站功能
Follow references/inbound.md for the receiver and durable worker. Follow references/outbound.md for the Postmark Email API adapter and the app-facing send helper. Integrate both with existing domain flows instead of creating a parallel email subsystem.
遵循references/inbound.md实现接收器和持久化处理逻辑。遵循references/outbound.md实现Postmark Email API适配器和面向应用的发送助手。将两者与现有业务流程集成,而非创建独立的邮件子系统。
5. Verify progressively
5. 逐步验证
Run focused contract checks while implementing, then the repository's normal format, lint, typecheck, build, unit, and interactive checks. Use the test matrix in references/common-quality.md. If an external send is requested, use only an explicitly approved safe recipient; otherwise prove the exact request with a stubbed Postmark client and route-level tests.
在实现过程中运行针对性的约定检查,然后执行仓库常规的格式检查、代码 lint、类型检查、构建、单元测试和交互式检查。使用references/common-quality.md中的测试矩阵。如果需要发送外部邮件,仅使用明确批准的安全收件人;否则通过Stubbed Postmark客户端和路由级测试验证请求的准确性。
6. Perform the final audit
6. 执行最终审计
Search the final diff for credential names, hardcoded secrets, SMTP usage, , production branches, direct browser-to-Postmark calls, raw email logging, and a second gateway. Confirm the task addresses are the only email values embedded in generated application code and that the database migration is included and applied through the app's normal command.
POSTMARK_ACCOUNT_TOKEN在最终代码差异中搜索凭证名称、硬编码密钥、SMTP使用、、生产环境分支、浏览器直接调用Postmark、原始邮件日志以及第二个网关的相关内容。确认任务提供的地址是生成的应用代码中唯一嵌入的邮件地址,且数据库迁移脚本已包含并通过应用的常规命令执行。
POSTMARK_ACCOUNT_TOKENCompletion checklist
完成检查清单
- The task's exact inbound and outbound addresses are used in one server-owned configuration module.
- protects the inbound route and
POSTMARK_INBOUND_WEBHOOK_SECRETauthorizes outbound HTTPS calls.POSTMARK_SERVER_TOKEN - The inbound route captures raw JSON, validates , persists before 200, deduplicates by a database constraint, and recovers pending/stale work.
MessageID - Outbound requests use ,
POST /email,X-Postmark-Server-Token, the task's From, and the task's inbound ReplyTo.MessageStream: "outbound" - SMTP, raw email, account-level provisioning, production behavior, and a Customware send gateway are absent.
- Sensitive values and message content are absent from browser bundles, responses, and logs.
- Migrations, focused tests, repository checks, build, and relevant browser verification pass.
- The final diff and reviewer requirements are read back before sign-off.
- 任务提供的精确入站和出站地址已在一个服务器专属配置模块中使用。
- 用于保护入站路由,
POSTMARK_INBOUND_WEBHOOK_SECRET用于授权出站HTTPS调用。POSTMARK_SERVER_TOKEN - 入站路由捕获原始JSON、验证、在返回200前持久化数据、通过数据库约束去重,并能恢复待处理/过期的任务。
MessageID - 出站请求使用、
POST /email、X-Postmark-Server-Token、任务指定的发件人地址和任务指定的入站回复地址。MessageStream: "outbound" - 未使用SMTP、原始邮件、账户级配置、生产环境行为和Customware发送网关。
- 敏感值和消息内容未出现在浏览器包、响应和日志中。
- 迁移脚本、针对性测试、仓库检查、构建和相关浏览器验证均已通过。
- 已重新阅读最终代码差异和评审要求,再进行签核。
Boundaries
边界说明
Use this skill for the generated app's Customware email implementation. The Customware control plane owns Postmark server provisioning, encryption, hidden ENV materialization, webhook URL reconciliation on sandbox restart, cleanup, and publish protection. Do not duplicate those responsibilities in the generated app.
Use for AI gateway or AI Elements work, for the support widget, and when the Builder task requires its full gated execution protocol. Those skills complement this one; they do not replace the email contracts here.
customware-aicustomware-support-widgettask-workflow本技能用于为生成的应用实现Customware邮件功能。Customware控制平面负责Postmark服务器的配置、加密、隐藏环境变量的实例化、沙箱重启时的webhook URL协调、清理和发布保护。请勿在生成的应用中重复这些职责。
AI网关或AI元素相关工作请使用技能,支持小部件相关工作请使用技能,当Builder任务需要完整的 gated 执行协议时请使用技能。这些技能可与本技能互补,但不能替代本文中的邮件约定。
customware-aicustomware-support-widgettask-workflow