吸收数字员工发送账单审计外壳

This commit is contained in:
baiyanyun
2026-06-12 22:48:27 +08:00
parent 26fbf51fc8
commit bd7d7b4913
12 changed files with 863 additions and 5 deletions

View File

@@ -1306,6 +1306,82 @@ function checkDigitalBackendMaterializedFacts() {
console.log("[DigitalEmployeeCheck] backend materialized business fact hooks OK");
}
function checkDigitalAdminRecordBillingArchiveShell() {
console.log("\n[DigitalEmployeeCheck] Verify admin send/billing/audit archive shell hooks");
const backendRoot = path.resolve(packageRoot, "..", "..", "..", "qiming-backend");
const qimingRoot = path.resolve(packageRoot, "..", "..", "..", "qiming");
const docsPath = path.resolve(packageRoot, "..", "..", "docs", "digital-employee-frontend-integration-plan.md");
const servicePath = path.join(
backendRoot,
"app-platform-modules",
"app-platform-agent",
"app-platform-agent-core-application",
"src",
"main",
"java",
"com",
"xspaceagi",
"agent",
"core",
"application",
"service",
"DigitalEmployeeSyncApplicationServiceImpl.java",
);
const controllerPath = path.join(
backendRoot,
"app-platform-modules",
"app-platform-agent",
"app-platform-agent-core-ui",
"src",
"main",
"java",
"com",
"xspaceagi",
"agent",
"web",
"ui",
"controller",
"DigitalEmployeeAdminRecordController.java",
);
const qimingServicePath = path.join(qimingRoot, "src", "services", "systemManage.ts");
const qimingTypesPath = path.join(qimingRoot, "src", "types", "interfaces", "systemManage.ts");
const qimingOpsPath = path.join(qimingRoot, "src", "pages", "SystemManagement", "Content", "DigitalEmployeeOps", "index.tsx");
const service = fs.readFileSync(servicePath, "utf8");
const controller = fs.readFileSync(controllerPath, "utf8");
const qimingService = fs.readFileSync(qimingServicePath, "utf8");
const qimingTypes = fs.readFileSync(qimingTypesPath, "utf8");
const qimingOps = fs.readFileSync(qimingOpsPath, "utf8");
const docs = fs.readFileSync(docsPath, "utf8");
const requiredSnippets = [
[controller, "/daily-reports/send-records", "backend daily report send record endpoint"],
[controller, "/billing/estimates", "backend billing estimate endpoint"],
[controller, "/audit-archives", "backend audit archive endpoint"],
[service, "recordDailyReportSendResult", "backend daily report send record service"],
[service, "queryBillingEstimates", "backend billing estimate service"],
[service, "recordAuditArchive", "backend audit archive service"],
[service, "sanitizeAdminRecordValue", "backend admin record redaction"],
[service, "authorization", "backend sensitive authorization guard"],
[service, "raw_input", "backend sensitive raw input guard"],
[qimingService, "apiDigitalEmployeeAdminDailyReportSendRecord", "qiming daily report send record helper"],
[qimingService, "apiDigitalEmployeeAdminBillingEstimates", "qiming billing estimate helper"],
[qimingService, "apiDigitalEmployeeAdminAuditArchive", "qiming audit archive helper"],
[qimingTypes, "DigitalEmployeeBillingEstimate", "qiming billing estimate type"],
[qimingTypes, "DigitalEmployeeAdminRecordSubmitParams", "qiming admin record submit type"],
[qimingOps, "记录发送结果", "qiming daily report send UI"],
[qimingOps, "标记归档", "qiming audit archive UI"],
[qimingOps, "估算 Token", "qiming billing token UI"],
[qimingOps, "估算成本 USD", "qiming billing cost UI"],
[docs, "发送账单审计外壳", "docs send billing audit shell absorption"],
];
const missing = requiredSnippets
.filter(([content, snippet]) => !content.includes(snippet))
.map(([, , label]) => label);
if (missing.length > 0) {
throw new Error(`Missing admin send/billing/audit archive shell hooks: ${missing.join(", ")}`);
}
console.log("[DigitalEmployeeCheck] admin send/billing/audit archive shell hooks OK");
}
function checkLocalDatabaseSchema() {
console.log("\n[DigitalEmployeeCheck] Verify local SQLite digital schema");
const dbPath = path.join(os.homedir(), ".qimingclaw", "qimingclaw.db");
@@ -1367,6 +1443,7 @@ function main() {
checkDigitalAdminActionLoop();
checkDigitalAdminPolicySnapshots();
checkDigitalBackendMaterializedFacts();
checkDigitalAdminRecordBillingArchiveShell();
checkLocalDatabaseSchema();
console.log("\n[DigitalEmployeeCheck] All checks passed");
} catch (error) {

View File

@@ -604,8 +604,8 @@ GET /api/digital-employee/approvals
- 建议:下一轮围绕管理端正式路由 UI 和跨设备冲突可视化,把 embedded 批量干预入口推进到管理端运营台。
11. **诊断 / 成本 / 审计视图**
- 已吸收:同步失败诊断较完整,部分 sandbox / memory / service 日志在 qimingclaw 其他模块中存在embedded adapter 已接管 `/api/doctor``/api/cost``/api/audit`,从 snapshot、runtime records、sync status、managed services 和 artifact delivery facts 生成诊断、估算成本和审计投影sandbox audit、token/cost 和 CLI/tool 调用事件已开始通过 `digital_events` 与 outbox `business_view` 提炼为 `sandbox_audit``token_cost``tool_call_audit` 分类,并只同步 session、tool、server、operation、status、exit code、duration、model、token 计数和估算成本等安全字段;数字员工首页已展示诊断/审计/Token/估算成本摘要,`/api/digital-employee/audits` 已提供本地审计业务视图诊断与审计风险通知联动已开始闭环。管理端正式审计视图预览已开始吸收embedded “技能审计”会消费 sandbox/tool/cost 风险来源并保留安全 payload preview。诊断修复动作预览已开始吸收“处置台”可把 doctor/audit/service/policy 风险转为可筛选、可标记和可安全重试的运营事项。
- 缺口:真实计费账单、独立 sandbox audit 文件归档、自动诊断修复动作和正式外部管理端审计视图尚未统一吸收。
- 已吸收:同步失败诊断较完整,部分 sandbox / memory / service 日志在 qimingclaw 其他模块中存在embedded adapter 已接管 `/api/doctor``/api/cost``/api/audit`,从 snapshot、runtime records、sync status、managed services 和 artifact delivery facts 生成诊断、估算成本和审计投影sandbox audit、token/cost 和 CLI/tool 调用事件已开始通过 `digital_events` 与 outbox `business_view` 提炼为 `sandbox_audit``token_cost``tool_call_audit` 分类,并只同步 session、tool、server、operation、status、exit code、duration、model、token 计数和估算成本等安全字段;数字员工首页已展示诊断/审计/Token/估算成本摘要,`/api/digital-employee/audits` 已提供本地审计业务视图诊断与审计风险通知联动已开始闭环。管理端正式审计视图预览已开始吸收embedded “技能审计”会消费 sandbox/tool/cost 风险来源并保留安全 payload preview。诊断修复动作预览已开始吸收“处置台”可把 doctor/audit/service/policy 风险转为可筛选、可标记和可安全重试的运营事项。发送账单审计外壳已开始吸收后端提供估算账单查询和审计归档记录接口qiming 运营台可显示 Token/估算成本并标记脱敏归档;归档记录会剔除 token、authorization、raw_input、prompt 和 command 等敏感字段。
- 缺口:真实计费账单、独立 sandbox audit 文件归档、自动诊断修复动作和正式外部管理端审计视图尚未统一吸收;当前账单仍是估算,审计归档只记录脱敏摘要和归档位置
- 建议:下一轮围绕管理端正式审计视图和诊断修复动作,把本地可追溯审计继续推进到可运营处置。
12. **管理端业务查询模型**
@@ -614,7 +614,7 @@ GET /api/digital-employee/approvals
- 建议:先使用 sync record 派生业务查询模型和 embedded 业务视图预览承接联调,再按容量和查询压力决定是否拆 Plan / Task / Run / Event 物理业务表。
13. **日报实体与导出交付**
- 已吸收embedded 页面可基于当前 workday projection 导出本地文本日报;生成日报时会通过 qimingclaw bridge 写入 `daily_report` text / HTML / PDF Artifact 与 `daily_report_generated` Event并可通过 `/api/digital-employee/daily-reports` 和详情接口读取只读日报投影。日报 HTML/PDF 导出、发送记录、管理端确认回执和日报发送审批已开始吸收,交付动作会写入 `daily_report_send_recorded` / `daily_report_confirmed` / `daily_report_approval_requested` 事件sync `business_view.category = daily_report` 可被管理端筛选消费。管理端正式日报页面预览已开始吸收embedded 新增“日报运营”入口,展示日报生成、交付、确认、审批和关联产物状态,并复用现有生成、记录发送、确认回执和请求审批动作。
- 已吸收embedded 页面可基于当前 workday projection 导出本地文本日报;生成日报时会通过 qimingclaw bridge 写入 `daily_report` text / HTML / PDF Artifact 与 `daily_report_generated` Event并可通过 `/api/digital-employee/daily-reports` 和详情接口读取只读日报投影。日报 HTML/PDF 导出、发送记录、管理端确认回执和日报发送审批已开始吸收,交付动作会写入 `daily_report_send_recorded` / `daily_report_confirmed` / `daily_report_approval_requested` 事件sync `business_view.category = daily_report` 可被管理端筛选消费。管理端正式日报页面预览已开始吸收embedded 新增“日报运营”入口,展示日报生成、交付、确认、审批和关联产物状态,并复用现有生成、记录发送、确认回执和请求审批动作。发送账单审计外壳已开始吸收qiming-backend 新增 `/api/digital-employee/admin/daily-reports/send-records`qiming 运营台可在日报详情中“记录发送结果”,但不接真实第三方发送通道。
- 缺口:没有正式 DailyReport 物理表、真实管理端发送通道、正式外部管理端日报页面和审批裁决回写闭环。
- 建议:先稳定 Artifact/Event 派生日报交付模型,再根据管理端联调需要决定是否物化 DailyReport 表与发送记录表。