Adding ability to monitor court reservations when performing a reservation

This commit is contained in:
Collin Duncan 2024-03-08 16:33:13 +01:00
parent 8410241219
commit 7bc30f99d0
No known key found for this signature in database
7 changed files with 142 additions and 4 deletions

View file

@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class AddMonitors1709910503052 implements MigrationInterface {
name = 'AddMonitors1709910503052'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "monitors" ("id" varchar PRIMARY KEY NOT NULL, "type" varchar(32) NOT NULL, "createdAt" datetime NOT NULL, "data" blob NOT NULL)`,
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "monitors"`)
}
}

View file

@ -10,6 +10,7 @@ import { LoggerMiddleware } from './logger/middleware'
import { LoggerModule } from './logger/module'
import { DatabaseLoggerService } from './logger/service.database_logger'
import { MembersModule } from './members/module'
import { MonitoringModule } from './monitoring/module'
import { NtfyModule } from './ntfy/module'
import { RecurringReservationsModule } from './recurringReservations/module'
import { ReservationsModule } from './reservations/module'
@ -59,6 +60,7 @@ import { WaitingListModule } from './waitingList/module'
MembersModule,
WaitingListModule,
NtfyModule,
MonitoringModule,
],
})
export class AppModule implements NestModule {

52
src/monitoring/entity.ts Normal file
View file

@ -0,0 +1,52 @@
import { Transform, Type } from 'class-transformer'
import { TransformationType } from 'class-transformer'
import { Dayjs } from 'dayjs'
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
import dayjs from '../common/dayjs'
export enum MonitorType {
CourtReservations = 'court_reservations',
}
@Entity({ name: 'monitors' })
export class Monitor {
@PrimaryGeneratedColumn('uuid')
id: string
@Column('varchar', { length: 32, nullable: false })
type: MonitorType
@Column('datetime', {
nullable: false,
transformer: {
to: (value: Dayjs) => value.format(),
from: (value: Date) => dayjs(value),
},
})
@Type(() => Dayjs)
@Transform(({ value, type }) => {
switch (type) {
case TransformationType.PLAIN_TO_CLASS:
return dayjs(value)
case TransformationType.CLASS_TO_PLAIN:
return value.format()
default:
return value
}
})
createdAt: Dayjs
@Column('blob', {
nullable: false,
transformer: {
to: (value) => value,
from: (value) => value,
},
})
data: unknown
constructor(partial: Partial<Monitor>) {
Object.assign(this, partial)
}
}

14
src/monitoring/module.ts Normal file
View file

@ -0,0 +1,14 @@
import { Module } from '@nestjs/common'
import { TypeOrmModule } from '@nestjs/typeorm'
import { LoggerModule } from '../logger/module'
import { NtfyModule } from '../ntfy/module'
import { Monitor } from './entity'
import { MonitorsService } from './service'
@Module({
imports: [LoggerModule, NtfyModule, TypeOrmModule.forFeature([Monitor])],
providers: [MonitorsService],
exports: [MonitorsService],
})
export class MonitoringModule {}

19
src/monitoring/service.ts Normal file
View file

@ -0,0 +1,19 @@
import { Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository } from 'typeorm'
import { Monitor, MonitorType } from './entity'
@Injectable()
export class MonitorsService {
constructor(
@InjectRepository(Monitor)
private readonly monitorsRepository: Repository<Monitor>,
) {}
async performMonitor(type: MonitorType, data: unknown) {
await this.monitorsRepository.save(
this.monitorsRepository.create({ type, data }),
)
}
}

View file

@ -509,6 +509,7 @@ export class BaanReserverenService {
try {
await this.init()
await this.navigateToDay(reservation.dateRangeStart)
await this.monitorCourtReservations()
await this.selectAvailableTime(reservation)
await this.selectOwner(reservation.ownerId)
await this.selectOpponent(
@ -591,10 +592,19 @@ export class BaanReserverenService {
return courtStatuses
}
public async monitorCourtReservations(date: Dayjs) {
public async monitorCourtReservations(date?: Dayjs, swallowError = true) {
try {
if (date) {
await this.init()
await this.navigateToDay(date)
}
return await this.getAllCourtStatuses()
} catch (error: unknown) {
this.loggerService.error('Failed to monitor court reservations')
if (!swallowError) {
throw error
}
}
}
}

26
test/app.e2e.spec.ts Normal file
View file

@ -0,0 +1,26 @@
import { INestApplication } from '@nestjs/common'
import { Test, TestingModule } from '@nestjs/testing'
import * as request from 'supertest'
import { AppModule } from '../src/app.module'
describe('AppController (e2e)', () => {
let app: INestApplication
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile()
app = moduleFixture.createNestApplication()
await app.init()
})
afterAll(async () => {
await app.close()
})
it('/ (GET)', async () => {
await request(app.getHttpServer()).get('/').expect(404)
})
})