wip: zen black
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 [
|
||||
|
||||
Reference in New Issue
Block a user