summaryrefslogtreecommitdiffhomepage
path: root/packages/console/app/src
diff options
context:
space:
mode:
authorFrank <[email protected]>2026-01-22 12:40:42 -0500
committerFrank <[email protected]>2026-01-22 13:02:28 -0500
commita890d51bbc6a5608ad5992c74ee49153775aceb3 (patch)
tree5b4e4b53cfc44db4242b23d3bce48bba4a303a67 /packages/console/app/src
parentbb582416f216de684bf6861353a3111cde2c461d (diff)
downloadopencode-a890d51bbc6a5608ad5992c74ee49153775aceb3.tar.gz
opencode-a890d51bbc6a5608ad5992c74ee49153775aceb3.zip
wip: zen black
Diffstat (limited to 'packages/console/app/src')
-rw-r--r--packages/console/app/src/routes/workspace/[id]/billing/black-section.tsx19
-rw-r--r--packages/console/app/src/routes/workspace/[id]/billing/index.tsx2
-rw-r--r--packages/console/app/src/routes/workspace/common.tsx2
-rw-r--r--packages/console/app/src/routes/zen/util/handler.ts11
4 files changed, 23 insertions, 11 deletions
diff --git a/packages/console/app/src/routes/workspace/[id]/billing/black-section.tsx b/packages/console/app/src/routes/workspace/[id]/billing/black-section.tsx
index beb5adbfc..448dafadc 100644
--- a/packages/console/app/src/routes/workspace/[id]/billing/black-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/billing/black-section.tsx
@@ -3,7 +3,7 @@ import { createStore } from "solid-js/store"
import { Show } from "solid-js"
import { Billing } from "@opencode-ai/console-core/billing.js"
import { Database, eq, and, isNull } from "@opencode-ai/console-core/drizzle/index.js"
-import { SubscriptionTable } from "@opencode-ai/console-core/schema/billing.sql.js"
+import { BillingTable, SubscriptionTable } from "@opencode-ai/console-core/schema/billing.sql.js"
import { Actor } from "@opencode-ai/console-core/actor.js"
import { Black } from "@opencode-ai/console-core/black.js"
import { withActor } from "~/context/auth.withActor"
@@ -20,19 +20,24 @@ const querySubscription = query(async (workspaceID: string) => {
fixedUsage: SubscriptionTable.fixedUsage,
timeRollingUpdated: SubscriptionTable.timeRollingUpdated,
timeFixedUpdated: SubscriptionTable.timeFixedUpdated,
+ subscription: BillingTable.subscription,
})
- .from(SubscriptionTable)
+ .from(BillingTable)
+ .innerJoin(SubscriptionTable, eq(SubscriptionTable.workspaceID, BillingTable.workspaceID))
.where(and(eq(SubscriptionTable.workspaceID, Actor.workspace()), isNull(SubscriptionTable.timeDeleted)))
.then((r) => r[0]),
)
- if (!row) return null
+ if (!row.subscription) return null
return {
+ plan: row.subscription.plan,
rollingUsage: Black.analyzeRollingUsage({
+ plan: row.subscription.plan,
usage: row.rollingUsage ?? 0,
timeUpdated: row.timeRollingUpdated ?? new Date(),
}),
weeklyUsage: Black.analyzeWeeklyUsage({
+ plan: row.subscription.plan,
usage: row.fixedUsage ?? 0,
timeUpdated: row.timeFixedUpdated ?? new Date(),
}),
@@ -89,10 +94,13 @@ export function BlackSection() {
return (
<section class={styles.root}>
+ <Show when={subscription()}>
+ {(sub) => (
+ <>
<div data-slot="section-title">
<h2>Subscription</h2>
<div data-slot="title-row">
- <p>You are subscribed to OpenCode Black for $200 per month.</p>
+ <p>You are subscribed to OpenCode Black for ${sub().plan} per month.</p>
<button
data-color="primary"
disabled={sessionSubmission.pending || store.sessionRedirecting}
@@ -102,8 +110,6 @@ export function BlackSection() {
</button>
</div>
</div>
- <Show when={subscription()}>
- {(sub) => (
<div data-slot="usage">
<div data-slot="usage-item">
<div data-slot="usage-header">
@@ -126,6 +132,7 @@ export function BlackSection() {
<span data-slot="reset-time">Resets in {formatResetTime(sub().weeklyUsage.resetInSec)}</span>
</div>
</div>
+ </>
)}
</Show>
</section>
diff --git a/packages/console/app/src/routes/workspace/[id]/billing/index.tsx b/packages/console/app/src/routes/workspace/[id]/billing/index.tsx
index 9784e57ab..a252a0234 100644
--- a/packages/console/app/src/routes/workspace/[id]/billing/index.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/billing/index.tsx
@@ -16,7 +16,7 @@ export default function () {
<div data-page="workspace-[id]">
<div data-slot="sections">
<Show when={sessionInfo()?.isAdmin}>
- <Show when={billingInfo()?.subscriptionID}>
+ <Show when={billingInfo()?.subscriptionID || billingInfo()?.timeSubscriptionBooked}>
<BlackSection />
</Show>
<BillingSection />
diff --git a/packages/console/app/src/routes/workspace/common.tsx b/packages/console/app/src/routes/workspace/common.tsx
index d97bf9e60..ddd3fd3e6 100644
--- a/packages/console/app/src/routes/workspace/common.tsx
+++ b/packages/console/app/src/routes/workspace/common.tsx
@@ -111,6 +111,8 @@ export const queryBillingInfo = query(async (workspaceID: string) => {
reloadError: billing.reloadError,
timeReloadError: billing.timeReloadError,
subscriptionID: billing.subscriptionID,
+ subscriptionPlan: billing.subscriptionPlan,
+ timeSubscriptionBooked: billing.timeSubscriptionBooked,
}
}, workspaceID)
}, "billing.get")
diff --git a/packages/console/app/src/routes/zen/util/handler.ts b/packages/console/app/src/routes/zen/util/handler.ts
index 0e848886f..29a6bfb2e 100644
--- a/packages/console/app/src/routes/zen/util/handler.ts
+++ b/packages/console/app/src/routes/zen/util/handler.ts
@@ -417,6 +417,7 @@ export async function handler(
timeMonthlyUsageUpdated: BillingTable.timeMonthlyUsageUpdated,
reloadTrigger: BillingTable.reloadTrigger,
timeReloadLockedTill: BillingTable.timeReloadLockedTill,
+ subscription: BillingTable.subscription,
},
user: {
id: UserTable.id,
@@ -488,10 +489,9 @@ export async function handler(
if (modelInfo.allowAnonymous) return
// Validate subscription billing
- if (authInfo.subscription) {
- const black = BlackData.get()
+ if (authInfo.billing.subscription && authInfo.subscription) {
const sub = authInfo.subscription
- const now = new Date()
+ const plan = authInfo.billing.subscription.plan
const formatRetryTime = (seconds: number) => {
const days = Math.floor(seconds / 86400)
@@ -505,6 +505,7 @@ export async function handler(
// Check weekly limit
if (sub.fixedUsage && sub.timeFixedUpdated) {
const result = Black.analyzeWeeklyUsage({
+ plan,
usage: sub.fixedUsage,
timeUpdated: sub.timeFixedUpdated,
})
@@ -518,6 +519,7 @@ export async function handler(
// Check rolling limit
if (sub.rollingUsage && sub.timeRollingUpdated) {
const result = Black.analyzeRollingUsage({
+ plan,
usage: sub.rollingUsage,
timeUpdated: sub.timeRollingUpdated,
})
@@ -666,7 +668,8 @@ export async function handler(
.where(and(eq(KeyTable.workspaceID, authInfo.workspaceID), eq(KeyTable.id, authInfo.apiKeyId))),
...(authInfo.subscription
? (() => {
- const black = BlackData.get()
+ const plan = authInfo.billing.subscription!.plan
+ const black = BlackData.get({ plan })
const week = getWeekBounds(new Date())
const rollingWindowSeconds = black.rollingWindow * 3600
return [