mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-24 20:28:16 +02:00
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.
52 lines
1.7 KiB
TypeScript
52 lines
1.7 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
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(),
|
|
usedCredits: z.number(),
|
|
availableCredits: z.number(),
|
|
});
|
|
export type BillingUsageBucket = z.infer<typeof BillingUsageBucketSchema>;
|
|
|
|
export const BillingInfoSchema = z.object({
|
|
userEmail: z.string().nullable(),
|
|
userId: z.string().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;
|
|
}
|