import { randomUUID } from "node:crypto"; import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { ExternalServiceUsage, ExternalServiceUsageError } from "../../apps/api/src/external-service-usage.js"; import { RegistrationService } from "../../apps/api/src/registration.js"; import { MockResendAdapter } from "../../apps/api/src/resend-adapter.js"; import { createApp } from "../../apps/api/src/app.js"; import { MockAmapAdapter } from "../../apps/api/src/amap-adapter.js"; const roots: string[] = []; const registrations: RegistrationService[] = []; afterEach(() => { for (const registration of registrations.splice(0)) registration.close(); for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true }); }); function createRegistration(now = Date.parse("2026-08-04T09:00:00.000Z")) { const root = mkdtempSync(join(tmpdir(), "dada-wp6-03-services-")); roots.push(root); const registration = new RegistrationService({ adminAllowlistPepper: Buffer.alloc(32, 0x91), challengePepper: Buffer.alloc(32, 0x92), clock: () => now, currentPrivacyNoticeVersion: "p0a-registration-notice-v1", databasePath: join(root, "dada.sqlite3"), invitePepper: Buffer.alloc(32, 0x93), resend: new MockResendAdapter(), sessionPepper: Buffer.alloc(32, 0x94), }); registrations.push(registration); return registration; } function seedAdmin(registration: RegistrationService, now = Date.parse("2026-08-04T09:00:00.000Z")) { const userId = randomUUID(); registration.database.prepare(` INSERT INTO users (user_id, normalized_email, role, status, counts_toward_stage_limit, registration_id, created_at) VALUES (?, ?, 'super_admin', 'active', 0, ?, ?) `).run(userId, `${userId}@example.invalid`, randomUUID(), now); registration.database.prepare("INSERT INTO admin_access (user_id, allowed) VALUES (?, 1)").run(userId); return userId; } function seedUser(registration: RegistrationService, now = Date.parse("2026-08-04T09:00:00.000Z")) { const userId = randomUUID(); registration.database.prepare(` INSERT INTO users (user_id, normalized_email, role, status, counts_toward_stage_limit, registration_id, created_at) VALUES (?, ?, 'user', 'active', 1, ?, ?) `).run(userId, `${userId}@example.invalid`, randomUUID(), now); registration.database.prepare("INSERT INTO user_profiles (user_id, creator_name, social_id) VALUES (?, 'Test User', '@test_user')").run(userId); registration.database.prepare("INSERT INTO credit_accounts (user_id, available_balance, reserved_balance, updated_at) VALUES (?, 10, 0, ?)").run(userId, now); return userId; } describe("TDD-WP6-SVC-001 quota hard stop", () => { it("claims Resend daily and monthly quotas transactionally and pauses before the next call", () => { const registration = createRegistration(); const usage = registration.serviceUsage; usage.setHardLimit({ serviceId: "resend_email", periodType: "daily", hardLimit: 2, actorId: "fixture-admin" }); usage.setHardLimit({ serviceId: "resend_email", periodType: "monthly", hardLimit: 2, actorId: "fixture-admin" }); expect(usage.claimResend()).toMatchObject({ allowed: true, remaining: 1 }); expect(usage.claimResend()).toMatchObject({ allowed: true, remaining: 0 }); expect(() => usage.claimResend()).toThrowError(ExternalServiceUsageError); expect(usage.read("resend_email").every((row) => row.status === "paused_quota")).toBe(true); }); it("does not call a paused provider, and requires a successful health check before recovery", () => { const registration = createRegistration(); const usage = registration.serviceUsage; usage.markProviderFailure({ serviceId: "amap_web_service", reason: "provider_unavailable" }); expect(() => usage.claimAmap()).toThrowError(ExternalServiceUsageError); expect(() => usage.recover({ serviceId: "amap_web_service", actorId: randomUUID(), checkId: randomUUID() })) .toThrowError(/health_check_required/); const check = usage.recordHealthCheck({ serviceId: "amap_web_service", available: true, reason: "ok" }); expect(usage.recover({ serviceId: "amap_web_service", actorId: randomUUID(), checkId: check.checkId })).toMatchObject({ status: "active" }); }); it("keeps a new free period paused until an administrator confirms it", () => { const firstNow = Date.parse("2026-08-04T23:59:00.000Z"); const registration = createRegistration(firstNow); registration.serviceUsage.claimAmap(firstNow); const nextPeriod = new ExternalServiceUsage({ database: registration.database, clock: () => Date.parse("2026-09-01T00:01:00.000Z"), }); expect(() => nextPeriod.claimAmap()).toThrowError(/service_paused_quota/); expect(nextPeriod.read("amap_web_service").find((row) => row.periodStart === Date.parse("2026-08-01T00:00:00.000Z"))?.status).toBe("active"); expect(nextPeriod.read("amap_web_service").find((row) => row.periodStart === Date.parse("2026-09-01T00:00:00.000Z"))?.status).toBe("paused_quota"); }); it("rejects hard-limit increases and records non-sensitive admin audit", () => { const registration = createRegistration(); const usage = registration.serviceUsage; expect(() => usage.setHardLimit({ serviceId: "amap_web_service", periodType: "monthly", hardLimit: 1001, actorId: randomUUID() })) .toThrowError(/hard_limit_increase_forbidden/); expect(registration.database.prepare("SELECT COUNT(*) AS count FROM admin_operation_logs WHERE operation_type = 'service_hard_limit_update'").get()) .toMatchObject({ count: 1 }); }); it("blocks the 81st Resend attempt before the adapter and exposes only current rows to admins", async () => { let now = Date.parse("2026-08-04T09:00:00.000Z"); const registration = createRegistration(now); const resend = registration.options.resend as MockResendAdapter; registration.serviceUsage.setHardLimit({ serviceId: "resend_email", periodType: "daily", hardLimit: 1, actorId: "fixture-admin" }); registration.serviceUsage.setHardLimit({ serviceId: "resend_email", periodType: "monthly", hardLimit: 1, actorId: "fixture-admin" }); const invite = registration.createInvite({ expiresAt: now + 86_400_000, maxUses: 3 }); await registration.sendRegistrationCode({ email: "quota-one@example.invalid", inviteCode: invite.code }); expect(() => registration.serviceUsage.claimResend()).toThrowError(/service_paused_quota/); expect(resend.calls).toHaveLength(1); const adminId = seedAdmin(registration, now); const adminSession = registration.issueAuthenticatedSession(adminId, "admin"); const csrfToken = registration.issueAdminCsrfToken(adminSession.sessionToken); const app = await createApp({ browserGate: false, networkBoundary: { allowTestPort: true }, registration }); await app.ready(); const response = await app.inject({ headers: { cookie: `dada_admin_session=${adminSession.sessionToken}`, host: "127.0.0.1:43121", origin: "http://127.0.0.1:43121" }, method: "GET", url: "/api/v1/admin/services", }); expect(response.statusCode).toBe(200); expect(response.json().services).toHaveLength(3); expect(response.json().services.find((row: { service_id: string; period_type: string }) => row.service_id === "resend_email" && row.period_type === "daily").service_status).toBe("paused_quota"); const health = await app.inject({ headers: { "idempotency-key": `${randomUUID()}${randomUUID()}`, "x-csrf-token": csrfToken, cookie: `dada_admin_session=${adminSession.sessionToken}`, host: "127.0.0.1:43121", origin: "http://127.0.0.1:43121" }, method: "POST", payload: { available: true, reason: "new_period" }, url: "/api/v1/admin/services/resend_email/health-check", }); expect(health.statusCode).toBe(200); await app.close(); }); it("stops DYN004 after its quota without affecting the rest of the editor", async () => { const registration = createRegistration(); const userId = seedUser(registration); const session = registration.issueAuthenticatedSession(userId, "user"); const csrfToken = registration.issueUserCsrfToken(session.sessionToken); const amap = new MockAmapAdapter(); registration.serviceUsage.setHardLimit({ serviceId: "amap_web_service", periodType: "monthly", hardLimit: 1, actorId: "fixture-admin" }); const app = await createApp({ amap, browserGate: false, networkBoundary: { allowTestPort: true }, registration }); const headers = { cookie: `dada_session=${session.sessionToken}`, host: "127.0.0.1:43121", origin: "http://127.0.0.1:43121", "x-csrf-token": csrfToken }; const first = await app.inject({ headers, method: "POST", payload: { latitude: 30, longitude: 120 }, url: "/api/v1/location/reverse-geocode" }); const second = await app.inject({ headers, method: "POST", payload: { latitude: 31, longitude: 121 }, url: "/api/v1/location/reverse-geocode" }); expect(first.statusCode).toBe(200); expect(second.statusCode).toBe(503); expect(amap.calls).toHaveLength(1); await app.close(); }); });