---
title: Module 开发
description: 使用明确 Manifest、Business API 与仓库本地检查加入业务能力。
---

Module 是 Lenso 应用中的稳定业务能力。无论实现链接到 Host，还是由 Provider
Service 交付，其身份与合约都保持不变。

从一个真实工作流开始：一份强类型 Business API、对应实现，以及在 Module
缺失时必定失败的 Smoke Check。

## 使用 Rust facade

```sh
cargo add lenso --features host
```

公开 facade 提供可序列化 Module 声明、Manifest lint、HTTP Route Metadata、
Runtime Function、Event Handler、Lifecycle 声明与 Console Surface。`host` feature
会启用可运行 Host 所需的公开 HTTP 与 Linked Module Authoring Helper。

## 声明 Module

```rust
use lenso::{
    ModuleHttpMethod, ModuleHttpRoute, ModuleManifest, ModuleManifestLintSeverity,
    lint_module_manifest,
};

pub fn manifest() -> ModuleManifest {
    ModuleManifest::builder("support/tickets")
        .capabilities(vec![
            "support.tickets.read".to_owned(),
            "support.tickets.write".to_owned(),
        ])
        .http_routes(vec![ModuleHttpRoute {
            method: ModuleHttpMethod::Post,
            path: "/v1/support/tickets".to_owned(),
            capability: Some("support.tickets.write".to_owned()),
            display_name: Some("Create ticket".to_owned()),
            story_title: Some("Ticket created".to_owned()),
            operation: None,
        }])
        .build()
}

#[test]
fn manifest_lints_cleanly() {
    let issues = lint_module_manifest(&manifest());
    assert!(issues
        .iter()
        .all(|issue| issue.severity != ModuleManifestLintSeverity::Error));
}
```

Manifest 声明公开形态。`support/tickets` 是 App Composition、Module Release 与
Business API Binding 使用的完全限定业务身份。Route Handler、SQL 与 Runtime
实现仍是应用自有代码。

## 创建脚手架

```sh
lenso module create billing
```

当前脚手架命令接收可运行的非限定本地 slug。它只是通用起点，不能替代
`support/tickets` 这类产品自有的完全限定身份。

只有运维工作流确实需要独立交互 Surface 时，才加入 Module 自有 Console UI：

```sh
lenso module create billing --with-console-ui
```

生成 UI 必须作为摘要绑定的 `console_ui_esm` 制品发布在同一 Module Release
中。它通过 Surface Gateway 使用生成的 Business API Client，不会获得目标
凭据。

## 实现 Business API

Operation 名称应体现领域：`listTickets`、`createTicket`、`updateTicket` 和
`closeTicket` 描述 Support Ticket 生命周期。在已提交 OpenAPI 合约中定义
Actor、Tenant、Deadline、Idempotency、Revision 与强类型错误行为。

Linked 实现把 Route Contribution 接入 `LinkedBinding`。Provider 实现把同一
Module 发布为精确 `lenso.module-release.v1` Release，并通过
`/lenso/provider/v1` 上的 `lenso.provider.v1` 提供锁定 Runtime。兼容性
`lenso.service.v1` Manifest 携带进程与打包 Metadata，不是 Runtime Module
Discovery 或 Digest Authority。两种交付模式都不会改变 Module 名称或
Operation ID。

## 最小垂直切片

1. 声明一个 Capability 和一个 Business API Operation。
2. 实现 Route 与持久化行为。
3. 从已提交合约生成 Client。
4. 通过公开 API 添加 Smoke Check。
5. 需要 UI 时，绑定一个精确 Console Surface 与窄 Surface Grant。
6. 组合新的 `lenso.app.json` 修订，并通过 `lenso dev up` 启动。
7. 连接 Console，检查 Module 的直接状态。

## 完成标准

- Manifest lint 通过；
- 公开 Business API 完成一个有用工作流；
- Module 未被已组合应用选择并绑定时，Smoke Check 失败；
- 生成 Client 与已提交合约一致；
- 选定 Console Surface 绑定到精确 Module Release 与制品；
- 浏览器和测试都不会绕过公开 API 访问 Store。

精确声明字段参见 [Manifest Reference](/docs/zh/manifest-reference)。Surface 设计
参见 [Business API 与 Console Surface](/docs/zh/admin-surfaces)和
[Module Console UI](/docs/zh/console-packages)。可运行产品边界参见
[示例](/docs/zh/examples)。
