From 23024e3533d706ab3a49b2d985d9af48139e83d6 Mon Sep 17 00:00:00 2001 From: npslaney Date: Wed, 28 Jan 2026 12:42:50 -0500 Subject: [PATCH 1/3] feat: export CheckoutStatus, CheckoutType, PriceAmountType types and schemas - Export CheckoutStatusSchema, CheckoutTypeSchema from contracts/checkout.ts - Export PriceAmountTypeSchema from schemas/product-price-input.ts - Use McpCustomerSchema for embedded customer in order/checkout contracts - Fix mcpContract.customer to only include MCP routes (exclude getSdk) - Remove customer/subscription from sdkContract (not yet implemented) - Bump version to 0.1.20 Addresses PR #498 feedback about type re-definitions Co-Authored-By: Claude Opus 4.5 --- package.json | 2 +- src/contracts/checkout.ts | 14 +++++++++----- src/contracts/order.ts | 6 +++--- src/index.ts | 20 +++++++++++++++----- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index fa70eae..ac51ce0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@moneydevkit/api-contract", - "version": "0.1.19", + "version": "0.1.20", "description": "API Contract for moneydevkit", "main": "./dist/index.cjs", "module": "./dist/index.js", diff --git a/src/contracts/checkout.ts b/src/contracts/checkout.ts index 1cc9026..2005b62 100644 --- a/src/contracts/checkout.ts +++ b/src/contracts/checkout.ts @@ -2,7 +2,7 @@ import { oc } from "@orpc/contract"; import { z } from "zod"; import { CheckoutSchema } from "../schemas/checkout"; import { CurrencySchema } from "../schemas/currency"; -import { CustomerSchema } from "../schemas/customer"; +import { McpCustomerSchema } from "../schemas/customer"; import { PaginationInputSchema, PaginationOutputSchema, @@ -148,13 +148,17 @@ export const paymentReceivedContract = oc .output(z.object({ ok: z.boolean() })); // List checkouts schemas -const CheckoutStatusSchema = z.enum([ +export const CheckoutStatusSchema = z.enum([ "UNCONFIRMED", "CONFIRMED", "PENDING_PAYMENT", "PAYMENT_RECEIVED", "EXPIRED", ]); +export type CheckoutStatus = z.infer; + +export const CheckoutTypeSchema = z.enum(["PRODUCTS", "AMOUNT", "TOP_UP"]); +export type CheckoutType = z.infer; const ListCheckoutsInputSchema = PaginationInputSchema.extend({ status: CheckoutStatusSchema.optional(), @@ -168,14 +172,14 @@ export const listCheckoutsContract = oc .input(ListCheckoutsInputSchema) .output(ListCheckoutsOutputSchema); -// MCP-specific embedded customer schema -const CheckoutCustomerSchema = CustomerSchema.nullable(); +// MCP-specific embedded customer schema (uses admin customer schema, not SDK customer) +const CheckoutCustomerSchema = McpCustomerSchema.nullable(); // MCP-specific summary schema for list (simpler than full CheckoutSchema) const CheckoutListItemSchema = z.object({ id: z.string(), status: CheckoutStatusSchema, - type: z.enum(["PRODUCTS", "AMOUNT", "TOP_UP"]), + type: CheckoutTypeSchema, currency: CurrencySchema, totalAmount: z.number().nullable(), customerId: z.string().nullable(), diff --git a/src/contracts/order.ts b/src/contracts/order.ts index 6ccdf8d..d74e719 100644 --- a/src/contracts/order.ts +++ b/src/contracts/order.ts @@ -1,15 +1,15 @@ import { oc } from "@orpc/contract"; import { z } from "zod"; -import { CustomerSchema } from "../schemas/customer"; +import { McpCustomerSchema } from "../schemas/customer"; import { OrderItemSchema, OrderSchema } from "../schemas/order"; import { PaginationInputSchema, PaginationOutputSchema, } from "../schemas/pagination"; -// Order with related data for list and get views +// Order with related data for list and get views (MCP uses admin customer schema) const OrderWithRelationsSchema = OrderSchema.extend({ - customer: CustomerSchema.nullable(), + customer: McpCustomerSchema.nullable(), orderItems: z.array(OrderItemSchema), }); diff --git a/src/index.ts b/src/index.ts index dda2775..2451ba4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,11 +6,17 @@ import { products } from "./contracts/products"; import { subscription } from "./contracts/subscription"; export type { + CheckoutStatus, + CheckoutType, ConfirmCheckout, CreateCheckout, PaymentReceived, RegisterInvoice, } from "./contracts/checkout"; +export { + CheckoutStatusSchema, + CheckoutTypeSchema, +} from "./contracts/checkout"; export type { BootstrapOnboarding, BootstrapOnboardingResponse, @@ -75,10 +81,12 @@ export { PaginationOutputSchema, } from "./schemas/pagination"; export type { + PriceAmountType, ProductPriceInput, RecurringIntervalInput, } from "./schemas/product-price-input"; export { + PriceAmountTypeSchema, ProductPriceInputSchema, RecurringIntervalInputSchema, } from "./schemas/product-price-input"; @@ -102,19 +110,21 @@ export const sdkContract = { registerInvoice: checkout.registerInvoice, paymentReceived: checkout.paymentReceived, }, - customer: { - get: customer.getSdk, - }, onboarding, products: { list: products.list, }, - subscription, }; // MCP contract - only the methods the MCP router implements export const mcpContract = { - customer, + customer: { + list: customer.list, + get: customer.get, + create: customer.create, + update: customer.update, + delete: customer.delete, + }, order, checkout: { list: checkout.listSummary, From 52055b393e8007e50c72ac564a34d37dd3bee406 Mon Sep 17 00:00:00 2001 From: npslaney Date: Wed, 28 Jan 2026 16:29:09 -0500 Subject: [PATCH 2/3] refactor: consolidate customer schemas for clearer naming - Rename McpCustomerSchema to CustomerSchema (pure customer data) - Create CustomerWithSubscriptionsSchema for SDK endpoint (customer + full subscriptions) - Remove CustomerSubscriptionSchema (now uses full SubscriptionSchema instead) - Update all imports and exports across contracts Co-Authored-By: Claude Opus 4.5 --- src/contracts/checkout.ts | 4 +-- src/contracts/customer.ts | 12 ++++----- src/contracts/order.ts | 6 ++--- src/index.ts | 9 ++----- src/schemas/customer.ts | 57 +++++++++++++-------------------------- 5 files changed, 32 insertions(+), 56 deletions(-) diff --git a/src/contracts/checkout.ts b/src/contracts/checkout.ts index 2005b62..0a9dc8c 100644 --- a/src/contracts/checkout.ts +++ b/src/contracts/checkout.ts @@ -2,7 +2,7 @@ import { oc } from "@orpc/contract"; import { z } from "zod"; import { CheckoutSchema } from "../schemas/checkout"; import { CurrencySchema } from "../schemas/currency"; -import { McpCustomerSchema } from "../schemas/customer"; +import { CustomerSchema } from "../schemas/customer"; import { PaginationInputSchema, PaginationOutputSchema, @@ -173,7 +173,7 @@ export const listCheckoutsContract = oc .output(ListCheckoutsOutputSchema); // MCP-specific embedded customer schema (uses admin customer schema, not SDK customer) -const CheckoutCustomerSchema = McpCustomerSchema.nullable(); +const CheckoutCustomerSchema = CustomerSchema.nullable(); // MCP-specific summary schema for list (simpler than full CheckoutSchema) const CheckoutListItemSchema = z.object({ diff --git a/src/contracts/customer.ts b/src/contracts/customer.ts index 467ce89..77f21a6 100644 --- a/src/contracts/customer.ts +++ b/src/contracts/customer.ts @@ -2,7 +2,7 @@ import { oc } from "@orpc/contract"; import { z } from "zod"; import { CustomerSchema, - McpCustomerSchema, + CustomerWithSubscriptionsSchema, GetCustomerInputSchema as SdkGetCustomerInputSchema, } from "../schemas/customer"; import { @@ -13,7 +13,7 @@ import { // MCP-specific schemas const ListCustomersInputSchema = PaginationInputSchema; const ListCustomersOutputSchema = PaginationOutputSchema.extend({ - customers: z.array(McpCustomerSchema), + customers: z.array(CustomerSchema), }); const McpGetCustomerInputSchema = z.object({ id: z.string() }); @@ -35,7 +35,7 @@ const DeleteCustomerInputSchema = z.object({ id: z.string() }); // SDK contract - uses flexible lookup (externalId/email/customerId) export const getSdkCustomerContract = oc .input(SdkGetCustomerInputSchema) - .output(CustomerSchema); + .output(CustomerWithSubscriptionsSchema); // MCP contracts export const listCustomersContract = oc @@ -44,15 +44,15 @@ export const listCustomersContract = oc export const getCustomerContract = oc .input(McpGetCustomerInputSchema) - .output(McpCustomerSchema); + .output(CustomerSchema); export const createCustomerContract = oc .input(CreateCustomerInputSchema) - .output(McpCustomerSchema); + .output(CustomerSchema); export const updateCustomerContract = oc .input(UpdateCustomerInputSchema) - .output(McpCustomerSchema); + .output(CustomerSchema); export const deleteCustomerContract = oc .input(DeleteCustomerInputSchema) diff --git a/src/contracts/order.ts b/src/contracts/order.ts index d74e719..6ccdf8d 100644 --- a/src/contracts/order.ts +++ b/src/contracts/order.ts @@ -1,15 +1,15 @@ import { oc } from "@orpc/contract"; import { z } from "zod"; -import { McpCustomerSchema } from "../schemas/customer"; +import { CustomerSchema } from "../schemas/customer"; import { OrderItemSchema, OrderSchema } from "../schemas/order"; import { PaginationInputSchema, PaginationOutputSchema, } from "../schemas/pagination"; -// Order with related data for list and get views (MCP uses admin customer schema) +// Order with related data for list and get views const OrderWithRelationsSchema = OrderSchema.extend({ - customer: McpCustomerSchema.nullable(), + customer: CustomerSchema.nullable(), orderItems: z.array(OrderItemSchema), }); diff --git a/src/index.ts b/src/index.ts index 2451ba4..179e042 100644 --- a/src/index.ts +++ b/src/index.ts @@ -56,16 +56,11 @@ export { SubscriptionWebhookEventSchema, SubscriptionWebhookPayloadSchema, } from "./schemas/subscription"; -export type { - Customer, - CustomerSubscription, - McpCustomer, -} from "./schemas/customer"; +export type { Customer, CustomerWithSubscriptions } from "./schemas/customer"; export { CustomerSchema, - CustomerSubscriptionSchema, + CustomerWithSubscriptionsSchema, GetCustomerInputSchema, - McpCustomerSchema, } from "./schemas/customer"; // New MCP schemas diff --git a/src/schemas/customer.ts b/src/schemas/customer.ts index 125309c..4ac8e71 100644 --- a/src/schemas/customer.ts +++ b/src/schemas/customer.ts @@ -1,36 +1,33 @@ import { z } from "zod"; -import { CurrencySchema } from "./currency"; -import { - RecurringIntervalSchema, - SubscriptionStatusSchema, -} from "./subscription"; +import { SubscriptionSchema } from "./subscription"; /** - * Summary of a subscription for the customer response. - * Contains the essential fields needed for displaying subscription status. + * Customer schema for API responses. + * Represents a customer in the organization (admin view). + * Note: Uses modifiedAt to match Prisma schema naming. */ -export const CustomerSubscriptionSchema = z.object({ +export const CustomerSchema = z.object({ id: z.string(), - productId: z.string(), - status: SubscriptionStatusSchema, - currentPeriodStart: z.string().datetime(), - currentPeriodEnd: z.string().datetime(), - cancelAtPeriodEnd: z.boolean().optional(), - amount: z.number(), - currency: CurrencySchema, - recurringInterval: RecurringIntervalSchema, + name: z.string().nullable(), + email: z.string().nullable(), + emailVerified: z.boolean(), + externalId: z.string().nullable(), + userMetadata: z.record(z.string(), z.any()).nullable(), + organizationId: z.string(), + createdAt: z.date(), + modifiedAt: z.date().nullable(), }); /** - * Customer data with their subscriptions. + * Customer data with their full subscriptions. * Returned by the SDK customer.get endpoint. */ -export const CustomerSchema = z.object({ +export const CustomerWithSubscriptionsSchema = z.object({ id: z.string(), email: z.string().nullable().optional(), name: z.string().nullable().optional(), externalId: z.string().nullable().optional(), - subscriptions: z.array(CustomerSubscriptionSchema), + subscriptions: z.array(SubscriptionSchema), }); /** @@ -56,24 +53,8 @@ export const GetCustomerInputSchema = z }, ); -/** - * Customer schema for MCP API responses. - * Represents a customer in the organization (admin view). - * Note: Uses modifiedAt to match Prisma schema naming. - */ -export const McpCustomerSchema = z.object({ - id: z.string(), - name: z.string().nullable(), - email: z.string().nullable(), - emailVerified: z.boolean(), - externalId: z.string().nullable(), - userMetadata: z.record(z.string(), z.any()).nullable(), - organizationId: z.string(), - createdAt: z.date(), - modifiedAt: z.date().nullable(), -}); - -export type CustomerSubscription = z.infer; export type Customer = z.infer; -export type McpCustomer = z.infer; +export type CustomerWithSubscriptions = z.infer< + typeof CustomerWithSubscriptionsSchema +>; export type GetCustomerInput = z.infer; From cbc1d5665b45f36c876a4801c0332f7ecf74785f Mon Sep 17 00:00:00 2001 From: npslaney Date: Wed, 28 Jan 2026 16:57:25 -0500 Subject: [PATCH 3/3] chore: remove outdated MCP-specific comment Addresses PR review feedback - schema is used more broadly now. Co-Authored-By: Claude Opus 4.5 --- src/contracts/checkout.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/contracts/checkout.ts b/src/contracts/checkout.ts index 0a9dc8c..5f7262b 100644 --- a/src/contracts/checkout.ts +++ b/src/contracts/checkout.ts @@ -172,7 +172,6 @@ export const listCheckoutsContract = oc .input(ListCheckoutsInputSchema) .output(ListCheckoutsOutputSchema); -// MCP-specific embedded customer schema (uses admin customer schema, not SDK customer) const CheckoutCustomerSchema = CustomerSchema.nullable(); // MCP-specific summary schema for list (simpler than full CheckoutSchema)