# @chaimp-org/feedback-ado 中文文档

规范地址：https://npmcn.com/package/%40chaimp-org/feedback-ado/

版本：0\.9\.0
npm 元数据更新时间：2026-11-05T23:30:36.597Z
中文译文更新时间：2026-11-09T09:26:13.105Z
软件包许可：未声明

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40chaimp-org/feedback-ado
原文对照：https://npmcn.com/package/%40chaimp-org/feedback-ado/?lang=original
项目主页：https://github.com/ChAImpNPO/portal#readme
源码仓库：https://github.com/ChAImpNPO/portal

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：88.4 kB，5 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：2 个
- 首次发布：2026-07-22T00:30:23.551Z
- 最新版本发布：2026-11-05T23:30:36.391Z
- 近 30 天下载量：3650（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：6（近 12 个月 6 个）

## 中文简介

ChAImp SaaS 通用反馈引擎——通过Vercel OIDC → Entra Federation(无秘密)将β反馈作为Azure DevOps工作项目存档.

## 安装

```sh
npm install @chaimp-org/feedback-ado
```

也可以使用：`pnpm add @chaimp-org/feedback-ado`、`yarn add @chaimp-org/feedback-ado`、`bun add @chaimp-org/feedback-ado`

## README

# @chaimp-org/feedback-ado (英语)

这个 **ChAImp SaaS 通用反馈引擎** - 每个产品一个实施 安装将用户的β反馈变成 **Azure DevOps 工作项目**, (中文(简体) ), 由产品Entra认证 **应用程序注册** 结束 **韦塞尔 OIDC 联邦** (没有秘密存放在任何地方).

## 为什么

每个产品都有(或需要)自己的"feedback ~ tracker"的复制品. 这是 单一、共享、经核实的执行:Bug/User-Story拆分、Markdown机构、, 标记、优先支持的路由,以及一个从未有过的弹性最佳呼叫 抛出(产品 DB 行保持真实的来源).

## 安装

```bash
pnpm add @chaimp-org/feedback-ado
```

## 使用量

在服务器路由中, 构建工作项目, 并将其存档 下级 `waitUntil` (一个赤裸的火与忘却的许诺在服务器无时被冻结) 在 ADO 创建完成前返回响应 :

```ts
import { waitUntil } from "@vercel/functions";
import { adoApiEnabled, buildFeedbackWorkItem, createAdoWorkItem } from "@chaimp-org/feedback-ado";

// ... after persisting the feedback row (source of truth) ...
if (adoApiEnabled()) {
  waitUntil(
    createAdoWorkItem(
      buildFeedbackWorkItem({
        category: parsed.category,        // "bug" → Bug, else User Story
        message: parsed.message,
        orgName: ctx.org.name,
        orgSlug: ctx.org.slug,
        userEmail: ctx.userEmail,
        plan: ctx.org.plan,
        page: parsed.page,
        priority: isPro,                  // ⚡ + Priority 1 + priority-support tag
        envLabel: process.env.NEXT_PUBLIC_ENV_LABEL,
      }),
    ).catch(() => {}),
  );
}
```

`buildFeedbackWorkItem` 是可选的——呼叫 `createAdoWorkItem(item)` 直接,如果 您想要自己塑造工作项目.

## 先通过ATFS(0.5.0)

`submitFeedback` 将反馈发送给门户的 ATFS 接收器 (单位:千美元)`POST /api/atfs/intake`) (中文(简体) ). 传送门对它进行分解并归档. 当传送门 肯定没有接受反馈, `submitFeedback` 直接在 ADO 中存档, 如 在0.4中,它从不扔.

```ts
import { waitUntil } from "@vercel/functions";
import { submitFeedback } from "@chaimp-org/feedback-ado";

waitUntil(
  submitFeedback(
    {
      category: parsed.category,
      message: parsed.message,
      product: "cartoncrew",
      orgId: ctx.org.id,            // the product's org id (the portal's tenant external_ref)
      orgName: ctx.org.name,
      orgSlug: ctx.org.slug,
      userEmail: ctx.userEmail,
      page: parsed.page,
    },
    { idempotencyKey: feedbackRow.id }, // your stored row id: a re-submit is then safe too
  ).then((r) => {
    if (!r.ok) console.warn("[feedback]", r.via, r.reason); // r.reason never holds a token
  }),
);
```

结果:

| `via` | `ok` | 含义 |
| --- | --- | --- |
| `atfs` | 真实 | 门户保存了下来. 没有直接归档 |
| `ado` | 真实 | 直接存档 . `reason` 说明为什么( 门户没有配置, ATFS 关闭, 无法到达, 拒绝) |
| `ado` | 虚假 | 门户网站没有接收, 而直接归档也失败了 |
| `uncertain` | 虚假 | 门户 **可能** 已贮藏了它,没有再试了。 没有直接提交,所以不能提交两次。 保持行并再次提交 稍后用同样的 `idempotencyKey` |

**无二相相相法相.** 直接归档只在门户时发生 绝对没有存储提交文件。 这意味着其中之一发生了:

-   门户没有配置;
-   传送门已回复 `accepted: false`· ;
-   在未知结果出现之前, 连接从未打开或传送门返回到 4xx (英语).

503是拒绝 只有当它的身体是 摄取者自己的JSON拒绝 (单位:千美元)`accepted: false`; 平台上的光线503或代理未知(0.7.0). 请求出道后的超时时间未知,重设和500,502或 504. 正在重新审理一个未知结果 **不变** 一能之钥. 门户保存 每个产品每个密钥一个项目,所以重试返回所储存的项目。 一旦有任何尝试 但不知道,只有门户的明确答复才能解决结果。 直接 倒置文件被标记 `atfs-fallback`。 。 。 .

**直接备案为一等功(0.7.0).** 直接归档带有标签 `fbk-<hash>` (单位:千美元)`idemKeyTag(key)`: SHA-256中最早的32个十六进制字符 单能键)。 在它创建之前,它寻找一个带有由WIQL标记的项目. 如果一个 ,该 id 以 `duplicate: true` 并且没有存档。 如果检查 失败, 没有文件, 结果就是 `ok: false`; 稍后再次提交相同的文件 键.

选项 : `idempotencyKey` (默认:随机UUID), `portal` (覆盖地洞;通过) `null` 跳过传送门, `retries` (违约2), `timeoutMs` (默认15000,以上) undici的10 s连接超时, `retryDelayMs` (违约500起), `surface`,加上每个 `createAdoWorkItemId` 选项.

## 配置(环境)

每个产品都有相同的可变名称;将其设置在产品的Vercel中 项目(和 `.env.secrets.local` 当地PAT倒计时:

| 瓦尔 | 目的 |
| --- | --- |
| `ADO_ORG` | 组织,例如:. `chaimporg` |
| `ADO_PROJECT` | 项目,例如:. `One` |
| `ADO_AREA_PATH` | **按产品需要**,比如说. `One\SaaS\<slug>` (缺省项目) |
| `ADO_TENANT_ID` | Entra 目录( 租户) id —— 首选的认证 |
| `ADO_CLIENT_ID` | Entra 应用程序( 客户端) id —— 首选认证 |
| `ADO_PAT` | **仅本地倒计时**; 当 `ADO_TENANT_ID`编号 :`ADO_CLIENT_ID` 未设定 |
| `ATFS_INTAKE_URL` | 0.5.0: 门户基础 URL, https(例如) `https://portal.chaimp.org`) (中文(简体) ). 未设置仅意味着直接归档 |
| `ATFS_INTAKE_TOKEN` | 0.5.0:本产品摄取代币. 门户持有与 `ATFS_INTAKE_TOKEN_<SLUG>`这是一个秘密,所以只保留在Vercel env |

### 首选认证——Vercel OIDC联合会(保密)

1.  启用 **OIDC 联合会** 在Vercel项目.
2.  在应用程序注册时,加一个 **联邦证书**: 发行者 `https://oidc.vercel.com/<team>`,主题 `owner:<team>:project:<vercel-project>:environment:<env>`,观众 `api://AzureADTokenExchange`。 。 。 .
3.  将服务主机添加到 ADO ORG 中 **贡献** 在区域路径.

包交换所注入的 `VERCEL_OIDC_TOKEN` azure DevOps 访问权限 符号( 资源) `499b84ac-…/.default`)通过 `@azure/identity`是因为 `ClientAssertionCredential`。没有隐藏秘密.

## 冲浪(产品与舞台)

发动机和有效载荷共享; **如何在UI中显示反馈是唯一 不同的东西** 在产品之间(复制/花粉、类别、放置),因此 配置 不是代码 声明a `FeedbackSurface` 每个产品:

```ts
const surface: FeedbackSurface = {
  product: "knowledgeretention",
  stage: "beta",                       // "ga" once it graduates — no code change
  title: "Beta feedback",              // GA products: "Send feedback" / "Help & feedback"
  categories: [
    { value: "bug", label: "Report a bug", isBug: true },
    { value: "idea", label: "Suggest something" },
    { value: "general", label: "General" },
  ],
  placement: "beta-badge",             // GA: "help-menu" | "footer" | "nav"
};

createAdoWorkItem(buildFeedbackWorkItem({ category, message, /* … */ }, surface));
```

`product` + 键 `stage` 流入工作项目 **标记** (单位:千美元)`beta`编号 :`ga`,产品弹)和 机体,因此分解区分 KR β bug 从卡通Crew GA bug(在 区域路径)。 "Beta"不是特例——这是 `stage`。 。 。 .

## API 密码

-   `submitFeedback(input, opts?): Promise<SubmitFeedbackResult>` (0.5.0)先将反馈发送给门户的ATFS摄取. 只有当门户绝对没有储存时,才直接归档(见上文).
-   `idemKeyTag(key): string` (0.7.0)——带有一能键的ADO标记.
-   `atfsIntakeConfig(): AtfsPortalConfig | null` (0.5.0)改为: `ATFS_INTAKE_URL` + 键 `ATFS_INTAKE_TOKEN`。 。 。 .
-   `adoApiEnabled(): boolean` – 足以显示配置文件( 如跳过; DB 是真相的来源) .
-   `createAdoWorkItem(item): Promise<boolean>` ——文件一个工作项目;从不丢出.
-   `createAdoWorkItemId(item, opts?): Promise<number | null>` 相同,但还原新的 工作项目 id (在任何失败时取消). `opts.idempotencyKey` (0.7.0)使它具有以下能力: 已标记的项目 `idemKeyTag(key)` 返回,而不是提交第二个. `opts.identity` (单位:千美元)`{ tenantId, clientId }`(d) 认证 作为不同的应用程序注册(例如,最不优惠的备案人), `opts.parentId` 添加 父为 `Hierarchy-Reverse` 关系(从未作为字段), `opts.areaPath` 覆盖 `ADO_AREA_PATH`, (中文(简体) ), `opts.iterationPath` 套装 `System.IterationPath`, (中文(简体) ), `opts.assignedTo` 套装 `System.AssignedTo` (显示名称), `opts.onFailure(reason)` 被告诉一个简短的无秘密 理由,当没有提交, `opts.fetchImpl` 为测试注入运输工具。 全体 选项是可选的;省略它们会保持先前的行为。 自0.6.0 a起 **错误** 将Markdown的正文放在两个步骤中 `System.Description` (董事会要求 描述除测试外的每个项目;用户故事不变.
-   `buildFeedbackWorkItem(input, surface?): WorkItemInput` ——共享房屋风格(标题,Markdown body,标签,优先级);可选 `surface` 驱动 Bug/Story映射并携带出品+级. 自0.8.0起,身体随标题而打开 `**Feedback** (the sender's own words, as typed; not verified):` 和消息作为块引用(每行前缀) `>` 每一分行形式都造出一条新线, `<` 逃脱了,那么 `---` 和元数据列表。 键入 `- **Env:** production` 线条保留在引文内,所以唯一未引用的元数据行是软件包自己的. 每个元数据值都保留在一条行上,其Markdown字符逃出. 标题是信息中最简单的第一道非空行,从来不是被引用的正文. 可选 `title` 输入( 平面文本、 被产品擦除、 从未逃脱; 控制字符和换行符成为空格; 最多120个字符) give `[category] slug: <title>` ,然后作为 `subject`曲吉主题. **部署命令:** 门户网站必须在产品发送前运行0.166.0或更晚 `title`; 一个旧的门户拒绝未知 `subject` (400个)和 `submitFeedback` 然后直接在 ADO 中归档项目 (`atfs-fallback`)),所以它从未丢失或两次存档,但跳过ATFS分录. 自0.9.0起(AB#16958),每一条被引用的行也是完全被逃脱的,因此消息从字面上使: `&` 财务报告和审定财务报表 `<` 成为实体, Markdown 字符 (``\ ` * _ [ ] ( ) ! > ~ | # $ @``)是反斜-被逃脱的,a `.` 或者说 `:` 在 URL 中,域名或电子邮件地址被跳出,因此没有自动链接,行首的列表,标题或设置ext标记被跳出. 没有键入链接、图像、 强调、 代码、 标题、 列表、 切换、 实体或 HTML 生成, 发件人选择的 URL 中没有任何负载 。 元数据值也逃脱 `&` 财务报告和审定财务报表 `~`。 。 。 . **发送纯文本 :** 文本一个产品已脱逃(`\-`, (中文(简体) ), `&lt;`现在显示它的后鞭和实体。 消息衍生标题最多保持了70个代码点,因此切口处的emoji从不被分拆. ATFS收录路径不变:它以纯文本的形式接收消息.
-   `quoteUntrusted(text): string` ——上面使用的被逃出块状引文,用于构建自己身体的产品(0.8.0;自0.9.0起被完全逃出.
-   `resolveType(category, surface?): WorkItemType` —— Bug vs 类用户故事( 使用表面) `categories`编号 :`isBug`; 默认为 `category === "bug"`) (中文(简体) ).
-   类型 : `FeedbackSurface`, (中文(简体) ), `FeedbackCategory`, (中文(简体) ), `FeedbackStage`, (中文(简体) ), `FeedbackInput`, (中文(简体) ), `WorkItemInput`, (中文(简体) ), `WorkItemType`。 。 。 .

## 常见问题

### @chaimp-org/feedback-ado 是什么？

ChAImp SaaS 通用反馈引擎——通过Vercel OIDC → Entra Federation\(无秘密\)将β反馈作为Azure DevOps工作项目存档\.

### 如何安装 @chaimp-org/feedback-ado？

在项目目录运行 npm install @chaimp-org/feedback-ado，或使用 pnpm add / yarn add / bun add。

### @chaimp-org/feedback-ado 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @chaimp-org/feedback-ado 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @chaimp-org/feedback-ado 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=20。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @chaimp-org/feedback-ado 可以商用吗？

@chaimp-org/feedback-ado 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @chaimp-org/feedback-ado 的下载量有多少？

根据 npm 官方下载统计，@chaimp-org/feedback-ado 在 2026/10/10 – 2026/11/08 这 30 天内被下载 3,650 次，日均约 122 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @chaimp-org/feedback-ado 还在维护吗？

最新版本 0\.9\.0 发布于 2026/11/06（3 天前）；至今共发布 6 个版本，其中过去 12 个月发布了 6 个；首次发布于 2026/07/22。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

