From 1d8cd6854386f46ce06289c7f730ab5a105451a1 Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Thu, 23 Jul 2026 18:25:51 +0100 Subject: [PATCH 1/2] refactor(billing): fetch billing history via the generated OpenAPI SDK Replace the hand-written StripeService.getCustomerTransactions call in the billing-history query with the generated api.v1.listStripeTransactions client, so its request/response types follow the API contract instead of being kept in sync by hand. Regenerate console-api-types for the transactions endpoint (offset pagination and the current response shape), derive the view's transaction type from the generated paths, and switch the query's error handling to ApiError. CSV export stays on the hand-written client. Ref CON-747 --- apps/api/swagger/openapi.json | 192 ++++-------------- .../BillingContainer.spec.tsx | 17 +- .../BillingContainer/BillingContainer.tsx | 7 +- .../BillingView/BillingView.spec.tsx | 2 +- .../billing-usage/BillingView/BillingView.tsx | 2 +- apps/deploy-web/src/queries/queryKeys.spec.ts | 64 ------ apps/deploy-web/src/queries/queryKeys.ts | 22 -- .../src/queries/usePaymentQueries.spec.tsx | 25 ++- .../src/queries/usePaymentQueries.ts | 30 +-- apps/deploy-web/tests/seeders/payment.ts | 3 +- .../console-api-types/src/operations.gen.ts | 2 +- packages/console-api-types/src/schema.d.ts | 47 +---- 12 files changed, 86 insertions(+), 327 deletions(-) diff --git a/apps/api/swagger/openapi.json b/apps/api/swagger/openapi.json index 621a3220b3..9255a81341 100644 --- a/apps/api/swagger/openapi.json +++ b/apps/api/swagger/openapi.json @@ -1632,22 +1632,14 @@ }, { "schema": { - "type": "string", - "description": "ID of the last transaction from the previous page (if paginating forwards)", - "example": "ch_1234567890" - }, - "required": false, - "name": "startingAfter", - "in": "query" - }, - { - "schema": { - "type": "string", - "description": "ID of the first transaction from the previous page (if paginating backwards)", - "example": "ch_0987654321" + "type": "number", + "description": "Number of transactions to skip for pagination", + "minimum": 0, + "example": 0, + "default": 0 }, "required": false, - "name": "endingBefore", + "name": "offset", "in": "query" }, { @@ -1692,9 +1684,20 @@ "id": { "type": "string" }, + "type": { + "type": "string", + "enum": [ + "payment_intent", + "coupon_claim", + "manual_credit" + ] + }, "amount": { "type": "number" }, + "amountRefunded": { + "type": "number" + }, "bonusAmount": { "type": "number" }, @@ -1707,136 +1710,17 @@ "created": { "type": "number" }, - "paymentMethod": { - "type": "object", - "nullable": true, - "properties": { - "type": { - "type": "string" - }, - "validated": { - "type": "boolean" - }, - "isDefault": { - "type": "boolean" - }, - "card": { - "type": "object", - "nullable": true, - "properties": { - "brand": { - "type": "string", - "nullable": true - }, - "last4": { - "type": "string", - "nullable": true - }, - "exp_month": { - "type": "number" - }, - "exp_year": { - "type": "number" - }, - "funding": { - "type": "string", - "nullable": true - }, - "country": { - "type": "string", - "nullable": true - }, - "network": { - "type": "string", - "nullable": true - }, - "three_d_secure_usage": { - "type": "object", - "nullable": true, - "properties": { - "supported": { - "type": "boolean", - "nullable": true - } - } - } - }, - "required": [ - "brand", - "last4", - "exp_month", - "exp_year" - ] - }, - "link": { - "type": "object", - "nullable": true, - "properties": { - "email": { - "type": "string", - "nullable": true - } - } - }, - "billing_details": { - "type": "object", - "properties": { - "address": { - "type": "object", - "nullable": true, - "properties": { - "city": { - "type": "string", - "nullable": true - }, - "country": { - "type": "string", - "nullable": true - }, - "line1": { - "type": "string", - "nullable": true - }, - "line2": { - "type": "string", - "nullable": true - }, - "postal_code": { - "type": "string", - "nullable": true - }, - "state": { - "type": "string", - "nullable": true - } - }, - "required": [ - "city", - "country", - "line1", - "line2", - "postal_code", - "state" - ] - }, - "email": { - "type": "string", - "nullable": true - }, - "name": { - "type": "string", - "nullable": true - }, - "phone": { - "type": "string", - "nullable": true - } - } - } - }, - "required": [ - "type" - ] + "cardBrand": { + "type": "string", + "nullable": true + }, + "cardLast4": { + "type": "string", + "nullable": true + }, + "stripeInvoiceId": { + "type": "string", + "nullable": true }, "receiptUrl": { "type": "string", @@ -1845,35 +1729,29 @@ "description": { "type": "string", "nullable": true - }, - "metadata": { - "type": "object", - "nullable": true, - "additionalProperties": { - "type": "string" - } } }, "required": [ "id", + "type", "amount", + "amountRefunded", "currency", "status", - "created", - "paymentMethod" + "created" ] } }, + "totalCount": { + "type": "number" + }, "hasMore": { "type": "boolean" - }, - "nextPage": { - "type": "string", - "nullable": true } }, "required": [ "transactions", + "totalCount", "hasMore" ] } diff --git a/apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.spec.tsx b/apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.spec.tsx index e249bffac9..a62e0310ad 100644 --- a/apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.spec.tsx +++ b/apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.spec.tsx @@ -1,11 +1,9 @@ import React from "react"; -import type { BillingTransaction } from "@akashnetwork/http-sdk"; +import { ApiError } from "@akashnetwork/openapi-sdk"; import type { PaginationState } from "@tanstack/react-table"; -import type { AxiosError } from "axios"; import { describe, expect, it, type MockedFunction, vi } from "vitest"; -import { mock } from "vitest-mock-extended"; -import type { usePaymentTransactionsQuery } from "@src/queries"; +import type { BillingTransaction, usePaymentTransactionsQuery } from "@src/queries"; import type { ChildrenProps } from "./BillingContainer"; import { BillingContainer } from "./BillingContainer"; @@ -28,12 +26,9 @@ describe(BillingContainer.name, () => { expect(child.isError).toBe(true); }); - it("passes error object if queryError is axios error", async () => { - const axiosError = mock({ - isAxiosError: true, - response: { data: { message: "fail" } } - }); - const { child } = await setup({ queryError: axiosError }); + it("surfaces the API error message when the query fails", async () => { + const apiError = new ApiError(500, { message: "fail" }, "GET /v1/stripe/transactions → 500"); + const { child } = await setup({ queryError: apiError }); expect(child.errorMessage).toBe("fail"); }); @@ -69,7 +64,7 @@ describe(BillingContainer.name, () => { data: { transactions: BillingTransaction[]; hasMore: boolean; totalCount: number }; isFetching: boolean; isError: boolean; - queryError: AxiosError; + queryError: Error; }> = {} ) { const useDefaultData = !Object.prototype.hasOwnProperty.call(overrides, "data"); diff --git a/apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.tsx b/apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.tsx index dc804017aa..e746f54789 100644 --- a/apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.tsx +++ b/apps/deploy-web/src/components/billing-usage/BillingContainer/BillingContainer.tsx @@ -1,10 +1,11 @@ import React, { useState } from "react"; -import type { BillingTransaction } from "@akashnetwork/http-sdk"; +import { ApiError, extractApiErrorMessage } from "@akashnetwork/openapi-sdk"; import { useToast } from "@akashnetwork/ui/hooks"; import type { PaginationState } from "@tanstack/react-table"; import axios from "axios"; import { useServices } from "@src/context/ServicesProvider"; +import type { BillingTransaction } from "@src/queries"; import { usePaymentTransactionsQuery } from "@src/queries"; import { createDateRange } from "@src/utils/dateUtils"; import { downloadCsv } from "@src/utils/domUtils"; @@ -56,8 +57,8 @@ export const BillingContainer: React.FC = ({ children, de }); React.useEffect(() => { - if (axios.isAxiosError(queryError)) { - setErrorMessage(queryError.response?.data.message || "An error occurred while fetching payment transactions."); + if (queryError instanceof ApiError) { + setErrorMessage(extractApiErrorMessage(queryError) || "An error occurred while fetching payment transactions."); } }, [queryError]); diff --git a/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx b/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx index 2d35913213..817512524c 100644 --- a/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx +++ b/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx @@ -1,8 +1,8 @@ import React from "react"; -import type { BillingTransaction } from "@akashnetwork/http-sdk"; import { TooltipProvider } from "@akashnetwork/ui/components"; import { describe, expect, it, vi } from "vitest"; +import type { BillingTransaction } from "@src/queries"; import type { BillingViewProps } from "./BillingView"; import { BillingView } from "./BillingView"; diff --git a/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx b/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx index 5dd8248b13..dd8fc1bbf0 100644 --- a/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx +++ b/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx @@ -1,6 +1,5 @@ import React from "react"; import { FormattedNumber } from "react-intl"; -import type { BillingTransaction } from "@akashnetwork/http-sdk"; import { Alert, AlertDescription, @@ -32,6 +31,7 @@ import { Download, Page } from "iconoir-react"; import Link from "next/link"; import { Title } from "@src/components/shared/Title"; +import type { BillingTransaction } from "@src/queries"; import { capitalizeFirstLetter } from "@src/utils/stringUtils"; export const COMPONENTS = { diff --git a/apps/deploy-web/src/queries/queryKeys.spec.ts b/apps/deploy-web/src/queries/queryKeys.spec.ts index d6b2329e47..2f778a908f 100644 --- a/apps/deploy-web/src/queries/queryKeys.spec.ts +++ b/apps/deploy-web/src/queries/queryKeys.spec.ts @@ -3,70 +3,6 @@ import { describe, expect, it } from "vitest"; import { QueryKeys } from "./queryKeys"; describe("QueryKeys", () => { - describe("Payment transactions query key", () => { - it("should return basic payment transactions key with no options", () => { - expect(QueryKeys.getPaymentTransactionsKey()).toEqual(["STRIPE_TRANSACTIONS"]); - }); - - it("should return payment transactions key with limit", () => { - expect(QueryKeys.getPaymentTransactionsKey({ limit: 10 })).toEqual(["STRIPE_TRANSACTIONS", "limit", "10"]); - expect(QueryKeys.getPaymentTransactionsKey({ limit: 50 })).toEqual(["STRIPE_TRANSACTIONS", "limit", "50"]); - }); - - it("returns payment transactions key with offset", () => { - expect(QueryKeys.getPaymentTransactionsKey({ offset: 10 })).toEqual(["STRIPE_TRANSACTIONS", "offset", "10"]); - expect(QueryKeys.getPaymentTransactionsKey({ offset: 20 })).toEqual(["STRIPE_TRANSACTIONS", "offset", "20"]); - }); - - it("should return payment transactions key with created start_date", () => { - const startDate = new Date(); - expect(QueryKeys.getPaymentTransactionsKey({ startDate })).toEqual(["STRIPE_TRANSACTIONS", "start_date", startDate.toISOString()]); - }); - - it("should return payment transactions key with created end_date", () => { - const endDate = new Date(); - expect(QueryKeys.getPaymentTransactionsKey({ endDate })).toEqual(["STRIPE_TRANSACTIONS", "end_date", endDate.toISOString()]); - }); - - it("should return payment transactions key with created start_date and end_date", () => { - const startDate = new Date(1234567890); - const endDate = new Date(1234567900); - expect(QueryKeys.getPaymentTransactionsKey({ startDate, endDate })).toEqual([ - "STRIPE_TRANSACTIONS", - "start_date", - startDate.toISOString(), - "end_date", - endDate.toISOString() - ]); - }); - - it("returns payment transactions key with multiple options", () => { - const startDate = new Date(1234567890); - const endDate = new Date(1234567900); - expect( - QueryKeys.getPaymentTransactionsKey({ - limit: 25, - offset: 50, - startDate, - endDate - }) - ).toEqual(["STRIPE_TRANSACTIONS", "limit", "25", "offset", "50", "start_date", startDate.toISOString(), "end_date", endDate.toISOString()]); - }); - - it("omits offset when it is null or zero", () => { - expect(QueryKeys.getPaymentTransactionsKey({ offset: null })).toEqual(["STRIPE_TRANSACTIONS"]); - expect(QueryKeys.getPaymentTransactionsKey({ offset: 0 })).toEqual(["STRIPE_TRANSACTIONS"]); - }); - - it("should handle partial created options", () => { - expect(QueryKeys.getPaymentTransactionsKey()).toEqual(["STRIPE_TRANSACTIONS"]); - const startDate = new Date(1234567890); - expect(QueryKeys.getPaymentTransactionsKey({ startDate })).toEqual(["STRIPE_TRANSACTIONS", "start_date", startDate.toISOString()]); - const endDate = new Date(1234567900); - expect(QueryKeys.getPaymentTransactionsKey({ endDate })).toEqual(["STRIPE_TRANSACTIONS", "end_date", endDate.toISOString()]); - }); - }); - describe("Export transactions CSV query key", () => { it("should return basic export transactions CSV key with timezone", () => { expect(QueryKeys.getExportTransactionsCsvKey({ timezone: "UTC" })).toEqual(["EXPORT_TRANSACTIONS_CSV", "UTC"]); diff --git a/apps/deploy-web/src/queries/queryKeys.ts b/apps/deploy-web/src/queries/queryKeys.ts index 27a65fe1e5..354a184b27 100644 --- a/apps/deploy-web/src/queries/queryKeys.ts +++ b/apps/deploy-web/src/queries/queryKeys.ts @@ -81,28 +81,6 @@ export class QueryKeys { */ static getManagedWalletCreateMutationKey = () => ["MANAGED_WALLET_CREATE"]; - static getPaymentTransactionsKey = (options?: { limit?: number; offset?: number | null; startDate?: Date | null; endDate?: Date | null }) => { - const key = ["STRIPE_TRANSACTIONS"]; - - if (options?.limit) { - key.push("limit", options.limit.toString()); - } - - if (options?.offset) { - key.push("offset", options.offset.toString()); - } - - if (options?.startDate) { - key.push("start_date", options.startDate.toISOString()); - } - - if (options?.endDate) { - key.push("end_date", options.endDate.toISOString()); - } - - return key; - }; - static getExportTransactionsCsvKey = (options: { startDate?: Date | null; endDate?: Date | null; timezone: string }) => { const key = ["EXPORT_TRANSACTIONS_CSV", options.timezone]; diff --git a/apps/deploy-web/src/queries/usePaymentQueries.spec.tsx b/apps/deploy-web/src/queries/usePaymentQueries.spec.tsx index 73eb10c021..cbe00b8a54 100644 --- a/apps/deploy-web/src/queries/usePaymentQueries.spec.tsx +++ b/apps/deploy-web/src/queries/usePaymentQueries.spec.tsx @@ -106,19 +106,16 @@ describe("usePaymentQueries", () => { }); it("fetches payment transactions", async () => { - const mockTransactions = { - transactions: createMockItems(createMockTransaction, 2) - }; - const stripeService = mock({ - getCustomerTransactions: vi.fn().mockResolvedValue(mockTransactions) - }); + const transactions = createMockItems(createMockTransaction, 2); + const listStripeTransactions = vi.fn().mockResolvedValue({ data: { transactions, totalCount: 2, hasMore: false } }); + const api = createProxy({ v1: { listStripeTransactions } }) as unknown as ApiService; const { result } = setupQuery(() => usePaymentTransactionsQuery({ limit: 2 }), { - services: { stripe: () => stripeService } + services: { api: () => api } }); await vi.waitFor(() => { - expect(stripeService.getCustomerTransactions).toHaveBeenCalledWith({ limit: 2 }); + expect(listStripeTransactions).toHaveBeenCalledWith(expect.objectContaining({ limit: 2 })); expect(result.current.isSuccess).toBe(true); - expect(result.current.data?.transactions).toEqual(mockTransactions.transactions); + expect(result.current.data?.transactions).toEqual(transactions); }); }); @@ -142,8 +139,9 @@ describe("usePaymentQueries", () => { const stripeService = mock({ confirmPayment: vi.fn().mockResolvedValue(mockPaymentResponse) }); + const api = createProxy({ v1: { listStripeTransactions: vi.fn() } }) as unknown as ApiService; const { result, queryClient } = setupQueryWithClient(() => usePaymentMutations(), { - services: { stripe: () => stripeService } + services: { stripe: () => stripeService, api: () => api } }); const invalidateQueriesSpy = vi.spyOn(queryClient, "invalidateQueries"); @@ -159,7 +157,7 @@ describe("usePaymentQueries", () => { await vi.waitFor(() => { expect(stripeService.confirmPayment).toHaveBeenCalled(); expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: QueryKeys.getPaymentMethodsKey() }); - expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: QueryKeys.getPaymentTransactionsKey() }); + expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: api.v1.listStripeTransactions.getKey() }); }); }); @@ -168,8 +166,9 @@ describe("usePaymentQueries", () => { const stripeService = mock({ confirmPayment: vi.fn().mockResolvedValue(mockPaymentResponse) }); + const api = createProxy({ v1: { listStripeTransactions: vi.fn() } }) as unknown as ApiService; const { result, queryClient } = setupQueryWithClient(() => usePaymentMutations(), { - services: { stripe: () => stripeService } + services: { stripe: () => stripeService, api: () => api } }); const invalidateQueriesSpy = vi.spyOn(queryClient, "invalidateQueries"); @@ -184,7 +183,7 @@ describe("usePaymentQueries", () => { await vi.waitFor(() => { expect(stripeService.confirmPayment).toHaveBeenCalled(); - expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: QueryKeys.getPaymentTransactionsKey() }); + expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: api.v1.listStripeTransactions.getKey() }); }); expect(invalidateQueriesSpy).not.toHaveBeenCalledWith({ queryKey: QueryKeys.getPaymentMethodsKey() }); }); diff --git a/apps/deploy-web/src/queries/usePaymentQueries.ts b/apps/deploy-web/src/queries/usePaymentQueries.ts index fc25c5a099..1039068a24 100644 --- a/apps/deploy-web/src/queries/usePaymentQueries.ts +++ b/apps/deploy-web/src/queries/usePaymentQueries.ts @@ -3,7 +3,6 @@ import type { ApplyCouponParams, ConfirmPaymentParams, ConfirmPaymentResponse, - CustomerTransactionsResponse, PaymentMethod, SetupIntentResponse, ThreeDSecureAuthParams @@ -43,6 +42,10 @@ export const useDefaultPaymentMethodQuery = ( }); }; +type ListStripeTransactionsResponse = paths["/v1/stripe/transactions"]["get"]["responses"][200]["content"]["application/json"]; + +export type BillingTransaction = ListStripeTransactionsResponse["data"]["transactions"][number]; + export interface UsePaymentTransactionsOptions { limit?: number; offset?: number | null; @@ -50,18 +53,17 @@ export interface UsePaymentTransactionsOptions { endDate?: Date | null; } -export const usePaymentTransactionsQuery = ( - options?: UsePaymentTransactionsOptions, - queryOptions?: Omit, "queryKey" | "queryFn"> -) => { - const { stripe } = useServices(); - return useQuery({ - ...queryOptions, - queryKey: QueryKeys.getPaymentTransactionsKey(options), - queryFn: async () => { - return await stripe.getCustomerTransactions(options); - } - }); +export const usePaymentTransactionsQuery = ({ limit, offset, startDate, endDate }: UsePaymentTransactionsOptions = {}) => { + const { api } = useServices(); + return api.v1.listStripeTransactions.useQuery( + { + limit, + offset: offset ?? undefined, + startDate: startDate?.toISOString(), + endDate: endDate?.toISOString() + }, + { select: response => response.data } + ); }; export const useSetupIntentMutation = () => { @@ -92,7 +94,7 @@ export const usePaymentMutations = () => { }); }, onSuccess: response => { - queryClient.invalidateQueries({ queryKey: QueryKeys.getPaymentTransactionsKey() }); + queryClient.invalidateQueries({ queryKey: api.v1.listStripeTransactions.getKey() }); if (!response.requiresAction) { queryClient.invalidateQueries({ queryKey: QueryKeys.getPaymentMethodsKey() }); diff --git a/apps/deploy-web/tests/seeders/payment.ts b/apps/deploy-web/tests/seeders/payment.ts index 25b5bae6c7..820ed7088f 100644 --- a/apps/deploy-web/tests/seeders/payment.ts +++ b/apps/deploy-web/tests/seeders/payment.ts @@ -1,6 +1,7 @@ -import type { BillingTransaction } from "@akashnetwork/http-sdk"; import { faker } from "@faker-js/faker"; +import type { BillingTransaction } from "@src/queries"; + export const createMockPaymentMethod = (overrides = {}) => ({ id: `pm_${faker.string.alphanumeric(24)}`, type: "card", diff --git a/packages/console-api-types/src/operations.gen.ts b/packages/console-api-types/src/operations.gen.ts index 8a5f9cfebd..0ffe39fe8a 100644 --- a/packages/console-api-types/src/operations.gen.ts +++ b/packages/console-api-types/src/operations.gen.ts @@ -85,7 +85,7 @@ export const operations = { method: "get", operationId: "listStripeTransactions", pathParams: [], - queryParams: ["limit", "startingAfter", "endingBefore", "startDate", "endDate"], + queryParams: ["limit", "offset", "startDate", "endDate"], hasBody: false }, exportStripeTransactions: { diff --git a/packages/console-api-types/src/schema.d.ts b/packages/console-api-types/src/schema.d.ts index c50ab56856..fd2cb7c16d 100644 --- a/packages/console-api-types/src/schema.d.ts +++ b/packages/console-api-types/src/schema.d.ts @@ -7642,8 +7642,7 @@ export interface operations { parameters: { query?: { limit?: number; - startingAfter?: string; - endingBefore?: string; + offset?: number; startDate?: string; endDate?: string; }; @@ -7663,52 +7662,22 @@ export interface operations { data: { transactions: { id: string; + /** @enum {string} */ + type: "payment_intent" | "coupon_claim" | "manual_credit"; amount: number; + amountRefunded: number; bonusAmount?: number; currency: string; status: string; created: number; - paymentMethod: { - type: string; - validated?: boolean; - isDefault?: boolean; - card?: { - brand: string | null; - last4: string | null; - exp_month: number; - exp_year: number; - funding?: string | null; - country?: string | null; - network?: string | null; - three_d_secure_usage?: { - supported?: boolean | null; - } | null; - } | null; - link?: { - email?: string | null; - } | null; - billing_details?: { - address?: { - city: string | null; - country: string | null; - line1: string | null; - line2: string | null; - postal_code: string | null; - state: string | null; - } | null; - email?: string | null; - name?: string | null; - phone?: string | null; - }; - } | null; + cardBrand?: string | null; + cardLast4?: string | null; + stripeInvoiceId?: string | null; receiptUrl?: string | null; description?: string | null; - metadata?: { - [key: string]: string; - } | null; }[]; + totalCount: number; hasMore: boolean; - nextPage?: string | null; }; }; }; From f671346bb21536fcfdb9f77ff1f4eb046f8e98cd Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Thu, 23 Jul 2026 21:30:42 +0100 Subject: [PATCH 2/2] fix(billing): tighten history type and status badge padding --- .../src/components/billing-usage/BillingView/BillingView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx b/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx index dd8fc1bbf0..943079d812 100644 --- a/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx +++ b/apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx @@ -113,7 +113,7 @@ export const BillingView: React.FC = ({
@@ -162,7 +162,7 @@ export const BillingView: React.FC = ({ cell: info => (