mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-24 20:28:16 +02:00
feat(billing): consume plan variant catalog
Fetch the public billing catalog during account config load and use durable plan IDs from /v1/me for display, analytics, and upgrade/manage labels. Renderer billing surfaces now resolve plan display data from the catalog and show Unknown when the backend returns an unmapped plan ID.
This commit is contained in:
parent
aa8dfb74ad
commit
f65f7e8fc8
7 changed files with 52 additions and 26 deletions
|
|
@ -1,7 +1,26 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
export const BillingPlanSchema = z.enum(['free', 'starter', 'pro']);
|
||||
export type BillingPlan = z.infer<typeof BillingPlanSchema>;
|
||||
export const BillingPlanCategorySchema = z.enum(['free', 'starter', 'pro']);
|
||||
export type BillingPlanCategory = z.infer<typeof BillingPlanCategorySchema>;
|
||||
|
||||
export const BillingPlanIdSchema = z.string().min(1);
|
||||
export type BillingPlanId = z.infer<typeof BillingPlanIdSchema>;
|
||||
|
||||
export const BillingCatalogPlanSchema = z.object({
|
||||
id: BillingPlanIdSchema,
|
||||
category: BillingPlanCategorySchema,
|
||||
displayName: z.string(),
|
||||
monthlyCredits: z.number(),
|
||||
dailyCredits: z.number(),
|
||||
monthlyPriceCents: z.number().nullable(),
|
||||
archived: z.boolean().optional(),
|
||||
});
|
||||
export type BillingCatalogPlan = z.infer<typeof BillingCatalogPlanSchema>;
|
||||
|
||||
export const BillingCatalogSchema = z.object({
|
||||
plans: z.array(BillingCatalogPlanSchema),
|
||||
});
|
||||
export type BillingCatalog = z.infer<typeof BillingCatalogSchema>;
|
||||
|
||||
export const BillingUsageBucketSchema = z.object({
|
||||
sanctionedCredits: z.number(),
|
||||
|
|
@ -13,12 +32,21 @@ export type BillingUsageBucket = z.infer<typeof BillingUsageBucketSchema>;
|
|||
export const BillingInfoSchema = z.object({
|
||||
userEmail: z.string().nullable(),
|
||||
userId: z.string().nullable(),
|
||||
subscriptionPlan: BillingPlanSchema.nullable(),
|
||||
subscriptionPlanId: BillingPlanIdSchema.nullable(),
|
||||
subscriptionStatus: z.string().nullable(),
|
||||
trialExpiresAt: z.string().nullable(),
|
||||
catalog: BillingCatalogSchema,
|
||||
monthly: BillingUsageBucketSchema,
|
||||
daily: BillingUsageBucketSchema.extend({
|
||||
usageDay: z.string(),
|
||||
}),
|
||||
});
|
||||
export type BillingInfo = z.infer<typeof BillingInfoSchema>;
|
||||
|
||||
export function getBillingPlanData(
|
||||
catalog: BillingCatalog,
|
||||
planId: string | null | undefined,
|
||||
): BillingCatalogPlan | null {
|
||||
if (!planId) return null;
|
||||
return catalog.plans.find((plan) => plan.id === planId) ?? null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { z } from 'zod';
|
||||
import { BillingCatalogSchema } from './billing.js';
|
||||
|
||||
export const RowboatApiConfig = z.object({
|
||||
appUrl: z.string(),
|
||||
websocketApiUrl: z.string(),
|
||||
supabaseUrl: z.string(),
|
||||
billing: BillingCatalogSchema,
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue