diff --git a/bun.lock b/bun.lock
index bdaef9db3..5f01b805b 100644
--- a/bun.lock
+++ b/bun.lock
@@ -84,10 +84,12 @@
"@solidjs/meta": "catalog:",
"@solidjs/router": "catalog:",
"@solidjs/start": "catalog:",
+ "@stripe/stripe-js": "8.6.1",
"chart.js": "4.5.1",
"nitro": "3.0.1-alpha.1",
"solid-js": "catalog:",
"solid-list": "0.3.0",
+ "solid-stripe": "0.8.1",
"vite": "catalog:",
"zod": "catalog:",
},
@@ -1663,6 +1665,8 @@
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
+ "@stripe/stripe-js": ["@stripe/stripe-js@8.6.1", "", {}, "sha512-UJ05U2062XDgydbUcETH1AoRQLNhigQ2KmDn1BG8sC3xfzu6JKg95Qt6YozdzFpxl1Npii/02m2LEWFt1RYjVA=="],
+
"@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
"@tailwindcss/node": ["@tailwindcss/node@4.1.11", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.11" } }, "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q=="],
@@ -3557,6 +3561,8 @@
"solid-refresh": ["solid-refresh@0.6.3", "", { "dependencies": { "@babel/generator": "^7.23.6", "@babel/helper-module-imports": "^7.22.15", "@babel/types": "^7.23.6" }, "peerDependencies": { "solid-js": "^1.3" } }, "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA=="],
+ "solid-stripe": ["solid-stripe@0.8.1", "", { "peerDependencies": { "@stripe/stripe-js": ">=1.44.1 <8.0.0", "solid-js": "^1.6.0" } }, "sha512-l2SkWoe51rsvk9u1ILBRWyCHODZebChSGMR6zHYJTivTRC0XWrRnNNKs5x1PYXsaIU71KYI6ov5CZB5cOtGLWw=="],
+
"solid-use": ["solid-use@0.9.1", "", { "peerDependencies": { "solid-js": "^1.7" } }, "sha512-UwvXDVPlrrbj/9ewG9ys5uL2IO4jSiwys2KPzK4zsnAcmEl7iDafZWW1Mo4BSEWOmQCGK6IvpmGHo1aou8iOFw=="],
"source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
diff --git a/infra/console.ts b/infra/console.ts
index 1368ef202..17e4deab6 100644
--- a/infra/console.ts
+++ b/infra/console.ts
@@ -122,6 +122,7 @@ const ZEN_MODELS = [
]
const ZEN_BLACK = new sst.Secret("ZEN_BLACK")
const STRIPE_SECRET_KEY = new sst.Secret("STRIPE_SECRET_KEY")
+const STRIPE_PUBLISHABLE_KEY = new sst.Secret("STRIPE_PUBLISHABLE_KEY")
const AUTH_API_URL = new sst.Linkable("AUTH_API_URL", {
properties: { value: auth.url.apply((url) => url!) },
})
@@ -177,6 +178,7 @@ new sst.cloudflare.x.SolidStart("Console", {
//VITE_DOCS_URL: web.url.apply((url) => url!),
//VITE_API_URL: gateway.url.apply((url) => url!),
VITE_AUTH_URL: auth.url.apply((url) => url!),
+ VITE_STRIPE_PUBLISHABLE_KEY: STRIPE_PUBLISHABLE_KEY.value,
},
transform: {
server: {
diff --git a/packages/console/app/package.json b/packages/console/app/package.json
index dff2adef7..469ca9222 100644
--- a/packages/console/app/package.json
+++ b/packages/console/app/package.json
@@ -6,7 +6,7 @@
"scripts": {
"typecheck": "tsgo --noEmit",
"dev": "vite dev --host 0.0.0.0",
- "dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai bun sst shell --stage=dev bun dev",
+ "dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai VITE_STRIPE_PUBLISHABLE_KEY=pk_test_51RtuLNE7fOCwHSD4mewwzFejyytjdGoSDK7CAvhbffwaZnPbNb2rwJICw6LTOXCmWO320fSNXvb5NzI08RZVkAxd00syfqrW7t bun sst shell --stage=dev bun dev",
"build": "./script/generate-sitemap.ts && vite build && ../../opencode/script/schema.ts ./.output/public/config.json",
"start": "vite start"
},
@@ -23,10 +23,12 @@
"@solidjs/meta": "catalog:",
"@solidjs/router": "catalog:",
"@solidjs/start": "catalog:",
+ "@stripe/stripe-js": "8.6.1",
"chart.js": "4.5.1",
"nitro": "3.0.1-alpha.1",
"solid-js": "catalog:",
"solid-list": "0.3.0",
+ "solid-stripe": "0.8.1",
"vite": "catalog:",
"zod": "catalog:"
},
diff --git a/packages/console/app/src/routes/auth/callback.ts b/packages/console/app/src/routes/auth/[...callback].ts
similarity index 91%
rename from packages/console/app/src/routes/auth/callback.ts
rename to packages/console/app/src/routes/auth/[...callback].ts
index 9b7296791..36a9c5194 100644
--- a/packages/console/app/src/routes/auth/callback.ts
+++ b/packages/console/app/src/routes/auth/[...callback].ts
@@ -5,6 +5,7 @@ import { useAuthSession } from "~/context/auth"
export async function GET(input: APIEvent) {
const url = new URL(input.request.url)
+
try {
const code = url.searchParams.get("code")
if (!code) throw new Error("No code found")
@@ -27,7 +28,7 @@ export async function GET(input: APIEvent) {
current: id,
}
})
- return redirect("/auth")
+ return redirect(url.pathname === "/auth/callback" ? "/auth" : url.pathname.replace("/auth/callback", ""))
} catch (e: any) {
return new Response(
JSON.stringify({
diff --git a/packages/console/app/src/routes/auth/authorize.ts b/packages/console/app/src/routes/auth/authorize.ts
index 166466ef8..0f0651ae3 100644
--- a/packages/console/app/src/routes/auth/authorize.ts
+++ b/packages/console/app/src/routes/auth/authorize.ts
@@ -2,6 +2,9 @@ import type { APIEvent } from "@solidjs/start/server"
import { AuthClient } from "~/context/auth"
export async function GET(input: APIEvent) {
- const result = await AuthClient.authorize(new URL("./callback", input.request.url).toString(), "code")
+ const url = new URL(input.request.url)
+ const cont = url.searchParams.get("continue") ?? ""
+ const callbackUrl = new URL(`./callback${cont}`, input.request.url)
+ const result = await AuthClient.authorize(callbackUrl.toString(), "code")
return Response.redirect(result.url, 302)
}
diff --git a/packages/console/app/src/routes/black/index.css b/packages/console/app/src/routes/black.css
similarity index 55%
rename from packages/console/app/src/routes/black/index.css
rename to packages/console/app/src/routes/black.css
index 418598792..72bf7a657 100644
--- a/packages/console/app/src/routes/black/index.css
+++ b/packages/console/app/src/routes/black.css
@@ -36,24 +36,73 @@
width: 100%;
flex-grow: 1;
- [data-slot="hero-black"] {
- margin-top: 110px;
+ [data-slot="hero"] {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ gap: 8px;
+ margin-top: 40px;
+ padding: 0 20px;
@media (min-width: 768px) {
- margin-top: 150px;
+ margin-top: 60px;
+ }
+
+ h1 {
+ color: rgba(255, 255, 255, 0.92);
+ font-size: 18px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 160%;
+ margin: 0;
+
+ @media (min-width: 768px) {
+ font-size: 24px;
+ }
+ }
+
+ p {
+ color: rgba(255, 255, 255, 0.59);
+ font-size: 15px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 160%;
+ margin: 0;
+
+ @media (min-width: 768px) {
+ font-size: 18px;
+ }
+ }
+ }
+
+ [data-slot="hero-black"] {
+ margin-top: 40px;
+ padding: 0 20px;
+
+ @media (min-width: 768px) {
+ margin-top: 60px;
+ }
+
+ svg {
+ width: 100%;
+ max-width: 540px;
+ height: auto;
+ filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.1));
}
}
[data-slot="cta"] {
display: flex;
flex-direction: column;
- gap: 32px;
+ gap: 16px;
align-items: center;
text-align: center;
- margin-top: -18px;
+ margin-top: -40px;
+ width: 100%;
@media (min-width: 768px) {
- margin-top: 40px;
+ margin-top: -20px;
}
[data-slot="heading"] {
@@ -328,6 +377,290 @@
}
}
}
+
+ /* Subscribe page styles */
+ [data-slot="subscribe-form"] {
+ display: flex;
+ flex-direction: column;
+ gap: 32px;
+ align-items: center;
+ margin-top: -18px;
+ width: 100%;
+ max-width: 540px;
+ padding: 0 20px;
+
+ @media (min-width: 768px) {
+ margin-top: 40px;
+ padding: 0;
+ }
+
+ [data-slot="form-card"] {
+ width: 100%;
+ border: 1px solid rgba(255, 255, 255, 0.17);
+ border-radius: 4px;
+ padding: 24px;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ }
+
+ [data-slot="plan-header"] {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ }
+
+ [data-slot="title"] {
+ color: rgba(255, 255, 255, 0.92);
+ font-size: 16px;
+ font-weight: 400;
+ margin-bottom: 8px;
+ }
+
+ [data-slot="icon"] {
+ color: rgba(255, 255, 255, 0.59);
+ }
+
+ [data-slot="price"] {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: baseline;
+ gap: 8px;
+ }
+
+ [data-slot="amount"] {
+ color: rgba(255, 255, 255, 0.92);
+ font-size: 24px;
+ font-weight: 500;
+ }
+
+ [data-slot="period"] {
+ color: rgba(255, 255, 255, 0.59);
+ font-size: 14px;
+ }
+
+ [data-slot="multiplier"] {
+ color: rgba(255, 255, 255, 0.39);
+ font-size: 14px;
+
+ &::before {
+ content: "·";
+ margin: 0 8px;
+ }
+ }
+
+ [data-slot="divider"] {
+ height: 1px;
+ background: rgba(255, 255, 255, 0.17);
+ }
+
+ [data-slot="section-title"] {
+ color: rgba(255, 255, 255, 0.92);
+ font-size: 16px;
+ font-weight: 400;
+ }
+
+ [data-slot="tax-id-section"] {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+
+ [data-slot="label"] {
+ color: rgba(255, 255, 255, 0.59);
+ font-size: 14px;
+ }
+
+ [data-slot="input"] {
+ width: 100%;
+ height: 44px;
+ padding: 0 12px;
+ background: #1a1a1a;
+ border: 1px solid rgba(255, 255, 255, 0.17);
+ border-radius: 4px;
+ color: #ffffff;
+ font-family: var(--font-mono);
+ font-size: 14px;
+ outline: none;
+ transition: border-color 0.15s ease;
+
+ &::placeholder {
+ color: rgba(255, 255, 255, 0.39);
+ }
+
+ &:focus {
+ border-color: rgba(255, 255, 255, 0.35);
+ }
+ }
+ }
+
+ [data-slot="checkout-form"] {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ }
+
+ [data-slot="error"] {
+ color: #ff6b6b;
+ font-size: 14px;
+ }
+
+ [data-slot="submit-button"] {
+ width: 100%;
+ height: 48px;
+ background: rgba(255, 255, 255, 0.92);
+ border: none;
+ border-radius: 4px;
+ color: #000;
+ font-family: var(--font-mono);
+ font-size: 16px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background 0.15s ease;
+
+ &:hover:not(:disabled) {
+ background: #e0e0e0;
+ }
+
+ &:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+ }
+
+ [data-slot="charge-notice"] {
+ color: #d4a500;
+ font-size: 14px;
+ text-align: center;
+ }
+
+ [data-slot="success"] {
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+
+ [data-slot="title"] {
+ color: rgba(255, 255, 255, 0.92);
+ font-size: 18px;
+ font-weight: 400;
+ margin: 0;
+ }
+
+ [data-slot="details"] {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+
+ > div {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ gap: 16px;
+ }
+
+ dt {
+ color: rgba(255, 255, 255, 0.59);
+ font-size: 14px;
+ font-weight: 400;
+ }
+
+ dd {
+ color: rgba(255, 255, 255, 0.92);
+ font-size: 14px;
+ font-weight: 400;
+ margin: 0;
+ text-align: right;
+ }
+ }
+
+ [data-slot="charge-notice"] {
+ color: #d4a500;
+ font-size: 14px;
+ text-align: left;
+ }
+ }
+
+ [data-slot="loading"] {
+ display: flex;
+ justify-content: center;
+ padding: 40px 0;
+
+ p {
+ color: rgba(255, 255, 255, 0.59);
+ font-size: 14px;
+ }
+ }
+
+ [data-slot="fine-print"] {
+ color: rgba(255, 255, 255, 0.39);
+ text-align: center;
+ font-size: 13px;
+ font-style: italic;
+
+ a {
+ color: rgba(255, 255, 255, 0.39);
+ text-decoration: underline;
+ }
+ }
+
+ [data-slot="workspace-picker"] {
+ [data-slot="workspace-list"] {
+ width: 100%;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 8px;
+ align-self: stretch;
+ outline: none;
+ overflow-y: auto;
+ max-height: 240px;
+ scrollbar-width: none;
+
+ &::-webkit-scrollbar {
+ display: none;
+ }
+
+ [data-slot="workspace-item"] {
+ width: 100%;
+ display: flex;
+ padding: 8px 12px;
+ align-items: center;
+ gap: 8px;
+ align-self: stretch;
+ cursor: pointer;
+
+ [data-slot="selected-icon"] {
+ visibility: hidden;
+ color: rgba(255, 255, 255, 0.39);
+ font-family: "IBM Plex Mono", monospace;
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 160%;
+ }
+
+ span:last-child {
+ color: rgba(255, 255, 255, 0.92);
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 160%;
+ }
+
+ &:hover,
+ &[data-active="true"] {
+ background: #161616;
+
+ [data-slot="selected-icon"] {
+ visibility: visible;
+ }
+ }
+ }
+ }
+ }
+ }
}
[data-component="footer"] {
diff --git a/packages/console/app/src/routes/black.tsx b/packages/console/app/src/routes/black.tsx
new file mode 100644
index 000000000..5a5b139dd
--- /dev/null
+++ b/packages/console/app/src/routes/black.tsx
@@ -0,0 +1,166 @@
+import { A, createAsync, RouteSectionProps } from "@solidjs/router"
+import { createMemo } from "solid-js"
+import { github } from "~/lib/github"
+import { config } from "~/config"
+import "./black.css"
+
+export default function BlackLayout(props: RouteSectionProps) {
+ const githubData = createAsync(() => github())
+ const starCount = createMemo(() =>
+ githubData()?.stars
+ ? new Intl.NumberFormat("en-US", {
+ notation: "compact",
+ compactDisplay: "short",
+ }).format(githubData()!.stars!)
+ : config.github.starsFormatted.compact,
+ )
+
+ return (
+
+
+
+
+
+
+
+
+
+
Access all the world's best coding models
+
Including Claude, GPT, Gemini and more
+
+
+
+
+ {props.children}
+
+
+
+ )
+}
diff --git a/packages/console/app/src/routes/black/common.tsx b/packages/console/app/src/routes/black/common.tsx
new file mode 100644
index 000000000..950531da1
--- /dev/null
+++ b/packages/console/app/src/routes/black/common.tsx
@@ -0,0 +1,43 @@
+import { Match, Switch } from "solid-js"
+
+export const plans = [
+ { id: "20", multiplier: null },
+ { id: "100", multiplier: "6x more usage than Black 20" },
+ { id: "200", multiplier: "21x more usage than Black 20" },
+] as const
+
+export type PlanID = (typeof plans)[number]["id"]
+export type Plan = (typeof plans)[number]
+
+export function PlanIcon(props: { plan: string }) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/packages/console/app/src/routes/black/index.tsx b/packages/console/app/src/routes/black/index.tsx
index f5a375adf..5d924a64b 100644
--- a/packages/console/app/src/routes/black/index.tsx
+++ b/packages/console/app/src/routes/black/index.tsx
@@ -1,276 +1,80 @@
-import { A, createAsync, useSearchParams } from "@solidjs/router"
-import "./index.css"
+import { A, useSearchParams } from "@solidjs/router"
import { Title } from "@solidjs/meta"
-import { github } from "~/lib/github"
import { createMemo, createSignal, For, Match, Show, Switch } from "solid-js"
-import { config } from "~/config"
-
-const plans = [
- { id: "20", amount: 20, multiplier: null },
- { id: "100", amount: 100, multiplier: "6x more usage than Black 20" },
- { id: "200", amount: 200, multiplier: "21x more usage than Black 20" },
-] as const
-
-function PlanIcon(props: { plan: string }) {
- return (
-
-
-
-
-
-
-
-
-
-
-
- )
-}
+import { PlanIcon, plans } from "./common"
export default function Black() {
const [params] = useSearchParams()
- const [selected, setSelected] = createSignal(params.plan as string | null)
+ const [selected, setSelected] = createSignal((params.plan as string) || null)
const selectedPlan = createMemo(() => plans.find((p) => p.id === selected()))
- const githubData = createAsync(() => github())
- const starCount = createMemo(() =>
- githubData()?.stars
- ? new Intl.NumberFormat("en-US", {
- notation: "compact",
- compactDisplay: "short",
- }).format(githubData()!.stars!)
- : config.github.starsFormatted.compact,
- )
-
return (
-
+ <>
opencode
-
-
-
-
-
-
-
-
-
-
-
-
-
- Access all the world's best coding models
-
-
Including Claude, GPT, Gemini, and more
-
-
-
-
-
- {(plan) => (
-
- )}
-
-
-
- Prices shown don't include applicable tax · Terms of Service
-
-
-
- {(plan) => (
-
-
+
+
+
+
+
+ {(plan) => (
+
+ )}
+
+
+
+ Prices shown don't include applicable tax · Terms of Service
+
+
+
+ {(plan) => (
+
+
+
-
- Prices shown don't include applicable tax · Terms of Service
+
+ ${plan().id}{" "}
+ per person billed monthly
+
+ {plan().multiplier}
+
+
+ - Your subscription will not start immediately
+ - You will be added to the waitlist and activated soon
+ - Your card will be only charged when your subscription is activated
+ - Usage limits apply, heavily automated use may reach limits sooner
+ - Subscriptions for individuals, contact Enterprise for teams
+ - Limits may be adjusted and plans may be discontinued in the future
+ - Cancel your subscription at anytime
+
+
+
setSelected(null)} data-slot="cancel">
+ Cancel
+
+
+ Continue
+
+
- )}
-
-
-
-
-
-
+
+ Prices shown don't include applicable tax · Terms of Service
+
+
+ )}
+
+
+
+ >
)
}
diff --git a/packages/console/app/src/routes/black/subscribe/[plan].tsx b/packages/console/app/src/routes/black/subscribe/[plan].tsx
new file mode 100644
index 000000000..5e13799dd
--- /dev/null
+++ b/packages/console/app/src/routes/black/subscribe/[plan].tsx
@@ -0,0 +1,450 @@
+import { A, createAsync, query, redirect, useParams } from "@solidjs/router"
+import { Title } from "@solidjs/meta"
+import { createEffect, createSignal, For, Match, Show, Switch } from "solid-js"
+import { type Stripe, type PaymentMethod, loadStripe } from "@stripe/stripe-js"
+import { Elements, PaymentElement, useStripe, useElements, AddressElement } from "solid-stripe"
+import { PlanID, plans } from "../common"
+import { getActor, useAuthSession } from "~/context/auth"
+import { withActor } from "~/context/auth.withActor"
+import { Actor } from "@opencode-ai/console-core/actor.js"
+import { and, Database, eq, isNull } from "@opencode-ai/console-core/drizzle/index.js"
+import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
+import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
+import { createList } from "solid-list"
+import { Modal } from "~/component/modal"
+import { BillingTable } from "@opencode-ai/console-core/schema/billing.sql.js"
+import { Billing } from "@opencode-ai/console-core/billing.js"
+
+const plansMap = Object.fromEntries(plans.map((p) => [p.id, p])) as Record
+const stripePromise = loadStripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY!)
+
+const getWorkspaces = query(async () => {
+ "use server"
+ const actor = await getActor()
+ if (actor.type === "public") throw redirect("/auth/authorize?continue=/black/subscribe")
+ return withActor(async () => {
+ return Database.use((tx) =>
+ tx
+ .select({
+ id: WorkspaceTable.id,
+ name: WorkspaceTable.name,
+ slug: WorkspaceTable.slug,
+ billing: {
+ customerID: BillingTable.customerID,
+ paymentMethodID: BillingTable.paymentMethodID,
+ paymentMethodType: BillingTable.paymentMethodType,
+ paymentMethodLast4: BillingTable.paymentMethodLast4,
+ subscriptionID: BillingTable.subscriptionID,
+ timeSubscriptionBooked: BillingTable.timeSubscriptionBooked,
+ },
+ })
+ .from(UserTable)
+ .innerJoin(WorkspaceTable, eq(UserTable.workspaceID, WorkspaceTable.id))
+ .innerJoin(BillingTable, eq(WorkspaceTable.id, BillingTable.workspaceID))
+ .where(
+ and(
+ eq(UserTable.accountID, Actor.account()),
+ isNull(WorkspaceTable.timeDeleted),
+ isNull(UserTable.timeDeleted),
+ ),
+ ),
+ )
+ })
+}, "black.subscribe.workspaces")
+
+const createSetupIntent = async (input: { plan: string; workspaceID: string }) => {
+ "use server"
+ const { plan, workspaceID } = input
+
+ if (!plan || !["20", "100", "200"].includes(plan)) return { error: "Invalid plan" }
+ if (!workspaceID) return { error: "Workspace ID is required" }
+
+ return withActor(async () => {
+ const session = await useAuthSession()
+ const account = session.data.account?.[session.data.current ?? ""]
+ const email = account?.email
+
+ const customer = await Database.use((tx) =>
+ tx
+ .select({
+ customerID: BillingTable.customerID,
+ subscriptionID: BillingTable.subscriptionID,
+ })
+ .from(BillingTable)
+ .where(eq(BillingTable.workspaceID, workspaceID))
+ .then((rows) => rows[0]),
+ )
+ if (customer?.subscriptionID) {
+ return { error: "This workspace already has a subscription" }
+ }
+
+ let customerID = customer?.customerID
+ if (!customerID) {
+ const customer = await Billing.stripe().customers.create({
+ email,
+ metadata: {
+ workspaceID,
+ },
+ })
+ customerID = customer.id
+ await Database.use((tx) =>
+ tx
+ .update(BillingTable)
+ .set({
+ customerID,
+ })
+ .where(eq(BillingTable.workspaceID, workspaceID)),
+ )
+ }
+
+ const intent = await Billing.stripe().setupIntents.create({
+ customer: customerID,
+ payment_method_types: ["card"],
+ metadata: {
+ workspaceID,
+ },
+ })
+
+ return { clientSecret: intent.client_secret ?? undefined }
+ }, workspaceID)
+}
+
+const bookSubscription = async (input: {
+ workspaceID: string
+ plan: PlanID
+ paymentMethodID: string
+ paymentMethodType: string
+ paymentMethodLast4?: string
+}) => {
+ "use server"
+ return withActor(
+ () =>
+ Database.use((tx) =>
+ tx
+ .update(BillingTable)
+ .set({
+ paymentMethodID: input.paymentMethodID,
+ paymentMethodType: input.paymentMethodType,
+ paymentMethodLast4: input.paymentMethodLast4,
+ subscriptionPlan: input.plan,
+ timeSubscriptionBooked: new Date(),
+ })
+ .where(eq(BillingTable.workspaceID, input.workspaceID)),
+ ),
+ input.workspaceID,
+ )
+}
+
+interface SuccessData {
+ plan: string
+ paymentMethodType: string
+ paymentMethodLast4?: string
+}
+
+function Failure(props: { message: string }) {
+ return (
+
+
Uh oh! {props.message}
+
+ )
+}
+
+function Success(props: SuccessData) {
+ return (
+
+
You're on the OpenCode Black waitlist
+
+
+
- Subscription plan
+ - OpenCode Black {props.plan}
+
+
+
- Amount
+ - ${props.plan} per month
+
+
+
- Payment method
+ -
+ {props.paymentMethodType}}>
+
+ {props.paymentMethodType} - {props.paymentMethodLast4}
+
+
+
+
+
+
- Date joined
+ - {new Date().toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })}
+
+
+
Your card will be charged when your subscription is activated
+
+ )
+}
+
+function IntentForm(props: { plan: PlanID; workspaceID: string; onSuccess: (data: SuccessData) => void }) {
+ const stripe = useStripe()
+ const elements = useElements()
+ const [error, setError] = createSignal(undefined)
+ const [loading, setLoading] = createSignal(false)
+
+ const handleSubmit = async (e: Event) => {
+ e.preventDefault()
+ if (!stripe() || !elements()) return
+
+ setLoading(true)
+ setError(undefined)
+
+ const result = await elements()!.submit()
+ if (result.error) {
+ setError(result.error.message ?? "An error occurred")
+ setLoading(false)
+ return
+ }
+
+ const { error: confirmError, setupIntent } = await stripe()!.confirmSetup({
+ elements: elements()!,
+ confirmParams: {
+ expand: ["payment_method"],
+ payment_method_data: {
+ allow_redisplay: "always",
+ },
+ },
+ redirect: "if_required",
+ })
+
+ if (confirmError) {
+ setError(confirmError.message ?? "An error occurred")
+ setLoading(false)
+ return
+ }
+
+ // TODO
+ console.log(setupIntent)
+ if (setupIntent?.status === "succeeded") {
+ const pm = setupIntent.payment_method as PaymentMethod
+
+ await bookSubscription({
+ workspaceID: props.workspaceID,
+ plan: props.plan,
+ paymentMethodID: pm.id,
+ paymentMethodType: pm.type,
+ paymentMethodLast4: pm.card?.last4,
+ })
+
+ props.onSuccess({
+ plan: props.plan,
+ paymentMethodType: pm.type,
+ paymentMethodLast4: pm.card?.last4,
+ })
+ }
+
+ setLoading(false)
+ }
+
+ return (
+
+ )
+}
+
+export default function BlackSubscribe() {
+ const workspaces = createAsync(() => getWorkspaces())
+ const [selectedWorkspace, setSelectedWorkspace] = createSignal(undefined)
+ const [success, setSuccess] = createSignal(undefined)
+ const [failure, setFailure] = createSignal(undefined)
+ const [clientSecret, setClientSecret] = createSignal(undefined)
+ const [stripe, setStripe] = createSignal(undefined)
+ const params = useParams()
+ const planData = plansMap[(params.plan as PlanID) ?? "20"] ?? plansMap["20"]
+ const plan = planData.id
+
+ // Resolve stripe promise once
+ createEffect(() => {
+ stripePromise.then((s) => {
+ if (s) setStripe(s)
+ })
+ })
+
+ // Auto-select if only one workspace
+ createEffect(() => {
+ const ws = workspaces()
+ if (ws?.length === 1 && !selectedWorkspace()) {
+ setSelectedWorkspace(ws[0].id)
+ }
+ })
+
+ // Fetch setup intent when workspace is selected (unless workspace already has payment method)
+ createEffect(async () => {
+ const id = selectedWorkspace()
+ if (!id) return
+
+ const ws = workspaces()?.find((w) => w.id === id)
+ if (ws?.billing?.subscriptionID) {
+ setFailure("This workspace already has a subscription")
+ return
+ }
+ if (ws?.billing?.paymentMethodID) {
+ if (!ws?.billing?.timeSubscriptionBooked) {
+ await bookSubscription({
+ workspaceID: id,
+ plan: planData.id,
+ paymentMethodID: ws.billing.paymentMethodID!,
+ paymentMethodType: ws.billing.paymentMethodType!,
+ paymentMethodLast4: ws.billing.paymentMethodLast4 ?? undefined,
+ })
+ }
+ setSuccess({
+ plan: planData.id,
+ paymentMethodType: ws.billing.paymentMethodType!,
+ paymentMethodLast4: ws.billing.paymentMethodLast4 ?? undefined,
+ })
+ return
+ }
+
+ const result = await createSetupIntent({ plan, workspaceID: id })
+ if (result.error) {
+ setFailure(result.error)
+ } else if ("clientSecret" in result) {
+ setClientSecret(result.clientSecret)
+ }
+ })
+
+ // Keyboard navigation for workspace picker
+ const { active, setActive, onKeyDown } = createList({
+ items: () => workspaces()?.map((w) => w.id) ?? [],
+ initialActive: null,
+ })
+
+ const handleSelectWorkspace = (id: string) => {
+ setSelectedWorkspace(id)
+ }
+
+ let listRef: HTMLUListElement | undefined
+
+ // Show workspace picker if multiple workspaces and none selected
+ const showWorkspacePicker = () => {
+ const ws = workspaces()
+ return ws && ws.length > 1 && !selectedWorkspace()
+ }
+
+ return (
+ <>
+ Subscribe to OpenCode Black
+
+
+
+ {(data) => }
+ {(data) => }
+
+ <>
+
+
Subscribe to OpenCode Black
+
+ ${planData.id} per month
+
+ {planData.multiplier}
+
+
+
+
+ Payment method
+
+
+ {selectedWorkspace() ? "Loading payment form..." : "Select a workspace to continue"}
+
+ }
+ >
+
+
+
+
+ >
+
+
+
+
+ {/* Workspace picker modal */}
+ {}} title="Select a workspace for this plan">
+
+
{
+ if (e.key === "Enter" && active()) {
+ handleSelectWorkspace(active()!)
+ } else {
+ onKeyDown(e)
+ }
+ }}
+ >
+
+ {(workspace) => (
+ - setActive(workspace.id)}
+ onClick={() => handleSelectWorkspace(workspace.id)}
+ >
+ [*]
+ {workspace.name || workspace.slug}
+
+ )}
+
+
+
+
+
+ Prices shown don't include applicable tax · Terms of Service
+
+
+ >
+ )
+}
diff --git a/packages/console/core/migrations/0051_jazzy_green_goblin.sql b/packages/console/core/migrations/0051_jazzy_green_goblin.sql
new file mode 100644
index 000000000..cadb4a709
--- /dev/null
+++ b/packages/console/core/migrations/0051_jazzy_green_goblin.sql
@@ -0,0 +1 @@
+ALTER TABLE `billing` ADD `time_subscription_booked` timestamp(3);
\ No newline at end of file
diff --git a/packages/console/core/migrations/0052_aromatic_agent_zero.sql b/packages/console/core/migrations/0052_aromatic_agent_zero.sql
new file mode 100644
index 000000000..c53ba5e2b
--- /dev/null
+++ b/packages/console/core/migrations/0052_aromatic_agent_zero.sql
@@ -0,0 +1 @@
+ALTER TABLE `billing` ADD `subscription_plan` enum('20','100','200');
\ No newline at end of file
diff --git a/packages/console/core/migrations/meta/0051_snapshot.json b/packages/console/core/migrations/meta/0051_snapshot.json
new file mode 100644
index 000000000..38002a288
--- /dev/null
+++ b/packages/console/core/migrations/meta/0051_snapshot.json
@@ -0,0 +1,1302 @@
+{
+ "version": "5",
+ "dialect": "mysql",
+ "id": "14cbf4c8-55f1-4488-956f-56fb5ccb3a5a",
+ "prevId": "a0d18802-c390-47d4-98f1-d1f83869cf0c",
+ "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
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "account_id_pk": {
+ "name": "account_id_pk",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "auth": {
+ "name": "auth",
+ "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
+ },
+ "provider": {
+ "name": "provider",
+ "type": "enum('email','github','google')",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "subject": {
+ "name": "subject",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "provider": {
+ "name": "provider",
+ "columns": [
+ "provider",
+ "subject"
+ ],
+ "isUnique": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "columns": [
+ "account_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "auth_id_pk": {
+ "name": "auth_id_pk",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "benchmark": {
+ "name": "benchmark",
+ "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
+ },
+ "model": {
+ "name": "model",
+ "type": "varchar(64)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "agent": {
+ "name": "agent",
+ "type": "varchar(64)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "result": {
+ "name": "result",
+ "type": "mediumtext",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "time_created": {
+ "name": "time_created",
+ "columns": [
+ "time_created"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "benchmark_id_pk": {
+ "name": "benchmark_id_pk",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "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_trigger": {
+ "name": "reload_trigger",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "reload_amount": {
+ "name": "reload_amount",
+ "type": "int",
+ "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
+ },
+ "subscription_id": {
+ "name": "subscription_id",
+ "type": "varchar(28)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "subscription_coupon_id": {
+ "name": "subscription_coupon_id",
+ "type": "varchar(28)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_subscription_booked": {
+ "name": "time_subscription_booked",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "global_customer_id": {
+ "name": "global_customer_id",
+ "columns": [
+ "customer_id"
+ ],
+ "isUnique": true
+ },
+ "global_subscription_id": {
+ "name": "global_subscription_id",
+ "columns": [
+ "subscription_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
+ },
+ "enrichment": {
+ "name": "enrichment",
+ "type": "json",
+ "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": {}
+ },
+ "subscription": {
+ "name": "subscription",
+ "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
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "rolling_usage": {
+ "name": "rolling_usage",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "fixed_usage": {
+ "name": "fixed_usage",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_rolling_updated": {
+ "name": "time_rolling_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_fixed_updated": {
+ "name": "time_fixed_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "workspace_user_id": {
+ "name": "workspace_user_id",
+ "columns": [
+ "workspace_id",
+ "user_id"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "subscription_workspace_id_id_pk": {
+ "name": "subscription_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
+ },
+ "enrichment": {
+ "name": "enrichment",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "usage_time_created": {
+ "name": "usage_time_created",
+ "columns": [
+ "workspace_id",
+ "time_created"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "usage_workspace_id_id_pk": {
+ "name": "usage_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "ip_rate_limit": {
+ "name": "ip_rate_limit",
+ "columns": {
+ "ip": {
+ "name": "ip",
+ "type": "varchar(45)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "interval": {
+ "name": "interval",
+ "type": "varchar(10)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "count": {
+ "name": "count",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "ip_rate_limit_ip_interval_pk": {
+ "name": "ip_rate_limit_ip_interval_pk",
+ "columns": [
+ "ip",
+ "interval"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "ip": {
+ "name": "ip",
+ "columns": {
+ "ip": {
+ "name": "ip",
+ "type": "varchar(45)",
+ "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
+ },
+ "usage": {
+ "name": "usage",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "ip_ip_pk": {
+ "name": "ip_ip_pk",
+ "columns": [
+ "ip"
+ ]
+ }
+ },
+ "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/0052_snapshot.json b/packages/console/core/migrations/meta/0052_snapshot.json
new file mode 100644
index 000000000..b5e1b4b8c
--- /dev/null
+++ b/packages/console/core/migrations/meta/0052_snapshot.json
@@ -0,0 +1,1309 @@
+{
+ "version": "5",
+ "dialect": "mysql",
+ "id": "00774acd-a1e5-49c0-b296-cacc9506a566",
+ "prevId": "14cbf4c8-55f1-4488-956f-56fb5ccb3a5a",
+ "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
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "account_id_pk": {
+ "name": "account_id_pk",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "auth": {
+ "name": "auth",
+ "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
+ },
+ "provider": {
+ "name": "provider",
+ "type": "enum('email','github','google')",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "subject": {
+ "name": "subject",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "provider": {
+ "name": "provider",
+ "columns": [
+ "provider",
+ "subject"
+ ],
+ "isUnique": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "columns": [
+ "account_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "auth_id_pk": {
+ "name": "auth_id_pk",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "benchmark": {
+ "name": "benchmark",
+ "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
+ },
+ "model": {
+ "name": "model",
+ "type": "varchar(64)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "agent": {
+ "name": "agent",
+ "type": "varchar(64)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "result": {
+ "name": "result",
+ "type": "mediumtext",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "time_created": {
+ "name": "time_created",
+ "columns": [
+ "time_created"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "benchmark_id_pk": {
+ "name": "benchmark_id_pk",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "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_trigger": {
+ "name": "reload_trigger",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "reload_amount": {
+ "name": "reload_amount",
+ "type": "int",
+ "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
+ },
+ "subscription_id": {
+ "name": "subscription_id",
+ "type": "varchar(28)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "subscription_coupon_id": {
+ "name": "subscription_coupon_id",
+ "type": "varchar(28)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "subscription_plan": {
+ "name": "subscription_plan",
+ "type": "enum('20','100','200')",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_subscription_booked": {
+ "name": "time_subscription_booked",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "global_customer_id": {
+ "name": "global_customer_id",
+ "columns": [
+ "customer_id"
+ ],
+ "isUnique": true
+ },
+ "global_subscription_id": {
+ "name": "global_subscription_id",
+ "columns": [
+ "subscription_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
+ },
+ "enrichment": {
+ "name": "enrichment",
+ "type": "json",
+ "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": {}
+ },
+ "subscription": {
+ "name": "subscription",
+ "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
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "rolling_usage": {
+ "name": "rolling_usage",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "fixed_usage": {
+ "name": "fixed_usage",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_rolling_updated": {
+ "name": "time_rolling_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_fixed_updated": {
+ "name": "time_fixed_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "workspace_user_id": {
+ "name": "workspace_user_id",
+ "columns": [
+ "workspace_id",
+ "user_id"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "subscription_workspace_id_id_pk": {
+ "name": "subscription_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
+ },
+ "enrichment": {
+ "name": "enrichment",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "usage_time_created": {
+ "name": "usage_time_created",
+ "columns": [
+ "workspace_id",
+ "time_created"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "usage_workspace_id_id_pk": {
+ "name": "usage_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "ip_rate_limit": {
+ "name": "ip_rate_limit",
+ "columns": {
+ "ip": {
+ "name": "ip",
+ "type": "varchar(45)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "interval": {
+ "name": "interval",
+ "type": "varchar(10)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "count": {
+ "name": "count",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "ip_rate_limit_ip_interval_pk": {
+ "name": "ip_rate_limit_ip_interval_pk",
+ "columns": [
+ "ip",
+ "interval"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "ip": {
+ "name": "ip",
+ "columns": {
+ "ip": {
+ "name": "ip",
+ "type": "varchar(45)",
+ "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
+ },
+ "usage": {
+ "name": "usage",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "ip_ip_pk": {
+ "name": "ip_ip_pk",
+ "columns": [
+ "ip"
+ ]
+ }
+ },
+ "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 9982daef5..019817f91 100644
--- a/packages/console/core/migrations/meta/_journal.json
+++ b/packages/console/core/migrations/meta/_journal.json
@@ -358,6 +358,20 @@
"when": 1767931290031,
"tag": "0050_bumpy_mephistopheles",
"breakpoints": true
+ },
+ {
+ "idx": 51,
+ "version": "5",
+ "when": 1768341152722,
+ "tag": "0051_jazzy_green_goblin",
+ "breakpoints": true
+ },
+ {
+ "idx": 52,
+ "version": "5",
+ "when": 1768343920467,
+ "tag": "0052_aromatic_agent_zero",
+ "breakpoints": true
}
]
-}
+}
\ No newline at end of file
diff --git a/packages/console/core/src/schema/billing.sql.ts b/packages/console/core/src/schema/billing.sql.ts
index 6c2cfcf96..f1300f849 100644
--- a/packages/console/core/src/schema/billing.sql.ts
+++ b/packages/console/core/src/schema/billing.sql.ts
@@ -1,4 +1,4 @@
-import { bigint, boolean, index, int, json, mysqlTable, uniqueIndex, varchar } from "drizzle-orm/mysql-core"
+import { bigint, boolean, index, int, json, mysqlEnum, mysqlTable, uniqueIndex, varchar } from "drizzle-orm/mysql-core"
import { timestamps, ulid, utc, workspaceColumns } from "../drizzle/types"
import { workspaceIndexes } from "./workspace.sql"
@@ -23,6 +23,8 @@ export const BillingTable = mysqlTable(
timeReloadLockedTill: utc("time_reload_locked_till"),
subscriptionID: varchar("subscription_id", { length: 28 }),
subscriptionCouponID: varchar("subscription_coupon_id", { length: 28 }),
+ subscriptionPlan: mysqlEnum("subscription_plan", ["20", "100", "200"] as const),
+ timeSubscriptionBooked: utc("time_subscription_booked"),
},
(table) => [
...workspaceIndexes(table),
diff --git a/packages/console/core/sst-env.d.ts b/packages/console/core/sst-env.d.ts
index 96fada3e3..b8e50a261 100644
--- a/packages/console/core/sst-env.d.ts
+++ b/packages/console/core/sst-env.d.ts
@@ -78,6 +78,10 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "STRIPE_PUBLISHABLE_KEY": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"STRIPE_SECRET_KEY": {
"type": "sst.sst.Secret"
"value": string
diff --git a/packages/console/function/sst-env.d.ts b/packages/console/function/sst-env.d.ts
index 96fada3e3..b8e50a261 100644
--- a/packages/console/function/sst-env.d.ts
+++ b/packages/console/function/sst-env.d.ts
@@ -78,6 +78,10 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "STRIPE_PUBLISHABLE_KEY": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"STRIPE_SECRET_KEY": {
"type": "sst.sst.Secret"
"value": string
diff --git a/packages/console/resource/sst-env.d.ts b/packages/console/resource/sst-env.d.ts
index 96fada3e3..b8e50a261 100644
--- a/packages/console/resource/sst-env.d.ts
+++ b/packages/console/resource/sst-env.d.ts
@@ -78,6 +78,10 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "STRIPE_PUBLISHABLE_KEY": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"STRIPE_SECRET_KEY": {
"type": "sst.sst.Secret"
"value": string
diff --git a/packages/enterprise/sst-env.d.ts b/packages/enterprise/sst-env.d.ts
index 96fada3e3..b8e50a261 100644
--- a/packages/enterprise/sst-env.d.ts
+++ b/packages/enterprise/sst-env.d.ts
@@ -78,6 +78,10 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "STRIPE_PUBLISHABLE_KEY": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"STRIPE_SECRET_KEY": {
"type": "sst.sst.Secret"
"value": string
diff --git a/packages/function/sst-env.d.ts b/packages/function/sst-env.d.ts
index 96fada3e3..b8e50a261 100644
--- a/packages/function/sst-env.d.ts
+++ b/packages/function/sst-env.d.ts
@@ -78,6 +78,10 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "STRIPE_PUBLISHABLE_KEY": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"STRIPE_SECRET_KEY": {
"type": "sst.sst.Secret"
"value": string
diff --git a/sst-env.d.ts b/sst-env.d.ts
index 035a5fc21..3160fc165 100644
--- a/sst-env.d.ts
+++ b/sst-env.d.ts
@@ -104,6 +104,10 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "STRIPE_PUBLISHABLE_KEY": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"STRIPE_SECRET_KEY": {
"type": "sst.sst.Secret"
"value": string