forked from wangziqi/gongxue-base
feat: complete PRD verification fixes and deployment readiness
- Add CommonModule to provide/export CampusScope across business modules - Replace DepartmentsModule imports with CommonModule in 11 modules - Add missing Class/Tenant repository imports to StudentsModule and SchedulesModule - Fix service specs with CampusScope, ClassRepository, StudentRepository mocks - Move better-sqlite3 to optionalDependencies for production Docker builds - Rewrite Dockerfiles for monorepo root build context - Update docker-compose.yml service build contexts
This commit is contained in:
@@ -54,7 +54,7 @@ import { ClassroomRentalsModule } from './classroom-rentals/classroom-rentals.mo
|
||||
import { SyncModule } from './sync/sync.module';
|
||||
import { NotificationsModule } from './notifications/notifications.module';
|
||||
import { DepartmentsModule } from './departments/departments.module';
|
||||
import { CampusScope } from './common/campus-scope';
|
||||
import { CommonModule } from './common/common.module';
|
||||
import { CampusScopeMiddleware } from './common/campus-scope.middleware';
|
||||
|
||||
@Module({
|
||||
@@ -139,9 +139,9 @@ import { CampusScopeMiddleware } from './common/campus-scope.middleware';
|
||||
SyncModule,
|
||||
NotificationsModule,
|
||||
DepartmentsModule,
|
||||
CommonModule,
|
||||
],
|
||||
providers: [
|
||||
CampusScope,
|
||||
{ provide: APP_GUARD, useClass: ThrottlerGuard },
|
||||
{ provide: APP_GUARD, useClass: JwtAuthGuard },
|
||||
{ provide: APP_GUARD, useClass: PermissionGuard },
|
||||
|
||||
@@ -4,12 +4,12 @@ import { AttendanceRecord, DingAttendanceRaw, Student, Class } from '../entities
|
||||
import { AttendanceService } from './attendance.service';
|
||||
import { AttendanceController } from './attendance.controller';
|
||||
import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([AttendanceRecord, DingAttendanceRaw, Student, Class]),
|
||||
OperationLogsModule,
|
||||
DepartmentsModule,
|
||||
CommonModule,
|
||||
],
|
||||
controllers: [AttendanceController],
|
||||
providers: [AttendanceService],
|
||||
|
||||
@@ -5,6 +5,9 @@ import { Repository } from 'typeorm';
|
||||
import { AttendanceService } from './attendance.service';
|
||||
import { AttendanceRecord } from '../entities/attendance-record.entity';
|
||||
import { DingAttendanceRaw } from '../entities/ding-attendance-raw.entity';
|
||||
import { Class } from '../entities/class.entity';
|
||||
import { Student } from '../entities/student.entity';
|
||||
import { CampusScope } from '../common/campus-scope';
|
||||
import { BatchCreateAttendanceDto } from './dto/attendance.dto';
|
||||
|
||||
describe('AttendanceService — batchCreate', () => {
|
||||
@@ -29,12 +32,18 @@ describe('AttendanceService — batchCreate', () => {
|
||||
};
|
||||
|
||||
const mockDingRepo = {};
|
||||
const mockClassRepo = { find: jest.fn().mockResolvedValue([]) };
|
||||
const mockStudentRepo = { find: jest.fn().mockResolvedValue([]) };
|
||||
const mockCampusScope = { getScopeDepartmentIds: jest.fn().mockResolvedValue(null), filter: jest.fn((w: any) => w) };
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
AttendanceService,
|
||||
{ provide: getRepositoryToken(AttendanceRecord), useValue: mockRepo },
|
||||
{ provide: getRepositoryToken(DingAttendanceRaw), useValue: mockDingRepo },
|
||||
{ provide: getRepositoryToken(Class), useValue: mockClassRepo },
|
||||
{ provide: getRepositoryToken(Student), useValue: mockStudentRepo },
|
||||
{ provide: CampusScope, useValue: mockCampusScope },
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { NotificationsModule } from '../notifications/notifications.module';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Bill } from '../entities/bill.entity';
|
||||
import { BillItem } from '../entities/bill-item.entity';
|
||||
@@ -27,7 +27,7 @@ import { BillsController } from './bills.controller';
|
||||
Student,
|
||||
]),
|
||||
NotificationsModule,
|
||||
DepartmentsModule,
|
||||
CommonModule,
|
||||
],
|
||||
controllers: [BillsController],
|
||||
providers: [BillsService, BillsExportService],
|
||||
|
||||
@@ -9,6 +9,7 @@ import { PersonalExpense } from '../entities/personal-expense.entity';
|
||||
import { Occupancy } from '../entities/occupancy.entity';
|
||||
import { Room } from '../entities/room.entity';
|
||||
import { Deposit } from '../entities/deposit.entity';
|
||||
import { CampusScope } from '../common/campus-scope';
|
||||
|
||||
type MockRepository<T> = Partial<Record<keyof Repository<T>, jest.Mock>>;
|
||||
|
||||
@@ -56,7 +57,7 @@ describe('BillsService — generateBills', () => {
|
||||
occRepo = mockRepo<Occupancy>();
|
||||
roomRepo = mockRepo<Room>();
|
||||
depositRepo = mockRepo<Deposit>();
|
||||
dataSource = { transaction: jest.fn() };
|
||||
dataSource = { transaction: jest.fn(), query: jest.fn().mockResolvedValue([]) };
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
@@ -69,6 +70,7 @@ describe('BillsService — generateBills', () => {
|
||||
{ provide: getRepositoryToken(Room), useValue: roomRepo },
|
||||
{ provide: getRepositoryToken(Deposit), useValue: depositRepo },
|
||||
{ provide: DataSource, useValue: dataSource },
|
||||
{ provide: CampusScope, useValue: { getScopeDepartmentIds: jest.fn().mockResolvedValue(null), filter: jest.fn((w: any) => w) } },
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
import { Class, ClassStudent, ClassTeacher } from '../entities';
|
||||
import { ClassesService } from './classes.service';
|
||||
import { ClassesController } from './classes.controller';
|
||||
@@ -8,7 +8,7 @@ import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||
import { NotificationsModule } from '../notifications/notifications.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Class, ClassStudent, ClassTeacher]), OperationLogsModule, NotificationsModule, DepartmentsModule],
|
||||
imports: [TypeOrmModule.forFeature([Class, ClassStudent, ClassTeacher]), OperationLogsModule, NotificationsModule, CommonModule],
|
||||
controllers: [ClassesController],
|
||||
providers: [ClassesService],
|
||||
exports: [ClassesService],
|
||||
|
||||
@@ -7,10 +7,10 @@ import { ClassSchedule } from '../entities/class-schedule.entity';
|
||||
import { ClassroomRentalsService } from './classroom-rentals.service';
|
||||
import { ClassroomRentalsController } from './classroom-rentals.controller';
|
||||
import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([ClassroomRental, Classroom, Tenant, ClassSchedule]), OperationLogsModule, DepartmentsModule],
|
||||
imports: [TypeOrmModule.forFeature([ClassroomRental, Classroom, Tenant, ClassSchedule]), OperationLogsModule, CommonModule],
|
||||
controllers: [ClassroomRentalsController],
|
||||
providers: [ClassroomRentalsService],
|
||||
exports: [ClassroomRentalsService],
|
||||
|
||||
@@ -6,10 +6,10 @@ import { ClassSchedule } from '../entities/class-schedule.entity';
|
||||
import { ClassroomsService } from './classrooms.service';
|
||||
import { ClassroomsController } from './classrooms.controller';
|
||||
import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Classroom, ClassroomRental, ClassSchedule]), OperationLogsModule, DepartmentsModule],
|
||||
imports: [TypeOrmModule.forFeature([Classroom, ClassroomRental, ClassSchedule]), OperationLogsModule, CommonModule],
|
||||
controllers: [ClassroomsController],
|
||||
providers: [ClassroomsService],
|
||||
exports: [ClassroomsService],
|
||||
|
||||
11
apps/server/src/common/common.module.ts
Normal file
11
apps/server/src/common/common.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { CampusScope } from './campus-scope';
|
||||
import { CampusScopeMiddleware } from './campus-scope.middleware';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
|
||||
@Module({
|
||||
imports: [DepartmentsModule],
|
||||
providers: [CampusScope, CampusScopeMiddleware],
|
||||
exports: [CampusScope, CampusScopeMiddleware, DepartmentsModule],
|
||||
})
|
||||
export class CommonModule {}
|
||||
@@ -13,11 +13,11 @@ import { Deposit } from '../entities/deposit.entity';
|
||||
import { ClassroomRental } from '../entities/classroom-rental.entity';
|
||||
import { ClassTeacher } from '../entities/class-teacher.entity';
|
||||
import { DashboardService } from './dashboard.service';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
import { DashboardController } from './dashboard.controller';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Room, Student, Occupancy, Bill, RoomExpense, Classroom, ClassSchedule, AttendanceRecord, Class, Deposit, ClassroomRental, ClassTeacher]), DepartmentsModule],
|
||||
imports: [TypeOrmModule.forFeature([Room, Student, Occupancy, Bill, RoomExpense, Classroom, ClassSchedule, AttendanceRecord, Class, Deposit, ClassroomRental, ClassTeacher]), CommonModule],
|
||||
controllers: [DashboardController],
|
||||
providers: [DashboardService],
|
||||
})
|
||||
|
||||
@@ -4,13 +4,13 @@ import { Student } from '../entities/student.entity';
|
||||
import { Deposit } from '../entities/deposit.entity';
|
||||
import { DepositInstallment } from '../entities/deposit-installment.entity';
|
||||
import { DepositsService } from './deposits.service';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
import { DepositsController } from './deposits.controller';
|
||||
import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||
import { NotificationsModule } from '../notifications/notifications.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Deposit, DepositInstallment, Student]), OperationLogsModule, NotificationsModule, DepartmentsModule],
|
||||
imports: [TypeOrmModule.forFeature([Deposit, DepositInstallment, Student]), OperationLogsModule, NotificationsModule, CommonModule],
|
||||
controllers: [DepositsController],
|
||||
providers: [DepositsService],
|
||||
exports: [DepositsService],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
import { RoomExpense } from '../entities/room-expense.entity';
|
||||
import { PersonalExpense } from '../entities/personal-expense.entity';
|
||||
import { Room } from '../entities/room.entity';
|
||||
@@ -13,7 +13,7 @@ import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([RoomExpense, PersonalExpense, Room, Student]),
|
||||
OperationLogsModule,
|
||||
DepartmentsModule,
|
||||
CommonModule,
|
||||
],
|
||||
controllers: [ExpensesController],
|
||||
providers: [ExpensesService],
|
||||
|
||||
@@ -8,10 +8,10 @@ import { OccupanciesService } from './occupancies.service';
|
||||
import { OccupanciesController } from './occupancies.controller';
|
||||
import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||
import { NotificationsModule } from '../notifications/notifications.module';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Occupancy, Room, Student, Deposit]), OperationLogsModule, NotificationsModule, DepartmentsModule],
|
||||
imports: [TypeOrmModule.forFeature([Occupancy, Room, Student, Deposit]), OperationLogsModule, NotificationsModule, CommonModule],
|
||||
controllers: [OccupanciesController],
|
||||
providers: [OccupanciesService],
|
||||
exports: [OccupanciesService],
|
||||
|
||||
@@ -6,10 +6,10 @@ import { RoomExpense } from '../entities/room-expense.entity';
|
||||
import { RoomsService } from './rooms.service';
|
||||
import { RoomsController } from './rooms.controller';
|
||||
import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Room, Occupancy, RoomExpense]), OperationLogsModule, DepartmentsModule],
|
||||
imports: [TypeOrmModule.forFeature([Room, Occupancy, RoomExpense]), OperationLogsModule, CommonModule],
|
||||
controllers: [RoomsController],
|
||||
providers: [RoomsService],
|
||||
exports: [RoomsService],
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ClassSchedule } from '../entities';
|
||||
import { ClassSchedule, Class } from '../entities';
|
||||
import { SchedulesService } from './schedules.service';
|
||||
import { SchedulesController } from './schedules.controller';
|
||||
import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||
import { NotificationsModule } from '../notifications/notifications.module';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([ClassSchedule]), OperationLogsModule, NotificationsModule, DepartmentsModule],
|
||||
imports: [TypeOrmModule.forFeature([ClassSchedule, Class]), OperationLogsModule, NotificationsModule, CommonModule],
|
||||
controllers: [SchedulesController],
|
||||
providers: [SchedulesService],
|
||||
exports: [SchedulesService],
|
||||
|
||||
@@ -4,6 +4,8 @@ import { ConflictException } from '@nestjs/common';
|
||||
import { Repository } from 'typeorm';
|
||||
import { SchedulesService } from './schedules.service';
|
||||
import { ClassSchedule } from '../entities/class-schedule.entity';
|
||||
import { Class } from '../entities/class.entity';
|
||||
import { CampusScope } from '../common/campus-scope';
|
||||
|
||||
/** Build a mock query-builder where each chain method returns `this`. */
|
||||
function mockQueryBuilder<T>(results: T[] = []) {
|
||||
@@ -28,6 +30,8 @@ describe('SchedulesService — checkConflict', () => {
|
||||
providers: [
|
||||
SchedulesService,
|
||||
{ provide: getRepositoryToken(ClassSchedule), useValue: mockRepo },
|
||||
{ provide: getRepositoryToken(Class), useValue: { find: jest.fn().mockResolvedValue([]) } },
|
||||
{ provide: CampusScope, useValue: { getScopeDepartmentIds: jest.fn().mockResolvedValue(null), filter: jest.fn((w: any) => w) } },
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Student } from '../entities/student.entity';
|
||||
import { DepartmentsModule } from '../departments/departments.module';
|
||||
import { Class } from '../entities/class.entity';
|
||||
import { Tenant } from '../entities/tenant.entity';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
import { ClassStudent } from '../entities/class-student.entity';
|
||||
import { AttendanceRecord } from '../entities/attendance-record.entity';
|
||||
import { StudentsService } from './students.service';
|
||||
import { StudentsController } from './students.controller';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Student, ClassStudent, AttendanceRecord]), DepartmentsModule],
|
||||
imports: [TypeOrmModule.forFeature([Student, Class, ClassStudent, AttendanceRecord, Tenant]), CommonModule],
|
||||
controllers: [StudentsController],
|
||||
providers: [StudentsService],
|
||||
exports: [StudentsService],
|
||||
|
||||
Reference in New Issue
Block a user