Skip to content

Commit 18edf0c

Browse files
Merge pull request #367 from Divineifed1/main
scheduled jobs implementation
2 parents 63755e9 + 1c4a94c commit 18edf0c

File tree

7 files changed

+118
-0
lines changed

7 files changed

+118
-0
lines changed

backend/src/app.module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import { DepartmentsModule } from './departments/departments.module';
3434
import { AssetTransfersModule } from './asset-transfers/asset-transfers.module';
3535
import { SearchModule } from './search/search.module';
3636
import { ApiKeyModule } from './api-key/api-key.module';
37+
import { NestModule } from './scheduled-jobs/nest/nest.module';
38+
import { ScheduledJobsModule } from './scheduled-jobs/scheduled-jobs.module';
3739

3840
@Module({
3941
imports: [
@@ -84,6 +86,8 @@ import { ApiKeyModule } from './api-key/api-key.module';
8486
WebhooksModule,
8587
AuditLogsModule,
8688
ApiKeyModule,
89+
NestModule,
90+
ScheduledJobsModule,
8791
],
8892
controllers: [AppController],
8993
providers: [
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export class CreateScheduledJobDto {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* eslint-disable prettier/prettier */
2+
import { IsOptional, IsString } from 'class-validator';
3+
4+
export class UpdateScheduleSettingsDto {
5+
@IsOptional() @IsString() licenseCheckCron?: string;
6+
@IsOptional() @IsString() insuranceReminderCron?: string;
7+
@IsOptional() @IsString() maintenanceCheckCron?: string;
8+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* eslint-disable prettier/prettier */
2+
import { Entity, PrimaryGeneratedColumn, Column, UpdateDateColumn } from 'typeorm';
3+
4+
@Entity('schedule_settings')
5+
export class ScheduleSettings {
6+
@PrimaryGeneratedColumn('uuid')
7+
id: string;
8+
9+
@Column({ default: '0 0 * * *' }) // every day at midnight
10+
licenseCheckCron: string;
11+
12+
@Column({ default: '0 8 * * *' }) // every day at 8am
13+
insuranceReminderCron: string;
14+
15+
@Column({ default: '0 9 * * MON' }) // every Monday at 9am
16+
maintenanceCheckCron: string;
17+
18+
@UpdateDateColumn()
19+
updatedAt: Date;
20+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* eslint-disable prettier/prettier */
2+
import { Controller, Get, Patch, Body } from '@nestjs/common';
3+
import { ScheduledJobsService } from './scheduled-jobs.service';
4+
import { UpdateScheduleSettingsDto } from './dto/update-scheduled-settings.dto';
5+
6+
@Controller('scheduled-jobs')
7+
export class ScheduledJobsController {
8+
constructor(private readonly scheduledJobsService: ScheduledJobsService) {}
9+
10+
@Get('settings')
11+
getSettings() {
12+
return this.scheduledJobsService.getSettings();
13+
}
14+
15+
@Patch('settings')
16+
updateSettings(@Body() dto: UpdateScheduleSettingsDto) {
17+
return this.scheduledJobsService.updateSettings(dto);
18+
}
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* eslint-disable prettier/prettier */
2+
import { Module } from '@nestjs/common';
3+
import { TypeOrmModule } from '@nestjs/typeorm';
4+
import { ScheduleModule } from '@nestjs/schedule';
5+
import { ScheduledJobsController } from './scheduled-jobs.controller';
6+
import { ScheduledJobsService } from './scheduled-jobs.service';
7+
import { ScheduleSettings } from './entities/scheduled-settings.entity';
8+
9+
@Module({
10+
imports: [
11+
TypeOrmModule.forFeature([ScheduleSettings]),
12+
ScheduleModule.forRoot(), // enables cron support
13+
],
14+
controllers: [ScheduledJobsController],
15+
providers: [ScheduledJobsService],
16+
})
17+
export class ScheduledJobsModule {}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* eslint-disable prettier/prettier */
2+
import { Injectable, Logger } from '@nestjs/common';
3+
import { Cron, CronExpression } from '@nestjs/schedule';
4+
import { InjectRepository } from '@nestjs/typeorm';
5+
import { Repository } from 'typeorm';
6+
import { ScheduleSettings } from './entities/scheduled-settings.entity';
7+
8+
@Injectable()
9+
export class ScheduledJobsService {
10+
private readonly logger = new Logger(ScheduledJobsService.name);
11+
12+
constructor(
13+
@InjectRepository(ScheduleSettings)
14+
private readonly settingsRepo: Repository<ScheduleSettings>,
15+
) {}
16+
17+
// 🕒 Daily check for license expiry
18+
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
19+
async checkLicenseExpiry() {
20+
this.logger.log('Running daily license expiry check...');
21+
// TODO: Query licenses expiring soon, send reminders
22+
}
23+
24+
// 🕗 Daily insurance reminder
25+
@Cron(CronExpression.EVERY_DAY_AT_8AM)
26+
async sendInsuranceReminders() {
27+
this.logger.log('Running insurance reminder task...');
28+
// TODO: Notify companies with upcoming insurance expiry
29+
}
30+
31+
// 🧰 Weekly maintenance scheduling
32+
@Cron(CronExpression.EVERY_DAY_AT_9AM)
33+
async scheduleMaintenanceTasks() {
34+
this.logger.log('Running weekly maintenance scheduler...');
35+
// TODO: Identify assets due for maintenance and alert teams
36+
}
37+
38+
// ⚙️ Update job intervals dynamically
39+
async updateSettings(newSettings: Partial<ScheduleSettings>) {
40+
const settings = await this.settingsRepo.findOne({});
41+
if (!settings) return this.settingsRepo.save(newSettings);
42+
Object.assign(settings, newSettings);
43+
return this.settingsRepo.save(settings);
44+
}
45+
46+
async getSettings() {
47+
return this.settingsRepo.findOne({});
48+
}
49+
}

0 commit comments

Comments
 (0)