TTeamDesk 学习手册

scripts/deployment-smoke.mjs

此代码来自构建时的仓库快照。修改源码后重新构建即可更新。

mjs
import { randomUUID } from 'node:crypto';
import assert from 'node:assert/strict';

// 仅在一次性验收部署上运行:创建测试账号和业务数据,不连接现有生产实例。
if (process.env.SMOKE_ALLOW_CREATE !== '1' || !process.env.SMOKE_BASE_URL)
  throw new Error(
    '请显式设置 SMOKE_ALLOW_CREATE=1 和 SMOKE_BASE_URL,目标必须为验收环境',
  );
const base = process.env.SMOKE_BASE_URL;
let cookie = '';
async function request(path, body) {
  const response = await fetch(`${base}${path}`, {
    method: body ? 'POST' : 'GET',
    headers: {
      'Content-Type': 'application/json',
      Origin: base,
      Cookie: cookie,
    },
    ...(body ? { body: JSON.stringify(body) } : {}),
    signal: AbortSignal.timeout(10000),
  });
  const cookies = response.headers.getSetCookie();
  if (cookies.length)
    cookie = cookies.map((value) => value.split(';')[0]).join('; ');
  assert(response.ok, `验收请求失败:${path} (${response.status})`);
  return response;
}
async function rpc(method, body) {
  return (await (await request(`/api/trpc/${method}`, body)).json()).result
    .data;
}
await request('/api/health');
await request('/api/auth/sign-up/email', {
  email: `smoke-${randomUUID()}@example.com`,
  name: '部署验收',
  password: randomUUID(),
});
assert(cookie, '注册后应建立会话');
const team = await rpc('team.create', { name: '一次性部署验收团队' });
await rpc('ticket.create', {
  teamId: team.id,
  title: '容器异步导出验收',
  description: '验证生产镜像中的独立 Worker 与数据库',
  priority: 'NORMAL',
});
const task = await rpc('task.createExport', { teamId: team.id, filters: {} });
let completed = false;
for (let attempt = 0; attempt < 30; attempt++) {
  const query = encodeURIComponent(
    JSON.stringify({ teamId: team.id, page: 1, pageSize: 10 }),
  );
  const result = (
    await (await request(`/api/trpc/task.list?input=${query}`)).json()
  ).result.data;
  const current = result.items.find((item) => item.id === task.id);
  assert(current?.status !== 'FAILED', '独立 Worker 执行失败');
  if (current?.status === 'COMPLETED') {
    completed = true;
    break;
  }
  await new Promise((resolve) => setTimeout(resolve, 1000));
}
assert(completed, '导出任务应在 30 秒内完成');
const file = await request(`/api/exports/${task.id}`);
assert(
  (await file.text()).includes('容器异步导出验收'),
  '下载文件应包含验收工单',
);
console.log(
  '部署验收通过:登录 → 创建团队与工单 → 独立 Worker 导出 → 鉴权下载。',
);

搜索教程

输入关键词,搜索全部章节。

阅读设置

外观
正文字号

从一张工单出发,读懂数据如何流转。

设置与进度仅保存在当前浏览器。