import type * as Analytics from '../../analytics/Analytics.js' import * as ApiKeys from '../../ApiKeys.js' import * as InvitationsApp from '../../apps/management/routes/invitations.js' import * as BillingSettings from '../../db/tables/billingSettings.js' import * as EnabledBillingSources from '../../db/tables/enabledBillingSources.js' import * as Memberships from '../../db/tables/memberships.js' import * as Organizations from '../../db/tables/organizations.js' import * as Projects from '../../db/tables/projects.js' import * as RoutesSubsidies from '../../db/tables/routesSubsidies.js' import * as SponsoredTransactions from '../../db/tables/sponsoredTransactions.js' import * as StripeCustomers from '../../db/tables/stripeCustomers.js' import * as Users from '../../db/tables/users.js' import * as WebhookDeliveries from '../../db/tables/webhookDeliveries.js' import * as WebhookSubscriptions from '../../db/tables/webhookSubscriptions.js' import type * as Email from '../../internal/Email.js' import * as RateLimit from '../../internal/RateLimit.js' import * as Store from '../../internal/Store.js' import * as Viem from '../../internal/Viem.js' import * as Deposit from '../../internal/routes/Deposit.js' import * as DepositAddress from '../../internal/routes/DepositAddress.js' import * as TestAdmin from '../../../test/Admin.js' import * as TestApp from '../../../test/App.js' import * as TestRoutes from '../../../test/Routes.js' import * as AdminOrganizations from './organizations.js' describe('GET /organizations', () => { test('lists summaries newest first with member and project counts', async () => { const { client, db } = TestAdmin.setup() const user = await Users.upsertByAddress(db, { address: `0x${'11'.repeat(20)}`, }) await Users.setEmail(db, user.id, 'owner@acme.example') const organization = await Organizations.createOwned(db, { name: 'Acme', userId: user.id }) await Projects.create(db, { name: 'Checkout', orgId: organization.id }) await Projects.create(db, { name: 'Treasury', orgId: organization.id }) const response = await client.organizations.$get({ query: {} }) const body = await TestApp.json(response, AdminOrganizations.schema.listOrganizations.Response) expect(response.status).toBe(200) expect(body.nextCursor).toBeNull() expect(body.data).toHaveLength(1) expect(body.data[0]).toMatchObject({ id: organization.id, memberCount: 1, name: 'Acme', projectCount: 2, userId: user.id, }) }) test('searches organization and member identity fields case-insensitively', async () => { const { client, db } = TestAdmin.setup() const user = await Users.upsertByAddress(db, { address: `0x${'22'.repeat(20)}`, }) await Users.setEmail(db, user.id, 'Owner@Example.com') const organization = await Organizations.createOwned(db, { name: 'Merchant Operations', userId: user.id, }) await Organizations.create(db, { id: 'org_unrelated', name: 'Unrelated' }) for (const query of ['merchant', organization.id, user.id, 'owner@']) { const response = await client.organizations.$get({ query: { query } }) const body = await TestApp.json( response, AdminOrganizations.schema.listOrganizations.Response, ) expect(body.data.map(({ id }) => id)).toEqual([organization.id]) } }) test('treats SQL wildcard characters as literal search text', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'A_B Merchant' }) await Organizations.create(db, { name: 'AcB Merchant' }) const response = await client.organizations.$get({ query: { query: 'a_b' } }) const body = await TestApp.json(response, AdminOrganizations.schema.listOrganizations.Response) expect(body.data.map(({ id }) => id)).toEqual([organization.id]) }) test('orders distinct creation times newest first', async () => { const { client, db } = TestAdmin.setup() vi.useFakeTimers() try { vi.setSystemTime(new Date('2026-01-01T00:00:00.000Z')) const older = await Organizations.create(db, { name: 'Older' }) vi.setSystemTime(new Date('2026-01-02T00:00:00.000Z')) const newer = await Organizations.create(db, { name: 'Newer' }) const response = await client.organizations.$get({ query: {} }) const body = await TestApp.json( response, AdminOrganizations.schema.listOrganizations.Response, ) expect(body.data.map(({ id }) => id)).toEqual([newer.id, older.id]) } finally { vi.useRealTimers() } }) test('rejects broad queries shorter than three characters', async () => { const { client } = TestAdmin.setup() const response = await client.organizations.$get({ query: { query: 'a' } }) expect(response.status).toBe(400) }) test('walks a stable cursor without duplicate organizations', async () => { const { client, db } = TestAdmin.setup() for (const id of ['org_f', 'org_e', 'org_d', 'org_c', 'org_b', 'org_a']) await Organizations.create(db, { id, name: id }) const firstResponse = await client.organizations.$get({ query: { limit: '5' } }) const first = await TestApp.json( firstResponse, AdminOrganizations.schema.listOrganizations.Response, ) expect(first.data).toHaveLength(5) expect(first.nextCursor).not.toBeNull() const secondResponse = await client.organizations.$get({ query: { cursor: first.nextCursor!, limit: '5' }, }) const second = await TestApp.json( secondResponse, AdminOrganizations.schema.listOrganizations.Response, ) expect(second.data).toHaveLength(1) expect(second.nextCursor).toBeNull() expect(new Set([...first.data, ...second.data].map(({ id }) => id)).size).toBe(6) }) }) describe('GET /organizations/:orgId', () => { test('returns counts and billing state split by environment', async () => { const { client, db } = TestAdmin.setup() const user = await Users.upsertByAddress(db, { address: `0x${'33'.repeat(20)}`, }) await Users.setEmail(db, user.id, 'owner@tempo.xyz') const organization = await Organizations.createOwned(db, { name: 'Tempo', userId: user.id }) await EnabledBillingSources.add(db, { createdBy: TestAdmin.identity.email, orgId: organization.id, source: 'stripe', }) await EnabledBillingSources.add(db, { createdBy: TestAdmin.identity.email, orgId: organization.id, source: 'tempo', }) await Projects.create(db, { name: 'API', orgId: organization.id }) await BillingSettings.upsert(db, { environment: 'production', orgId: organization.id, spendLimit: '250', txFeeLimit: '0.50', }) await BillingSettings.upsert(db, { environment: 'sandbox', orgId: organization.id, spendLimit: '1000', }) await StripeCustomers.create(db, { environment: 'production', orgId: organization.id, stripeCustomerId: 'cus_admin_lookup', }) await StripeCustomers.setStatus(db, organization.id, 'active', 'production') const response = await client.organizations[':orgId'].$get({ param: { orgId: organization.id }, }) const body = await TestApp.json(response, AdminOrganizations.schema.getOrganization.Response) expect(response.status).toBe(200) expect(body.memberCount).toBe(1) expect(body.projectCount).toBe(1) expect(body.billing.enabledSources).toEqual(['stripe', 'tempo']) expect(body.billing.production).toMatchObject({ settings: { spendLimit: '250', txFeeLimit: '0.50' }, source: { status: 'active', stripeCustomerId: 'cus_admin_lookup' }, }) expect(body.billing.sandbox).toMatchObject({ settings: { spendLimit: '1000', txFeeLimit: null }, source: null, }) }) test('returns empty counts and billing for a memberless organization', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Support-created' }) const response = await client.organizations[':orgId'].$get({ param: { orgId: organization.id }, }) const body = await TestApp.json(response, AdminOrganizations.schema.getOrganization.Response) expect(body).toMatchObject({ billing: { enabledSources: [], production: { settings: null, source: null }, sandbox: { settings: null, source: null }, }, memberCount: 0, projectCount: 0, }) }) test('returns 404 for an unknown organization', async () => { const { client } = TestAdmin.setup() const response = await client.organizations[':orgId'].$get({ param: { orgId: 'org_missing' }, }) const body = (await response.json()) as { error: { code: string } } expect(response.status).toBe(404) expect(body.error.code).toBe('not_found') }) }) describe('GET /organizations/:orgId/subsidies', () => { test('returns Routes and sponsorship policies', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Subsidies' }) await RoutesSubsidies.upsertOrganization(db, { frequency: 'tx', maxAmount: '5', orgId: organization.id, }) await Organizations.setSponsorshipSubsidy(db, organization.id, { attributionSpendLimit: '1000', durationDays: 90, }) const addressSnapshot = TestRoutes.depositAddressSnapshot({ address: 'source-admin-usage', subsidize: true, }) const address = await DepositAddress.create(db, { deliveryStrategy: 'provider', environment: 'production', orgId: organization.id, providerOutputToken: addressSnapshot.destinationToken, snapshot: addressSnapshot, }) const amount = { baseUnits: '250000', currency: 'USD', decimals: 6, formatted: '0.25' } const deposit = await Deposit.create(db, { providerRequestId: 'request_admin_usage', settlementTransaction: `0x${'aa'.repeat(32)}`, settlementTransactionHash: `0x${'bb'.repeat(32)}`, snapshot: TestRoutes.depositSnapshot(address.id), sourceTransactionHash: `0x${'cc'.repeat(32)}`, subsidyAmount: amount, }) await Deposit.transition(db, { expectedVersion: deposit.version, id: deposit.id, status: 'completed', subsidyAmount: amount, }) const response = await client.organizations[':orgId'].subsidies.$get({ param: { orgId: organization.id }, }) expect( await TestApp.json(response, AdminOrganizations.schema.getOrganizationSubsidies.Response), ).toEqual({ routes: { frequency: 'tx', maxAmount: '5' }, routesUsage: { amount: '0.25', count: 1, from: expect.any(String), to: expect.any(String), }, sponsorship: { attributionSpendLimit: '1000', durationDays: 90 }, }) }) test('returns disabled policies and rejects an unknown organization', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Disabled subsidies' }) const response = await client.organizations[':orgId'].subsidies.$get({ param: { orgId: organization.id }, }) expect( await TestApp.json(response, AdminOrganizations.schema.getOrganizationSubsidies.Response), ).toEqual({ routes: null, routesUsage: { amount: '0', count: 0, from: expect.any(String), to: expect.any(String), }, sponsorship: { attributionSpendLimit: null, durationDays: null }, }) const missing = await client.organizations[':orgId'].subsidies.$get({ param: { orgId: 'org_missing' }, }) expect(missing.status).toBe(404) }) }) describe('PUT /organizations/:orgId/subsidies/routes', () => { test('enables and disables a maximum subsidy amount', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Routes' }) const enabled = await client.organizations[':orgId'].subsidies.routes.$put({ json: { enabled: true, frequency: 'tx', maxAmount: '25.50' }, param: { orgId: organization.id }, }) expect( await TestApp.json(enabled, AdminOrganizations.schema.setOrganizationRoutesSubsidy.Response), ).toEqual({ frequency: 'tx', maxAmount: '25.50' }) expect(await RoutesSubsidies.getOrganization(db, organization.id)).toMatchObject({ enabled: true, frequency: 'tx', maxAmount: '25.50', }) const disabled = await client.organizations[':orgId'].subsidies.routes.$put({ json: { enabled: false }, param: { orgId: organization.id }, }) expect( await TestApp.json(disabled, AdminOrganizations.schema.setOrganizationRoutesSubsidy.Response), ).toBeNull() expect(await RoutesSubsidies.getOrganization(db, organization.id)).toBeUndefined() }) test('rejects invalid limits and unknown organizations', async () => { const { app, client } = TestAdmin.setup() for (const maxAmount of ['0', '0.000000', '-1', '1.0000001']) { const invalid = await app.request('/organizations/org_example/subsidies/routes', { body: JSON.stringify({ enabled: true, frequency: 'tx', maxAmount }), headers: { 'content-type': 'application/json' }, method: 'PUT', }) expect(invalid.status).toBe(400) } const invalidFrequency = await app.request('/organizations/org_example/subsidies/routes', { body: JSON.stringify({ enabled: true, frequency: 'day', maxAmount: '5' }), headers: { 'content-type': 'application/json' }, method: 'PUT', }) expect(invalidFrequency.status).toBe(400) const missing = await client.organizations[':orgId'].subsidies.routes.$put({ json: { enabled: true, frequency: 'tx', maxAmount: '5' }, param: { orgId: 'org_missing' }, }) expect(missing.status).toBe(404) }) }) describe('PUT /organizations/:orgId/subsidies/sponsorship', () => { test('enables and disables a 90-day per-attribution policy', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Privy' }) const enabled = await client.organizations[':orgId'].subsidies.sponsorship.$put({ json: { attributionSpendLimit: '1000', enabled: true }, param: { orgId: organization.id }, }) expect( await TestApp.json( enabled, AdminOrganizations.schema.setOrganizationSponsorshipSubsidy.Response, ), ).toEqual({ attributionSpendLimit: '1000', durationDays: 90 }) const disabled = await client.organizations[':orgId'].subsidies.sponsorship.$put({ json: { enabled: false }, param: { orgId: organization.id }, }) expect( await TestApp.json( disabled, AdminOrganizations.schema.setOrganizationSponsorshipSubsidy.Response, ), ).toEqual({ attributionSpendLimit: null, durationDays: null }) }) test('enables an uncapped policy', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Privy' }) const response = await client.organizations[':orgId'].subsidies.sponsorship.$put({ json: { enabled: true }, param: { orgId: organization.id }, }) expect( await TestApp.json( response, AdminOrganizations.schema.setOrganizationSponsorshipSubsidy.Response, ), ).toEqual({ attributionSpendLimit: null, durationDays: 90 }) }) test('rejects invalid limits and unknown organizations', async () => { const { app, client } = TestAdmin.setup() const invalid = await app.request('/organizations/org_example/subsidies/sponsorship', { body: JSON.stringify({ attributionSpendLimit: '-1', enabled: true }), headers: { 'content-type': 'application/json' }, method: 'PUT', }) expect(invalid.status).toBe(400) const missing = await client.organizations[':orgId'].subsidies.sponsorship.$put({ json: { attributionSpendLimit: '1000', enabled: true }, param: { orgId: 'org_missing' }, }) expect(missing.status).toBe(404) }) }) describe('PUT/DELETE /organizations/:orgId/billing-sources/:source', () => { test('enables and disables sources idempotently', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Billing sources' }) for (const source of ['tempo', 'stripe', 'stripe'] as const) { const response = await client.organizations[':orgId']['billing-sources'][':source'].$put({ param: { orgId: organization.id, source }, }) const body = await TestApp.json(response, AdminOrganizations.schema.setBillingSource.Response) expect(response.status).toBe(200) expect(body.data).toEqual(source === 'tempo' ? ['tempo'] : ['stripe', 'tempo']) } expect(await EnabledBillingSources.listByOrg(db, organization.id)).toMatchObject([ { createdBy: TestAdmin.identity.email, source: 'stripe' }, { createdBy: TestAdmin.identity.email, source: 'tempo' }, ]) for (const source of ['stripe', 'stripe'] as const) { const response = await client.organizations[':orgId']['billing-sources'][':source'].$delete({ param: { orgId: organization.id, source }, }) const body = await TestApp.json(response, AdminOrganizations.schema.setBillingSource.Response) expect(response.status).toBe(200) expect(body.data).toEqual(['tempo']) } const detailResponse = await client.organizations[':orgId'].$get({ param: { orgId: organization.id }, }) const detail = await TestApp.json( detailResponse, AdminOrganizations.schema.getOrganization.Response, ) expect(detail.billing.enabledSources).toEqual(['tempo']) }) test('rejects unsupported sources and unknown organizations', async () => { const { app, client } = TestAdmin.setup() const invalid = await app.request('/organizations/org_example/billing-sources/card', { method: 'PUT', }) expect(invalid.status).toBe(400) const missing = await client.organizations[':orgId']['billing-sources'][':source'].$put({ param: { orgId: 'org_missing', source: 'stripe' }, }) expect(missing.status).toBe(404) }) test('records billing-source mutations in the admin audit log', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Audited billing' }) await client.organizations[':orgId']['billing-sources'][':source'].$put({ param: { orgId: organization.id, source: 'tempo' }, }) const records = await db.kysely .selectFrom('admin_audit_logs') .selectAll() .orderBy('createdAt', 'desc') .execute() expect(records[0]).toMatchObject({ actor: TestAdmin.identity.email, method: 'PUT', path: `/organizations/${organization.id}/billing-sources/tempo`, status: 200, }) }) }) describe('GET /organizations/:orgId/members', () => { test('returns a bounded cursor page without duplicates', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Members' }) for (let index = 0; index < 6; index++) { const user = await Users.upsertByAddress(db, { address: `0x${String(index + 1).padStart(40, '0')}`, }) await Users.setEmail(db, user.id, `member-${index}@example.com`) await Memberships.create(db, { orgId: organization.id, role: 'member', userId: user.id }) } const firstResponse = await client.organizations[':orgId'].members.$get({ param: { orgId: organization.id }, query: { limit: '5' }, }) const first = await TestApp.json( firstResponse, AdminOrganizations.schema.listOrganizationMembers.Response, ) const secondResponse = await client.organizations[':orgId'].members.$get({ param: { orgId: organization.id }, query: { cursor: first.nextCursor!, limit: '5' }, }) const second = await TestApp.json( secondResponse, AdminOrganizations.schema.listOrganizationMembers.Response, ) expect(first.data).toHaveLength(5) expect(second.data).toHaveLength(1) expect(new Set([...first.data, ...second.data].map(({ userId }) => userId)).size).toBe(6) }) }) describe('POST /organizations/:orgId/invitations', () => { test('creates and emails the standard organization invitation', async () => { const db = TestApp.database() const sent: Email.Message[] = [] const admin = TestAdmin.setup({ db, email: { from: 'noreply@tempo.test', send: (message) => { sent.push(message) return Promise.resolve() }, }, }) const organization = await Organizations.create(db, { name: 'Members' }) const response = await admin.client.organizations[':orgId'].invitations.$post({ json: { email: 'new.member@example.com', role: 'admin' }, param: { orgId: organization.id }, }) const invitation = await TestApp.json(response, InvitationsApp.schema.Invitation) expect(response.status).toBe(200) expect(invitation).toMatchObject({ email: 'new.member@example.com', invitedBy: 'super_admin', orgId: organization.id, role: 'admin', }) expect(sent).toMatchObject([ { subject: `You've been invited to Members on the Tempo Developer Platform`, to: 'new.member@example.com', }, ]) }) test('caps admin invitation email dispatch with the shared global quota', async () => { const now = () => new Date('2026-01-01T00:00:00.000Z') const store = Store.memory() const limiter = RateLimit.memory({ now, store }) for (let index = 0; index < 100; index++) await limiter.consume({ key: 'invitation-email:global', limit: { limit: 100, period: 'minute' }, }) const sent: Email.Message[] = [] const admin = TestAdmin.setup({ email: { from: 'noreply@tempo.test', send: (message) => { sent.push(message) return Promise.resolve() }, }, rateLimit: { now, store }, }) const organization = await Organizations.create(admin.db, { name: 'Members' }) const response = await admin.client.organizations[':orgId'].invitations.$post({ json: { email: 'new.member@example.com', role: 'admin' }, param: { orgId: organization.id }, }) expect({ scope: response.headers.get('rateLimit-scope'), sent: sent.length, status: response.status, }).toEqual({ scope: 'invitation-email-global', sent: 0, status: 429 }) }) }) describe('GET /organizations/:orgId/projects', () => { test('returns a bounded cursor page without duplicates', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Projects' }) for (let index = 0; index < 6; index++) await Projects.create(db, { name: `Project ${index}`, orgId: organization.id }) const firstResponse = await client.organizations[':orgId'].projects.$get({ param: { orgId: organization.id }, query: { limit: '5' }, }) const first = await TestApp.json( firstResponse, AdminOrganizations.schema.listOrganizationProjects.Response, ) const secondResponse = await client.organizations[':orgId'].projects.$get({ param: { orgId: organization.id }, query: { cursor: first.nextCursor!, limit: '5' }, }) const second = await TestApp.json( secondResponse, AdminOrganizations.schema.listOrganizationProjects.Response, ) expect(first.data).toHaveLength(5) expect(second.data).toHaveLength(1) expect(new Set([...first.data, ...second.data].map(({ id }) => id)).size).toBe(6) }) }) describe('GET /organizations/:orgId/api-keys', () => { test('returns active key environment, scopes, and creator without tokens', async () => { const { client, db, store } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Keys' }) await ApiKeys.mint(store, { createdBy: 'ops@tempo.xyz', environment: 'sandbox', orgId: organization.id, scopes: ['data:read'], }) const response = await client.organizations[':orgId']['api-keys'].$get({ param: { orgId: organization.id }, }) const body = await TestApp.json( response, AdminOrganizations.schema.listOrganizationApiKeys.Response, ) expect(body.data[0]).toMatchObject({ createdBy: 'ops@tempo.xyz', environment: 'sandbox', scopes: ['data:read'], }) expect(body.data[0]).not.toHaveProperty('status') expect(body.data[0]).not.toHaveProperty('token') }) }) describe('GET /organizations/:orgId/usage', () => { test('returns recent totals and error breakdowns from analytics', async () => { const { client, db } = TestAdmin.setup({ analytics: usageAnalytics }) const organization = await Organizations.create(db, { name: 'Usage' }) const response = await client.organizations[':orgId'].usage.$get({ param: { orgId: organization.id }, query: { period: '7d' }, }) const body = await TestApp.json( response, AdminOrganizations.schema.getOrganizationUsage.Response, ) expect(body).toMatchObject({ byError: [{ code: 'upstream_error', requests: 2 }], byRoute: [{ averageDurationMs: 12.5, errors: 2, requests: 20, route: '/v1/tokens' }], byStatus: [{ requests: 2, status: 500 }], period: '7d', totals: { averageDurationMs: 10.5, errors: 2, requests: 25 }, }) }) }) describe('GET /organizations/:orgId/sponsorship', () => { test('includes configured Zone charges in each environment', async () => { const { client, db } = TestAdmin.setup({ zones: [ TestApp.zone({ chainId: 8001, rpcUrl: 'https://zone.example', sourceChainId: Viem.chainId.mainnet, }), TestApp.zone({ chainId: 8002, rpcUrl: 'https://zone.example', sourceChainId: Viem.chainId.mainnet, }), TestApp.zone({ chainId: 8003, rpcUrl: 'https://zone.example' }), ], }) const organization = await Organizations.create(db, { name: 'Zone sponsorship' }) for (const [index, row] of [ { chainId: Viem.chainId.mainnet, feeAmount: '100000' }, { chainId: 8001, feeAmount: '200000' }, { chainId: 8002, feeMax: '250000' }, { chainId: 8003, feeMax: '900000' }, { billable: false, chainId: 8001, feeMax: '900000' }, { chainId: 8004, feeMax: '900000' }, { billable: false, chainId: Viem.chainId.testnet, environment: 'sandbox' as const, feeMax: '150000', }, { billable: false, chainId: 8003, environment: 'sandbox' as const, feeAmount: '350000' }, ].entries()) { const { feeAmount, ...input } = row const record = await SponsoredTransactions.upsert(db, { apiKeyId: 'key_1', billable: true, environment: 'production', feeMax: '1000000', orgId: organization.id, projectId: 'prj_1', signPayload: `0x${String(index + 10).repeat(32)}`, transaction: `0x${'22'.repeat(32)}`, ...input, }) if (feeAmount) await SponsoredTransactions.finalize(db, record.id, { feeAmount, finalizedAt: new Date().toISOString(), }) } const response = await client.organizations[':orgId'].sponsorship.$get({ param: { orgId: organization.id }, }) const body = await TestApp.json( response, AdminOrganizations.schema.organizationSponsorship.GetResponse, ) expect(response.status).toBe(200) expect(body.production.committedSpend).toMatchInlineSnapshot(`"0.55"`) expect(body.sandbox.committedSpend).toMatchInlineSnapshot(`"0.5"`) }) test('returns current-period committed spend split by environment', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Sponsorship' }) await SponsoredTransactions.upsert(db, { apiKeyId: 'key_1', billable: true, chainId: Viem.chainId.mainnet, environment: 'production', feeMax: '1250000', orgId: organization.id, projectId: 'prj_1', signPayload: `0x${'11'.repeat(32)}`, transaction: `0x${'22'.repeat(32)}`, }) const response = await client.organizations[':orgId'].sponsorship.$get({ param: { orgId: organization.id }, }) const body = await TestApp.json( response, AdminOrganizations.schema.organizationSponsorship.GetResponse, ) expect(body.production).toMatchObject({ committedSpend: '1.25', currency: 'usd', period: 'month', }) expect(body.sandbox).toMatchObject({ committedSpend: '0', currency: 'usd', period: 'month', }) }) }) describe('GET /organizations/:orgId/webhooks', () => { test('redacts destinations and returns recent delivery failures', async () => { const { client, db } = TestAdmin.setup() const organization = await Organizations.create(db, { name: 'Webhooks' }) const createdAt = new Date().toISOString() await WebhookSubscriptions.insert(db, { chainId: 4217, createdAt, destination: { type: 'url', url: 'https://hooks.example.com/private/path' }, eventType: 'token:transfer', failureCount: 1, filters: {}, id: 'wh_admin_visibility', owner: { orgId: organization.id, type: 'api_key' }, secret: 'secret', status: 'active', updatedAt: createdAt, }) for (let index = 0; index < 26; index++) await WebhookDeliveries.insert( db, { attempt: 1, createdAt, envelope: { chainId: 4217, createdAt, data: {}, id: `evt_admin_visibility_${index}`, subscriptionId: 'wh_admin_visibility', type: 'token:transfer', }, error: 'HTTP 500', eventId: `evt_admin_visibility_${index}`, id: `whd_admin_visibility_${index}`, requestUrl: 'https://hooks.example.com/private/path', responseStatus: 500, status: 'failed', subscriptionId: 'wh_admin_visibility', }, new Date(Date.now() + 60_000).toISOString(), ) const oldCreatedAt = new Date(Date.now() - 8 * 24 * 60 * 60 * 1_000).toISOString() await WebhookDeliveries.insert( db, { attempt: 1, createdAt: oldCreatedAt, envelope: { chainId: 4217, createdAt: oldCreatedAt, data: {}, id: 'evt_admin_visibility_old', subscriptionId: 'wh_admin_visibility', type: 'token:transfer', }, error: 'HTTP 500', eventId: 'evt_admin_visibility_old', id: 'whd_admin_visibility_old', requestUrl: 'https://hooks.example.com/private/path', responseStatus: 500, status: 'failed', subscriptionId: 'wh_admin_visibility', }, new Date(Date.now() + 60_000).toISOString(), ) const response = await client.organizations[':orgId'].webhooks.$get({ param: { orgId: organization.id }, }) const body = await TestApp.json( response, AdminOrganizations.schema.getOrganizationWebhooks.Response, ) expect(body.subscriptions[0]?.destination).toBe('https://hooks.example.com/…') expect(body.failureCount).toBe(26) expect(body.failures).toHaveLength(25) expect(body.failures[0]).toMatchObject({ error: 'HTTP 500', responseStatus: 500 }) expect(body.failuresTruncated).toBe(true) }) }) const usageAnalytics: Analytics.Analytics = { async insert() {}, async migrate() {}, async query(sql) { if (sql.includes('GROUP BY code')) return [{ code: 'upstream_error', requests: 2 }] as never[] if (sql.includes('GROUP BY route')) return [{ averageDurationMs: 12.5, errors: 2, requests: 20, route: '/v1/tokens' }] as never[] if (sql.includes('GROUP BY status')) return [{ requests: 2, status: 500 }] as never[] if (sql.includes('GROUP BY key_id') || sql.includes('GROUP BY toStartOf')) return [] return [{ averageDurationMs: 10.5, errors: 2, requests: 25 }] as never[] }, }