diff --git a/adopter/web/components/dashboard/DemoBanner.tsx b/adopter/web/components/dashboard/DemoBanner.tsx index 4156cfba..965343e3 100644 --- a/adopter/web/components/dashboard/DemoBanner.tsx +++ b/adopter/web/components/dashboard/DemoBanner.tsx @@ -1,4 +1,5 @@ import { getAdopterConfig } from '@beakerstack/shared/config/adopterRuntime'; +import { landingConfig } from '@adopter/config/landing'; import { ExternalLink } from 'lucide-react'; export function DemoBanner() { @@ -24,7 +25,7 @@ export function DemoBanner() {
{ const actual = jest.requireActual('@react-navigation/native'); @@ -240,7 +241,9 @@ describe('BillingOverviewScreen', () => { const { getByText } = renderWithNav(); expect(getByText('Payment problem')).toBeTruthy(); expect(getByText(/Your last payment did not go through/i)).toBeTruthy(); - expect(getByText(/Beaker Stack web app/i)).toBeTruthy(); + expect( + getByText(`${branding.displayName} web app`, { exact: false }) + ).toBeTruthy(); }); it('shows downgrade pending banner with target plan name from catalog', () => { diff --git a/apps/mobile/src/screens/billing/BillingOverviewScreen.tsx b/apps/mobile/src/screens/billing/BillingOverviewScreen.tsx index 34e1ec02..0a92b9f1 100644 --- a/apps/mobile/src/screens/billing/BillingOverviewScreen.tsx +++ b/apps/mobile/src/screens/billing/BillingOverviewScreen.tsx @@ -11,10 +11,7 @@ import { import { formatMonthYear } from '@beakerstack/billing/presentation'; import { useAuthContext } from '@beakerstack/shared/contexts/AuthContext'; import { getAdopterConfig } from '@beakerstack/shared/config/adopterRuntime'; -import { - billingConfig, - BEAKERSTACK_METER_AI_SUMMARIZE, -} from '@adopter/config/billing'; +import { billingConfig, METER_AI_SUMMARIZE } from '@adopter/config/billing'; import { numericPlanFeature } from '../../billing/planFeatureValue'; import { useDemoCollectionCount } from '@adopter/mobile/billing/useDemoCollectionCount'; import { BillingLayout } from './BillingLayout'; @@ -139,8 +136,8 @@ export function BillingOverviewScreen(): ReactElement { used, limit, loading: usageLoad, - } = useUsage( - BEAKERSTACK_METER_AI_SUMMARIZE + } = useUsage( + METER_AI_SUMMARIZE ); const { count: colCount, diff --git a/apps/mobile/src/screens/billing/BillingUsageScreen.tsx b/apps/mobile/src/screens/billing/BillingUsageScreen.tsx index b5121168..305faf9a 100644 --- a/apps/mobile/src/screens/billing/BillingUsageScreen.tsx +++ b/apps/mobile/src/screens/billing/BillingUsageScreen.tsx @@ -19,7 +19,7 @@ import { } from '@beakerstack/billing/presentation'; import { billingConfig as adopterBillingConfig, - BEAKERSTACK_METER_AI_SUMMARIZE, + METER_AI_SUMMARIZE, } from '@adopter/config/billing'; import { numericPlanFeature } from '../../billing/planFeatureValue'; import { useDemoCollectionCount } from '@adopter/mobile/billing/useDemoCollectionCount'; @@ -143,7 +143,7 @@ export function BillingUsageScreen(): ReactElement { {Object.keys(plan.usage_limits).map(m => ( - meter={m as typeof BEAKERSTACK_METER_AI_SUMMARIZE} + meter={m as typeof METER_AI_SUMMARIZE} variant='expanded' label={meterCopy[m]?.label ?? m} description={meterCopy[m]?.description} diff --git a/apps/web/src/admin/__tests__/adminUsageColumns.test.ts b/apps/web/src/admin/__tests__/adminUsageColumns.test.ts index d136f142..b336c3b6 100644 --- a/apps/web/src/admin/__tests__/adminUsageColumns.test.ts +++ b/apps/web/src/admin/__tests__/adminUsageColumns.test.ts @@ -1,9 +1,10 @@ import { describe, expect, it } from 'vitest'; import { adminProductId, getAdminUsageMeterKeys } from '../adminUsageColumns'; +import { billingConfig } from '@adopter/config/billing'; describe('adminUsageColumns', () => { it('exports product id from billing config', () => { - expect(adminProductId).toBe('beakerstack'); + expect(adminProductId).toBe(billingConfig.productId); }); it('collects usage meter keys from all plans', () => { diff --git a/apps/web/src/billing/__tests__/beakerstackBillingConfig.test.ts b/apps/web/src/billing/__tests__/beakerstackBillingConfig.test.ts index f2fc6f3b..dbb1af48 100644 --- a/apps/web/src/billing/__tests__/beakerstackBillingConfig.test.ts +++ b/apps/web/src/billing/__tests__/beakerstackBillingConfig.test.ts @@ -1,8 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { - BEAKERSTACK_METER_AI_SUMMARIZE, - billingConfig, -} from '@adopter/config/billing'; +import { METER_AI_SUMMARIZE, billingConfig } from '@adopter/config/billing'; describe('billingConfig', () => { it('defines a parsed product with public plans', () => { @@ -13,6 +10,6 @@ describe('billingConfig', () => { }); it('exposes meter key constant for AI usage', () => { - expect(BEAKERSTACK_METER_AI_SUMMARIZE).toBe('ai_summarize'); + expect(METER_AI_SUMMARIZE).toBe('ai_summarize'); }); }); diff --git a/apps/web/src/billing/__tests__/useDemoCollections.test.tsx b/apps/web/src/billing/__tests__/useDemoCollections.test.tsx index 821b0084..28669ecf 100644 --- a/apps/web/src/billing/__tests__/useDemoCollections.test.tsx +++ b/apps/web/src/billing/__tests__/useDemoCollections.test.tsx @@ -1,6 +1,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { act, renderHook, waitFor } from '@testing-library/react'; import { useDemoCollections } from '@adopter/web/billing/useDemoCollections'; +import { appIdentity } from '@adopter/config/app-identity'; const { rpc, mockClient } = vi.hoisted(() => { const rpc = vi.fn(); @@ -113,7 +114,7 @@ describe('useDemoCollections', () => { }); expect(rpc).toHaveBeenCalledWith( 'billing_demo_add_collection', - expect.objectContaining({ p_product_id: 'beakerstack' }) + expect.objectContaining({ p_product_id: appIdentity.productId }) ); }); @@ -138,7 +139,7 @@ describe('useDemoCollections', () => { expect(rpc).toHaveBeenCalledWith( 'billing_demo_delete_collection', expect.objectContaining({ - p_product_id: 'beakerstack', + p_product_id: appIdentity.productId, p_collection_id: 'x', }) ); @@ -168,7 +169,7 @@ describe('useDemoCollections', () => { expect(rpc).toHaveBeenCalledWith( 'billing_demo_add_item', expect.objectContaining({ - p_product_id: 'beakerstack', + p_product_id: appIdentity.productId, p_collection_id: 'col', }) ); diff --git a/apps/web/src/pages/__tests__/DashboardPage.test.tsx b/apps/web/src/pages/__tests__/DashboardPage.test.tsx index c0166d44..4447dae7 100644 --- a/apps/web/src/pages/__tests__/DashboardPage.test.tsx +++ b/apps/web/src/pages/__tests__/DashboardPage.test.tsx @@ -10,6 +10,7 @@ import { ProfileProvider } from '@beakerstack/shared/contexts/ProfileContext'; import { getAdopterConfig } from '@beakerstack/shared/config/adopterRuntime'; import { brandNameRegex } from '@adopter/config/branding'; import { billingConfig } from '@adopter/config/billing'; +import { landingConfig } from '@adopter/config/landing'; import { supabase } from '@/lib/supabase'; const mockNavigate = vi.fn(); @@ -222,9 +223,10 @@ describe('DashboardPage', () => { it('links to GitHub repo from demo banner', async () => { await renderWithAuth(); const link = screen.getByRole('link', { name: /view on github/i }); + expect(landingConfig.finalCta.secondaryCta?.href).toBeDefined(); expect(link).toHaveAttribute( 'href', - 'https://github.com/Artificer-Innovations/BeakerStack' + landingConfig.finalCta.secondaryCta?.href ); }); diff --git a/apps/web/src/pages/__tests__/SignupInvitePage.test.tsx b/apps/web/src/pages/__tests__/SignupInvitePage.test.tsx index 257487b5..86e3db93 100644 --- a/apps/web/src/pages/__tests__/SignupInvitePage.test.tsx +++ b/apps/web/src/pages/__tests__/SignupInvitePage.test.tsx @@ -2,6 +2,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; +import { billingConfig } from '@adopter/config/billing'; import SignupInvitePage, { finalizeInviteSignup, getInviteTokenFromHash, @@ -111,7 +112,7 @@ describe('SignupInvitePage helpers', () => { body: expect.objectContaining({ action: 'consume', token: 'tok', - productId: 'beakerstack', + productId: billingConfig.productId, }), }) ); diff --git a/apps/web/src/pages/billing/BillingOverviewPage.tsx b/apps/web/src/pages/billing/BillingOverviewPage.tsx index 8a8ba37b..22406353 100644 --- a/apps/web/src/pages/billing/BillingOverviewPage.tsx +++ b/apps/web/src/pages/billing/BillingOverviewPage.tsx @@ -10,10 +10,7 @@ import { type BillingUiStateKind, } from '@beakerstack/billing'; import { useAuthContext } from '@beakerstack/shared/contexts/AuthContext'; -import { - billingConfig, - BEAKERSTACK_METER_AI_SUMMARIZE, -} from '@adopter/config/billing'; +import { billingConfig, METER_AI_SUMMARIZE } from '@adopter/config/billing'; import { formatMonthYear } from '@beakerstack/billing/presentation'; import { useDemoCollectionCount } from '@adopter/web/billing/useDemoCollectionCount'; import { Banner } from '../../components/billing/Banner.web'; @@ -43,8 +40,8 @@ export default function BillingOverviewPage() { used, limit, loading: usageLoad, - } = useUsage( - BEAKERSTACK_METER_AI_SUMMARIZE + } = useUsage( + METER_AI_SUMMARIZE ); const { items: invoices, loading: invLoad } = useInvoices< typeof billingConfig diff --git a/apps/web/src/pages/billing/BillingPlansPage.tsx b/apps/web/src/pages/billing/BillingPlansPage.tsx index 226bed72..75696a0b 100644 --- a/apps/web/src/pages/billing/BillingPlansPage.tsx +++ b/apps/web/src/pages/billing/BillingPlansPage.tsx @@ -11,10 +11,7 @@ import { } from '@beakerstack/billing'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; -import { - billingConfig, - BEAKERSTACK_METER_AI_SUMMARIZE, -} from '@adopter/config/billing'; +import { billingConfig, METER_AI_SUMMARIZE } from '@adopter/config/billing'; import { annualListCentsFromSync, computeDowngradeBlockers, @@ -61,8 +58,8 @@ export default function BillingPlansPage() { } = useBillingStripeActions(); const { used: aiUsed } = useUsage< typeof billingConfig, - typeof BEAKERSTACK_METER_AI_SUMMARIZE - >(BEAKERSTACK_METER_AI_SUMMARIZE); + typeof METER_AI_SUMMARIZE + >(METER_AI_SUMMARIZE); const { count: colCount = 0, maxItemsInAnyCollection = 0 } = useDemoCollectionCount(); diff --git a/apps/web/src/pages/billing/BillingUsagePage.tsx b/apps/web/src/pages/billing/BillingUsagePage.tsx index 0a3d39c5..ec05b9c3 100644 --- a/apps/web/src/pages/billing/BillingUsagePage.tsx +++ b/apps/web/src/pages/billing/BillingUsagePage.tsx @@ -6,7 +6,7 @@ import { import { UsageIndicator } from '@beakerstack/billing/web'; import { billingConfig as adopterBillingConfig, - BEAKERSTACK_METER_AI_SUMMARIZE, + METER_AI_SUMMARIZE, } from '@adopter/config/billing'; import { booleanFeatureLabel, @@ -74,7 +74,7 @@ export default function BillingUsagePage() { {Object.keys(plan.usage_limits).map(m => (
- meter={m as typeof BEAKERSTACK_METER_AI_SUMMARIZE} + meter={m as typeof METER_AI_SUMMARIZE} variant='expanded' label={meterCopy[m]?.label ?? m} description={meterCopy[m]?.description}