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
This commit is contained in:
+364
@@ -0,0 +1,364 @@
|
||||
|
||||
export interface IndexingConfig {
|
||||
chunkSize: number;
|
||||
chunkOverlap: number;
|
||||
embeddingModelId: string;
|
||||
mode?: 'fast' | 'precise'; // Processing mode: fast/precise
|
||||
groupIds?: string[]; // Groups to associate with the file upon upload
|
||||
}
|
||||
|
||||
|
||||
export interface VisionAnalysisResult {
|
||||
text: string; // Extracted text content
|
||||
images: ImageDescription[]; // Image descriptions
|
||||
layout: string; // Layout type
|
||||
confidence: number; // 信頼度 (0-1)
|
||||
pageIndex?: number; // Page number
|
||||
}
|
||||
|
||||
export interface ImageDescription {
|
||||
type: string; // Image type (graph/diagram/flowchart etc.)
|
||||
description: string; // Detailed description
|
||||
position?: number; // Position within the page
|
||||
}
|
||||
|
||||
export interface PipelineResult {
|
||||
success: boolean;
|
||||
fileId: string;
|
||||
fileName: string;
|
||||
totalPages: number;
|
||||
processedPages: number;
|
||||
failedPages: number;
|
||||
results: VisionAnalysisResult[];
|
||||
cost: number; // Cost (USD)
|
||||
duration: number; // Duration (seconds)
|
||||
mode: 'precise';
|
||||
}
|
||||
|
||||
export interface ModeRecommendation {
|
||||
recommendedMode: 'precise' | 'fast';
|
||||
reason: string;
|
||||
estimatedCost?: number; // Estimated cost (USD)
|
||||
estimatedTime?: number; // Estimated time (seconds)
|
||||
warnings?: string[];
|
||||
}
|
||||
|
||||
// Type definitions for knowledge base extensions
|
||||
export interface KnowledgeGroup {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
color: string;
|
||||
fileCount: number;
|
||||
parentId?: string | null;
|
||||
children?: KnowledgeGroup[];
|
||||
createdAt: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface CreateGroupData {
|
||||
name: string;
|
||||
description?: string;
|
||||
color?: string;
|
||||
parentId?: string | null;
|
||||
}
|
||||
|
||||
export interface UpdateGroupData {
|
||||
name?: string;
|
||||
description?: string;
|
||||
color?: string;
|
||||
parentId?: string | null;
|
||||
}
|
||||
|
||||
export interface KnowledgeFile {
|
||||
id: string;
|
||||
name: string;
|
||||
originalName: string;
|
||||
size: number;
|
||||
type: string;
|
||||
status: 'pending' | 'indexing' | 'extracted' | 'vectorized' | 'failed' | 'ready' | 'error';
|
||||
groups?: KnowledgeGroup[];
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface SearchHistoryItem {
|
||||
id: string;
|
||||
title: string;
|
||||
selectedGroups: string[] | null;
|
||||
messageCount: number;
|
||||
lastMessageAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface SearchHistoryDetail {
|
||||
id: string;
|
||||
title: string;
|
||||
selectedGroups: string[] | null;
|
||||
messages: Array<{
|
||||
id: string;
|
||||
role: 'user' | 'assistant';
|
||||
content: string;
|
||||
sources?: Array<{
|
||||
fileName: string;
|
||||
content: string;
|
||||
score: number;
|
||||
chunkIndex: number;
|
||||
}>;
|
||||
createdAt: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface PDFStatus {
|
||||
status: 'pending' | 'converting' | 'ready' | 'failed';
|
||||
pdfPath?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface NoteCategory {
|
||||
id: string
|
||||
name: string
|
||||
parentId?: string
|
||||
level: number
|
||||
userId: string
|
||||
tenantId: string
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export interface Note {
|
||||
id: string;
|
||||
title: string;
|
||||
content: string;
|
||||
userId: string;
|
||||
tenantId?: string;
|
||||
groupId?: string;
|
||||
categoryId?: string;
|
||||
sharingStatus: 'PRIVATE' | 'TENANT' | 'GLOBAL_PENDING' | 'GLOBAL_APPROVED';
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
user?: {
|
||||
id: string;
|
||||
username: string;
|
||||
name?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface RawFile {
|
||||
name: string;
|
||||
type: string;
|
||||
size: number;
|
||||
content: string;
|
||||
preview?: string;
|
||||
file: File; // Keep original file for upload
|
||||
isNote?: boolean;
|
||||
textContent?: string;
|
||||
}
|
||||
|
||||
export enum Role {
|
||||
USER = 'user',
|
||||
MODEL = 'model',
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
id: string;
|
||||
role: Role;
|
||||
text: string;
|
||||
timestamp: number;
|
||||
isError?: boolean;
|
||||
sources?: ChatSource[];
|
||||
}
|
||||
|
||||
export interface ChatSource {
|
||||
fileName: string;
|
||||
title?: string;
|
||||
content: string;
|
||||
score: number;
|
||||
chunkIndex: number;
|
||||
fileId?: string;
|
||||
}
|
||||
|
||||
export interface ChatState {
|
||||
messages: Message[];
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
export type Language = 'ja' | 'en' | 'zh';
|
||||
|
||||
export enum ModelType {
|
||||
// Changed from type to enum
|
||||
LLM = "llm",
|
||||
EMBEDDING = "embedding",
|
||||
RERANK = "rerank",
|
||||
VISION = "vision",
|
||||
}
|
||||
|
||||
// 1. Model Definition (The "Provider" setup)
|
||||
export interface ModelConfig {
|
||||
id: string;
|
||||
name: string; // Display name, e.g. "My DeepSeek"
|
||||
modelId: string; // The actual string ID sent to API, e.g., "gpt-4o"
|
||||
baseUrl?: string; // Base URL for OpenAI compatible API
|
||||
apiKey?: string; // API key for the service
|
||||
type: ModelType;
|
||||
dimensions?: number; // Vector dimensions of the embedding model
|
||||
supportsVision?: boolean; // Whether it supports vision capabilities
|
||||
|
||||
// ==================== Additional Fields ====================
|
||||
/**
|
||||
* Model's input token limit
|
||||
* e.g., OpenAI=8191, Gemini=2048
|
||||
*/
|
||||
maxInputTokens?: number;
|
||||
|
||||
/**
|
||||
* Batch processing limit (maximum number of inputs per request)
|
||||
* e.g., OpenAI=2048, Gemini=100
|
||||
*/
|
||||
maxBatchSize?: number;
|
||||
|
||||
/**
|
||||
* Whether it is a vector model (for identification in system settings)
|
||||
*/
|
||||
isVectorModel?: boolean;
|
||||
|
||||
/**
|
||||
* Model provider name (for display)
|
||||
* e.g., "OpenAI", "Google Gemini", "Custom"
|
||||
*/
|
||||
providerName?: string;
|
||||
|
||||
/**
|
||||
* Whether it is enabled
|
||||
*/
|
||||
isEnabled?: boolean;
|
||||
|
||||
/**
|
||||
* Whether to use this model as the default
|
||||
*/
|
||||
isDefault?: boolean;
|
||||
}
|
||||
|
||||
// 2. Application Logic Settings (The "App" setup)
|
||||
export interface AppSettings {
|
||||
// References to ModelConfig IDs
|
||||
selectedLLMId: string;
|
||||
selectedEmbeddingId: string; // Default for new uploads, and used for query encoding
|
||||
selectedRerankId: string;
|
||||
|
||||
// Model Hyperparameters
|
||||
temperature: number;
|
||||
maxTokens: number;
|
||||
|
||||
// Retrieval
|
||||
enableRerank: boolean;
|
||||
topK: number;
|
||||
similarityThreshold: number; // Similarity threshold for vector search
|
||||
rerankSimilarityThreshold: number; // Similarity threshold for reranking
|
||||
enableFullTextSearch: boolean; // Whether to enable full-text search
|
||||
hybridVectorWeight: number; // Vector weight for hybrid search
|
||||
|
||||
// Search Enhancement
|
||||
enableQueryExpansion: boolean;
|
||||
enableHyDE: boolean;
|
||||
|
||||
chunkSize?: number;
|
||||
chunkOverlap?: number;
|
||||
|
||||
// Language
|
||||
language?: string;
|
||||
|
||||
// Coach
|
||||
coachKbId?: string;
|
||||
|
||||
// Vision
|
||||
selectedVisionId?: string;
|
||||
}
|
||||
|
||||
// Default Models (Frontend specific)
|
||||
export const DEFAULT_MODELS: ModelConfig[] = [];
|
||||
|
||||
export const DEFAULT_SETTINGS: AppSettings = {
|
||||
selectedLLMId: '',
|
||||
selectedEmbeddingId: '',
|
||||
selectedRerankId: '',
|
||||
selectedVisionId: '',
|
||||
|
||||
temperature: 0.3,
|
||||
maxTokens: 8192,
|
||||
|
||||
enableRerank: false,
|
||||
topK: 4,
|
||||
similarityThreshold: 0.3, // Default similarity threshold for vector search
|
||||
rerankSimilarityThreshold: 0.5, // Default similarity threshold for reranking
|
||||
enableFullTextSearch: false, // Turn off full-text search by default
|
||||
hybridVectorWeight: 0.7, // Vector weight for hybrid search
|
||||
enableQueryExpansion: false,
|
||||
enableHyDE: false,
|
||||
chunkSize: 1000,
|
||||
chunkOverlap: 100,
|
||||
language: 'ja',
|
||||
};
|
||||
|
||||
export const API_BASE_URL = '/api'
|
||||
|
||||
export interface Tenant {
|
||||
id: string;
|
||||
name: string;
|
||||
domain?: string;
|
||||
parentId?: string | null;
|
||||
children?: Tenant[];
|
||||
members?: TenantMember[];
|
||||
settings_obj?: any;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface TenantMember {
|
||||
id: string;
|
||||
userId: string;
|
||||
tenantId: string;
|
||||
role: string;
|
||||
user?: {
|
||||
id: string;
|
||||
username: string;
|
||||
displayName?: string;
|
||||
email?: string;
|
||||
};
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// Assessment Template Types
|
||||
export interface AssessmentTemplate {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
keywords?: string[];
|
||||
questionCount: number;
|
||||
difficultyDistribution?: Record<string, number>;
|
||||
style?: string;
|
||||
knowledgeBaseId?: string;
|
||||
knowledgeGroupId?: string;
|
||||
knowledgeGroup?: KnowledgeGroup;
|
||||
isActive: boolean;
|
||||
version: number;
|
||||
creatorId: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface CreateTemplateData {
|
||||
name: string;
|
||||
description?: string;
|
||||
keywords?: string[];
|
||||
questionCount?: number;
|
||||
difficultyDistribution?: Record<string, number>;
|
||||
style?: string;
|
||||
knowledgeBaseId?: string;
|
||||
knowledgeGroupId?: string;
|
||||
}
|
||||
|
||||
export interface UpdateTemplateData extends Partial<CreateTemplateData> {
|
||||
isActive?: boolean;
|
||||
}
|
||||
Reference in New Issue
Block a user