feat: 🎸 openapi contracts for schedules and get customer
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,8 @@ import {
|
||||
AttachParamsV1Schema,
|
||||
BILLING_PREVIEW_RESPONSE_EXAMPLE,
|
||||
BillingResponseSchema,
|
||||
CreateScheduleParamsV0Schema,
|
||||
CreateScheduleResponseSchema,
|
||||
ExtAttachPreviewResponseSchema,
|
||||
ExtPreviewUpdateSubscriptionResponseSchema,
|
||||
ExtUpdateSubscriptionV1ParamsSchema,
|
||||
@@ -14,6 +16,7 @@ import {
|
||||
import { oc } from "@orpc/contract";
|
||||
import {
|
||||
billingAttachJsDoc,
|
||||
billingCreateScheduleJsDoc,
|
||||
billingMultiAttachJsDoc,
|
||||
billingPreviewAttachJsDoc,
|
||||
billingPreviewMultiAttachJsDoc,
|
||||
@@ -227,6 +230,66 @@ export const billingSetupPaymentContract = oc
|
||||
}),
|
||||
);
|
||||
|
||||
export const billingCreateScheduleContract = oc
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/v1/billing.create_schedule",
|
||||
operationId: "createSchedule",
|
||||
tags: ["billing"],
|
||||
description: billingCreateScheduleJsDoc,
|
||||
spec: (spec) => ({
|
||||
...spec,
|
||||
"x-speakeasy-name-override": "createSchedule",
|
||||
}),
|
||||
})
|
||||
.input(
|
||||
CreateScheduleParamsV0Schema.meta({
|
||||
title: "CreateScheduleParams",
|
||||
examples: [
|
||||
{
|
||||
customer_id: "cus_123",
|
||||
phases: [
|
||||
{
|
||||
starts_at: 1735689600000,
|
||||
plans: [{ plan_id: "trial_plan" }],
|
||||
},
|
||||
{
|
||||
starts_at: 1736899200000,
|
||||
plans: [{ plan_id: "pro_plan" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
)
|
||||
.output(
|
||||
CreateScheduleResponseSchema.meta({
|
||||
title: "CreateScheduleResponse",
|
||||
examples: [
|
||||
{
|
||||
customer_id: "cus_123",
|
||||
entity_id: null,
|
||||
status: "created",
|
||||
schedule_id: "sch_1234",
|
||||
phases: [
|
||||
{
|
||||
phase_id: "sphs_1111",
|
||||
starts_at: 1735689600000,
|
||||
customer_product_ids: ["cus_prod_1111"],
|
||||
},
|
||||
{
|
||||
phase_id: "sphs_2222",
|
||||
starts_at: 1736899200000,
|
||||
customer_product_ids: ["cus_prod_2222"],
|
||||
},
|
||||
],
|
||||
invoice: null,
|
||||
payment_url: null,
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
export const billingMultiAttachContract = oc
|
||||
.route({
|
||||
method: "POST",
|
||||
|
||||
@@ -9,10 +9,14 @@ import {
|
||||
DeleteCustomerParamsSchema,
|
||||
DeleteCustomerResponseSchema,
|
||||
} from "@api/customers/crud/deleteCustomerParams.js";
|
||||
import { GetCustomerParamsV1Schema } from "@api/customers/crud/getCustomerParams.js";
|
||||
import { ListCustomersV2ParamsSchema } from "@api/customers/crud/listCustomersParamsV2.js";
|
||||
import { UpdateCustomerParamsV1Schema } from "@api/customers/crud/updateCustomerParams.js";
|
||||
import { oc } from "@orpc/contract";
|
||||
import { getOrCreateCustomerJsDoc } from "../jsDocs/customerJsDocs";
|
||||
import {
|
||||
getCustomerJsDoc,
|
||||
getOrCreateCustomerJsDoc,
|
||||
} from "../jsDocs/customerJsDocs";
|
||||
|
||||
export const getOrCreateCustomerContract = oc
|
||||
.route({
|
||||
@@ -40,6 +44,38 @@ export const getOrCreateCustomerContract = oc
|
||||
)
|
||||
.output(ApiCustomerV5Schema);
|
||||
|
||||
export const getCustomerContract = oc
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/v1/customers.get",
|
||||
operationId: "getCustomer",
|
||||
tags: ["customers"],
|
||||
description: getCustomerJsDoc,
|
||||
spec: (spec) => ({
|
||||
...spec,
|
||||
"x-speakeasy-name-override": "get",
|
||||
}),
|
||||
})
|
||||
.input(
|
||||
GetCustomerParamsV1Schema.meta({
|
||||
title: "GetCustomerParams",
|
||||
examples: [
|
||||
{
|
||||
customer_id: "cus_123",
|
||||
},
|
||||
{
|
||||
customer_id: "cus_123",
|
||||
expand: ["invoices", "entities"],
|
||||
},
|
||||
],
|
||||
}),
|
||||
)
|
||||
.output(
|
||||
ApiCustomerV5Schema.meta({
|
||||
examples: [API_CUSTOMER_V5_EXAMPLE],
|
||||
}),
|
||||
);
|
||||
|
||||
export const listCustomersContract = oc
|
||||
.route({
|
||||
method: "POST",
|
||||
|
||||
4
packages/openapi/v2.1/contracts/index.ts
vendored
4
packages/openapi/v2.1/contracts/index.ts
vendored
@@ -9,6 +9,7 @@ import {
|
||||
} from "./balancesContract.js";
|
||||
import {
|
||||
billingAttachContract,
|
||||
billingCreateScheduleContract,
|
||||
billingMultiAttachContract,
|
||||
billingOpenCustomerPortalContract,
|
||||
billingPreviewAttachContract,
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
} from "./billingContract.js";
|
||||
import {
|
||||
deleteCustomerContract,
|
||||
getCustomerContract,
|
||||
getOrCreateCustomerContract,
|
||||
listCustomersContract,
|
||||
updateCustomerContract,
|
||||
@@ -55,6 +57,7 @@ import {
|
||||
export const v2_1ContractRouter = oc.router({
|
||||
// Customers
|
||||
getOrCreateCustomer: getOrCreateCustomerContract,
|
||||
getCustomer: getCustomerContract,
|
||||
listCustomers: listCustomersContract,
|
||||
updateCustomer: updateCustomerContract,
|
||||
deleteCustomer: deleteCustomerContract,
|
||||
@@ -75,6 +78,7 @@ export const v2_1ContractRouter = oc.router({
|
||||
|
||||
// Billing
|
||||
billingAttach: billingAttachContract,
|
||||
billingCreateSchedule: billingCreateScheduleContract,
|
||||
billingMultiAttach: billingMultiAttachContract,
|
||||
billingPreviewAttach: billingPreviewAttachContract,
|
||||
billingPreviewMultiAttach: billingPreviewMultiAttachContract,
|
||||
|
||||
30
packages/openapi/v2.1/jsDocs/billingJsDocs.ts
vendored
30
packages/openapi/v2.1/jsDocs/billingJsDocs.ts
vendored
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
AttachParamsV1Schema,
|
||||
CreateScheduleParamsV0Schema,
|
||||
MultiAttachParamsV0Schema,
|
||||
UpdateSubscriptionV1ParamsSchema,
|
||||
} from "@autumn/shared";
|
||||
@@ -179,6 +180,35 @@ export const billingMultiAttachJsDoc = createJSDocDescription({
|
||||
"A billing response with customer ID, invoice details, and payment URL (if checkout required).",
|
||||
});
|
||||
|
||||
export const billingCreateScheduleJsDoc = createJSDocDescription({
|
||||
description:
|
||||
"Creates a multi-phase subscription schedule for a customer. The first phase starts immediately and subsequent phases automatically transition at their scheduled start times.",
|
||||
whenToUse:
|
||||
"Use this endpoint to schedule future plan changes (e.g. switch from a trial plan to a paid plan on a specific date) or to define a sequence of plans that should activate over time.",
|
||||
body: CreateScheduleParamsV0Schema,
|
||||
examples: [
|
||||
example({
|
||||
description: "Schedule a transition from a trial plan to a paid plan",
|
||||
values: {
|
||||
customerId: "cus_123",
|
||||
phases: [
|
||||
{
|
||||
startsAt: Date.now(),
|
||||
plans: [{ planId: "trial_plan" }],
|
||||
},
|
||||
{
|
||||
startsAt: Date.now() + 14 * 24 * 60 * 60 * 1000,
|
||||
plans: [{ planId: "pro_plan" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
methodName: "billing.createSchedule",
|
||||
returns:
|
||||
"A create-schedule response with the schedule ID, persisted phases, and any required payment or checkout URL.",
|
||||
});
|
||||
|
||||
export const billingPreviewMultiAttachJsDoc = createJSDocDescription({
|
||||
description:
|
||||
"Previews the billing changes that would occur when attaching multiple plans, without actually making any changes.",
|
||||
|
||||
29
packages/openapi/v2.1/jsDocs/customerJsDocs.ts
vendored
29
packages/openapi/v2.1/jsDocs/customerJsDocs.ts
vendored
@@ -1,4 +1,7 @@
|
||||
import { CreateCustomerParamsV0Schema } from "@autumn/shared";
|
||||
import {
|
||||
CreateCustomerParamsV0Schema,
|
||||
GetCustomerParamsV1Schema,
|
||||
} from "@autumn/shared";
|
||||
import { createJSDocDescription, example } from "../../utils/jsDocs/index.js";
|
||||
|
||||
export const getOrCreateCustomerJsDoc = createJSDocDescription({
|
||||
@@ -19,3 +22,27 @@ export const getOrCreateCustomerJsDoc = createJSDocDescription({
|
||||
],
|
||||
methodName: "getOrCreate",
|
||||
});
|
||||
|
||||
export const getCustomerJsDoc = createJSDocDescription({
|
||||
description:
|
||||
"Fetches a customer by ID, optionally expanding related data such as invoices or entities.",
|
||||
whenToUse:
|
||||
"Use this when you know the customer exists or assert they exist without creating them.",
|
||||
body: GetCustomerParamsV1Schema,
|
||||
examples: [
|
||||
example({
|
||||
description: "Fetch a customer by external ID",
|
||||
values: {
|
||||
customerId: "cus_123",
|
||||
},
|
||||
}),
|
||||
example({
|
||||
description: "Fetch a customer with expanded invoices and entities",
|
||||
values: {
|
||||
customerId: "cus_123",
|
||||
expand: ["invoices", "entities"],
|
||||
},
|
||||
}),
|
||||
],
|
||||
methodName: "get",
|
||||
});
|
||||
|
||||
2
packages/openapi/v2.1/openapi2.1.ts
vendored
2
packages/openapi/v2.1/openapi2.1.ts
vendored
@@ -16,6 +16,7 @@ import {
|
||||
CustomerDataSchema,
|
||||
CustomerExpandEnum,
|
||||
CustomerIdSchema,
|
||||
GetCustomerParamsV1Schema,
|
||||
LATEST_VERSION,
|
||||
PreviewUpdateSubscriptionResponseSchema,
|
||||
SetupPaymentParamsV1Schema,
|
||||
@@ -54,6 +55,7 @@ async function generateOpenApiDocument(): Promise<Record<string, unknown>> {
|
||||
// in the OpenAPI output, which removeInternalFields() will then strip
|
||||
registerInternalSchemas(BaseApiCustomerSchema);
|
||||
registerInternalSchemas(CreateCustomerParamsV1Schema);
|
||||
registerInternalSchemas(GetCustomerParamsV1Schema);
|
||||
registerInternalSchemas(AttachParamsV1Schema);
|
||||
registerInternalSchemas(UpdateSubscriptionV1ParamsSchema);
|
||||
registerInternalSchemas(SetupPaymentParamsV1Schema);
|
||||
|
||||
Reference in New Issue
Block a user