# @qfei-design/make-app-observability 中文文档

规范地址：https://npmcn.com/package/%40qfei-design/make-app-observability/

版本：0\.1\.11
npm 元数据更新时间：2026-11-02T06:00:21.046Z
中文译文更新时间：2026-11-02T06:16:22.881Z
软件包许可：未声明

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

原始 npm 页面：https://www.npmjs.com/package/%40qfei-design/make-app-observability
原文对照：https://npmcn.com/package/%40qfei-design/make-app-observability/?lang=original

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

- 包体积（解压后）：81.5 kB，24 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.12\.0
- 运行依赖：0 个
- peer 依赖：react ^18\.2\.0 \|\| ^19\.0\.0，react-dom ^18\.2\.0 \|\| ^19\.0\.0
- 首次发布：2026-09-10T11:15:50.246Z
- 最新版本发布：2026-11-02T06:00:20.840Z
- 已发布版本数：9（近 12 个月 9 个）

## 中文简介

共享Make App错误显示和Trace ID显示合约。

## 安装

```sh
npm install @qfei-design/make-app-observability
```

也可以使用：`pnpm add @qfei-design/make-app-observability`、`yarn add @qfei-design/make-app-observability`、`bun add @qfei-design/make-app-observability`

## README

# @qfei-design/make-app-observability

Make App 统一错误展示与 Trace ID 呈现组件。它将错误卡片的布局、无障碍语义、复制反馈和 Trace ID 展示规则收敛到同一 npm 包，避免业务页面各自拼装 Toast 或 Alert。

## 包负责什么

-   提供无 React 依赖的错误呈现模型：`normalizeMakeAppErrorNotice`。
-   为所有真实请求失败展示格式正确的 Trace ID，包括 HTTP 非 2xx、网络异常和 HTTP 2xx 的业务码错误。
-   提供与 Make App 设计一致的 `MakeAppErrorNotice`：错误图标、关闭按钮、Trace ID 区、复制和“已复制”状态。
-   提供响应式、作用域限定的样式，不覆盖宿主全局 `button`、`body` 或弹层样式。
-   在当前源码版本中统一管理全局 Toast 的生命周期：默认三秒关闭，支持 `duration` 秒数与 `0` 常驻；页面内提示保持常驻。

## 宿主负责什么

-   在统一请求适配器中生成/保存 Trace ID，并把 HTTP 状态和错误类别转换为安全的用户文案。
-   页面不得直接使用 `message.error`、`Alert` 或裸 `fetch` 来呈现 Make 业务请求错误；应统一交给应用的错误出口渲染本组件。
-   在应用根节点或全局错误 Provider 中导入样式一次，并维护错误队列、业务重试和错误日志；包负责关闭计时，通过 `onClose` 通知宿主清理队列。
-   继续确保 Service 返回 `X-Log-ID`、日志带 Trace ID，且不向浏览器暴露 token 或原始内部错误。

包不发起请求、不保存 Trace ID、不记录错误日志，也不自动探测宿主 UI 框架；这些运行时边界仍由 Make App 负责。

## 安装

```bash
pnpm add @qfei-design/make-app-observability
```

在 Make App UI 入口导入一次样式：

```ts
import "@qfei-design/make-app-observability/styles.css";
```

## 使用

```tsx
import {
  MakeAppErrorNotice,
  MakeAppErrorNoticeViewport,
  type MakeAppErrorKind,
} from "@qfei-design/make-app-observability/react";

type Props = {
  kind: MakeAppErrorKind;
  status?: number;
  traceId?: string;
  visible: boolean;
  onClose: () => void;
};

export function GlobalMakeAppError(props: Props) {
  if (!props.visible) return null;

  return (
    <MakeAppErrorNoticeViewport>
      <MakeAppErrorNotice
        kind={props.kind}
        status={props.status}
        title="process/start 网络异常，请刷新后重试或更换网络后重试"
        traceId={props.traceId}
        onClose={props.onClose}
      />
    </MakeAppErrorNoticeViewport>
  );
}
```

`MakeAppErrorNoticeViewport` 在桌面和手机视口均将整个错误队列 portal 到 `document.body`，统一处理居中偏上、安全区、队列间距和超长内容滚动，避免单张卡片受宿主 `transform` containing block 影响或多张卡片相互覆盖。两端均水平居中；桌面队列默认从顶部 24px 开始向下排列，手机保持垂直居中偏上。 桌面采用顶部 Toast 定位，距顶部至少 `24px` 并避让安全区；手机队列中心相对可用视口中心向上偏移 `clamp(24px, 5vh, 48px)`。四边保留至少 `12px` 和安全区；长队列从安全区顶部开始并允许滚动。 宿主可通过容器的 `--make-app-error-center-offset` 调整手机向上偏移量（`0px` 为手机垂直居中），不需要额外的全屏定位 wrapper。 桌面卡片最大宽度 `440px`；桌面使用白底、红色左边线和紧凑标题/Trace ID 两行布局，右侧为关闭及复制图标。 手机（`640px` 及以下）沿用桌面的白底、灰色细边框、红色左边线、8px 圆角和普通等宽 Trace ID，仅增加底部双按钮：左侧「关闭」、右侧「复制」。手机卡片最大宽度 `380px`，两侧保留至少 `12px` 和安全区；按钮高度 `32px`，复制成功显示「已复制」与勾选。标题 14px，卡片留白略增，窄屏 Trace ID 自然换行。 viewport 内的卡片可带宿主 DOM wrapper，居中和卡片交互保持有效；首次服务端渲染和 hydration 保持一致，挂载后 portal 到 body。 宿主负责错误队列状态，并且一个全局错误出口只应渲染一个 viewport 容器；页面内嵌错误无需使用该容器。 viewport 默认使用 `z-index: 2000`；如果宿主的抽屉、预览或其他 overlay 层级更高，可通过 `<MakeAppErrorNoticeViewport zIndex={2400}>` 显式对齐宿主层级。portal 会脱离原宿主元素的 stacking context。

`kind` 必须明确传入：

-   `http`：存在合法 Trace ID 时显示。
-   `network`：存在合法 Trace ID 时显示，即使没有 HTTP 状态。
-   `business`：HTTP 2xx 的业务码异常同样显示合法 Trace ID，便于定位服务端校验失败。

包只消费宿主已经归一化的错误，不读取业务响应体，也不定义哪些业务 `code` 代表成功。 宿主请求层必须先判断 HTTP 状态，再在 HTTP 2xx 时继续判断业务 `code`：业务成功才返回数据， 非成功业务码应归类为 `kind: "business"`，并优先提取公共非空字符串 `msg`，按接口兼容 `message`，连同 本次请求的 Trace ID 传入组件。不得因为 HTTP 状态为 200 就直接认定业务成功。HTTP 4xx/5xx 也保留有效公共原因； 不能按错误码或固定文案白名单覆盖具体原因和联系人，缺失公共原因时才兜底。禁止的是内部堆栈、凭据、原始 Error 和完整响应对象， 不是已确认的用户可见 `msg`。详细边界与宿主验收见 [公共业务原因](https://npmcn.com/package/%40qfei-design/make-app-observability/PUBLIC_API.md#%E5%85%AC%E5%85%B1%E4%B8%9A%E5%8A%A1%E5%8E%9F%E5%9B%A0%E4%B8%8E%E5%86%85%E9%83%A8%E8%AF%8A%E6%96%AD)。

稳定入口和完整契约见 [PUBLIC\_API.md](https://npmcn.com/package/%40qfei-design/make-app-observability/PUBLIC_API.md)。

## Toast 自动关闭（当前源码改动，尚未发布）

`MakeAppErrorNoticeViewport` 默认 `duration={3}`，单位为秒。内部的全局错误卡片和权限 Toast 会在三秒后隐藏，并调用各自的 `onClose` 一次，供宿主清理对应队列项。 单条卡片的 `duration` 优先于 viewport；`duration={0}` 关闭自动计时，支持小数秒。 负数、NaN、Infinity 回退到有效的默认值。

```tsx
<MakeAppErrorNoticeViewport duration={3}>
  <MakeAppErrorNotice kind="network" title="网络异常" onClose={removeError} />
  <MakeAppPermissionNotice variant="toast" duration={5} onClose={removePermissionToast} />
</MakeAppErrorNoticeViewport>
```

无 viewport 的错误卡片默认常驻，可显式指定 `duration`；权限 `toast` 即使独立渲染也默认三秒。 权限 `inline/page` 始终常驻并忽略 `duration`。手动关闭会取消计时器；卸载不会触发关闭回调。 包自身控制隐藏，即使未提供 `onClose` 也会按时关闭；宿主应提供回调清理队列，不再另建关闭计时器。 回调只用于清理提示，不能自动保存、删除或重试请求。

每次重新触发提示，都从该次触发重新计算完整显示时长。推荐给每个事件传 `noticeKey`（字符串或数字）； 即使文案、Trace ID、关闭回调都相同，只要 `noticeKey` 改变就会重新显示并重新计时。React `key` 也可用于独立通知。

```tsx
<MakeAppPermissionNotice noticeKey={eventId} variant="toast" onClose={removePermissionToast} />
```

兼容未传 `noticeKey` 的宿主：包把新的 `onClose` 函数引用视为重新触发信号，因此现有每次通知 更换关闭回调的接入方式无需改业务代码。若宿主每次普通重渲染也创建新的回调，计时同样会重置； 需要避免这种延长时，应使用显式 `noticeKey`。显式标识不变时，管理员加载或回调更新均不会重置计时。 如果相同文案、React key、noticeKey 与关闭回调都没有变化，包无法区分新事件与普通重渲染，宿主必须改变事件标识。 回调及计时信号只在 React 提交后更新，暂停或放弃的渲染不会影响当前提示。 需要长时间阅读或复制 Trace ID 时，宿主可以配置更长时长或 `duration={0}`。 以上默认行为仅存在于当前本地源码产物，接入前应核对实际安装包，不能根据相同的版本号推断。

## 权限拒绝提示（本分支新增，尚未发布）

新增 `MakeAppPermissionNotice`，在同一包内统一 Toast、表单/内容区、页面居中三种权限提示。 已发布的 `0.1.8` 不含此 API；接入前必须确认实际安装产物导出，版本由后续发布流程确定。 原 `MakeAppErrorNotice`、Trace ID 展示/复制与 viewport 默认行为保持不变。

```tsx
import { MakeAppPermissionNotice, MakeAppErrorNoticeViewport } from "@qfei-design/make-app-observability/react";
import "@qfei-design/make-app-observability/styles.css";

// 内容区或表单内：放在原容器中，保留导航、标题和允许保留的输入。
<MakeAppPermissionNotice
  variant="inline"
  scope="resource"
  administrators={administrators}
  administratorStatus={administratorStatus}
  retryStatus={retryStatus}
  onRetry={refreshAccess}
/>

// 整个 App 无授权入口时，由宿主选择原入口的挂载位置与高度。
<MakeAppPermissionNotice variant="page" scope="app" administrators={administrators} onRetry={refreshAccess} />

// 全局 Toast 放到宿主已有的同一个错误出口，避免每个 Toast 创建 viewport。
<MakeAppErrorNoticeViewport>
  <MakeAppPermissionNotice variant="toast" operationName="导出" administrators={administrators} />
</MakeAppErrorNoticeViewport>
```

`administrators` 只接收当前 App 的直接授权人员 `{ userId, name, avatarUrl? }`，不传部门、Agent 或展开部门成员。Toast 显示姓名文字，inline/page 显示头像+姓名标签。空列表保留通用授权提示； 加载/查询失败不会展示旧联系人。姓名按文本渲染，头像允许 HTTPS 或安全站内绝对路径，加载失败用姓名首字。

宿主必须先确认是权限拒绝：401、未知403、租户不匹配和服务故障沿原错误出口处理，不能仅凭HTTP状态 使用此组件。包不请求管理员、不推断授权、不自动刷新或重试；包统一管理 Toast 关闭计时，宿主拥有队列状态。 `onRetry` 只由用户点击触发；`retryStatus` 支持 idle/checking/denied/error/restored，checking 禁用重复检查，denied 保留原授权引导而不追加重复提示， restored 只展示恢复结果，不重放导出/保存/删除。宿主刷新权限和授权后 Schema，再决定是否读取数据或允许用户重新操作。 只撤销记录读取权限时，由宿主清空旧行数据并把 inline 提示放在数据区，保留已授权表头和导航。

新增样式都同时限定在 `.make-app-error-notice.make-app-error-notice--permission`，不会改变原错误卡片。 可在新组件根节点通过 `style`/`className` 设置 `--make-app-permission-primary`、 `--make-app-permission-primary-hover`、`--make-app-permission-text` 和 `--make-app-permission-muted`。

本地视觉示例：先 `pnpm build`，再 `pnpm dev`，打开 `/examples/permission-notice/`。 示例通过公开包入口加载构建产物，用夹具演示三种样式、管理员和刷新状态，可与原错误卡片共同展示；不请求真实 IAM。

## 常见问题

### @qfei-design/make-app-observability 是什么？

共享Make App错误显示和Trace ID显示合约。

### 如何安装 @qfei-design/make-app-observability？

在项目目录运行 npm install @qfei-design/make-app-observability，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（^18\.2\.0 \|\| ^19\.0\.0）、react-dom（^18\.2\.0 \|\| ^19\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @qfei-design/make-app-observability 支持 TypeScript 吗？

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

### @qfei-design/make-app-observability 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @qfei-design/make-app-observability 需要什么版本的 Node\.js？

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

### @qfei-design/make-app-observability 可以商用吗？

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

### @qfei-design/make-app-observability 还在维护吗？

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

