From 728f8a14e9fb7360fce92640bfa5658af8cadb4f Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 6 May 2025 19:33:30 +0200 Subject: [PATCH] feat(entities): Added created/updated at to all entities --- src/models/entities/ConfigFlags.ts | 25 ++++++++++++++++++++++++- src/models/entities/Donation.ts | 26 ++++++++++++++++++++++++-- src/models/entities/GroupContact.ts | 25 ++++++++++++++++++++++++- src/models/entities/Permission.ts | 26 ++++++++++++++++++++++++-- src/models/entities/Principal.ts | 25 +++++++++++++++++++++++-- src/models/entities/RunnerCard.ts | 26 ++++++++++++++++++++++++-- src/models/entities/RunnerGroup.ts | 24 +++++++++++++++++++++++- src/models/entities/Scan.ts | 23 ++++++++++++++++++++++- src/models/entities/ScanStation.ts | 24 +++++++++++++++++++++++- src/models/entities/StatsClient.ts | 25 +++++++++++++++++++++++-- src/models/entities/Track.ts | 23 ++++++++++++++++++++++- src/models/entities/UserAction.ts | 24 +++++++++++++++++++++++- 12 files changed, 279 insertions(+), 17 deletions(-) diff --git a/src/models/entities/ConfigFlags.ts b/src/models/entities/ConfigFlags.ts index 3dd6c69..dbe1ad0 100644 --- a/src/models/entities/ConfigFlags.ts +++ b/src/models/entities/ConfigFlags.ts @@ -1,8 +1,10 @@ import { + IsInt, IsNotEmpty, + IsPositive, IsString } from "class-validator"; -import { Column, Entity, PrimaryColumn } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryColumn } from "typeorm"; /** * Defines the ConfigFlag entity. @@ -24,4 +26,25 @@ export class ConfigFlag { @IsString() @IsNotEmpty() value: string; + + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } } diff --git a/src/models/entities/Donation.ts b/src/models/entities/Donation.ts index b9a6ef0..363252d 100644 --- a/src/models/entities/Donation.ts +++ b/src/models/entities/Donation.ts @@ -1,7 +1,8 @@ import { - IsInt + IsInt, + IsPositive } from "class-validator"; -import { Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { ResponseDonation } from '../responses/ResponseDonation'; import { Donor } from './Donor'; @@ -40,6 +41,27 @@ export abstract class Donation { @IsInt() paidAmount: number; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Turns this entity into it's response class. */ diff --git a/src/models/entities/GroupContact.ts b/src/models/entities/GroupContact.ts index dd6eed1..0660100 100644 --- a/src/models/entities/GroupContact.ts +++ b/src/models/entities/GroupContact.ts @@ -5,9 +5,11 @@ import { IsOptional, IsPhoneNumber, + IsPositive, + IsString } from "class-validator"; -import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { config } from '../../config'; import { ResponseGroupContact } from '../responses/ResponseGroupContact'; import { Address } from "./Address"; @@ -81,6 +83,27 @@ export class GroupContact { @OneToMany(() => RunnerGroup, group => group.contact, { nullable: true }) groups: RunnerGroup[]; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Turns this entity into it's response class. */ diff --git a/src/models/entities/Permission.ts b/src/models/entities/Permission.ts index 4bba550..077dd8c 100644 --- a/src/models/entities/Permission.ts +++ b/src/models/entities/Permission.ts @@ -1,9 +1,10 @@ import { IsEnum, IsInt, - IsNotEmpty + IsNotEmpty, + IsPositive } from "class-validator"; -import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; import { PermissionAction } from '../enums/PermissionAction'; import { PermissionTarget } from '../enums/PermissionTargets'; import { ResponsePermission } from '../responses/ResponsePermission'; @@ -45,6 +46,27 @@ export class Permission { @IsEnum(PermissionAction) action: PermissionAction; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Turn this into a string for exporting and jwts. * Mainly used to shrink the size of jwts (otherwise the would contain entire objects). diff --git a/src/models/entities/Principal.ts b/src/models/entities/Principal.ts index f33d0be..476af1b 100644 --- a/src/models/entities/Principal.ts +++ b/src/models/entities/Principal.ts @@ -1,5 +1,5 @@ -import { IsInt } from 'class-validator'; -import { Entity, OneToMany, PrimaryGeneratedColumn, TableInheritance } from 'typeorm'; +import { IsInt, IsPositive } from 'class-validator'; +import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn, TableInheritance } from 'typeorm'; import { ResponsePrincipal } from '../responses/ResponsePrincipal'; import { Permission } from './Permission'; @@ -23,6 +23,27 @@ export abstract class Principal { @OneToMany(() => Permission, permission => permission.principal, { nullable: true }) permissions: Permission[]; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Turns this entity into it's response class. */ diff --git a/src/models/entities/RunnerCard.ts b/src/models/entities/RunnerCard.ts index db31ec5..93aeecd 100644 --- a/src/models/entities/RunnerCard.ts +++ b/src/models/entities/RunnerCard.ts @@ -3,9 +3,10 @@ import { IsInt, - IsOptional + IsOptional, + IsPositive } from "class-validator"; -import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { RunnerCardIdOutOfRangeError } from '../../errors/RunnerCardErrors'; import { ResponseRunnerCard } from '../responses/ResponseRunnerCard'; import { Runner } from "./Runner"; @@ -48,6 +49,27 @@ export class RunnerCard { @OneToMany(() => TrackScan, scan => scan.track, { nullable: true }) scans: TrackScan[]; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Generates a ean-13 compliant string for barcode generation. */ diff --git a/src/models/entities/RunnerGroup.ts b/src/models/entities/RunnerGroup.ts index 332bd33..d17df88 100644 --- a/src/models/entities/RunnerGroup.ts +++ b/src/models/entities/RunnerGroup.ts @@ -2,9 +2,10 @@ import { IsInt, IsNotEmpty, IsOptional, + IsPositive, IsString } from "class-validator"; -import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { ResponseRunnerGroup } from '../responses/ResponseRunnerGroup'; import { GroupContact } from "./GroupContact"; import { Runner } from "./Runner"; @@ -46,6 +47,27 @@ export abstract class RunnerGroup { @OneToMany(() => Runner, runner => runner.group, { nullable: true }) runners: Runner[]; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Returns the total distance ran by this group's runners based on all their valid scans. */ diff --git a/src/models/entities/Scan.ts b/src/models/entities/Scan.ts index 2424a0c..3c53585 100644 --- a/src/models/entities/Scan.ts +++ b/src/models/entities/Scan.ts @@ -5,7 +5,7 @@ import { IsPositive } from "class-validator"; -import { Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { ResponseScan } from '../responses/ResponseScan'; import { Runner } from "./Runner"; @@ -40,6 +40,27 @@ export class Scan { @IsBoolean() valid: boolean = true; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * The scan's distance in meters. * This is the "real" value used by "normal" scans.. diff --git a/src/models/entities/ScanStation.ts b/src/models/entities/ScanStation.ts index 38f7803..49ae740 100644 --- a/src/models/entities/ScanStation.ts +++ b/src/models/entities/ScanStation.ts @@ -3,9 +3,10 @@ import { IsInt, IsNotEmpty, IsOptional, + IsPositive, IsString } from "class-validator"; -import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { ResponseScanStation } from '../responses/ResponseScanStation'; import { Track } from "./Track"; import { TrackScan } from "./TrackScan"; @@ -78,6 +79,27 @@ export class ScanStation { @IsBoolean() enabled?: boolean = true; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Turns this entity into it's response class. */ diff --git a/src/models/entities/StatsClient.ts b/src/models/entities/StatsClient.ts index eb48cbf..7fadb86 100644 --- a/src/models/entities/StatsClient.ts +++ b/src/models/entities/StatsClient.ts @@ -1,5 +1,5 @@ -import { IsInt, IsOptional, IsString } from "class-validator"; -import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; +import { IsInt, IsOptional, IsPositive, IsString } from "class-validator"; +import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryGeneratedColumn } from "typeorm"; import { ResponseStatsClient } from '../responses/ResponseStatsClient'; /** * Defines the StatsClient entity. @@ -47,6 +47,27 @@ export class StatsClient { @IsOptional() cleartextkey?: string; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Turns this entity into it's response class. */ diff --git a/src/models/entities/Track.ts b/src/models/entities/Track.ts index 5e172f7..843abb7 100644 --- a/src/models/entities/Track.ts +++ b/src/models/entities/Track.ts @@ -5,7 +5,7 @@ import { IsPositive, IsString } from "class-validator"; -import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { ResponseTrack } from '../responses/ResponseTrack'; import { ScanStation } from "./ScanStation"; import { TrackScan } from "./TrackScan"; @@ -63,6 +63,27 @@ export class Track { @OneToMany(() => TrackScan, scan => scan.track, { nullable: true }) scans: TrackScan[]; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Turns this entity into it's response class. */ diff --git a/src/models/entities/UserAction.ts b/src/models/entities/UserAction.ts index d598be0..0d17912 100644 --- a/src/models/entities/UserAction.ts +++ b/src/models/entities/UserAction.ts @@ -3,9 +3,10 @@ import { IsInt, IsNotEmpty, IsOptional, + IsPositive, IsString } from "class-validator"; -import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; import { PermissionAction } from '../enums/PermissionAction'; import { User } from './User'; @@ -53,6 +54,27 @@ export class UserAction { @IsString() changed: string; + @Column({ type: 'bigint', nullable: true, readonly: true }) + @IsInt() + @IsPositive() + created_at: number; + + @Column({ type: 'bigint', nullable: true }) + @IsInt() + @IsPositive() + updated_at: number; + + @BeforeInsert() + public setCreatedAt() { + this.created_at = Math.floor(Date.now() / 1000); + this.updated_at = Math.floor(Date.now() / 1000); + } + + @BeforeUpdate() + public setUpdatedAt() { + this.updated_at = Math.floor(Date.now() / 1000); + } + /** * Turns this entity into it's response class. */