Skip to content
Draft
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
19 changes: 15 additions & 4 deletions app/api/analyses/[id]/analyze/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from 'next/server'
import { generateText } from 'ai'
import { getCreditBalance, deductCredits, CREDITS } from '@/lib/credits'
import { getAnalysisById } from '@/lib/queries'
import { getCurrentUser } from '@/lib/auth'

const model = 'openai/gpt-4-turbo'

Expand All @@ -22,15 +23,25 @@ interface AppSuggestion {

export async function POST(request: NextRequest) {
try {
const { analysisId, selectedRepos, userId } = (await request.json()) as {
const user = await getCurrentUser()
if (!user?.id) {
return NextResponse.json({ error: 'Sign in with GitHub to analyze repositories.' }, { status: 401 })
}

const { analysisId, selectedRepos } = (await request.json()) as {
analysisId: string
selectedRepos: SelectedRepository[]
userId: string
}
const userId = user.id

// Check credit balance before proceeding
if (!userId) {
return NextResponse.json({ error: 'User ID required' }, { status: 401 })
if (!analysisId || !Array.isArray(selectedRepos)) {
return NextResponse.json({ error: 'Missing required fields' }, { status: 400 })
}

const analysis = await getAnalysisById(analysisId)
if (!analysis) {
return NextResponse.json({ error: 'Analysis not found' }, { status: 404 })
}

const currentBalance = await getCreditBalance(userId)
Expand Down
15 changes: 8 additions & 7 deletions app/api/credits/summary/route.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { NextRequest, NextResponse } from 'next/server'
import { getOrCreateUserCredits, getCreditUsageSummary } from '@/lib/credits'
import { getCurrentUser } from '@/lib/auth'

export async function GET(request: NextRequest) {
export async function GET(_request: NextRequest) {
try {
const userId = request.nextUrl.searchParams.get('userId')
const user = await getCurrentUser()

if (!userId) {
if (!user?.id) {
return NextResponse.json(
{ error: 'User ID is required' },
{ status: 400 }
{ error: 'Sign in with GitHub to view credits.' },
{ status: 401 }
)
}

// Get credits and usage summary
const [credits, summary] = await Promise.all([
getOrCreateUserCredits(userId),
getCreditUsageSummary(userId),
getOrCreateUserCredits(user.id),
getCreditUsageSummary(user.id),
])

return NextResponse.json({
Expand Down
61 changes: 31 additions & 30 deletions app/api/generate-scaffold/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ import { NextRequest, NextResponse } from 'next/server'
import Anthropic from '@anthropic-ai/sdk'
import { getAnthropicModel } from '@/lib/anthropic-model'
import { getCreditBalance, deductCredits, CREDITS } from '@/lib/credits'

const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
})
import { getCurrentUser } from '@/lib/auth'
import { getSubscriptionByGithubId, upsertSubscription } from '@/lib/queries'

Expand All @@ -18,11 +14,14 @@ export async function POST(request: NextRequest) {
)
}

const { appName, description, technologies, existingFiles, missingFiles, userId } = await request.json()
const { appName, description, technologies, existingFiles, missingFiles } = await request.json()
const user = await getCurrentUser()
if (!user) {
return NextResponse.json({ error: 'Sign in with GitHub to generate scaffolds.' }, { status: 401 })
}
if (!user.id) {
return NextResponse.json({ error: 'Unable to load your billing profile. Please sign in again.' }, { status: 401 })
}

let sub = await getSubscriptionByGithubId(user.github_id).catch(() => null)
if (!sub) {
Expand All @@ -35,26 +34,22 @@ export async function POST(request: NextRequest) {
)
}

const { appName, description, technologies, existingFiles, missingFiles } = await request.json()

if (!appName || !description || !technologies) {
return NextResponse.json({ error: 'Missing required fields' }, { status: 400 })
}

// Check credit balance before proceeding
if (userId) {
const currentBalance = await getCreditBalance(userId)
if (currentBalance < CREDITS.SCAFFOLD_COST) {
return NextResponse.json(
{
error: 'Insufficient credits',
required: CREDITS.SCAFFOLD_COST,
available: currentBalance,
message: 'Upgrade to Pro to get unlimited scaffold generation with 5,000 monthly credits.',
},
{ status: 402 }
)
}
const currentBalance = await getCreditBalance(user.id)
if (currentBalance < CREDITS.SCAFFOLD_COST) {
return NextResponse.json(
{
error: 'Insufficient credits',
required: CREDITS.SCAFFOLD_COST,
available: currentBalance,
message: 'Upgrade to Pro to get unlimited scaffold generation with 5,000 monthly credits.',
},
{ status: 402 }
)
}

console.log('[v0] Generating scaffold for app:', appName)
Expand Down Expand Up @@ -142,17 +137,23 @@ Example structure:

// Deduct credits after successful generation
let creditsUsed = 0
if (userId) {
const deductResult = await deductCredits(userId, CREDITS.SCAFFOLD_COST, 'scaffold', {
appName,
technologies,
})

if (deductResult.success) {
creditsUsed = CREDITS.SCAFFOLD_COST
console.log(`[v0] Deducted ${CREDITS.SCAFFOLD_COST} credits from user ${userId}`)
}
const deductResult = await deductCredits(user.id, CREDITS.SCAFFOLD_COST, 'scaffold', {
appName,
technologies,
})

if (!deductResult.success) {
return NextResponse.json(
{
error: 'Insufficient credits',
required: CREDITS.SCAFFOLD_COST,
available: currentBalance,
},
{ status: 402 }
)
}
creditsUsed = CREDITS.SCAFFOLD_COST
console.log(`[v0] Deducted ${CREDITS.SCAFFOLD_COST} credits from user ${user.id}`)

return NextResponse.json({
success: true,
Expand Down
Loading