import assert from "node:assert/strict"; import { dbRun } from "../server/db.mjs"; const api = process.env.AI_DRAMA_API_BASE || "http://127.0.0.1:8787"; const scope = { "x-organization-id": "org-studio-lab", "x-workspace-id": "ws-local-aidrama", "x-project-id": "thunder-mouth" }; async function request(path, headers = {}, options = {}) { const response = await fetch(`${api}${path}`, { ...options, headers: { "content-type": "application/json", ...headers, ...(options.headers || {}) } }); const payload = await response.json().catch(() => ({})); return { response, payload }; } function assertOk(result, label) { assert.equal(result.response.ok, true, `${label}: ${result.response.status} ${result.payload.detail || result.payload.error || ""}`); return result.payload; } async function login(email) { const result = await request("/api/auth/login", {}, { method: "POST", body: JSON.stringify({ email, password: "Demo@123456" }) }); return { authorization: `Bearer ${assertOk(result, `${email} 登录`).session.token}` }; } function findEntitlement(payload, key) { const entitlement = payload.entitlements?.find((item) => item.key === key); assert.ok(entitlement, `缺少权益 ${key}`); return entitlement; } function entitlementSnapshot(entitlement) { return { limitValue: Number(entitlement.limitValue || 0), enabled: Boolean(entitlement.enabled), enforcement: entitlement.enforcement || "block", source: entitlement.source || "plan", overrideReason: entitlement.overrideReason || "" }; } const owner = { ...(await login("producer@local.test")), ...scope }; const writer = { ...(await login("writer@local.test")), ...scope }; const createdRequestIds = []; let originalKnowledgeEntitlement = null; try { const commercial = assertOk(await request("/api/organizations/org-studio-lab/commercial", owner), "读取商业运营"); assert.ok(Array.isArray(commercial.commercialApprovalCatalog) && commercial.commercialApprovalCatalog.length >= 6, "商业审批类型目录缺失"); assert.ok(commercial.commercialApprovalSummary && Number.isFinite(commercial.commercialApprovalSummary.total), "商业审批摘要缺失"); const knowledgeEntitlement = findEntitlement(commercial, "limit.knowledge_documents"); originalKnowledgeEntitlement = entitlementSnapshot(knowledgeEntitlement); const requestedLimit = Number(knowledgeEntitlement.limitValue || 0) + 13; const crossTenant = await request("/api/organizations/org-studio-lab/commercial-approvals", writer, { method: "POST", body: JSON.stringify({ requestType: "entitlement_overage", targetKey: "limit.knowledge_documents", requestedValue: requestedLimit, workspaceId: "ws-northstar-main", businessReason: "验证商业审批不能把申请单挂到其他组织工作区。" }) }); assert.equal(crossTenant.response.status, 403, "跨组织工作区绑定必须被拒绝"); assert.equal(crossTenant.payload.error, "approval_workspace_scope_mismatch", "跨组织审批错误码不稳定"); const submitted = assertOk(await request("/api/organizations/org-studio-lab/commercial-approvals", writer, { method: "POST", body: JSON.stringify({ requestType: "entitlement_overage", targetKey: "limit.knowledge_documents", requestedValue: requestedLimit, priority: "high", title: "Smoke 知识库素材额度扩容", businessReason: "导入原创小说后需要更多知识库分块素材,仍限定本地 RAG 和原创商用证据。", evidence: { evidenceRef: "smoke://commercial-approval/knowledge-entitlement" } }) }), "提交商业审批"); createdRequestIds.push(submitted.request.id); assert.equal(submitted.request.status, "submitted", "新申请应处于待审批状态"); const mine = assertOk(await request("/api/organizations/org-studio-lab/commercial-approvals?mine=1", writer), "读取我的申请"); assert.ok(mine.requests.some((item) => item.id === submitted.request.id), "申请人必须能看到自己的商业审批"); const decided = assertOk(await request(`/api/organizations/org-studio-lab/commercial-approvals/${encodeURIComponent(submitted.request.id)}/decision`, owner, { method: "POST", body: JSON.stringify({ decision: "approved", decisionNote: "smoke 自动审批扩容" }) }), "审批通过商业申请"); assert.equal(decided.request.status, "approved", "审批通过后状态应变为 approved"); assert.equal(decided.request.effect?.kind, "entitlement_overridden", "权益扩容审批应自动同步组织权益"); assert.equal(findEntitlement(decided.commercial, "limit.knowledge_documents").limitValue, requestedLimit, "知识库素材额度未按审批结果提升"); const cancelTarget = commercial.costCenters?.[0]?.code || "local-gpu"; const cancellable = assertOk(await request("/api/organizations/org-studio-lab/commercial-approvals", writer, { method: "POST", body: JSON.stringify({ requestType: "budget_increase", targetKey: cancelTarget, requestedValue: 999, priority: "low", title: "Smoke 可取消预算申请", businessReason: "验证申请人可以取消尚未审批的商业治理申请。" }) }), "提交可取消申请"); createdRequestIds.push(cancellable.request.id); const cancelled = assertOk(await request(`/api/organizations/org-studio-lab/commercial-approvals/${encodeURIComponent(cancellable.request.id)}/decision`, writer, { method: "POST", body: JSON.stringify({ decision: "cancelled", decisionNote: "smoke 自助取消" }) }), "申请人取消申请"); assert.equal(cancelled.request.status, "cancelled", "申请人取消后状态应为 cancelled"); console.log(`commercial approvals smoke passed: ${api}`); } finally { if (originalKnowledgeEntitlement) { dbRun( "UPDATE organization_entitlements SET limit_value = ?, enabled = ?, enforcement = ?, source = ?, override_reason = ?, updated_at = ? WHERE organization_id = 'org-studio-lab' AND entitlement_key = 'limit.knowledge_documents'", [originalKnowledgeEntitlement.limitValue, originalKnowledgeEntitlement.enabled ? 1 : 0, originalKnowledgeEntitlement.enforcement, originalKnowledgeEntitlement.source, originalKnowledgeEntitlement.overrideReason, new Date().toISOString()] ); } for (const requestId of createdRequestIds) { dbRun("DELETE FROM audit_logs WHERE target_type = 'commercial_approval_request' AND target_id = ?", [requestId]); dbRun("DELETE FROM commercial_approval_requests WHERE id = ?", [requestId]); } }