diff --git a/bun.lock b/bun.lock index ee18e5e6..19a205f5 100644 --- a/bun.lock +++ b/bun.lock @@ -112,6 +112,7 @@ "version": "0.15.5", "dependencies": { "@opencode-ai/console-core": "workspace:*", + "@opencode-ai/console-resource": "workspace:*", }, }, "packages/css": { diff --git a/packages/console/app/src/component/icon.tsx b/packages/console/app/src/component/icon.tsx index fc27ef3b..0395cad5 100644 --- a/packages/console/app/src/component/icon.tsx +++ b/packages/console/app/src/component/icon.tsx @@ -100,6 +100,17 @@ export function IconCreditCard(props: JSX.SvgSVGAttributes) { ) } +export function IconStripe(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + export function IconChevron(props: JSX.SvgSVGAttributes) { return ( diff --git a/packages/console/app/src/routes/stripe/webhook.ts b/packages/console/app/src/routes/stripe/webhook.ts index c12f47af..f1fa73c9 100644 --- a/packages/console/app/src/routes/stripe/webhook.ts +++ b/packages/console/app/src/routes/stripe/webhook.ts @@ -32,7 +32,8 @@ export async function POST(input: APIEvent) { .update(BillingTable) .set({ paymentMethodID, - paymentMethodLast4: paymentMethod.card!.last4, + paymentMethodLast4: paymentMethod.card?.last4 ?? null, + paymentMethodType: paymentMethod.type, }) .where(eq(BillingTable.customerID, customerID)) }) @@ -77,7 +78,8 @@ export async function POST(input: APIEvent) { balance: sql`${BillingTable.balance} + ${centsToMicroCents(Billing.CHARGE_AMOUNT)}`, customerID, paymentMethodID: paymentMethod.id, - paymentMethodLast4: paymentMethod.card!.last4, + paymentMethodLast4: paymentMethod.card?.last4 ?? null, + paymentMethodType: paymentMethod.type, reload: true, reloadError: null, timeReloadError: null, diff --git a/packages/console/app/src/routes/workspace/[id]/billing/billing-section.module.css b/packages/console/app/src/routes/workspace/[id]/billing/billing-section.module.css index 123bb1c8..b562dcd4 100644 --- a/packages/console/app/src/routes/workspace/[id]/billing/billing-section.module.css +++ b/packages/console/app/src/routes/workspace/[id]/billing/billing-section.module.css @@ -70,6 +70,12 @@ font-weight: 500; color: var(--color-text); } + + [data-slot="type"] { + font-size: var(--font-size-sm); + font-weight: 400; + color: var(--color-text-muted); + } } } diff --git a/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx b/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx index f9084bbf..af4a47e4 100644 --- a/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx +++ b/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx @@ -1,8 +1,8 @@ import { json, query, action, useParams, useAction, createAsync, useSubmission } from "@solidjs/router" -import { createMemo, Show } from "solid-js" +import { createMemo, Match, Show, Switch } from "solid-js" import { Billing } from "@opencode-ai/console-core/billing.js" import { withActor } from "~/context/auth.withActor" -import { IconCreditCard } from "~/component/icon" +import { IconCreditCard, IconStripe } from "~/component/icon" import styles from "./billing-section.module.css" import { Database, eq } from "@opencode-ai/console-core/drizzle/index.js" import { BillingTable } from "@opencode-ai/console-core/schema/billing.sql.js" @@ -61,6 +61,7 @@ export function BillingSection() { // Scenario 1: User has not added billing details and has no balance // const balanceInfo = () => ({ // balance: 0, + // paymentMethodType: null as string | null, // paymentMethodLast4: null as string | null, // reload: false, // reloadError: null as string | null, @@ -70,6 +71,7 @@ export function BillingSection() { // Scenario 2: User has not added billing details but has a balance // const balanceInfo = () => ({ // balance: 1500000000, // $15.00 + // paymentMethodType: null as string | null, // paymentMethodLast4: null as string | null, // reload: false, // reloadError: null as string | null, @@ -79,6 +81,7 @@ export function BillingSection() { // Scenario 3: User has added billing details (reload enabled) // const balanceInfo = () => ({ // balance: 750000000, // $7.50 + // paymentMethodType: "card", // paymentMethodLast4: "4242", // reload: true, // reloadError: null as string | null, @@ -88,12 +91,23 @@ export function BillingSection() { // Scenario 4: User has billing details but reload failed // const balanceInfo = () => ({ // balance: 250000000, // $2.50 + // paymentMethodType: "card", // paymentMethodLast4: "4242", // reload: true, // reloadError: "Your card was declined." as string, // timeReloadError: new Date(Date.now() - 3600000) as Date // 1 hour ago // }) + // Scenario 5: User has Link payment method + // const balanceInfo = () => ({ + // balance: 500000000, // $5.00 + // paymentMethodType: "link", + // paymentMethodLast4: null as string | null, + // reload: true, + // reloadError: null as string | null, + // timeReloadError: null as Date | null + // }) + const balanceAmount = createMemo(() => { return ((balanceInfo()?.balance ?? 0) / 100000000).toFixed(2) }) @@ -136,13 +150,25 @@ export function BillingSection() {
- + }> + + + +
- ----}> - •••• - {balanceInfo()?.paymentMethodLast4} - + ----}> + •••• + {balanceInfo()?.paymentMethodLast4} + + } + > + + Linked to Stripe + +
diff --git a/packages/console/core/migrations/0033_cynical_jack_flag.sql b/packages/console/core/migrations/0033_cynical_jack_flag.sql new file mode 100644 index 00000000..5e9adfc7 --- /dev/null +++ b/packages/console/core/migrations/0033_cynical_jack_flag.sql @@ -0,0 +1 @@ +ALTER TABLE `billing` ADD `payment_method_type` varchar(32); \ No newline at end of file diff --git a/packages/console/core/migrations/meta/0033_snapshot.json b/packages/console/core/migrations/meta/0033_snapshot.json new file mode 100644 index 00000000..eb682adc --- /dev/null +++ b/packages/console/core/migrations/meta/0033_snapshot.json @@ -0,0 +1,893 @@ +{ + "version": "5", + "dialect": "mysql", + "id": "91ef8fda-ca96-4a3f-af29-dd6ae7136398", + "prevId": "b2406421-f22d-4153-a2a4-6deafe70ee54", + "tables": { + "account": { + "name": "account", + "columns": { + "id": { + "name": "id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_created": { + "name": "time_created", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "time_updated": { + "name": "time_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)" + }, + "time_deleted": { + "name": "time_deleted", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "email": { + "name": "email", + "columns": [ + "email" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "billing": { + "name": "billing", + "columns": { + "id": { + "name": "id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_created": { + "name": "time_created", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "time_updated": { + "name": "time_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)" + }, + "time_deleted": { + "name": "time_deleted", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "payment_method_id": { + "name": "payment_method_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "payment_method_type": { + "name": "payment_method_type", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "payment_method_last4": { + "name": "payment_method_last4", + "type": "varchar(4)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "balance": { + "name": "balance", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "monthly_limit": { + "name": "monthly_limit", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "monthly_usage": { + "name": "monthly_usage", + "type": "bigint", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "time_monthly_usage_updated": { + "name": "time_monthly_usage_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "reload": { + "name": "reload", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "reload_error": { + "name": "reload_error", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "time_reload_error": { + "name": "time_reload_error", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "time_reload_locked_till": { + "name": "time_reload_locked_till", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "global_customer_id": { + "name": "global_customer_id", + "columns": [ + "customer_id" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "billing_workspace_id_id_pk": { + "name": "billing_workspace_id_id_pk", + "columns": [ + "workspace_id", + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "payment": { + "name": "payment", + "columns": { + "id": { + "name": "id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_created": { + "name": "time_created", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "time_updated": { + "name": "time_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)" + }, + "time_deleted": { + "name": "time_deleted", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "customer_id": { + "name": "customer_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "invoice_id": { + "name": "invoice_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "payment_id": { + "name": "payment_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "amount": { + "name": "amount", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_refunded": { + "name": "time_refunded", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "payment_workspace_id_id_pk": { + "name": "payment_workspace_id_id_pk", + "columns": [ + "workspace_id", + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "usage": { + "name": "usage", + "columns": { + "id": { + "name": "id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_created": { + "name": "time_created", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "time_updated": { + "name": "time_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)" + }, + "time_deleted": { + "name": "time_deleted", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "model": { + "name": "model", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "input_tokens": { + "name": "input_tokens", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "output_tokens": { + "name": "output_tokens", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "reasoning_tokens": { + "name": "reasoning_tokens", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cache_read_tokens": { + "name": "cache_read_tokens", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cache_write_5m_tokens": { + "name": "cache_write_5m_tokens", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cache_write_1h_tokens": { + "name": "cache_write_1h_tokens", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "key_id": { + "name": "key_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "usage_workspace_id_id_pk": { + "name": "usage_workspace_id_id_pk", + "columns": [ + "workspace_id", + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "key": { + "name": "key", + "columns": { + "id": { + "name": "id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_created": { + "name": "time_created", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "time_updated": { + "name": "time_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)" + }, + "time_deleted": { + "name": "time_deleted", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "key": { + "name": "key", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_used": { + "name": "time_used", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "global_key": { + "name": "global_key", + "columns": [ + "key" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "key_workspace_id_id_pk": { + "name": "key_workspace_id_id_pk", + "columns": [ + "workspace_id", + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "model": { + "name": "model", + "columns": { + "id": { + "name": "id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_created": { + "name": "time_created", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "time_updated": { + "name": "time_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)" + }, + "time_deleted": { + "name": "time_deleted", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "model": { + "name": "model", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "model_workspace_model": { + "name": "model_workspace_model", + "columns": [ + "workspace_id", + "model" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "model_workspace_id_id_pk": { + "name": "model_workspace_id_id_pk", + "columns": [ + "workspace_id", + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "provider": { + "name": "provider", + "columns": { + "id": { + "name": "id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_created": { + "name": "time_created", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "time_updated": { + "name": "time_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)" + }, + "time_deleted": { + "name": "time_deleted", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "credentials": { + "name": "credentials", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "workspace_provider": { + "name": "workspace_provider", + "columns": [ + "workspace_id", + "provider" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "provider_workspace_id_id_pk": { + "name": "provider_workspace_id_id_pk", + "columns": [ + "workspace_id", + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "user": { + "name": "user", + "columns": { + "id": { + "name": "id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_created": { + "name": "time_created", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "time_updated": { + "name": "time_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)" + }, + "time_deleted": { + "name": "time_deleted", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "account_id": { + "name": "account_id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_seen": { + "name": "time_seen", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "enum('admin','member')", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "monthly_limit": { + "name": "monthly_limit", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "monthly_usage": { + "name": "monthly_usage", + "type": "bigint", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "time_monthly_usage_updated": { + "name": "time_monthly_usage_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "user_account_id": { + "name": "user_account_id", + "columns": [ + "workspace_id", + "account_id" + ], + "isUnique": true + }, + "user_email": { + "name": "user_email", + "columns": [ + "workspace_id", + "email" + ], + "isUnique": true + }, + "global_account_id": { + "name": "global_account_id", + "columns": [ + "account_id" + ], + "isUnique": false + }, + "global_email": { + "name": "global_email", + "columns": [ + "email" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "user_workspace_id_id_pk": { + "name": "user_workspace_id_id_pk", + "columns": [ + "workspace_id", + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "workspace": { + "name": "workspace", + "columns": { + "id": { + "name": "id", + "type": "varchar(30)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "time_created": { + "name": "time_created", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "time_updated": { + "name": "time_updated", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)" + }, + "time_deleted": { + "name": "time_deleted", + "type": "timestamp(3)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "slug": { + "name": "slug", + "columns": [ + "slug" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "workspace_id": { + "name": "workspace_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + } + }, + "views": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "tables": {}, + "indexes": {} + } +} \ No newline at end of file diff --git a/packages/console/core/migrations/meta/_journal.json b/packages/console/core/migrations/meta/_journal.json index ab781877..5e6168e5 100644 --- a/packages/console/core/migrations/meta/_journal.json +++ b/packages/console/core/migrations/meta/_journal.json @@ -232,6 +232,13 @@ "when": 1759976329502, "tag": "0032_white_doctor_doom", "breakpoints": true + }, + { + "idx": 33, + "version": "5", + "when": 1760637384217, + "tag": "0033_cynical_jack_flag", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/console/core/src/billing.ts b/packages/console/core/src/billing.ts index 7102a4e5..297edebd 100644 --- a/packages/console/core/src/billing.ts +++ b/packages/console/core/src/billing.ts @@ -27,6 +27,7 @@ export namespace Billing { .select({ customerID: BillingTable.customerID, paymentMethodID: BillingTable.paymentMethodID, + paymentMethodType: BillingTable.paymentMethodType, paymentMethodLast4: BillingTable.paymentMethodLast4, balance: BillingTable.balance, reload: BillingTable.reload, diff --git a/packages/console/core/src/schema/billing.sql.ts b/packages/console/core/src/schema/billing.sql.ts index 215f0a47..c72eba28 100644 --- a/packages/console/core/src/schema/billing.sql.ts +++ b/packages/console/core/src/schema/billing.sql.ts @@ -9,6 +9,7 @@ export const BillingTable = mysqlTable( ...timestamps, customerID: varchar("customer_id", { length: 255 }), paymentMethodID: varchar("payment_method_id", { length: 255 }), + paymentMethodType: varchar("payment_method_type", { length: 32 }), paymentMethodLast4: varchar("payment_method_last4", { length: 4 }), balance: bigint("balance", { mode: "number" }).notNull(), monthlyLimit: int("monthly_limit"), diff --git a/packages/console/scripts/package.json b/packages/console/scripts/package.json index e0af9198..bcd80b82 100644 --- a/packages/console/scripts/package.json +++ b/packages/console/scripts/package.json @@ -10,6 +10,7 @@ "shell-prod": "sst shell --stage production -- bun" }, "dependencies": { - "@opencode-ai/console-core": "workspace:*" + "@opencode-ai/console-core": "workspace:*", + "@opencode-ai/console-resource": "workspace:*" } }