mirror of
https://github.com/anomalyco/opencode.git
synced 2026-02-01 22:48:16 +00:00
wip: black
This commit is contained in:
@@ -475,31 +475,50 @@ export async function handler(
|
||||
const sub = authInfo.subscription
|
||||
const now = new Date()
|
||||
|
||||
// Check monthly limit
|
||||
const formatRetryTime = (seconds: number) => {
|
||||
const days = Math.floor(seconds / 86400)
|
||||
if (days >= 1) return `${days} day${days > 1 ? "s" : ""}`
|
||||
const hours = Math.floor(seconds / 3600)
|
||||
const minutes = Math.ceil((seconds % 3600) / 60)
|
||||
if (hours >= 1) return `${hours}hr ${minutes}min`
|
||||
return `${minutes}min`
|
||||
}
|
||||
|
||||
// Check monthly limit (based on subscription billing cycle)
|
||||
if (
|
||||
sub.subMonthlyUsage &&
|
||||
sub.timeSubMonthlyUsageUpdated &&
|
||||
sub.subMonthlyUsage >= centsToMicroCents(black.monthlyLimit * 100) &&
|
||||
now.getUTCFullYear() === sub.timeSubMonthlyUsageUpdated.getUTCFullYear() &&
|
||||
now.getUTCMonth() === sub.timeSubMonthlyUsageUpdated.getUTCMonth()
|
||||
sub.subMonthlyUsage >= centsToMicroCents(black.monthlyLimit * 100)
|
||||
) {
|
||||
const nextMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1))
|
||||
throw new SubscriptionError(
|
||||
`Rate limit exceeded. Please try again later.`,
|
||||
Math.ceil((nextMonth.getTime() - now.getTime()) / 1000),
|
||||
const subscribeDay = sub.timeSubscribed!.getUTCDate()
|
||||
const cycleStart = new Date(
|
||||
Date.UTC(
|
||||
now.getUTCFullYear(),
|
||||
now.getUTCDate() >= subscribeDay ? now.getUTCMonth() : now.getUTCMonth() - 1,
|
||||
subscribeDay,
|
||||
),
|
||||
)
|
||||
const cycleEnd = new Date(Date.UTC(cycleStart.getUTCFullYear(), cycleStart.getUTCMonth() + 1, subscribeDay))
|
||||
if (sub.timeSubMonthlyUsageUpdated >= cycleStart && sub.timeSubMonthlyUsageUpdated < cycleEnd) {
|
||||
const retryAfter = Math.ceil((cycleEnd.getTime() - now.getTime()) / 1000)
|
||||
throw new SubscriptionError(
|
||||
`Subscription quota exceeded. Retry in ${formatRetryTime(retryAfter)}.`,
|
||||
retryAfter,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Check interval limit
|
||||
const intervalMs = black.intervalLength * 86400 * 1000
|
||||
const intervalMs = black.intervalLength * 3600 * 1000
|
||||
if (sub.subIntervalUsage && sub.timeSubIntervalUsageUpdated) {
|
||||
const currentInterval = Math.floor(now.getTime() / intervalMs)
|
||||
const usageInterval = Math.floor(sub.timeSubIntervalUsageUpdated.getTime() / intervalMs)
|
||||
if (currentInterval === usageInterval && sub.subIntervalUsage >= centsToMicroCents(black.intervalLimit * 100)) {
|
||||
const nextInterval = (currentInterval + 1) * intervalMs
|
||||
const retryAfter = Math.ceil((nextInterval - now.getTime()) / 1000)
|
||||
throw new SubscriptionError(
|
||||
`Rate limit exceeded. Please try again later.`,
|
||||
Math.ceil((nextInterval - now.getTime()) / 1000),
|
||||
`Subscription quota exceeded. Retry in ${formatRetryTime(retryAfter)}.`,
|
||||
retryAfter,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -641,27 +660,41 @@ export async function handler(
|
||||
.set({ timeUsed: sql`now()` })
|
||||
.where(and(eq(KeyTable.workspaceID, authInfo.workspaceID), eq(KeyTable.id, authInfo.apiKeyId))),
|
||||
...(authInfo.subscription
|
||||
? [
|
||||
db
|
||||
.update(UserTable)
|
||||
.set({
|
||||
subMonthlyUsage: sql`
|
||||
? (() => {
|
||||
const now = new Date()
|
||||
const subscribeDay = authInfo.subscription.timeSubscribed!.getUTCDate()
|
||||
const cycleStart = new Date(
|
||||
Date.UTC(
|
||||
now.getUTCFullYear(),
|
||||
now.getUTCDate() >= subscribeDay ? now.getUTCMonth() : now.getUTCMonth() - 1,
|
||||
subscribeDay,
|
||||
),
|
||||
)
|
||||
const cycleEnd = new Date(
|
||||
Date.UTC(cycleStart.getUTCFullYear(), cycleStart.getUTCMonth() + 1, subscribeDay),
|
||||
)
|
||||
return [
|
||||
db
|
||||
.update(UserTable)
|
||||
.set({
|
||||
subMonthlyUsage: sql`
|
||||
CASE
|
||||
WHEN MONTH(${UserTable.timeSubMonthlyUsageUpdated}) = MONTH(now()) AND YEAR(${UserTable.timeSubMonthlyUsageUpdated}) = YEAR(now()) THEN ${UserTable.subMonthlyUsage} + ${cost}
|
||||
WHEN ${UserTable.timeSubMonthlyUsageUpdated} >= ${cycleStart} AND ${UserTable.timeSubMonthlyUsageUpdated} < ${cycleEnd} THEN ${UserTable.subMonthlyUsage} + ${cost}
|
||||
ELSE ${cost}
|
||||
END
|
||||
`,
|
||||
timeSubMonthlyUsageUpdated: sql`now()`,
|
||||
subIntervalUsage: sql`
|
||||
timeSubMonthlyUsageUpdated: sql`now()`,
|
||||
subIntervalUsage: sql`
|
||||
CASE
|
||||
WHEN FLOOR(UNIX_TIMESTAMP(${UserTable.timeSubIntervalUsageUpdated}) / (${BlackData.get().intervalLength} * 86400)) = FLOOR(UNIX_TIMESTAMP(now()) / (${BlackData.get().intervalLength} * 86400)) THEN ${UserTable.subIntervalUsage} + ${cost}
|
||||
WHEN FLOOR(UNIX_TIMESTAMP(${UserTable.timeSubIntervalUsageUpdated}) / (${BlackData.get().intervalLength} * 3600)) = FLOOR(UNIX_TIMESTAMP(now()) / (${BlackData.get().intervalLength} * 3600)) THEN ${UserTable.subIntervalUsage} + ${cost}
|
||||
ELSE ${cost}
|
||||
END
|
||||
`,
|
||||
timeSubIntervalUsageUpdated: sql`now()`,
|
||||
})
|
||||
.where(and(eq(UserTable.workspaceID, authInfo.workspaceID), eq(UserTable.id, authInfo.user.id))),
|
||||
]
|
||||
timeSubIntervalUsageUpdated: sql`now()`,
|
||||
})
|
||||
.where(and(eq(UserTable.workspaceID, authInfo.workspaceID), eq(UserTable.id, authInfo.user.id))),
|
||||
]
|
||||
})()
|
||||
: [
|
||||
db
|
||||
.update(BillingTable)
|
||||
|
||||
Reference in New Issue
Block a user