You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
resolveEmailCapabilityArg({appName: 'From The Key',defaultTemplateContext: {appName: 'From The Context'}},{OS_APP_NAME: 'From The Env'},).options.defaultTemplateContext.appName// => 'From The Context'
Resolution order in serve.ts:
1. config.email.* from objectstack.config.ts
2. OS_EMAIL_* environment variables (override per setting)
3. Default -> provider='log'
实施 #5307 时实测
resolveEmailCapabilityArg的模板上下文解析顺序,发现一处与文档声明相反的优先级。#5307 的 PR 只把实测到的现状写进 TSDoc 并用测试钉住,没有改行为——改不改是契约决定,故单独立单。实测(origin/main @ ed0d2aa)
packages/cli/src/commands/serve.ts,resolveEmailCapabilityArg内:appName先算,defaultTemplateContext再整体展开覆盖在它上面。于是:config.email.defaultTemplateContext.appNameOS_APP_NAME(环境变量)config.email.appNameconfig.appName复现(无需起服务):
为什么是问题
EmailServiceConfigSchema的头部 TSDoc(也是生成文档content/docs/references/system/email-config.mdx的开头)写的是:「环境变量逐项覆盖配置」是这个文件对所有键的承诺,
apiKey/defaultFrom/retries/queueDelivery/ SMTP 一族都照此执行。只有appName这一项,一旦作者同时写了defaultTemplateContext.appName,env 就失效——而且是静默失效。具体后果:同一份
objectstack.config.ts部署到多环境,运维在生产设OS_APP_NAME=Acme覆盖仓库里写死的defaultTemplateContext: { appName: 'Acme Dev' },发出去的品牌邮件仍然叫 Acme Dev。连带地,没有配defaultFrom时的兜底发件人也是从这个值 slug 化来的(no-reply@acme-dev.local),所以错的不止是正文。两种读法(需要维护者定)
A:现状即正确 —— 「显式完整上下文」比「便捷单键 + env」更具体,应该赢。那就该在 TSDoc 里把
appName标为 env 规则的显式例外(spec: EmailServiceConfigSchema 未声明 CLI 实读的 queueDelivery / appName / defaultTemplateContext(与 #5104 同族,不同键) #5307 的 PR 已按这个读法把现状写清楚了),不改代码。B:env 必须赢 —— 与文件声明的解析顺序一致,也与其余所有键一致。改法是把 env/键的解析结果放在展开之后:
注意这里要显式把
defaultTemplateContext.appName插进链条(排在两个专用来源之后、顶层configAppName之前),否则从 B 改过去会把「只写了defaultTemplateContext.appName、没写appName」的既有配置直接降级到'ObjectStack'—— 修一个静默错值换来另一个,更糟。倾向 B:一份配置多环境部署时 env 覆盖是运维的唯一手段,而当前行为让这个手段在一个键上无声失效;例外规则(A)要求作者读到 TSDoc 的那一段才知道,属于「必须记住才不会踩」的设计。但 B 会改变既有部署的可观察行为(user-visible,需要 changeset),不是能顺手带的改动。
关联
appName/defaultTemplateContext声明的同一次实测;该 PR 在packages/cli/src/commands/serve-email-config-parity.contract.test.ts以spreads defaultTemplateContext OVER the resolved appName, as documented钉住现状并指回本单——若选 B,那条测试连同 schema TSDoc 一起改。OS_APP_NAME是不合OS_{DOMAIN}_{FEATURE}形状的历史遗留变量,AGENTS.md 已把这类列为 debt;本单不涉及改名)