import test from "node:test"; import assert from "node:assert/strict"; import { createHmac } from "node:crypto"; import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import type { GenerationTask } from "@miragenflow/contracts"; import { createHttpServer } from "../src/app/http.ts"; import { createTotpSecret, encryptSecret, hashChallenge } from "../src/shared/auth.ts"; import { createStore, reserveBalance } from "../src/store.ts"; const accessTokenSecret = "v1-regression-test-secret"; function config(overrides: Record = {}) { return { host: "127.0.0.1", port: 0, accessTokenSecret, accessTokenTtlSeconds: 900, refreshCookieName: "refresh", adminEmail: "admin@example.com", adminPassword: "change-me-now", adminMfaRequired: false, userMfaRequired: false, ...overrides, }; } function totpCode(secret: string, now = Date.now()) { const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; let buffer = 0; let bits = 0; const bytes: number[] = []; for (const character of secret) { const value = alphabet.indexOf(character); buffer = (buffer << 5) | value; bits += 5; if (bits >= 8) { bytes.push((buffer >>> (bits - 8)) & 255); bits -= 8; } } const message = Buffer.alloc(8); message.writeBigInt64BE(BigInt(Math.floor(now / 30_000))); const digest = createHmac("sha1", Buffer.from(bytes)).update(message).digest(); const offset = digest[digest.length - 1] & 15; const value = ((digest[offset] & 127) << 24) | (digest[offset + 1] << 16) | (digest[offset + 2] << 8) | digest[offset + 3]; return String(value % 1_000_000).padStart(6, "0"); } async function start(overrides: Record = {}) { const store = createStore(); const server = createHttpServer(store, config(overrides)); await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); const address = server.address(); assert.ok(address && typeof address !== "string"); return { store, server, base: `http://127.0.0.1:${address.port}` }; } async function registerAndLogin(base: string, email: string, password = "password123", deviceId?: string) { const registration = await fetch(`${base}/api/v1/auth/register`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email, password, deviceId }) }); const registered = await registration.json() as { data: { userId: string; devVerificationCode: string } }; assert.equal(registration.status, 201); const verification = await fetch(`${base}/api/v1/auth/verify-email`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ userId: registered.data.userId, code: registered.data.devVerificationCode }) }); assert.equal(verification.status, 200); const login = await fetch(`${base}/api/v1/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email, password, deviceId }) }); return { registered: registered.data, login, payload: await login.json() as { data: { accessToken?: string; mfaRequired?: boolean; challengeId?: string; challengeType?: "verify" | "setup"; mfaEnrollment?: { secret: string; recoveryCodes: string[] } } } }; } async function loginAdmin(base: string, email: string, password: string, secret: string, recoveryCode?: string) { const first = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email, password }) }); const firstPayload = await first.json() as { data: { accessToken?: string; challengeId?: string; mfaRequired?: boolean } }; assert.equal(firstPayload.data.mfaRequired, true); const second = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email, password, challengeId: firstPayload.data.challengeId, ...(recoveryCode ? { recoveryCode } : { mfaCode: totpCode(secret) }) }) }); const secondPayload = await second.json() as { data: { accessToken: string } }; assert.equal(second.status, 200); return secondPayload.data.accessToken; } test("user MFA recovery endpoint consumes a recovery code once", async () => { const { server, base } = await start({ userMfaRequired: true }); try { const first = await registerAndLogin(base, "recovery-endpoint@example.com"); assert.equal(first.payload.data.challengeType, "setup"); const recoveryCode = first.payload.data.mfaEnrollment?.recoveryCodes[0]; assert.ok(recoveryCode); assert.equal(first.payload.data.mfaRequired, true); const confirmed = await fetch(`${base}/api/v1/auth/mfa/verify`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ challengeId: first.payload.data.challengeId, code: totpCode(first.payload.data.mfaEnrollment!.secret) }) }); assert.equal(confirmed.status, 200); const secondLogin = await fetch(`${base}/api/v1/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "recovery-endpoint@example.com", password: "password123" }) }); const second = { payload: await secondLogin.json() as { data: { accessToken?: string; mfaRequired?: boolean; challengeId?: string } } }; const recovered = await fetch(`${base}/api/v1/auth/mfa/recovery`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ challengeId: second.payload.data.challengeId, recoveryCode }) }); assert.equal(recovered.status, 200); assert.ok((await recovered.json() as { data: { accessToken?: string } }).data.accessToken); const thirdLogin = await fetch(`${base}/api/v1/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "recovery-endpoint@example.com", password: "password123" }) }); const third = { payload: await thirdLogin.json() as { data: { challengeId?: string } } }; const repeated = await fetch(`${base}/api/v1/auth/mfa/recovery`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ challengeId: third.payload.data.challengeId, recoveryCode }) }); assert.equal(repeated.status, 401); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("sessions, plan entitlements, and remaining plan balance are user-scoped", async () => { const { server, base } = await start(); try { const first = await registerAndLogin(base, "sessions-plans@example.com", "password123", "browser-a"); const second = await fetch(`${base}/api/v1/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "sessions-plans@example.com", password: "password123", deviceId: "browser-b" }) }); const secondPayload = await second.json() as { data: { accessToken: string } }; const auth = (token: string) => ({ authorization: `Bearer ${token}`, "content-type": "application/json" }); const sessions = await fetch(`${base}/api/v1/me/sessions`, { headers: auth(first.payload.data.accessToken!) }); const sessionItems = (await sessions.json() as { data: { items: Array<{ id: string; deviceId?: string }> } }).data.items; assert.equal(sessionItems.length, 2); const browserA = sessionItems.find((item) => item.deviceId === "browser-a"); assert.ok(browserA); const revoked = await fetch(`${base}/api/v1/me/sessions/${browserA.id}`, { method: "DELETE", headers: auth(first.payload.data.accessToken!) }); assert.equal(revoked.status, 200); assert.equal((await fetch(`${base}/api/v1/me`, { headers: auth(first.payload.data.accessToken!) })).status, 401); const remaining = await fetch(`${base}/api/v1/me/sessions`, { headers: auth(secondPayload.data.accessToken) }); assert.equal((await remaining.json() as { data: { items: unknown[] } }).data.items.length, 1); const purchase = await fetch(`${base}/api/v1/plans/starter/purchase`, { method: "POST", headers: { ...auth(secondPayload.data.accessToken), "idempotency-key": "plan-regression" }, body: "{}" }); assert.equal(purchase.status, 202); const plans = await fetch(`${base}/api/v1/me/plans`, { headers: auth(secondPayload.data.accessToken) }); const planPayload = await plans.json() as { data: { items: Array<{ plan?: { id: string }; remainingBalance: number }> } }; assert.equal(plans.status, 200); assert.equal(planPayload.data.items[0].plan?.id, "starter"); assert.equal(planPayload.data.items[0].remainingBalance, 100); const task = await fetch(`${base}/api/v1/tasks/image`, { method: "POST", headers: { ...auth(secondPayload.data.accessToken), "idempotency-key": "plan-bucket-task" }, body: JSON.stringify({ modelProductId: "basic-image-v1", prompt: "plan bucket" }) }); assert.equal(task.status, 202); await new Promise((resolve) => setTimeout(resolve, 150)); const afterTask = await fetch(`${base}/api/v1/me/plans`, { headers: auth(secondPayload.data.accessToken) }); assert.equal((await afterTask.json() as { data: { items: Array<{ remainingBalance: number }> } }).data.items[0].remainingBalance, 90); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("admin image model products publish capability parameters and require a resolution matrix", async () => { const { server, base } = await start(); try { const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const headers = { authorization: `Bearer ${loginPayload.data.accessToken}`, "content-type": "application/json" }; const created = await fetch(`${base}/api/v1/admin/model-products`, { method: "POST", headers: { ...headers, "idempotency-key": "model-capability-create" }, body: JSON.stringify({ id: "openai-image-product", publicModelId: "gpt-image-2", name: "OpenAI 图片模型", capabilities: ["image"], channelGroupId: "image-default", basePrice: 20, resolutions: [{ id: "1K", label: "1K", width: 1024, height: 1024, priceMultiplier: 1, ratios: ["1:1", "16:9"] }] }) }); assert.equal(created.status, 201); const createdPayload = await created.json() as { data: { item: { capabilitiesSchema?: Array<{ capability: string; parameters?: Record }> } } }; const imageSchema = createdPayload.data.item.capabilitiesSchema?.find((item) => item.capability === "image"); assert.ok(imageSchema); assert.deepEqual(imageSchema.parameters?.ratio.enum, ["auto", "1:1", "16:9", "9:16", "3:4", "4:5", "3:2", "2:3", "4:3", "1.91:1", "2.35:1", "21:9"]); assert.deepEqual(imageSchema.parameters?.resolution.enum, ["1K", "2K", "4K"]); assert.deepEqual(imageSchema.parameters?.input_fidelity.enum, ["low", "high"]); const invalid = await fetch(`${base}/api/v1/admin/model-products`, { method: "POST", headers: { ...headers, "idempotency-key": "model-capability-invalid" }, body: JSON.stringify({ id: "openai-image-invalid", publicModelId: "gpt-image-invalid", name: "无分辨率图片模型", capabilities: ["image"], channelGroupId: "image-default", basePrice: 20, resolutions: [] }) }); assert.equal(invalid.status, 422); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("admin channel groups bind model products separately from request channels", async () => { const { server, base, store } = await start(); try { const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const headers = { authorization: `Bearer ${loginPayload.data.accessToken}`, "content-type": "application/json" }; const firstProduct = await fetch(`${base}/api/v1/admin/model-products`, { method: "POST", headers: { ...headers, "idempotency-key": "channel-group-product-first" }, body: JSON.stringify({ id: "group-basic-image", publicModelId: "group-basic-image-v1", name: "分组基础图片", capabilities: ["image"], enabled: false, basePrice: 10, resolutions: [{ id: "1K", label: "1K", width: 1024, height: 1024, priceMultiplier: 1, ratios: ["1:1"] }] }) }); assert.equal(firstProduct.status, 201); const secondProduct = await fetch(`${base}/api/v1/admin/model-products`, { method: "POST", headers: { ...headers, "idempotency-key": "channel-group-product-second" }, body: JSON.stringify({ id: "group-advanced-image", publicModelId: "group-advanced-image-v1", name: "分组高级图片", capabilities: ["image"], enabled: false, basePrice: 25, resolutions: [{ id: "2K", label: "2K", width: 2048, height: 2048, priceMultiplier: 1.5, ratios: ["1:1"] }] }) }); assert.equal(secondProduct.status, 201); const created = await fetch(`${base}/api/v1/admin/channel-groups`, { method: "POST", headers: { ...headers, "idempotency-key": "channel-group-product-bind" }, body: JSON.stringify({ id: "image-product-group", name: "图片产品组", capabilities: ["image"], productIds: ["group-basic-image"], channelIds: ["channel-a"], retryBudget: 2 }) }); assert.equal(created.status, 201); const createdPayload = await created.json() as { data: { item: { productIds?: string[] } } }; assert.deepEqual(createdPayload.data.item.productIds, ["group-basic-image"]); assert.equal(store.products.find((product) => product.id === "group-basic-image")?.channelGroupId, "image-product-group"); const listed = await fetch(`${base}/api/v1/admin/channel-groups`, { headers }); assert.equal(listed.status, 200); const listedPayload = await listed.json() as { data: { items: Array<{ id: string; productIds?: string[]; products?: Array<{ productId: string }> }> } }; const listedGroup = listedPayload.data.items.find((item) => item.id === "image-product-group"); assert.deepEqual(listedGroup?.productIds, ["group-basic-image"]); assert.deepEqual(listedGroup?.products?.map((product) => product.productId), ["group-basic-image"]); const edited = await fetch(`${base}/api/v1/admin/channel-groups/image-product-group`, { method: "PATCH", headers: { ...headers, "If-Match": "1", "idempotency-key": "channel-group-product-rebind" }, body: JSON.stringify({ productIds: ["group-advanced-image"], capabilities: ["image"], channelIds: ["channel-a"], retryBudget: 2, enabled: true }) }); assert.equal(edited.status, 200); assert.equal(store.products.find((product) => product.id === "group-basic-image")?.channelGroupId, undefined); assert.equal(store.products.find((product) => product.id === "group-basic-image")?.enabled, false); assert.equal(store.products.find((product) => product.id === "group-advanced-image")?.channelGroupId, "image-product-group"); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("admin channel groups reject incompatible or silently migrated model products", async () => { const { server, base, store } = await start(); try { const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const headers = { authorization: `Bearer ${loginPayload.data.accessToken}`, "content-type": "application/json" }; const imageGroup = await fetch(`${base}/api/v1/admin/channel-groups`, { method: "POST", headers: { ...headers, "idempotency-key": "channel-group-capability-image" }, body: JSON.stringify({ id: "capability-image-group", name: "图片能力组", capabilities: ["image"], productIds: [], channelIds: ["channel-a"], retryBudget: 1 }) }); assert.equal(imageGroup.status, 201); const product = await fetch(`${base}/api/v1/admin/model-products`, { method: "POST", headers: { ...headers, "idempotency-key": "channel-group-capability-product" }, body: JSON.stringify({ id: "capability-image-product", publicModelId: "capability-image-v1", name: "能力校验图片产品", capabilities: ["image"], channelGroupId: "capability-image-group", basePrice: 5, resolutions: [{ id: "1K", label: "1K", width: 1024, height: 1024, priceMultiplier: 1, ratios: ["1:1"] }] }) }); assert.equal(product.status, 201); const textGroup = await fetch(`${base}/api/v1/admin/channel-groups`, { method: "POST", headers: { ...headers, "idempotency-key": "channel-group-capability-text" }, body: JSON.stringify({ id: "capability-text-group", name: "文字能力组", capabilities: ["text"], productIds: [], channelIds: ["channel-a"], retryBudget: 1 }) }); assert.equal(textGroup.status, 201); const incompatibleMode = await fetch(`${base}/api/v1/admin/channel-groups/capability-image-group`, { method: "PATCH", headers: { ...headers, "If-Match": "1", "idempotency-key": "channel-group-capability-change" }, body: JSON.stringify({ capabilities: ["text"] }) }); assert.equal(incompatibleMode.status, 422); assert.deepEqual(store.channelGroups.find((group) => group.id === "capability-image-group")?.capabilities, ["image"]); assert.equal(store.products.find((item) => item.id === "capability-image-product")?.channelGroupId, "capability-image-group"); const incompatibleProduct = await fetch(`${base}/api/v1/admin/model-products/capability-image-product`, { method: "PATCH", headers: { ...headers, "If-Match": "1", "idempotency-key": "channel-group-capability-product-change" }, body: JSON.stringify({ channelGroupId: "capability-text-group" }) }); assert.equal(incompatibleProduct.status, 422); assert.equal(store.products.find((item) => item.id === "capability-image-product")?.channelGroupId, "capability-image-group"); const duplicateBinding = await fetch(`${base}/api/v1/admin/channel-groups`, { method: "POST", headers: { ...headers, "idempotency-key": "channel-group-ownership-conflict" }, body: JSON.stringify({ id: "capability-other-group", name: "重复绑定组", capabilities: ["image"], productIds: ["capability-image-product"], channelIds: ["channel-a"], retryBudget: 1 }) }); assert.equal(duplicateBinding.status, 409); assert.equal(store.channelGroups.some((group) => group.id === "capability-other-group"), false); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("message provider and template writes survive a file-store restart", async () => { const directory = await mkdtemp(join(tmpdir(), "miragenflow-message-persistence-")); const file = join(directory, "store.json"); const store = createStore(file); const server = createHttpServer(store, config()); await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); const address = server.address(); assert.ok(address && typeof address !== "string"); const base = `http://127.0.0.1:${address.port}`; try { const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const headers = { authorization: `Bearer ${loginPayload.data.accessToken}`, "content-type": "application/json" }; const provider = await fetch(`${base}/api/v1/admin/message-providers`, { method: "POST", headers: { ...headers, "idempotency-key": "persistent-message-provider-create" }, body: JSON.stringify({ id: "persistent-message-provider", name: "持久化消息适配器", channel: "email" }) }); assert.equal(provider.status, 201); const template = await fetch(`${base}/api/v1/admin/message-templates`, { method: "POST", headers: { ...headers, "idempotency-key": "persistent-message-template-create" }, body: JSON.stringify({ purpose: "register", channel: "email", content: "验证码:{{code}}" }) }); assert.equal(template.status, 201); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } const restored = createStore(file); try { assert.equal(restored.messageProviders.has("persistent-message-provider"), true); assert.equal([...restored.messageTemplates.values()].some((item) => item.content === "验证码:{{code}}"), true); } finally { await rm(directory, { recursive: true, force: true }); } }); test("admin unknown-task reconciliation stores real image metadata and clamps the charge", async () => { const { store, server, base } = await start(); const taskId = "reconcile-image-task"; const ownerId = "reconcile-user"; const now = new Date().toISOString(); assert.equal(reserveBalance(store, ownerId, 10, taskId), false); store.balances.set(ownerId, { available: 100, reserved: 0 }); assert.equal(reserveBalance(store, ownerId, 10, taskId), true); store.tasks.set(taskId, { id: taskId, ownerId, taskType: "image", modelProductId: "basic-image", status: "unknown", estimatedCost: 10, reservedCost: 10, count: 2, pricingSnapshot: { basePrice: 5, multiplier: 1, unitVersion: 1 }, createdAt: now, updatedAt: now, eventSequence: 0, channelGroupId: "image-default", routeSnapshotVersion: 1, attempts: [{ id: "reconcile-attempt", channelId: "channel-a", sequence: 1, status: "unknown", startedAt: now, reconciliationStatus: "pending" }], outputs: [], inputSnapshot: { references: [], params: { resolution: "2K" } }, } satisfies GenerationTask); try { const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const invalidForm = new FormData(); invalidForm.set("outcome", "success"); invalidForm.append("file", new Blob([Buffer.from("not-an-image")], { type: "image/png" }), "invalid.png"); const invalid = await fetch(`${base}/api/v1/admin/tasks/${taskId}/reconcile`, { method: "POST", headers: { authorization: `Bearer ${loginPayload.data.accessToken}`, "idempotency-key": "reconcile-image-invalid", "if-match": "0" }, body: invalidForm }); assert.equal(invalid.status, 415); assert.equal(store.tasks.get(taskId)?.status, "unknown"); assert.equal(store.balances.get(ownerId)?.reserved, 10); const form = new FormData(); form.set("outcome", "success"); form.set("chargedAmount", "99"); form.append("file", new Blob([Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAF/gL+XwAAAABJRU5ErkJggg==", "base64")], { type: "image/png" }), "result.png"); const response = await fetch(`${base}/api/v1/admin/tasks/${taskId}/reconcile`, { method: "POST", headers: { authorization: `Bearer ${loginPayload.data.accessToken}`, "idempotency-key": "reconcile-image-success", "if-match": "0" }, body: form }); assert.equal(response.status, 200); const payload = await response.json() as { data: { item: GenerationTask } }; const settledEntries = store.ledger.filter((entry) => entry.type === "settle" && entry.referenceId === taskId).length; const repeatedForm = new FormData(); repeatedForm.set("outcome", "success"); repeatedForm.set("chargedAmount", "99"); repeatedForm.append("file", new Blob([Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAF/gL+XwAAAABJRU5ErkJggg==", "base64")], { type: "image/png" }), "result.png"); const repeated = await fetch(`${base}/api/v1/admin/tasks/${taskId}/reconcile`, { method: "POST", headers: { authorization: `Bearer ${loginPayload.data.accessToken}`, "idempotency-key": "reconcile-image-success", "if-match": "0" }, body: repeatedForm }); assert.equal(repeated.status, 200); assert.equal(store.ledger.filter((entry) => entry.type === "settle" && entry.referenceId === taskId).length, settledEntries); const conflicting = await fetch(`${base}/api/v1/admin/tasks/${taskId}/reconcile`, { method: "POST", headers: { authorization: `Bearer ${loginPayload.data.accessToken}`, "content-type": "application/json", "idempotency-key": "reconcile-image-success" }, body: JSON.stringify({ outcome: "failure" }) }); assert.equal(conflicting.status, 409); const output = payload.data.item.outputs[0]; assert.equal(payload.data.item.status, "succeeded"); assert.equal(payload.data.item.reservedCost, 0); assert.equal(output.metadata?.width, 1); assert.equal(output.metadata?.height, 1); assert.equal(output.metadata?.size, "1x1"); assert.equal(output.metadata?.format, "png"); assert.equal(output.metadata?.source, "base64"); assert.equal(output.metadata?.resolution, "2K"); assert.equal(output.unitPriceSnapshot, 5); assert.equal(output.chargedAmount, 10); assert.equal(store.balances.get(ownerId)?.reserved, 0); assert.equal(store.ledger.some((entry) => entry.type === "settle" && entry.referenceId === taskId), true); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("admin unknown-task failure reconciliation releases the full reservation", async () => { const { store, server, base } = await start(); const taskId = "reconcile-failure-task"; const ownerId = "reconcile-failure-user"; const now = new Date().toISOString(); store.balances.set(ownerId, { available: 20, reserved: 0 }); assert.equal(reserveBalance(store, ownerId, 10, taskId), true); store.tasks.set(taskId, { id: taskId, ownerId, taskType: "image", modelProductId: "basic-image", status: "unknown", estimatedCost: 10, reservedCost: 10, createdAt: now, updatedAt: now, eventSequence: 0, channelGroupId: "image-default", routeSnapshotVersion: 1, attempts: [{ id: "reconcile-failure-attempt", channelId: "channel-a", sequence: 1, status: "unknown", startedAt: now, reconciliationStatus: "pending" }], outputs: [], } satisfies GenerationTask); try { const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const response = await fetch(`${base}/api/v1/admin/tasks/${taskId}/reconcile`, { method: "POST", headers: { authorization: `Bearer ${loginPayload.data.accessToken}`, "content-type": "application/json", "idempotency-key": "reconcile-failure", "if-match": "0" }, body: JSON.stringify({ outcome: "failure" }) }); assert.equal(response.status, 200); assert.equal(store.tasks.get(taskId)?.status, "failed"); assert.equal(store.tasks.get(taskId)?.reservedCost, 0); assert.deepEqual({ available: store.balances.get(ownerId)?.available, reserved: store.balances.get(ownerId)?.reserved }, { available: 20, reserved: 0 }); assert.equal(store.tasks.get(taskId)?.attempts[0]?.reconciliationStatus, "confirmed_failure"); assert.equal(store.ledger.some((entry) => entry.type === "release" && entry.referenceId === taskId), true); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("finance administrators can list balance targets and require separate MFA approval", async () => { const firstSecret = createTotpSecret(); const secondSecret = createTotpSecret(); const securitySecret = createTotpSecret(); const recoveryCode = "ADMINRECOVERY"; const { store, server, base } = await start({ adminMfaRequired: true, adminAccounts: [ { id: "admin:first", email: "first-admin@example.com", password: "first-admin-password", role: "finance", mfaSecret: firstSecret, mfaRequired: true }, { id: "admin:second", email: "second-admin@example.com", password: "second-admin-password", role: "finance", mfaSecret: secondSecret, mfaRequired: true, recoveryCodeHashes: [hashChallenge(recoveryCode, accessTokenSecret)] }, { id: "admin:security", email: "security-admin@example.com", password: "security-admin-password", role: "support", mfaSecret: securitySecret, mfaRequired: true }, ], }); try { const user = await registerAndLogin(base, "approval-user@example.com"); const requester = await loginAdmin(base, "first-admin@example.com", "first-admin-password", firstSecret); const approver = await loginAdmin(base, "second-admin@example.com", "second-admin-password", secondSecret, recoveryCode); const securityOnly = await loginAdmin(base, "security-admin@example.com", "security-admin-password", securitySecret); const targets = await fetch(`${base}/api/v1/admin/billing/users`, { headers: { authorization: `Bearer ${requester}` } }); assert.equal(targets.status, 200); const target = ((await targets.json()) as { data: { items: Array> } }).data.items.find((item) => item.id === user.registered.userId); assert.ok(target); const allowedTargetFields = ["balance", "displayName", "email", "id", "phone", "status", "username"]; assert.deepEqual(Object.keys(target).filter((key) => !allowedTargetFields.includes(key)), []); assert.ok("balance" in target); assert.equal((await fetch(`${base}/api/v1/admin/users`, { headers: { authorization: `Bearer ${requester}` } })).status, 403); const forbidden = await fetch(`${base}/api/v1/admin/users/${user.registered.userId}/balance-adjustments`, { method: "POST", headers: { authorization: `Bearer ${securityOnly}`, "content-type": "application/json", "idempotency-key": "security-balance-adjustment" }, body: JSON.stringify({ amount: 1, reason: "不应允许安全管理员调账" }) }); assert.equal(forbidden.status, 403); const request = await fetch(`${base}/api/v1/admin/users/${user.registered.userId}/balance-adjustments`, { method: "POST", headers: { authorization: `Bearer ${requester}`, "content-type": "application/json", "idempotency-key": "balance-adjustment-request" }, body: JSON.stringify({ amount: 25, reason: "人工账本回归测试" }) }); assert.equal(request.status, 202); assert.equal((await fetch(`${base}/api/v1/balance`, { headers: { authorization: `Bearer ${user.payload.data.accessToken!}` } })).status, 200); const before = await fetch(`${base}/api/v1/balance`, { headers: { authorization: `Bearer ${user.payload.data.accessToken!}` } }); assert.equal((await before.json() as { data: { available: number } }).data.available, 0); const approval = ((await request.json()) as { data: { item: { id: string } } }).data.item; const execute = await fetch(`${base}/api/v1/admin/approvals/${approval.id}/approve`, { method: "POST", headers: { authorization: `Bearer ${approver}`, "content-type": "application/json", "idempotency-key": "balance-adjustment-approve", "if-match": "1" }, body: JSON.stringify({ mfaCode: totpCode(secondSecret) }) }); assert.equal(execute.status, 200); assert.ok(store.adminAccounts.get("admin:second")?.mfaLastTotpCounter !== undefined); const after = await fetch(`${base}/api/v1/balance`, { headers: { authorization: `Bearer ${user.payload.data.accessToken!}` } }); assert.equal((await after.json() as { data: { available: number } }).data.available, 25); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("local super administrator can approve its own balance increase and deduction", async () => { const { store, server, base } = await start({ adminSelfApprovalAllowed: true }); try { const user = await registerAndLogin(base, "self-approval-balance@example.com"); store.balances.set(user.registered.userId, { available: 10, reserved: 0 }); const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const adminHeaders = (idempotencyKey: string) => ({ authorization: `Bearer ${loginPayload.data.accessToken}`, "content-type": "application/json", "idempotency-key": idempotencyKey }); const adjust = async (amount: number, key: string) => { const request = await fetch(`${base}/api/v1/admin/users/${user.registered.userId}/balance-adjustments`, { method: "POST", headers: adminHeaders(`${key}-request`), body: JSON.stringify({ amount, reason: amount > 0 ? "本地增加金币" : "本地扣减金币" }) }); assert.equal(request.status, 202); const approval = ((await request.json()) as { data: { item: { id: string; version: number } } }).data.item; const execute = await fetch(`${base}/api/v1/admin/approvals/${approval.id}/approve`, { method: "POST", headers: { ...adminHeaders(`${key}-approve`), "if-match": String(approval.version) }, body: "{}" }); assert.equal(execute.status, 200); }; await adjust(40, "self-balance-add"); assert.equal((await (await fetch(`${base}/api/v1/balance`, { headers: { authorization: `Bearer ${user.payload.data.accessToken!}` } })).json() as { data: { available: number } }).data.available, 50); assert.equal((store.buckets.get(user.registered.userId) || []).reduce((total, bucket) => total + bucket.remaining, 0), 50); await adjust(10, "self-balance-add-second-bucket"); assert.equal((store.buckets.get(user.registered.userId) || []).reduce((total, bucket) => total + bucket.remaining, 0), 60); await adjust(-55, "self-balance-deduct-across-buckets"); assert.equal((await (await fetch(`${base}/api/v1/balance`, { headers: { authorization: `Bearer ${user.payload.data.accessToken!}` } })).json() as { data: { available: number } }).data.available, 5); assert.deepEqual((store.buckets.get(user.registered.userId) || []).map((bucket) => bucket.remaining), [0, 0, 5]); assert.ok(store.ledger.filter((entry) => entry.userId === user.registered.userId && entry.type === "adjustment").every((entry) => Boolean(entry.bucketId))); assert.equal([...store.adminIdempotency.values()].every((record) => record.state === "completed"), true); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("administrator initial plan grant creates matching balance bucket ledger and entitlement", async () => { const { store, server, base } = await start(); try { const plan = store.plans.find((item) => item.includedBalance > 0); assert.ok(plan); const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const accessToken = (await login.json() as { data: { accessToken: string } }).data.accessToken; const headers = { authorization: `Bearer ${accessToken}`, "content-type": "application/json", "idempotency-key": "initial-plan-user" }; const body = JSON.stringify({ username: "initial-plan-user", email: "initial-plan@example.com", password: "password123", planId: plan.id, welcomeMessage: "欢迎使用" }); const response = await fetch(`${base}/api/v1/admin/users`, { method: "POST", headers, body }); assert.equal(response.status, 201); const firstPayload = await response.json() as { data: { item: { id: string }; initialPassword?: string } }; const userId = firstPayload.data.item.id; assert.equal(firstPayload.data.initialPassword, "password123"); const entitlement = [...store.entitlements.values()].find((item) => item.userId === userId); assert.ok(entitlement?.creditBucketId); const bucket = (store.buckets.get(userId) || []).find((item) => item.id === entitlement.creditBucketId); assert.equal(bucket?.remaining, plan.includedBalance); assert.equal(store.balances.get(userId)?.available, plan.includedBalance); assert.equal(store.ledger.find((entry) => entry.referenceId === entitlement.id)?.bucketId, bucket?.id); assert.ok([...store.messageOutbox.values()].some((item) => item.idempotencyKey === "initial-plan-user:welcome")); assert.ok(store.audit.some((item) => item.action === "user.create" && item.objectId === userId)); const counts = { users: store.users.size, buckets: store.buckets.get(userId)?.length, ledger: store.ledger.length, entitlements: store.entitlements.size, messages: store.messageOutbox.size, audit: store.audit.length }; const replay = await fetch(`${base}/api/v1/admin/users`, { method: "POST", headers, body }); assert.equal(replay.status, 201); const replayPayload = await replay.json() as { data: { item: { id: string }; initialPassword?: string } }; assert.equal(replayPayload.data.item.id, userId); assert.equal(replayPayload.data.initialPassword, undefined); assert.deepEqual({ users: store.users.size, buckets: store.buckets.get(userId)?.length, ledger: store.ledger.length, entitlements: store.entitlements.size, messages: store.messageOutbox.size, audit: store.audit.length }, counts); const idempotency = [...store.adminIdempotency.values()].find((item) => item.statusCode === 201); assert.equal(idempotency?.state, "completed"); assert.equal(JSON.stringify(idempotency?.data).includes("password123"), false); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("admin user status mutations reject stale versions", async () => { const { store, server, base } = await start(); try { const user = await registerAndLogin(base, "user-version-conflict@example.com"); const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const accessToken = (await login.json() as { data: { accessToken: string } }).data.accessToken; const auth = { authorization: `Bearer ${accessToken}`, "content-type": "application/json" }; const detail = await fetch(`${base}/api/v1/admin/users/${user.registered.userId}`, { headers: auth }); assert.equal(detail.status, 200); const detailPayload = await detail.json() as { data: { item: { version: number; status: string } } }; assert.equal(detailPayload.data.item.version, 1); const freeze = await fetch(`${base}/api/v1/admin/users/${user.registered.userId}/freeze`, { method: "POST", headers: { ...auth, "if-match": String(detailPayload.data.item.version), "idempotency-key": "user-version-freeze" }, body: "{}" }); assert.equal(freeze.status, 200); const freezePayload = await freeze.json() as { data: { version: number; status: string } }; assert.equal(freezePayload.data.status, "frozen"); assert.equal(freezePayload.data.version, 2); const stale = await fetch(`${base}/api/v1/admin/users/${user.registered.userId}`, { method: "PATCH", headers: { ...auth, "if-match": "1", "idempotency-key": "user-version-stale-update" }, body: JSON.stringify({ status: "active" }) }); assert.equal(stale.status, 409); const stalePayload = await stale.json() as { error?: { code?: string } }; assert.equal(stalePayload.error?.code, "VERSION_CONFLICT"); assert.equal(store.users.get(user.registered.userId)?.status, "frozen"); assert.equal(store.users.get(user.registered.userId)?.version, 2); const unfreeze = await fetch(`${base}/api/v1/admin/users/${user.registered.userId}/unfreeze`, { method: "POST", headers: { ...auth, "if-match": "2", "idempotency-key": "user-version-unfreeze" }, body: "{}" }); assert.equal(unfreeze.status, 200); assert.equal((await unfreeze.json() as { data: { version: number; status: string } }).data.version, 3); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("assets enforce ownership and deduplicate repeated object saves", async () => { const { store, server, base } = await start(); try { const owner = await registerAndLogin(base, "asset-owner@example.com"); const other = await registerAndLogin(base, "asset-other@example.com"); const objectId = "object-owner-1"; store.objects.set(objectId, { id: objectId, ownerId: owner.registered.userId, mimeType: "image/png", data: Buffer.from("x").toString("base64"), expiresAt: new Date(Date.now() + 60_000).toISOString() }); const auth = { authorization: `Bearer ${owner.payload.data.accessToken!}`, "content-type": "application/json" }; const first = await fetch(`${base}/api/v1/assets`, { method: "POST", headers: auth, body: JSON.stringify({ objectId, type: "image", title: "测试资产" }) }); const firstPayload = await first.json() as { data: { id: string } }; assert.equal(first.status, 201); const second = await fetch(`${base}/api/v1/assets`, { method: "POST", headers: auth, body: JSON.stringify({ objectId, type: "image", title: "重复保存" }) }); const secondPayload = await second.json() as { data: { id: string } }; assert.equal(second.status, 200); assert.equal(secondPayload.data.id, firstPayload.data.id); const denied = await fetch(`${base}/api/v1/assets`, { method: "POST", headers: { authorization: `Bearer ${other.payload.data.accessToken!}`, "content-type": "application/json" }, body: JSON.stringify({ objectId, type: "image" }) }); assert.equal(denied.status, 403); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("WebDAV manifest retention is capped and valid writes keep the local record", async () => { const { store, server, base } = await start(); try { const user = await registerAndLogin(base, "webdav-retention@example.com"); store.webdav.set(user.registered.userId, { userId: user.registered.userId, configured: true, directory: "miragenflow", state: "ready", retentionDays: 30, encryptedUrl: encryptSecret("https://127.0.0.1:1", accessTokenSecret), manifestRetentionExpiresAt: new Date().toISOString(), manifestExtensionDays: 0 }); const auth = { authorization: `Bearer ${user.payload.data.accessToken!}`, "content-type": "application/json" }; const extension = await fetch(`${base}/api/v1/me/webdav/manifest/retention`, { method: "POST", headers: auth, body: JSON.stringify({ days: 20 }) }); assert.equal(extension.status, 200); assert.equal((await extension.json() as { data: { manifestExtensionDays: number } }).data.manifestExtensionDays, 20); const overLimit = await fetch(`${base}/api/v1/me/webdav/manifest/retention`, { method: "POST", headers: auth, body: JSON.stringify({ days: 11 }) }); assert.equal(overLimit.status, 422); const write = await fetch(`${base}/api/v1/me/webdav/file`, { method: "PUT", headers: auth, body: JSON.stringify({ path: "canvas/manifest.json", mimeType: "application/json", data: "eA==" }) }); assert.equal(write.status, 202); assert.ok(store.webdavFiles.has(`${user.registered.userId}:canvas/manifest.json`)); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("expired buckets append one adjustment ledger entry before reservation", () => { const store = createStore(); const userId = "expired-bucket-user"; const bucketId = "expired-bucket"; store.balances.set(userId, { available: 10, reserved: 0 }); store.buckets.set(userId, [{ id: bucketId, userId, source: "plan", remaining: 10, priority: 0, expiresAt: new Date(Date.now() - 1_000).toISOString() }]); assert.equal(reserveBalance(store, userId, 1, "expired-reservation"), false); assert.equal(store.buckets.get(userId)?.[0].remaining, 0); assert.deepEqual({ available: store.balances.get(userId)?.available, reserved: store.balances.get(userId)?.reserved }, { available: 0, reserved: 0 }); assert.equal(store.ledger.filter((entry) => entry.idempotencyKey === `expire:${userId}:${bucketId}`).length, 1); }); test("expired bucket adjustment never drives aggregate balance below zero", () => { const store = createStore(); const userId = "expired-bucket-clamp"; store.balances.set(userId, { available: 3, reserved: 0 }); store.buckets.set(userId, [{ id: "expired-large", userId, source: "plan", remaining: 10, priority: 0, expiresAt: new Date(Date.now() - 1_000).toISOString() }]); assert.equal(reserveBalance(store, userId, 1, "clamp-reservation"), false); assert.deepEqual({ available: store.balances.get(userId)?.available, reserved: store.balances.get(userId)?.reserved }, { available: 0, reserved: 0 }); assert.equal(store.ledger.find((entry) => entry.idempotencyKey === `expire:${userId}:expired-large`)?.amount, -3); }); test("task route snapshots follow channel-group priority order", async () => { const { store, server, base } = await start(); try { const user = await registerAndLogin(base, "channel-order@example.com"); store.balances.set(user.registered.userId, { available: 100, reserved: 0 }); const group = store.channelGroups.find((item) => item.id === "image-default"); assert.ok(group); group.channelIds = ["channel-c", "channel-a", "channel-d", "channel-b"]; group.channelPriorities = { "channel-c": 0, "channel-a": 1, "channel-d": 2, "channel-b": 3 }; const response = await fetch(`${base}/api/v1/tasks/image`, { method: "POST", headers: { authorization: `Bearer ${user.payload.data.accessToken!}`, "content-type": "application/json", "idempotency-key": "channel-order-task" }, body: JSON.stringify({ modelProductId: "basic-image-v1", prompt: "route snapshot" }) }); assert.equal(response.status, 202); const task = [...store.tasks.values()].find((item) => item.ownerId === user.registered.userId); assert.deepEqual(task?.routeSnapshot?.channelIds, ["channel-c", "channel-a", "channel-d", "channel-b"]); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("documented admin singleton and detail method aliases remain callable", async () => { const { server, base } = await start(); try { const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const headers = (key: string) => ({ authorization: `Bearer ${loginPayload.data.accessToken}`, "content-type": "application/json", "idempotency-key": key }); assert.equal((await fetch(`${base}/api/v1/admin/billing/units`, { headers: headers("alias-units-get") })).status, 200); assert.equal((await fetch(`${base}/api/v1/admin/billing/units`, { method: "POST", headers: headers("alias-units-post"), body: JSON.stringify({ name: "金币" }) })).status, 201); assert.equal((await fetch(`${base}/api/v1/admin/billing/conversion-rules`, { method: "POST", headers: headers("alias-conversion-post"), body: JSON.stringify({ conversionRate: 1, rounding: "round" }) })).status, 201); assert.equal((await fetch(`${base}/api/v1/admin/pricing-rules`, { method: "POST", headers: headers("alias-pricing-post"), body: JSON.stringify({ modelProductId: "basic-image", basePrice: 10 }) })).status, 201); assert.equal((await fetch(`${base}/api/v1/admin/storage-policies`, { method: "POST", headers: headers("alias-storage-post"), body: JSON.stringify({ retentionDays: 30 }) })).status, 201); assert.equal((await fetch(`${base}/api/v1/admin/recharge-orders/unknown-order`, { headers: headers("alias-order-detail") })).status, 404); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("audit actors use the user name and direct administrator email", async () => { const { store, server, base } = await start(); try { const user = await registerAndLogin(base, "audit-actor@example.com"); const userRecord = store.users.get(user.registered.userId); assert.ok(userRecord); userRecord.username = "日志用户"; const now = new Date().toISOString(); store.audit.push( { id: "audit-user-actor", actorId: userRecord.id, action: "user.password.change", objectType: "user", objectId: userRecord.id, requestId: "audit-user-request", createdAt: now }, { id: "audit-admin-actor", actorId: "admin", action: "admin.login.succeeded", objectType: "admin", objectId: "admin", requestId: "audit-admin-request", createdAt: now }, ); const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const response = await fetch(`${base}/api/v1/admin/audit-logs`, { headers: { authorization: `Bearer ${loginPayload.data.accessToken}` } }); assert.equal(response.status, 200); const items = (await response.json() as { data: { items: Array<{ id: string; actorName: string }> } }).data.items; assert.equal(items.find((item) => item.id === "audit-user-actor")?.actorName, "日志用户"); assert.equal(items.find((item) => item.id === "audit-admin-actor")?.actorName, "admin@example.com"); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("admin system settings are independent, versioned, and apply auth switches immediately", async () => { const { server, base } = await start(); try { const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const loginPayload = await login.json() as { data: { accessToken: string } }; const authHeaders = { authorization: `Bearer ${loginPayload.data.accessToken}` }; const initial = await fetch(`${base}/api/v1/admin/settings`, { headers: authHeaders }); assert.equal(initial.status, 200); const initialPayload = await initial.json() as { data: { items: Array<{ version: number; userVerificationRequired: boolean }> } }; const current = initialPayload.data.items[0]; assert.ok(current); assert.equal(current.userVerificationRequired, true); const updated = await fetch(`${base}/api/v1/admin/settings`, { method: "PATCH", headers: { ...authHeaders, "content-type": "application/json", "idempotency-key": "settings-update-1", "if-match": String(current.version) }, body: JSON.stringify({ adminMfaRequired: false, adminCaptchaRequired: false, userMfaRequired: false, userVerificationRequired: false, captchaRequired: false, rateLimitWindowMs: 120000, rateLimitMax: 20, queueMaxConcurrent: 8, auditRetentionDays: 180, auditMaxEntries: 5000 }) }); assert.equal(updated.status, 200); const updatedPayload = await updated.json() as { data: { item: { version: number; userVerificationRequired: boolean; rateLimitWindowMs: number } } }; assert.equal(updatedPayload.data.item.version, current.version + 1); assert.equal(updatedPayload.data.item.userVerificationRequired, false); assert.equal(updatedPayload.data.item.rateLimitWindowMs, 120000); const policy = await fetch(`${base}/api/v1/auth/policy`); assert.deepEqual((await policy.json() as { data: unknown }).data, { captchaRequired: false, userVerificationRequired: false, userMfaRequired: false }); const stale = await fetch(`${base}/api/v1/admin/settings`, { method: "PATCH", headers: { ...authHeaders, "content-type": "application/json", "idempotency-key": "settings-update-stale", "if-match": String(current.version) }, body: JSON.stringify({ rateLimitMax: 21 }) }); assert.equal(stale.status, 409); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } }); test("admin recharge order PATCH only uses guarded failure/refund transitions", async () => { const { store, server, base } = await start(); try { const user = await registerAndLogin(base, "admin-order-patch@example.com"); const login = await fetch(`${base}/api/v1/admin/auth/login`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email: "admin@example.com", password: "change-me-now" }) }); const admin = await login.json() as { data: { accessToken: string } }; const headers = { authorization: `Bearer ${admin.data.accessToken}`, "content-type": "application/json", "idempotency-key": "admin-order-patch" }; const orderId = "admin-order-fixture"; store.rechargeOrders.set(orderId, { id: orderId, userId: user.registered.userId, provider: "mock", status: "pending", fiatAmount: 10, balanceAmount: 10, unitVersion: 1, idempotencyKey: "fixture-order", createdAt: new Date().toISOString() }); const failed = await fetch(`${base}/api/v1/admin/recharge-orders/${orderId}`, { method: "PATCH", headers: { ...headers, "if-match": "1" }, body: JSON.stringify({ status: "failed" }) }); assert.equal(failed.status, 200); const refund = await fetch(`${base}/api/v1/admin/recharge-orders/${orderId}`, { method: "PATCH", headers: { ...headers, "idempotency-key": "admin-order-refund", "if-match": "2" }, body: JSON.stringify({ status: "refunded" }) }); assert.equal(refund.status, 409); assert.equal(store.balances.get(user.registered.userId)?.available, 0); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } });