Files
aurak/web/services/assessmentService.ts
T
Developer 0a9588abb7 feat: implement QuestionBank CRUD with pagination and template query
- Add pagination support to findAll (page, limit query params)
- Add findByTemplateId method to service
- Add GET /by-template/:templateId endpoint to controller
- Service already includes CRUD for QuestionBank and QuestionBankItem
2026-04-23 17:19:11 +08:00

100 lines
3.5 KiB
TypeScript

import { apiClient } from './apiClient';
export interface AssessmentSession {
id: string;
userId: string;
knowledgeBaseId: string;
threadId: string;
status: 'IN_PROGRESS' | 'COMPLETED';
finalScore?: number;
finalReport?: string;
createdAt: string;
updatedAt: string;
knowledgeBase?: { id: string; name: string };
knowledgeGroup?: { id: string; name: string };
}
export interface AssessmentState {
messages: any[];
assessmentSessionId: string;
knowledgeBaseId: string;
questions: any[];
currentQuestionIndex: number;
shouldFollowUp: boolean;
scores: Record<string, number>;
feedbackHistory?: any[];
status?: 'IN_PROGRESS' | 'COMPLETED';
report?: string;
finalScore?: number;
}
export class AssessmentService {
async startSession(knowledgeBaseId: string, language: string, templateId?: string): Promise<AssessmentSession> {
const { data } = await apiClient.post<AssessmentSession>('/assessment/start', { knowledgeBaseId, language, templateId });
return data;
}
async submitAnswer(sessionId: string, answer: string, language: string): Promise<AssessmentState> {
const { data } = await apiClient.post<AssessmentState>(`/assessment/${sessionId}/answer`, { answer, language });
return data;
}
async getSessionState(sessionId: string): Promise<AssessmentState> {
const { data } = await apiClient.get<AssessmentState>(`/assessment/${sessionId}/state`);
return data;
}
async getHistory(): Promise<AssessmentSession[]> {
const { data } = await apiClient.get<AssessmentSession[]>('/assessment');
return data;
}
async deleteSession(sessionId: string): Promise<void> {
await apiClient.delete(`/assessment/${sessionId}`);
}
async *startSessionStream(sessionId: string, templateId?: string): AsyncIterableIterator<any> {
const query = templateId ? `?templateId=${templateId}` : '';
const response = await apiClient.request(`/assessment/${sessionId}/start-stream${query}`, {
method: 'GET',
});
yield* this.parseStream(response);
}
async *submitAnswerStream(sessionId: string, answer: string, language: string, templateId?: string): AsyncIterableIterator<any> {
const query = new URLSearchParams({ answer, language, ...(templateId && { templateId }) }).toString();
const response = await apiClient.request(`/assessment/${sessionId}/answer-stream?${query}`, {
method: 'GET',
});
yield* this.parseStream(response);
}
private async *parseStream(response: Response): AsyncIterableIterator<any> {
const reader = response.body?.getReader();
if (!reader) return;
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.substring(6));
yield data;
} catch (e) {
console.error('Failed to parse SSE data:', line);
}
}
}
}
}
}
export const assessmentService = new AssessmentService();