用途
该技能是 Forge 框架下的工程化工作流指南,适用于包含 forge.toml 文件的仓库,即使用 Forge 构建的 Rust 全栈应用。Forge 是单二进制、PostgreSQL 支撑的全栈 Rust 框架,技术栈为 Axum + Tokio + SQLx;宏会生成运行时接线和前端绑定,但每个 handler 都必须在 src/main.rs 中注册,宏本身不会完成注册。
编译循环硬性规则
- 手工执行任何
cargo check/cargo build时,SQLX_OFFLINE=true是强制的,CI 会全局设置。否则 sqlx 会针对实时DATABASE_URL校验每个sqlx::query!(),包括已发布的 forge-runtime crate 中无法编辑的查询,从而在第三方代码中出现大量“column does not exist”错误。最简单的做法是在 shell rc 中执行eval "$(forge env)",或手动export SQLX_OFFLINE=true。 forge check会自动准备 offline 缓存:当src/比.sqlx/新时,会先运行cargo sqlx prepare --workspace。使用原始cargo check时,编辑任何sqlx::query!()后仍需运行forge migrate prepare。在缓存已正确的 CI 中可传--no-prepare。forge migrate prepare在缺少 cargo-sqlx 时会硬失败,需先安装:cargo install sqlx-cli --no-default-features --features postgres。- 所有 forge 命令会向上查找
forge.toml,可在任意子目录运行,启动时会打印解析出的根目录,无需先cd。 - 编译循环感觉异常时,先运行
forge doctor,它会一次性检查 rustc、cargo-sqlx、SQLX_OFFLINE、DATABASE_URL 可达性、Docker、前端工具链、forge.toml 语法、.sqlx/新鲜度以及最新迁移文件是否为空。 cargo sqlx prepare通过即代表编译通过,不必仅为“确认”再跑forge check。仅在有新编辑或需运行其余验证套件(注册、schema、clippy)时才运行forge check。
会话启动流程
先运行 bash docs/skills/forge-idiomatic-engineer/scripts/orient.sh。该脚本会向上查找 forge.toml,然后输出结构化信息:项目名、认证模式、前端、环境就绪情况、.sqlx/ 缓存新鲜度、src/main.rs / src/functions/mod.rs / src/schema/mod.rs 的内容、按类型分组的已注册 handler、最新迁移、启用响应式的表以及具体下一步提示。一次调用可替代五次独立读取。
每会话须阅读一次 references/pitfalls.md 和 references/resilience.md,脚本不会打印它们。脚本不可用时(旧检出、沙箱环境),读取 forge.toml、Cargo.toml、src/main.rs、src/functions/mod.rs 及 migrations/ 下最新文件。这些文件只有在你写入时才变化,会话中途重读通常是浪费上下文。自动压缩后应信任摘要中的文件清单。需要读取文件时,一次性完整读取,不要发出重叠范围。Forge handler 文件很少超过 600 行。
Handler 类型与命名规则
Handler 类型包括只读查询 #[forge::query](后缀 Query)、数据变更 #[forge::mutation](Mutation)、后台任务 #[forge::job](Job)、定时任务 #[forge::cron](Cron)、持久工作流 #[forge::workflow](Workflow)、长驻进程 #[forge::daemon](Daemon)、外部 HTTP 事件 #[forge::webhook](Webhook)以及 AI agent 工具 #[forge::mcp_tool](McpTool),各类均需对应 .register_* 注册,或使用 .auto_register() 通过 inventory 自动收集。
命名规则:仅支持 pub async fn handler,私有函数会导致代码生成失败;snake_case 函数名会被宏转换为 PascalCase 加类型后缀,函数名中不要包含类型(写 heartbeat 而非 heartbeat_daemon,否则得到 HeartbeatDaemonDaemon);#[forge::model] 必须是结构体上的第一个属性。
Context API
ctx.db()→ ForgeDb(一个 sqlx::Executor),可直接传给查询宏。ctx.conn().await?→ ForgeConn(事务性,仅 mutation),将&mut conn传给查询宏。ctx.user_id()→ 在 QueryContext 与 MutationContext 上返回Result<Uuid>,无主体时返回ForgeError::Unauthorized。MutationContext 上没有ctx.auth()方法。ctx.db_conn()→ DbConn,用于需在查询和变更中通用的共享辅助函数(约定相反,详见 references/patterns.md)。
让类型推断命名绑定,除非辅助函数签名需要,不要显式导入 ForgeConn / ForgeDb / DbConn。
工作流
- 定向:读取会话启动文件清单及 pitfalls.md、resilience.md,通过
frontend/package.json(Svelte)或frontend/Cargo.toml(Dioxus)检测前端。 - 规划切片:写代码前确定本次 PR 涉及的 handler、迁移与前端改动,保持外科手术式、垂直、单一功能。
- 检查点循环,一次一个 handler:用
forge new <kind> <name>生成脚手架(类型含 query、mutation、job、cron、workflow、daemon、webhook、mcp_tool、model、enum);编辑替换占位 SQL/业务逻辑;运行forge check;失败则修根因并只重跑失败步骤,不要带着错误写下一个;进入下一个 handler。 - 后端稳定后运行
forge generate,永不编辑生成文件。 - 前端:针对生成的绑定接 UI,用
forge test跑 Playwright E2E。 - 收尾:
forge check干净、forge test通过,写简短变更总结。
用户在你诊断问题后说“fix it”时直接修复,不要再次确认;仅在破坏性操作(数据删除、schema 删除、强制推送)时暂停确认。
架构默认选项
认证:社交 OAuth、密码 + HS256 或 RS256,编码前选定;社交登录必须通过 user_identities 表关联。环境变量用 ctx.env_require() / ctx.env_or(),不用 std::env::var()。HTTP 用 ctx.http(),需要 bytes_stream() 或自定义重定向策略时用 ctx.raw_http()。SQL 只用 sqlx::query!() / query_as!() 感叹号宏。任务/工作流只在 mutation 内派发(事务默认开启),不要在派发的 mutation 上设置 transactional = false。共享逻辑在两个 handler 需要时立即提取到 src/utils/。
参考文档选择
新 handler 必读 references/resilience.md;宏、上下文、错误、配置、CLI 见 references/api.md;后端模式见 references/patterns.md;可复制配方见 references/recipes.md;前端原则见 references/frontend.md;SvelteKit 见 references/frontend/svelte.md;Dioxus 见 references/frontend/dioxus.md;测试见 references/testing.md;构建或运行时调试见 references/pitfalls.md。
工程原则
为失败而设计(认证失效、实体消失、网络故障);零死代码,工作区 lint 拒绝 dead_code、unwrap_used、panic、indexing_slicing、unsafe_code;每个 PR 一个薄垂直切片;边界校验在 handler 入口完成并返回 ForgeError 变体,绝不用 unwrap/expect/panic;作用域由宏在编译期强制,私有查询必须按 user_id / owner_id 过滤,共享/管理数据用 #[query(unscoped)] 退出;事务派发编译期强制,dispatch_job 和 start_workflow 需要事务性 mutation;系统表禁止操作(forge_* 表不可 INSERT/UPDATE/DELETE),改用 dispatch_job、start_workflow、record_signal;迁移仅向前,不写 -- @down,可选 -- @up 标记会被剥离,用 SELECT forge_enable_reactivity('table_name'); 启用响应式,不用 IF NOT EXISTS;未找到处理用 fetch_optional().await?.ok_or_else(|| ForgeError::NotFound(format!(...)))。
完成输出契约
完成后报告:变更(涉及文件、处理的失败模式、新增测试含失败路径)、验证(运行的命令、阻塞项、最终 forge check 结果)、审查(韧性缺口、假设)。每个 handler 都必须能挺过认证被撤销、实体被删除、并发修改和网络中断。
限制
资料未提供该技能的收费、价格、平台、具体效果等信息。