# @lark-apaas/fullstack-cli

> Fullstack 开发工具集 - 文件派生、数据库 Schema 生成、OpenAPI 生成、能力管理、构建工具

## 功能

1. **自动派生** - 自动管理项目脚本和配置文件
2. **数据库 Schema 生成** - 从现有数据库生成 Drizzle ORM schema
3. **OpenAPI 生成** - 自动生成 API 文档和客户端 SDK
4. **Action 插件管理** - 安装、更新、删除 action 插件
5. **能力配置管理** - 查看、充血、迁移能力配置
6. **构建工具** - 获取 STI 制品上传凭证等构建相关操作

## 安装

```bash
npm install --save-dev @lark-apaas/fullstack-cli
```

## 使用

### 1. 自动派生

每次运行 `npm install` 时，会自动派生文件到项目：

**派生内容：**
- `scripts/` - Shell 脚本目录（总是覆盖）
- `.gitignore` - 追加 fullstack-cli 相关忽略规则

⚠️ **`scripts/` 目录由 CLI 自动管理，请勿手动修改！**

### 2. 生成数据库 Schema

从现有数据库生成 Drizzle ORM schema：

```bash
npm run gen:db-schema
```

**环境变量配置：**
```bash
# 必需
SUDA_DATABASE_URL=postgresql://user:pass@host:port/dbname?schema=public

# 可选
DB_SCHEMA_OUTPUT=server/database/schema.ts  # 输出路径
DRIZZLE_SCHEMA_FILTER=public,custom         # Schema 过滤器
DRIZZLE_TABLES_FILTER=users,orders          # 表过滤器
```

**工作流程：**
1. 从 `SUDA_DATABASE_URL` 读取数据库连接
2. 使用 CLI 内置的 `drizzle.config.ts`（用户无需维护）
3. 执行 `drizzle-kit introspect`
4. 后处理 schema（通过 devtool-kits）
5. 输出到 `server/database/schema.ts`

### 3. 生成 OpenAPI 文档

自动生成 OpenAPI 文档和客户端 SDK：

```bash
npm run gen:openapi
```

**环境变量配置：**
```bash
# 可选
APP_MODULE_PATH=server/app.module    # AppModule 路径（不含扩展名）
CLIENT_BASE_PATH=/                   # 客户端基础路径
```

**工作流程：**
1. 动态导入用户项目的 `AppModule`
2. 挂载 DevToolsModule
3. 生成 OpenAPI 文档和客户端 SDK

### 4. Action 插件管理

管理 Action 插件的安装、更新、删除和查看：

```bash
# 安装插件（默认最新版）
fullstack-cli action-plugin install @office/feishu-create-group

# 安装指定版本
fullstack-cli action-plugin install @office/feishu-create-group@1.0.0

# 更新插件到最新版
fullstack-cli action-plugin update @office/feishu-create-group

# 删除插件
fullstack-cli action-plugin remove @office/feishu-create-group

# 查看已安装的插件列表
fullstack-cli action-plugin list
```

**命令别名：**
| 完整命令 | 别名 |
|----------|------|
| `action-plugin install` | `action-plugin i` |
| `action-plugin update` | `action-plugin up` |
| `action-plugin remove` | `action-plugin rm` |
| `action-plugin list` | `action-plugin ls` |

**插件存储：**
- 插件文件：`node_modules/<plugin-name>/`（标准 npm 包位置）
- 配置文件：`.capabilityrc.json`（记录已安装的 action 插件元信息）

### 5. 能力配置管理

查看和管理项目中的能力配置：

```bash
# 列出所有能力（充血后，带 actions 信息）
fullstack-cli capability list

# 列出所有能力（原始配置，不充血）
fullstack-cli capability list --summary

# 获取指定能力配置
fullstack-cli capability list --id create_feishu_group_for_task

# 获取指定能力原始配置
fullstack-cli capability list --id create_feishu_group_for_task --summary
```

**能力充血：**
- 默认返回充血后的能力配置，包含从插件 manifest 读取的 actions 信息
- 支持动态 Schema：manifest 中标记 `{ dynamic: true }` 的 schema 会运行时生成
- Schema 优先级：`capability.paramsSchema > 动态 schema > 静态 schema`
- 充血失败时返回原始配置 + `_hydrateError` 字段（不抛异常）
- `--summary` 返回原始配置（存储在 `server/capabilities/*.json` 中的内容）

### 6. 能力迁移

将老版本 capability 配置（`capabilities.json`）迁移到新版本（独立 JSON 文件）：

```bash
# 执行迁移
fullstack-cli capability migration

# 预览模式（不修改文件）
fullstack-cli capability migration --dry-run

# 跳过插件安装
fullstack-cli capability migration --skip-install

# 跳过代码迁移
fullstack-cli capability migration --skip-code
```

**迁移步骤：**

1. **JSON 文件迁移**
   - 读取 `server/capabilities.json`（老格式：数组）
   - 转换为独立文件 `server/capabilities/<id>.json`（新格式）
   - 自动备份原文件为 `capabilities.json.backup`

2. **插件安装**
   - 根据 `sourceActionID → pluginID` 映射表查找对应插件
   - 自动调用 `fullstack-cli action-plugin install` 安装缺失的插件

3. **代码迁移**
   - 扫描 `server/` 目录下的 TypeScript 文件
   - 移除 capability 直接导入 `import xxx from '@/capabilities/xxx'`
   - 添加 `CapabilityService` 依赖注入
   - 替换调用点为 `capabilityService.load('xxx').call('run', params)`

**老格式 vs 新格式：**

```typescript
// 老格式 (capabilities.json)
{
  "id": "create_group",
  "sourceActionID": "feishu_group_create",  // 老字段
  "name": "创建群组",
  "desc": "创建飞书群组",                    // 老字段
  "actionInput": { ... },                    // 老字段
  "inputSchema": { ... }
}

// 新格式 (server/capabilities/create_group.json)
{
  "id": "create_group",
  "pluginID": "@official/feishu-group",      // 新字段
  "pluginVersion": "1.0.0",                  // 新字段
  "name": "创建群组",
  "description": "创建飞书群组",             // 重命名
  "formValue": { ... },                      // 重命名
  "paramsSchema": { ... }
}
```

**映射文件格式：**

```json
{
  "feishu_group_create": "@official/feishu-group",
  "feishu_send_message": "@official/feishu-message"
}
```

### 7. 构建工具

获取构建流程所需的 STI 制品上传凭证：

```bash
# Pipeline 发布场景 - 需要 commit-id
fullstack-cli build get-token --app-id app_xxx --scene pipeline --commit-id abc123

# 静态资源部署场景
fullstack-cli build get-token --app-id app_xxx --scene static
```

**参数说明：**

| 参数 | 必填 | 说明 |
|------|------|------|
| `--app-id <id>` | 是 | 应用 ID |
| `--scene <scene>` | 是 | 构建场景（`pipeline`、`static`） |
| `--commit-id <id>` | scene=pipeline 时必填 | Git Commit ID |

**输出：** stdout 输出 API 返回的完整 JSON，日志/错误输出到 stderr，便于脚本解析：

```bash
token_response=$(fullstack-cli build get-token --app-id "$APP_ID" --scene pipeline --commit-id "$COMMIT_ID")
credential=$(echo "$token_response" | jq -r '.data.accessKeyID')
```

**环境变量：**
- `FORCE_AUTHN_INNERAPI_DOMAIN` — API 域名
- `FORCE_AUTHN_ACCESS_KEY` — Access Key
- `FORCE_AUTHN_ACCESS_SECRET` — Secret Key
- `FORCE_FRAMEWORK_CLI_CANARY_ENV` — Canary 环境（可选）

### 8. CLI 命令

```bash
# 查看帮助
fullstack-cli --help

# 生成数据库 schema
fullstack-cli gen-db-schema

# 生成 OpenAPI
fullstack-cli gen-openapi

# Action 插件管理
fullstack-cli action-plugin --help
fullstack-cli action-plugin install <plugin>
fullstack-cli action-plugin list

# 能力配置管理
fullstack-cli capability --help
fullstack-cli capability list
fullstack-cli capability migration --dry-run

# 构建工具
fullstack-cli build --help
fullstack-cli build get-token --app-id <id> --scene <scene> [--commit-id <id>]

# 查看版本
fullstack-cli --version
```

### 9. 全局选项

#### Canary 环境

支持通过 `--canary` 选项指定 canary 环境，会在 HTTP 请求中添加 `x-tt-env` header：

```bash
# 通过命令行参数指定
fullstack-cli --canary boe_canary action-plugin install @office/feishu-create-group

# 也可以放在命令后面
fullstack-cli action-plugin install @office/feishu-create-group --canary boe_canary
```

也支持通过环境变量设置：

```bash
FORCE_FRAMEWORK_CLI_CANARY_ENV=boe_canary fullstack-cli action-plugin install @office/feishu-create-group
```

## package.json 配置

在用户项目的 `package.json` 中添加：

```json
{
  "scripts": {
    "gen:db-schema": "fullstack-cli gen-db-schema",
    "gen:openapi": "NODE_ENV=development DEPRECATED_SKIP_INIT_DB_CONNECTION=true fullstack-cli gen-openapi"
  },
  "devDependencies": {
    "@lark-apaas/fullstack-cli": "^0.1.0",
    "drizzle-kit": "^0.20.0"  // 如果使用数据库功能
  }
}
```

## 技术细节

### 派生配置

派生规则在 `src/postinstall.config.ts` 中定义：

```typescript
export default {
  sync: [
    {
      from: 'templates/scripts',
      to: 'scripts',
      type: 'directory',
      overwrite: true,
    },
    {
      from: 'templates/.gitignore.append',
      to: '.gitignore',
      type: 'append',
    },
  ],
  permissions: {
    '**/*.sh': 0o755,
  },
};
```

### Drizzle 配置

CLI 内置 `templates/drizzle.config.ts`，通过环境变量动态配置：
- 用户**无需**维护 `drizzle.config.ts`
- 所有配置通过环境变量传递
- 使用绝对路径指向用户项目

### OpenAPI 生成

- 动态导入用户的 `AppModule`
- 使用 `@lark-apaas/fullstack-nestjs-core` 的 DevToolsModule
- 自动生成客户端 SDK

## 依赖关系

```
fullstack-cli
  ↓ 依赖
@lark-apaas/devtool-kits (核心逻辑)

用户项目 peerDependencies:
  - @nestjs/core (用于 gen-openapi)
  - @lark-apaas/fullstack-nestjs-core (用于 gen-openapi)
  - drizzle-kit (用于 gen-db-schema，可选)
```

## 升级说明

### 从旧版本迁移

**可以删除的文件：**
- ❌ `scripts/gen-db-schema.ts` - 已内置到 CLI
- ❌ `scripts/gen-openapi.ts` - 已内置到 CLI
- ❌ `drizzle.config.ts` - 已由 CLI 管理

**更新 package.json：**
```diff
{
  "scripts": {
-   "gen:db-schema": "ts-node scripts/gen-db-schema.ts",
+   "gen:db-schema": "fullstack-cli gen-db-schema",
-   "gen:openapi": "nest start --entryFile ../scripts/gen-openapi",
+   "gen:openapi": "fullstack-cli gen-openapi"
  }
}
```

### Capability 迁移

如果项目使用老版本的 capability 系统（`capabilities.json` 文件），可以使用迁移命令自动升级：

```bash
# 1. 先预览迁移效果
fullstack-cli capability migration --dry-run

# 2. 确认无误后执行迁移
fullstack-cli capability migration
```

迁移会自动完成：
- JSON 配置文件格式转换
- 插件安装
- 代码调用方式更新（从直接导入改为 CapabilityService 注入）

## License

MIT
