---
title: "应用描述与运行时"
description: "application.json 字段、可选界面、权限与 createApplication 运行契约。"
canonical_url: "https://docs.mcent.cn/qicore/application-manifest"
---
# 应用描述与运行时

> application.json 字段、可选界面、权限与 createApplication 运行契约。

`application.json` 描述可安装应用的身份和产物。服务端入口返回运行定义与工厂；装配器核对两者，不从 HTTP 请求选择导入路径。

## 最小描述

以下为仅提供服务端的完整描述示例：

```json
{
  "format": "qicore-application-v1",
  "key": "notes-app",
  "packageKey": "app_notes_demo",
  "version": "0.1.0",
  "name": "笔记示例应用",
  "pendingTasks": []
}
```

示例标识用于说明字段，真实应用使用自己的持久业务身份和已登记包身份。

<table>
<thead>
  <tr>
    <th>
      字段
    </th>
    
    <th>
      约束与用途
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        format
      </code>
    </td>
    
    <td>
      应用固定为 <code>
        qicore-application-v1
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        key
      </code>
    </td>
    
    <td>
      业务作用域标识，2—64 位，小写字母开头，其后为小写字母、数字或连字符
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        packageKey
      </code>
    </td>
    
    <td>
      安装、授权和版本定位标识，2—64 位，小写字母开头，其后为小写字母、数字或下划线
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        version
      </code>
    </td>
    
    <td>
      <code>
        主版本.次版本.修订号
      </code>
      
       三段数字，独立于框架版本
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        name
      </code>
    </td>
    
    <td>
      1—100 字符，必须与服务端定义一致
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pendingTasks
      </code>
    </td>
    
    <td>
      必填数组；无持久任务时为 <code>
        []
      </code>
      
      ，最多 30 项
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        web
      </code>
    </td>
    
    <td>
      可选的后台、H5、小程序产物声明
    </td>
  </tr>
</tbody>
</table>

`tenant`、`admin`、`platform`、`public`、`system` 是保留业务标识。描述采用严格字段校验，不能把服务端能力对象或任意自定义字段放到顶层 JSON。

`key` 与 `packageKey` 的对应关系是持久身份。改显示名称、升级、卸载或重新选择开发目录，都不能用另一个包接管旧 key，也不能用新 key 接管同一包的数据。

## 服务端入口

最小入口可从 SDK 的 `templates/application-package` 取得。以下示例只证明服务端装配，不提供业务路由：

```js
import descriptor from './application.json' with { type: 'json' }

export function createApplication(sdk) {
  if (sdk?.version !== 1) throw Error('APPLICATION_SDK_UNSUPPORTED')
  const { Fault } = sdk.api
  const notFound = () => { throw new Fault('NOT_FOUND', '接口不存在', 404) }

  return {
    format: descriptor.format,
    version: descriptor.version,
    definition: {
      key: descriptor.key,
      name: descriptor.name,
      licensePackageKey: descriptor.packageKey,
      permissions: [],
      defaultConfig: () => ({}),
      validateConfig(value) {
        if (!value || typeof value !== 'object' ||
            Array.isArray(value) || Object.keys(value).length) {
          throw new Fault('NOTES_CONFIG_INVALID', '请检查配置字段')
        }
        return {}
      }
    },
    createRuntime({ db, storage }) {
      return {
        key: descriptor.key,
        consumerPaths: [],
        connect() {}, initialize() {}, tick() {},
        admin: notFound, consumer: notFound,
        health: () => true,
        close() {}
      }
    }
  }
}
```

实际入口可借用 `db` 和已绑定当前应用的 `storage`。共享资源归宿主管理；工厂和 `close()` 不创建或断开另一套宿主数据库。

## definition 与权限

`definition` 必须提供 `key/name/licensePackageKey/permissions/defaultConfig/validateConfig`。可选公共能力适配器在服务端定义中提供，方法签名见[服务端 SDK](https://docs.mcent.cn/qicore/server-sdk)。

`permissions` 是应用内权限名，如 `notes.read`、`notes.write`；当前格式要求至少包含一处分段点。权限不得重复，最多 200 项。对外完整授权名包含应用前缀，例如 `notes-app:notes.read`。

`permissionLabels` 可为真实权限提供名称。声明权限不等于给所有用户授权，后端仍须逐次核验当前会话、租户、应用、角色和资源归属。

## consumerPaths 与生命周期

`consumerPaths` 声明业务接口的一级路径，如 `["notes"]`。每项以小写字母开头，只包含小写字母、数字或连字符；`dev` 被保留。公共客户端路径由宿主处理，业务应用应使用自己的路径。

运行时必须提供 `connect`、`initialize`、`tick`、`admin`、`consumer`、`health` 和 `close`；健康检查必须明确返回 `true`。各方法的调用与恢复责任见[生命周期与打包](https://docs.mcent.cn/qicore/lifecycle-and-packaging)。

## 可选界面声明

只有实际构建出对应产物时，才把下列片段合并到描述：

```json
{
  "web": {
    "admin": {
      "entrypoint": "web/admin/server/index.mjs",
      "publicDir": "web/admin/public",
      "routes": [{
        "path": "/tenant/notes",
        "label": "笔记",
        "permission": "notes.read",
        "group": "content",
        "icon": "i-lucide-layout-grid"
      }]
    },
    "h5": { "directory": "web/h5" },
    "miniProgram": {
      "directory": "web/mini-program",
      "manifest": "web/mini-program/mini-program-template.json"
    }
  }
}
```

使用此后台片段时，`definition.permissions` 同时声明 `notes.read`。后台路由为 `/tenant/<单段路径>`，同一应用内不重复，不能覆盖登录、用户、角色、渠道、钱包等宿主保留页。

后台 routes 为 1—40 项；group 支持 `workbench/users/production/transactions/materials/content/decoration/channels/permissions/settings`。icon 必须使用 SDK 校验器允许的已有图标。

不同应用可以声明相同业务页面路径，宿主按服务端核验后的当前租户应用分发。后台 SSR、客户端身份和资源路径分别核对，不能仅凭浏览器传入的应用编号授权。

## 声明持久任务

每个 `pendingTasks` 项包含表名 `table`、状态列 `statusColumn` 和 1—20 个 `pendingStates`；可选 `tenantIdColumn`、`applicationKeyColumn` 用于限定范围。

表名和列名只能使用校验器接受的 SQL 标识符，不接受 SQL 表达式。任务未完成时会影响切换或卸载；声明检查不会替应用执行任意清理 SQL。


## Sitemap

See the full [sitemap](https://docs.mcent.cn/sitemap.md) for all pages.
