improvement(routes): type all untyped routes (#1848)

* improvement(routes): type all untyped routes

* fix routes, remove unused workspace members route

* fix obfuscation of errors behind zod errors

* remove extraneous comments
This commit is contained in:
Waleed
2025-11-07 15:24:30 -08:00
committed by GitHub
parent c4278266ef
commit bb7016a99f
48 changed files with 1043 additions and 558 deletions

View File

@@ -1,8 +1,11 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { env } from '@/lib/env'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/sim-agent/constants'
const GenerateApiKeySchema = z.object({}).optional()
export async function POST(req: NextRequest) {
try {
const session = await getSession()
@@ -15,7 +18,18 @@ export async function POST(req: NextRequest) {
// Move environment variable access inside the function
const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT
await req.json().catch(() => ({}))
const body = await req.json().catch(() => ({}))
const validationResult = GenerateApiKeySchema.safeParse(body)
if (!validationResult.success) {
return NextResponse.json(
{
error: 'Invalid request body',
details: validationResult.error.errors,
},
{ status: 400 }
)
}
const res = await fetch(`${SIM_AGENT_API_URL}/api/validate-key/generate`, {
method: 'POST',

View File

@@ -1,25 +1,39 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkServerSideUsageLimits } from '@/lib/billing/calculations/usage-monitor'
import { checkInternalApiKey } from '@/lib/copilot/utils'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('CopilotApiKeysValidate')
const ValidateApiKeySchema = z.object({
userId: z.string().min(1, 'userId is required'),
})
export async function POST(req: NextRequest) {
try {
// Authenticate via internal API key header
const auth = checkInternalApiKey(req)
if (!auth.success) {
return new NextResponse(null, { status: 401 })
}
const body = await req.json().catch(() => null)
const userId = typeof body?.userId === 'string' ? body.userId : undefined
if (!userId) {
return NextResponse.json({ error: 'userId is required' }, { status: 400 })
const validationResult = ValidateApiKeySchema.safeParse(body)
if (!validationResult.success) {
logger.warn('Invalid validation request', { errors: validationResult.error.errors })
return NextResponse.json(
{
error: 'userId is required',
details: validationResult.error.errors,
},
{ status: 400 }
)
}
const { userId } = validationResult.data
logger.info('[API VALIDATION] Validating usage limit', { userId })
const { isExceeded, currentUsage, limit } = await checkServerSideUsageLimits(userId)

View File

@@ -1,4 +1,5 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { env } from '@/lib/env'
import { createLogger } from '@/lib/logs/console/logger'
@@ -7,6 +8,13 @@ const logger = createLogger('CopilotTrainingExamplesAPI')
export const runtime = 'nodejs'
export const dynamic = 'force-dynamic'
const TrainingExampleSchema = z.object({
json: z.string().min(1, 'JSON string is required'),
title: z.string().min(1, 'Title is required'),
tags: z.array(z.string()).optional(),
metadata: z.record(z.unknown()).optional(),
})
export async function POST(request: NextRequest) {
const baseUrl = env.AGENT_INDEXER_URL
if (!baseUrl) {
@@ -23,8 +31,24 @@ export async function POST(request: NextRequest) {
try {
const body = await request.json()
const validationResult = TrainingExampleSchema.safeParse(body)
if (!validationResult.success) {
logger.warn('Invalid training example format', { errors: validationResult.error.errors })
return NextResponse.json(
{
error: 'Invalid training example format',
details: validationResult.error.errors,
},
{ status: 400 }
)
}
const validatedData = validationResult.data
logger.info('Sending workflow example to agent indexer', {
hasJsonField: typeof body?.json === 'string',
hasJsonField: typeof validatedData.json === 'string',
title: validatedData.title,
})
const upstream = await fetch(`${baseUrl}/examples/add`, {
@@ -33,7 +57,7 @@ export async function POST(request: NextRequest) {
'Content-Type': 'application/json',
'x-api-key': apiKey,
},
body: JSON.stringify(body),
body: JSON.stringify(validatedData),
})
if (!upstream.ok) {

View File

@@ -5,18 +5,25 @@ import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('CopilotTrainingAPI')
// Schema for the request body
const WorkflowStateSchema = z.record(z.unknown())
const OperationSchema = z.object({
type: z.string(),
data: z.record(z.unknown()).optional(),
timestamp: z.number().optional(),
metadata: z.record(z.unknown()).optional(),
})
const TrainingDataSchema = z.object({
title: z.string().min(1),
prompt: z.string().min(1),
input: z.any(), // Workflow state (start)
output: z.any(), // Workflow state (end)
operations: z.any(),
title: z.string().min(1, 'Title is required'),
prompt: z.string().min(1, 'Prompt is required'),
input: WorkflowStateSchema,
output: WorkflowStateSchema,
operations: z.array(OperationSchema),
})
export async function POST(request: NextRequest) {
try {
// Check for required environment variables
const baseUrl = env.AGENT_INDEXER_URL
if (!baseUrl) {
logger.error('Missing AGENT_INDEXER_URL environment variable')
@@ -32,7 +39,6 @@ export async function POST(request: NextRequest) {
)
}
// Parse and validate request body
const body = await request.json()
const validationResult = TrainingDataSchema.safeParse(body)
@@ -51,10 +57,9 @@ export async function POST(request: NextRequest) {
logger.info('Sending training data to agent indexer', {
title,
operationsCount: Array.isArray(operations) ? operations.length : 0,
operationsCount: operations.length,
})
// Forward to agent indexer
const upstreamUrl = `${baseUrl}/operations/add`
const upstreamResponse = await fetch(upstreamUrl, {
method: 'POST',