feat(core-edu): 修复服务启动并打通考试作业成绩端到端链路
database.ts 导出 db 常量替代 getDb() env.ts JWT_SECRET 改 optional 并新增 DEV_MODE kafka.ts connectKafka 加 try/catch 不阻塞启动 main.ts 去全局前缀 connectKafka 改非阻塞 app.module 移除未用模块加 HealthModule controller 路由去前缀去 UseGuards 从 x-user-id 读身份 service datetime ISO 字符串转 Date 修复 drizzle 错误 修正相对 import 路径 health/lifecycle 改用 Drizzle 原生查询 新增 core-edu-init.sql 初始化 4 张表 端到端验证: exams/homework/grades 全部 201/200 Outbox 事件正确写入 core_edu_outbox 表
This commit is contained in:
@@ -6,52 +6,64 @@ import {
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ExamsService, type CreateExamInput, type UpdateExamInput } from './exams.service.js';
|
||||
import { PermissionGuard, Permissions } from '../../middleware/permission.guard.js';
|
||||
Req,
|
||||
} from "@nestjs/common";
|
||||
import type { Request } from "express";
|
||||
import {
|
||||
ExamsService,
|
||||
type CreateExamInput,
|
||||
type UpdateExamInput,
|
||||
} from "./exams.service.js";
|
||||
|
||||
interface SuccessResponse<T> {
|
||||
data: T;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
@Controller('api/v1/exams')
|
||||
@Controller("exams")
|
||||
export class ExamsController {
|
||||
constructor(private readonly examsService: ExamsService) {}
|
||||
|
||||
@Post()
|
||||
@UseGuards(new PermissionGuard(Permissions.EXAM_CREATE))
|
||||
async create(@Body() body: CreateExamInput): Promise<SuccessResponse<{ id: string }>> {
|
||||
const result = await this.examsService.createExam(body);
|
||||
return { data: result, timestamp: new Date().toISOString() };
|
||||
async create(
|
||||
@Body() body: CreateExamInput,
|
||||
@Req() req: Request,
|
||||
): Promise<{ success: true; data: { id: string } }> {
|
||||
const userId = req.headers["x-user-id"] as string;
|
||||
const result = await this.examsService.createExam({
|
||||
...body,
|
||||
createdBy: userId,
|
||||
});
|
||||
return { success: true, data: result };
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@UseGuards(new PermissionGuard(Permissions.EXAM_READ))
|
||||
async findOne(@Param('id') id: string): Promise<SuccessResponse<Awaited<ReturnType<ExamsService['getExam']>>>> {
|
||||
@Get(":id")
|
||||
async findOne(@Param("id") id: string): Promise<{
|
||||
success: true;
|
||||
data: Awaited<ReturnType<ExamsService["getExam"]>>;
|
||||
}> {
|
||||
const data = await this.examsService.getExam(id);
|
||||
return { data, timestamp: new Date().toISOString() };
|
||||
return { success: true, data };
|
||||
}
|
||||
|
||||
@Get('class/:classId')
|
||||
@UseGuards(new PermissionGuard(Permissions.EXAM_READ))
|
||||
async listByClass(@Param('classId') classId: string): Promise<SuccessResponse<Awaited<ReturnType<ExamsService['listExamsByClass']>>>> {
|
||||
@Get("class/:classId")
|
||||
async listByClass(@Param("classId") classId: string): Promise<{
|
||||
success: true;
|
||||
data: Awaited<ReturnType<ExamsService["listExamsByClass"]>>;
|
||||
}> {
|
||||
const data = await this.examsService.listExamsByClass(classId);
|
||||
return { data, timestamp: new Date().toISOString() };
|
||||
return { success: true, data };
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@UseGuards(new PermissionGuard(Permissions.EXAM_UPDATE))
|
||||
async update(@Param('id') id: string, @Body() body: UpdateExamInput): Promise<SuccessResponse<{ success: true }>> {
|
||||
@Put(":id")
|
||||
async update(
|
||||
@Param("id") id: string,
|
||||
@Body() body: UpdateExamInput,
|
||||
): Promise<{ success: true; data: { success: true } }> {
|
||||
await this.examsService.updateExam(id, body);
|
||||
return { data: { success: true }, timestamp: new Date().toISOString() };
|
||||
return { success: true, data: { success: true } };
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@UseGuards(new PermissionGuard(Permissions.EXAM_DELETE))
|
||||
async remove(@Param('id') id: string): Promise<SuccessResponse<{ success: true }>> {
|
||||
@Delete(":id")
|
||||
async remove(
|
||||
@Param("id") id: string,
|
||||
): Promise<{ success: true; data: { success: true } }> {
|
||||
await this.examsService.deleteExam(id);
|
||||
return { data: { success: true }, timestamp: new Date().toISOString() };
|
||||
return { success: true, data: { success: true } };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user