submission api client

This commit is contained in:
2025-05-24 19:33:40 +01:00
parent 7d789ba82f
commit 00923e273b
2 changed files with 72 additions and 1 deletions

View File

@@ -5,10 +5,23 @@ import type {
QuestionDetail,
QuestionListResponse,
Stats,
SubmissionRequest,
SubmissionResponse,
} from "@/types";
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
export class ApiError extends Error {
constructor(
public status: number,
public statusText: string,
public detail?: string
) {
super(detail || `API error: ${status} ${statusText}`);
this.name = "ApiError";
}
}
async function fetchApi<T>(
endpoint: string,
options?: RequestInit
@@ -23,7 +36,14 @@ async function fetchApi<T>(
});
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
let detail: string | undefined;
try {
const errorBody = await response.json();
detail = errorBody.detail;
} catch {
// Ignore JSON parse errors
}
throw new ApiError(response.status, response.statusText, detail);
}
return response.json();
@@ -77,3 +97,13 @@ export async function getPattern(slug: string): Promise<Pattern> {
export async function getStats(): Promise<Stats> {
return fetchApi<Stats>("/api/stats");
}
export async function submitSolution(
slug: string,
submission: SubmissionRequest
): Promise<SubmissionResponse> {
return fetchApi<SubmissionResponse>(`/api/questions/${slug}/submit`, {
method: "POST",
body: JSON.stringify(submission),
});
}

View File

@@ -61,6 +61,17 @@ export interface Solution {
explanation: string | null;
}
export interface VisibleTestCase {
id: number;
input: Record<string, unknown>;
expected: unknown;
}
export interface HiddenTestInput {
id: number;
input: Record<string, unknown>;
}
export interface QuestionDetail extends QuestionListItem {
description: string;
constraints: string | null;
@@ -69,6 +80,9 @@ export interface QuestionDetail extends QuestionListItem {
output: string;
explanation?: string;
}> | null;
function_signature: string | null;
visible_test_cases: VisibleTestCase[] | null;
hidden_test_inputs: HiddenTestInput[] | null;
explanation: Explanation | null;
solutions: Solution[];
updated_at: string;
@@ -114,3 +128,30 @@ export interface Stats {
by_category: CategoryCount[];
by_pattern: PatternCount[];
}
export interface HiddenTestOutput {
test_id: number;
output: unknown;
}
export interface SubmissionRequest {
code: string;
hidden_outputs: HiddenTestOutput[];
}
export interface TestResult {
test_id: number;
passed: boolean;
input?: Record<string, unknown>;
expected?: unknown;
actual: unknown;
error?: string;
}
export interface SubmissionResponse {
passed: boolean;
visible_results: TestResult[];
hidden_results: TestResult[];
total_passed: number;
total_tests: number;
}