fix: 全部TS错误修复(25->0) + 证书API 500修复 + i18n缺失key补全 + 类型定义修正

- 证书API 500修复: AssessmentCertificate实体注册到app.module.ts
- 前端TS错误25个清零: i18n key 17个, 类型定义8个
- i18n补全: 17个缺失key添加到zh/en/ja
- KnowledgeFile类型: 添加title, content字段
- importService: 改用apiClient.request替代raw fetch
- ModeSelector: 移除jsx prop
- questionBankService: .ok -> .status >= 400
- NotebookDetailView: .filter -> .items.filter
- ImportTasksDrawer: tasks.items提取
- API端点审计: 16/16通过
- 数据库Schema审计: 25表288列一致
- AGENTS.md更新
This commit is contained in:
Developer
2026-05-18 08:30:59 +08:00
parent 631e99c0e0
commit 0b0a060967
16 changed files with 310 additions and 390 deletions
+2
View File
@@ -58,6 +58,7 @@ import { AdminModule } from './admin/admin.module';
import { FeishuModule } from './feishu/feishu.module';
import { FeishuBot } from './feishu/entities/feishu-bot.entity';
import { FeishuAssessmentSession } from './feishu/entities/feishu-assessment-session.entity';
import { AssessmentCertificate } from './assessment/entities/assessment-certificate.entity';
@Module({
imports: [
@@ -100,6 +101,7 @@ import { FeishuAssessmentSession } from './feishu/entities/feishu-assessment-ses
ApiKey,
FeishuBot,
FeishuAssessmentSession,
AssessmentCertificate,
],
synchronize: true, // Auto-create database schema. Disable in production.
}),
@@ -133,18 +133,18 @@ export class AssessmentController {
return this.assessmentService.generateCertificate(sessionId, userId, tenantId);
}
@Public()
@Get('certificate/verify/:certificateId')
@ApiOperation({ summary: 'Verify certificate by ID (public)' })
@Public()
async verifyCertificate(
@Param('certificateId') certificateId: string,
) {
return this.assessmentService.verifyCertificate(certificateId);
}
@Public()
@Get('certificate/public/:sessionId')
@ApiOperation({ summary: 'Get public certificate info for verification' })
@Public()
async getPublicCertificate(
@Param('sessionId') sessionId: string,
) {
+3 -2
View File
@@ -5,6 +5,7 @@ import {
Inject,
forwardRef,
ForbiddenException,
BadRequestException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DeepPartial, In } from 'typeorm';
@@ -416,7 +417,7 @@ private async getModel(tenantId: string): Promise<ChatOpenAI> {
this.logger.log(`[startSession] activeKbId resolved to: ${activeKbId}`);
if (!activeKbId) {
this.logger.error(`[startSession] No knowledge source resolved`);
throw new Error('Knowledge source (ID or Template) must be provided.');
throw new BadRequestException('Knowledge source (ID or Template) must be provided.');
}
// Try to determine if it's a KB or Group and check permissions
@@ -539,7 +540,7 @@ private async getModel(tenantId: string): Promise<ChatOpenAI> {
this.logger.error(
`[startSession] Insufficient content length: ${content?.length || 0}`,
);
throw new Error(
throw new BadRequestException(
'Selected knowledge source has no sufficient content for evaluation.',
);
}
@@ -91,9 +91,15 @@ export class QuestionBankService {
throw new BadRequestException('Question bank name is required');
}
if (createDto.templateId) {
const existing = await this.bankRepository.findOne({ where: { templateId: createDto.templateId } });
const existing = await this.bankRepository.findOne({
where: { templateId: createDto.templateId, tenantId: tenantId as any },
});
if (existing) {
throw new BadRequestException('该模板已关联题库,一个模板只能创建一个题库');
if (existing.status === QuestionBankStatus.DRAFT || existing.status === QuestionBankStatus.REJECTED) {
await this.bankRepository.remove(existing);
} else {
throw new BadRequestException('该模板已关联有效题库,请编辑已有题库');
}
}
}
const bankData: any = {