Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion common/src/constants/limits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ export const MAX_DATE = new Date(86399999999999)
export const BILLING_PERIOD_DAYS = 30
export const SESSION_MAX_AGE_SECONDS = 30 * 24 * 60 * 60 // 30 days
export const SESSION_TIME_WINDOW_MS = 30 * 60 * 1000 // 30 minutes - used for matching sessions created around fingerprint creation
export const CREDITS_REFERRAL_BONUS = 500
// Referral credits disabled 2026-04-17: setting bonus to 0 stops new referral credit grants
// without removing the referral-tracking records. See scripts/opus-or-bleed.ts for the
// abuse pattern that motivated this (self-referral rings farming 1000 free credits per
// signup and burning them on Opus). Development focus is shifting to freebuff which has
// no credit system, so we don't need this growth lever going forward.
export const CREDITS_REFERRAL_BONUS = 0
export const AFFILIATE_USER_REFFERAL_LIMIT = 500

// Default number of free credits granted per cycle
Expand Down
1 change: 1 addition & 0 deletions common/src/testing/fixtures/agent-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export const TEST_AGENT_RUNTIME_IMPL = Object.freeze({
referral_code: 'ref-test-code',
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
} as const
return Object.fromEntries(
fields.map((field) => [field, user[field as keyof typeof user]]),
Expand Down
1 change: 1 addition & 0 deletions common/src/types/contracts/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type GetUserUsageDataFn = (params: {
totalDebt: number
netBalance: number
breakdown: Record<string, number>
principals: Record<string, number>
}
nextQuotaReset: string
autoTopupTriggered?: boolean
Expand Down
2 changes: 2 additions & 0 deletions common/src/types/contracts/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type User = {
referral_code: string | null
stripe_customer_id: string | null
banned: boolean
created_at: Date
}
export const userColumns = [
'id',
Expand All @@ -16,6 +17,7 @@ export const userColumns = [
'referral_code',
'stripe_customer_id',
'banned',
'created_at',
] as const
export type UserColumn = keyof User
export type GetUserInfoFromApiKeyInput<T extends UserColumn> = {
Expand Down
1 change: 1 addition & 0 deletions evals/impl/agent-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const EVALS_AGENT_RUNTIME_IMPL = Object.freeze<AgentRuntimeDeps>({
referral_code: 'ref-test-code',
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
}),
fetchAgentFromDatabase: async () => null,
startAgentRun: async () => 'test-agent-run-id',
Expand Down
66 changes: 3 additions & 63 deletions freebuff/web/src/app/api/auth/[...nextauth]/auth-options.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
// TODO: Extract shared auth config to packages/auth to avoid duplication with web/src/app/api/auth/[...nextauth]/auth-options.ts
import { DrizzleAdapter } from '@auth/drizzle-adapter'
import { processAndGrantCredit } from '@codebuff/billing'
import { trackEvent } from '@codebuff/common/analytics'
import { AnalyticsEvent } from '@codebuff/common/constants/analytics-events'
import {
DEFAULT_FREE_CREDITS_GRANT,
SESSION_MAX_AGE_SECONDS,
} from '@codebuff/common/old-constants'
import { getNextQuotaReset } from '@codebuff/common/util/dates'
import { generateCompactId } from '@codebuff/common/util/string'
import { SESSION_MAX_AGE_SECONDS } from '@codebuff/common/old-constants'
import { loops } from '@codebuff/internal'
import db from '@codebuff/internal/db'
import * as schema from '@codebuff/internal/db/schema'
Expand All @@ -18,7 +12,6 @@ import { logSyncFailure } from '@codebuff/internal/util/sync-failure'
import { eq } from 'drizzle-orm'
import GitHubProvider from 'next-auth/providers/github'

import type { Logger } from '@codebuff/common/types/contracts/logger'
import type { NextAuthOptions } from 'next-auth'
import type { Adapter } from 'next-auth/adapters'

Expand Down Expand Up @@ -78,53 +71,6 @@ async function createAndLinkStripeCustomer(params: {
}
}

async function createInitialCreditGrant(params: {
userId: string
expiresAt: Date | null
logger: Logger
}): Promise<void> {
const { userId, expiresAt, logger } = params

try {
const operationId = `free-${userId}-${generateCompactId()}`
const nextQuotaReset = getNextQuotaReset(expiresAt)

await processAndGrantCredit({
...params,
amount: DEFAULT_FREE_CREDITS_GRANT,
type: 'free',
description: 'Initial free credits',
expiresAt: nextQuotaReset,
operationId,
})

logger.info(
{
userId,
operationId,
creditsGranted: DEFAULT_FREE_CREDITS_GRANT,
expiresAt: nextQuotaReset,
},
'Initial free credit grant created.',
)
} catch (grantError) {
const errorMessage =
grantError instanceof Error
? grantError.message
: 'Unknown error creating initial credit grant'
logger.error(
{ userId, error: grantError },
'Failed to create initial credit grant.',
)
await logSyncFailure({
id: userId,
errorMessage,
provider: 'stripe',
logger,
})
}
}

export const authOptions: NextAuthOptions = {
adapter: DrizzleAdapter(db, {
usersTable: schema.user,
Expand Down Expand Up @@ -194,18 +140,12 @@ export const authOptions: NextAuthOptions = {
return
}

const customerId = await createAndLinkStripeCustomer({
await createAndLinkStripeCustomer({
...userData,
userId: userData.id,
})

if (customerId) {
await createInitialCreditGrant({
userId: userData.id,
expiresAt: userData.next_quota_reset,
logger,
})
}
// Freebuff is free - new accounts do not receive any credit grant.

await loops.sendSignupEventToLoops({
...userData,
Expand Down
1 change: 1 addition & 0 deletions sdk/e2e/utils/e2e-mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const MOCK_USER = {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
} as const

function buildMockAgentTemplate(params: {
Expand Down
15 changes: 15 additions & 0 deletions sdk/src/__tests__/run-cancellation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -98,6 +99,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -192,6 +194,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -234,6 +237,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -272,6 +276,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -307,6 +312,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -358,6 +364,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -439,6 +446,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -509,6 +517,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -637,6 +646,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -720,6 +730,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})

const abortController = new AbortController()
Expand Down Expand Up @@ -748,6 +759,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -814,6 +826,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -904,6 +917,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-2')
Expand Down Expand Up @@ -987,6 +1001,7 @@ describe('Run Cancellation Handling', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down
5 changes: 5 additions & 0 deletions sdk/src/__tests__/run-file-filter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ describe('CodebuffClientOptions fileFilter', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -160,6 +161,7 @@ describe('CodebuffClientOptions fileFilter', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -243,6 +245,7 @@ describe('CodebuffClientOptions fileFilter', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -327,6 +330,7 @@ describe('CodebuffClientOptions fileFilter', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down Expand Up @@ -399,6 +403,7 @@ describe('CodebuffClientOptions fileFilter', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down
1 change: 1 addition & 0 deletions sdk/src/__tests__/run-handle-event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('CodebuffClient handleEvent / handleStreamChunk', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down
1 change: 1 addition & 0 deletions sdk/src/__tests__/run-mcp-tool-filter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ describe('MCP tool filtering', () => {
referral_code: null,
stripe_customer_id: null,
banned: false,
created_at: new Date('2024-01-01T00:00:00Z'),
})
spyOn(databaseModule, 'fetchAgentFromDatabase').mockResolvedValue(null)
spyOn(databaseModule, 'startAgentRun').mockResolvedValue('run-1')
Expand Down
Loading
Loading