# 应用卡片（App Card）

**每个 Nexus 应用都有一张应用卡片**。它由平台按「清单 + 部署时的静态分析 + 通道指针 + 数据流状态 + 使用日志」自动生成——开发者不用手写，也就不会和代码对不上。一张卡片回答六个问题：

| 问题 | 卡片上的栏目 | 来自 |
| --- | --- | --- |
| 这是谁的应用？ | 负责（部门 · 岗位 / 智能体 · 负责人）、简介 | 清单 `owner`、`summary` |
| 哪个版本在线上？ | 正式 / 测试 / 最新版本号、发布记录条数 | 通道指针、发布记录 |
| 用了哪些 SDK？ | 登记的 SDK、部署时分析出的实际用到、登记了没用到 | 清单 `sdk` + 部署静态分析（用了没登记的直接拒收） |
| 连了哪些数据？ | **是否连数据库**（读写公司语义层 = 连了）、读哪些类型、能执行哪些 Action、直接写哪些类型、订阅哪些数据流（发布端在线吗）、调哪些模型 / 数据集 | 清单 `semantic` `streams` `models` `datasets` + 数据流状态 |
| 对外提供什么、依赖谁？ | 对外能力（显式导出 + 自动提取）、依赖的能力、工作流摘要（几步、怎么触发） | 清单 `exports` `workflow`（[工作流 SDK](workflow)） |
| 谁能用、用得怎么样？ | 访问范围、分享（全公司 / 指定账号 / 公开链接）、近 7 天打开 / 操作 / 反馈 / 错误 | 清单 `auth`、分享、日志 SDK |

卡片只有元数据，不含业务数据。

## 怎么看

- 应用里：顶栏「卡片」按钮（本公司成员及以上）。企业数据浏览器、部门看板、工作流画布都带；画布上每一步还能看到能力提供方的精简卡片。
- SDK：`appCard()`（缺省是当前应用，也可以 `appCard("quote-sales")`）

  ```js
  import { appCard } from "/developer/sdk/v1/aidc.js";
  const card = await appCard();
  card.data.database.connected;   // true = 读写公司语义层
  ```

- CLI：`aidc app card [slug|目录]`（Markdown 表格，方便贴进文档或交给智能体）
- API：`GET /api/v1/developer/apps/{命名空间}/{slug}/card`（公司应用：本公司成员及以上；公开应用：匿名可读，按 IP 限流）
- 应用登记表 `aidc app registry` 每行也带负责部门、对外能力与依赖。

## 开发规范（每个应用都要做到）

1. **写 `owner`**：`{ "department": "采购部", "team": "行情小兴", "contact": "张三" }`。画布按部门分泳道，卡片第一行就是它；没写显示「未登记」。
2. **写 `summary`**：一句话说清这个应用给谁用、做什么（≤ 240 字）。
3. **`sdk` 如实登记**：代码里 import 了哪些 SDK 就登记哪些——部署时静态分析，用了没登记的拒收；登记了没用到的卡片上会标出来。
4. **数据如实登记**：读写语义层的类型与 Action 写进 `semantic`，订阅的数据流写进 `streams`，调用的模型写进 `models`——票据只放行登记过的，卡片的「连了哪些数据」也照它写。
5. **想让别的应用用，就导出能力**：把本部门可以对外提供的查询 / Action 写进 `exports`（名字、参数、说明），工作流按 `<slug>/<能力名>` 调用；没写的也会按登记的类型 / Action 自动提取，但显式导出的名字和参数才是给人看的契约。
6. **版本号按 SemVer**：`version` 每次改动都升；卡片上的正式 / 测试版本号就是它。

## 字段

```json
{
  "card": 1,
  "app": { "namespace": "cell-aidc", "slug": "quote-sales", "title": "营业部 · 询价与报价（演示）", "summary": "…", "owner": { "department": "营业部", "team": "营业小兴-报价" } },
  "versions": { "live": "1.0.0", "test": "1.0.0", "latest": "1.0.0", "releases": 2 },
  "sdk": { "declared": [{ "id": "data", "name": "数据" }, …], "detected": […], "unused": [] },
  "data": {
    "database": { "connected": true, "store": "AIDC 语义层（中枢 Supabase Postgres，按公司隔离）", "reads": [{ "apiName": "demo.rfq", "title": "询价单（演示）" }], "writes": [], "actions": [{ "apiName": "demo.register_rfq", "title": "登记询价" }] },
    "streams": [{ "name": "tj8100-progress", "title": "天津 8100 生产进度", "publisher": { "status": "ok", "live": true } }],
    "datasets": [], "models": [], "storage": "none"
  },
  "capabilities": { "exports": [{ "ref": "quote-sales/rfq", "kind": "get", "title": "询价单" }], "auto": […], "uses": [] },
  "workflow": null,
  "access": { "mode": "company", "shares": { "company": 0, "users": 0, "public": 0 } },   // company | restricted（清单 auth.access）；AIDC 官方公开样板是 public
  "usage": { "last7d": { "opens": 12, "actions": 3, "feedback": 1, "errors": 0 }, "openFeedback": 1 },
  "urls": { "test": "/developer/cell-aidc/apps/quote-sales", "production": "/nexus/cell-aidc/apps/quote-sales" }
}
```
