Compare commits

...

9 Commits
1.4.3 ... dev

Author SHA1 Message Date
e27e819609
chore(release): 1.5.2
All checks were successful
Build release images / build-container (push) Successful in 1m9s
2025-05-26 19:30:33 +02:00
0f532b139c
feat(mailer): Log error message when sending selfservice forgotten mail fails 2025-05-26 19:30:16 +02:00
eebcc2e328
feat(mailer): Add logging for selfservice forgotten mail requests 2025-05-26 19:29:37 +02:00
284954d064
chore(release): 1.5.1
All checks were successful
Build release images / build-container (push) Successful in 1m12s
2025-05-26 19:24:04 +02:00
401ca923a6
feat(mailer): Log error when sending selfservice forgotten mail fails 2025-05-26 19:23:30 +02:00
bf1f6411e0
chore(release): 1.5.0
All checks were successful
Build release images / build-container (push) Successful in 1m17s
2025-05-06 19:41:36 +02:00
f225cc4954
feat(responses): Added created_at/updated_at 2025-05-06 19:38:20 +02:00
728f8a14e9
feat(entities): Added created/updated at to all entities 2025-05-06 19:33:30 +02:00
a4480589a0
feat(participants): Added created/updated at 2025-05-06 19:29:46 +02:00
28 changed files with 475 additions and 28 deletions

View File

@ -2,9 +2,33 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC. All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [1.5.2](https://git.odit.services/lfk/backend/compare/1.5.1...1.5.2)
- feat(mailer): Add logging for selfservice forgotten mail requests [`eebcc2e`](https://git.odit.services/lfk/backend/commit/eebcc2e3284230135e3911b4edaecd1a9cfd2100)
- feat(mailer): Log error message when sending selfservice forgotten mail fails [`0f532b1`](https://git.odit.services/lfk/backend/commit/0f532b139c2bc5cd89ca2dbff0867825a9363250)
#### [1.5.1](https://git.odit.services/lfk/backend/compare/1.5.0...1.5.1)
> 26 May 2025
- chore(release): 1.5.1 [`284954d`](https://git.odit.services/lfk/backend/commit/284954d064f09951c13584e9d50a83be2c4b9f72)
- feat(mailer): Log error when sending selfservice forgotten mail fails [`401ca92`](https://git.odit.services/lfk/backend/commit/401ca923a61bc5988e73209c086bc9a5a4fa04f9)
#### [1.5.0](https://git.odit.services/lfk/backend/compare/1.4.3...1.5.0)
> 6 May 2025
- feat(entities): Added created/updated at to all entities [`728f8a1`](https://git.odit.services/lfk/backend/commit/728f8a14e9fb7360fce92640bfa5658af8cadb4f)
- feat(responses): Added created_at/updated_at [`f225cc4`](https://git.odit.services/lfk/backend/commit/f225cc49548605de48cf6c6e6f7c86b163236545)
- feat(participants): Added created/updated at [`a448058`](https://git.odit.services/lfk/backend/commit/a4480589a0e23a4481332ab5efa0777c62bbab56)
- chore(release): 1.5.0 [`bf1f641`](https://git.odit.services/lfk/backend/commit/bf1f6411e0f5113842a537f5bcf632638bdf1048)
#### [1.4.3](https://git.odit.services/lfk/backend/compare/1.4.2...1.4.3) #### [1.4.3](https://git.odit.services/lfk/backend/compare/1.4.2...1.4.3)
> 1 May 2025
- feat(runners): Include collected distance donation amount in runner detail [`4494afc`](https://git.odit.services/lfk/backend/commit/4494afc64b433d26b54a293fe156d13c40faad95) - feat(runners): Include collected distance donation amount in runner detail [`4494afc`](https://git.odit.services/lfk/backend/commit/4494afc64b433d26b54a293fe156d13c40faad95)
- chore(release): 1.4.3 [`0ad9eeb`](https://git.odit.services/lfk/backend/commit/0ad9eeb52f18af3ea7d86fe1bf15edb04f4cfd2d)
#### [1.4.2](https://git.odit.services/lfk/backend/compare/1.4.1...1.4.2) #### [1.4.2](https://git.odit.services/lfk/backend/compare/1.4.1...1.4.2)

View File

@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-backend", "name": "@odit/lfk-backend",
"version": "1.4.3", "version": "1.5.2",
"main": "src/app.ts", "main": "src/app.ts",
"repository": "https://git.odit.services/lfk/backend", "repository": "https://git.odit.services/lfk/backend",
"author": { "author": {

View File

@ -76,6 +76,21 @@ export class Mailer {
*/ */
public static async sendSelfserviceForgottenMail(to_address: string, runner_id: number, firstname: string, middlename: string, lastname: string, token: string, locale: string = "en") { public static async sendSelfserviceForgottenMail(to_address: string, runner_id: number, firstname: string, middlename: string, lastname: string, token: string, locale: string = "en") {
try { try {
console.log("Mail request", {
to: to_address,
templateName: 'welcome',
language: locale,
data: {
to: to_address,
templateName: 'welcome',
language: locale,
data: {
name: `${firstname} ${middlename} ${lastname}`,
barcode_content: `${runner_id}`,
link: `${process.env.SELFSERVICE_URL}/profile/${token}`
}
}
})
await axios.request({ await axios.request({
method: 'POST', method: 'POST',
url: `${Mailer.base}/api/v1/email`, url: `${Mailer.base}/api/v1/email`,
@ -96,6 +111,7 @@ export class Mailer {
}); });
} catch (error) { } catch (error) {
if (Mailer.testing) { return true; } if (Mailer.testing) { return true; }
console.error("Error while sending selfservice forgotten mail:", error.message);
throw new MailSendingError(); throw new MailSendingError();
} }
} }

View File

@ -1,8 +1,10 @@
import { import {
IsInt,
IsNotEmpty, IsNotEmpty,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { Column, Entity, PrimaryColumn } from "typeorm"; import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryColumn } from "typeorm";
/** /**
* Defines the ConfigFlag entity. * Defines the ConfigFlag entity.
@ -24,4 +26,25 @@ export class ConfigFlag {
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
value: string; 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);
}
} }

View File

@ -1,7 +1,8 @@
import { import {
IsInt IsInt,
IsPositive
} from "class-validator"; } 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 { ResponseDonation } from '../responses/ResponseDonation';
import { Donor } from './Donor'; import { Donor } from './Donor';
@ -40,6 +41,27 @@ export abstract class Donation {
@IsInt() @IsInt()
paidAmount: number; 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. * Turns this entity into it's response class.
*/ */

View File

@ -5,9 +5,11 @@ import {
IsOptional, IsOptional,
IsPhoneNumber, IsPhoneNumber,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { config } from '../../config'; import { config } from '../../config';
import { ResponseGroupContact } from '../responses/ResponseGroupContact'; import { ResponseGroupContact } from '../responses/ResponseGroupContact';
import { Address } from "./Address"; import { Address } from "./Address";
@ -81,6 +83,27 @@ export class GroupContact {
@OneToMany(() => RunnerGroup, group => group.contact, { nullable: true }) @OneToMany(() => RunnerGroup, group => group.contact, { nullable: true })
groups: RunnerGroup[]; 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. * Turns this entity into it's response class.
*/ */

View File

@ -5,9 +5,11 @@ import {
IsOptional, IsOptional,
IsPhoneNumber, IsPhoneNumber,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { Column, Entity, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryGeneratedColumn, TableInheritance } from "typeorm";
import { config } from '../../config'; import { config } from '../../config';
import { ResponseParticipant } from '../responses/ResponseParticipant'; import { ResponseParticipant } from '../responses/ResponseParticipant';
import { Address } from "./Address"; import { Address } from "./Address";
@ -83,6 +85,27 @@ export abstract class Participant {
@IsString() @IsString()
created_via?: string; created_via?: 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. * Turns this entity into it's response class.
*/ */

View File

@ -1,9 +1,10 @@
import { import {
IsEnum, IsEnum,
IsInt, IsInt,
IsNotEmpty IsNotEmpty,
IsPositive
} from "class-validator"; } 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 { PermissionAction } from '../enums/PermissionAction';
import { PermissionTarget } from '../enums/PermissionTargets'; import { PermissionTarget } from '../enums/PermissionTargets';
import { ResponsePermission } from '../responses/ResponsePermission'; import { ResponsePermission } from '../responses/ResponsePermission';
@ -45,6 +46,27 @@ export class Permission {
@IsEnum(PermissionAction) @IsEnum(PermissionAction)
action: 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. * Turn this into a string for exporting and jwts.
* Mainly used to shrink the size of jwts (otherwise the would contain entire objects). * Mainly used to shrink the size of jwts (otherwise the would contain entire objects).

View File

@ -1,5 +1,5 @@
import { IsInt } from 'class-validator'; import { IsInt, IsPositive } from 'class-validator';
import { Entity, OneToMany, PrimaryGeneratedColumn, TableInheritance } from 'typeorm'; import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn, TableInheritance } from 'typeorm';
import { ResponsePrincipal } from '../responses/ResponsePrincipal'; import { ResponsePrincipal } from '../responses/ResponsePrincipal';
import { Permission } from './Permission'; import { Permission } from './Permission';
@ -23,6 +23,27 @@ export abstract class Principal {
@OneToMany(() => Permission, permission => permission.principal, { nullable: true }) @OneToMany(() => Permission, permission => permission.principal, { nullable: true })
permissions: Permission[]; 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. * Turns this entity into it's response class.
*/ */

View File

@ -3,9 +3,10 @@ import {
IsInt, IsInt,
IsOptional IsOptional,
IsPositive
} from "class-validator"; } 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 { RunnerCardIdOutOfRangeError } from '../../errors/RunnerCardErrors';
import { ResponseRunnerCard } from '../responses/ResponseRunnerCard'; import { ResponseRunnerCard } from '../responses/ResponseRunnerCard';
import { Runner } from "./Runner"; import { Runner } from "./Runner";
@ -48,6 +49,27 @@ export class RunnerCard {
@OneToMany(() => TrackScan, scan => scan.track, { nullable: true }) @OneToMany(() => TrackScan, scan => scan.track, { nullable: true })
scans: TrackScan[]; 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. * Generates a ean-13 compliant string for barcode generation.
*/ */

View File

@ -2,9 +2,10 @@ import {
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
IsPositive,
IsString IsString
} from "class-validator"; } 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 { ResponseRunnerGroup } from '../responses/ResponseRunnerGroup';
import { GroupContact } from "./GroupContact"; import { GroupContact } from "./GroupContact";
import { Runner } from "./Runner"; import { Runner } from "./Runner";
@ -46,6 +47,27 @@ export abstract class RunnerGroup {
@OneToMany(() => Runner, runner => runner.group, { nullable: true }) @OneToMany(() => Runner, runner => runner.group, { nullable: true })
runners: Runner[]; 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. * Returns the total distance ran by this group's runners based on all their valid scans.
*/ */

View File

@ -5,7 +5,7 @@ import {
IsPositive IsPositive
} from "class-validator"; } 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 { ResponseScan } from '../responses/ResponseScan';
import { Runner } from "./Runner"; import { Runner } from "./Runner";
@ -40,6 +40,27 @@ export class Scan {
@IsBoolean() @IsBoolean()
valid: boolean = true; 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. * The scan's distance in meters.
* This is the "real" value used by "normal" scans.. * This is the "real" value used by "normal" scans..

View File

@ -3,9 +3,10 @@ import {
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
IsPositive,
IsString IsString
} from "class-validator"; } 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 { ResponseScanStation } from '../responses/ResponseScanStation';
import { Track } from "./Track"; import { Track } from "./Track";
import { TrackScan } from "./TrackScan"; import { TrackScan } from "./TrackScan";
@ -78,6 +79,27 @@ export class ScanStation {
@IsBoolean() @IsBoolean()
enabled?: boolean = true; 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. * Turns this entity into it's response class.
*/ */

View File

@ -1,5 +1,5 @@
import { IsInt, IsOptional, IsString } from "class-validator"; import { IsInt, IsOptional, IsPositive, IsString } from "class-validator";
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import { ResponseStatsClient } from '../responses/ResponseStatsClient'; import { ResponseStatsClient } from '../responses/ResponseStatsClient';
/** /**
* Defines the StatsClient entity. * Defines the StatsClient entity.
@ -47,6 +47,27 @@ export class StatsClient {
@IsOptional() @IsOptional()
cleartextkey?: string; 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. * Turns this entity into it's response class.
*/ */

View File

@ -5,7 +5,7 @@ import {
IsPositive, IsPositive,
IsString IsString
} from "class-validator"; } 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 { ResponseTrack } from '../responses/ResponseTrack';
import { ScanStation } from "./ScanStation"; import { ScanStation } from "./ScanStation";
import { TrackScan } from "./TrackScan"; import { TrackScan } from "./TrackScan";
@ -63,6 +63,27 @@ export class Track {
@OneToMany(() => TrackScan, scan => scan.track, { nullable: true }) @OneToMany(() => TrackScan, scan => scan.track, { nullable: true })
scans: TrackScan[]; 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. * Turns this entity into it's response class.
*/ */

View File

@ -3,9 +3,10 @@ import {
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
IsPositive,
IsString IsString
} from "class-validator"; } 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 { PermissionAction } from '../enums/PermissionAction';
import { User } from './User'; import { User } from './User';
@ -53,6 +54,27 @@ export class UserAction {
@IsString() @IsString()
changed: string; 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. * Turns this entity into it's response class.
*/ */

View File

@ -40,6 +40,14 @@ export class ResponseAnonymousDonation implements IResponse {
@IsInt() @IsInt()
paidAmount: number; paidAmount: number;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseDonation object from a scan. * Creates a ResponseDonation object from a scan.
* @param donation The donation the response shall be build for. * @param donation The donation the response shall be build for.
@ -54,5 +62,7 @@ export class ResponseAnonymousDonation implements IResponse {
else { else {
this.status = DonationStatus.PAID; this.status = DonationStatus.PAID;
} }
this.created_at = donation.created_at;
this.updated_at = donation.updated_at;
} }
} }

View File

@ -47,6 +47,14 @@ export class ResponseDonation implements IResponse {
@IsInt() @IsInt()
paidAmount: number; paidAmount: number;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseDonation object from a scan. * Creates a ResponseDonation object from a scan.
* @param donation The donation the response shall be build for. * @param donation The donation the response shall be build for.
@ -64,5 +72,7 @@ export class ResponseDonation implements IResponse {
else { else {
this.status = DonationStatus.PAID; this.status = DonationStatus.PAID;
} }
this.created_at = donation.created_at;
this.updated_at = donation.updated_at;
} }
} }

View File

@ -1,4 +1,4 @@
import { IsInt, IsObject, IsString } from "class-validator"; import { IsInt, IsObject, IsPositive, IsString } from "class-validator";
import { Address } from '../entities/Address'; import { Address } from '../entities/Address';
import { GroupContact } from '../entities/GroupContact'; import { GroupContact } from '../entities/GroupContact';
import { ResponseObjectType } from '../enums/ResponseObjectType'; import { ResponseObjectType } from '../enums/ResponseObjectType';
@ -64,6 +64,14 @@ export class ResponseGroupContact implements IResponse {
@IsObject() @IsObject()
address?: Address; address?: Address;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseGroupContact object from a contact. * Creates a ResponseGroupContact object from a contact.
* @param contact The contact the response shall be build for. * @param contact The contact the response shall be build for.
@ -82,5 +90,7 @@ export class ResponseGroupContact implements IResponse {
this.groups.push(group.toResponse()); this.groups.push(group.toResponse());
} }
} }
this.created_at = contact.created_at;
this.updated_at = contact.updated_at;
} }
} }

View File

@ -1,4 +1,4 @@
import { IsInt, IsObject, IsOptional, IsString } from "class-validator"; import { IsInt, IsObject, IsOptional, IsPositive, IsString } from "class-validator";
import { Address } from '../entities/Address'; import { Address } from '../entities/Address';
import { Participant } from '../entities/Participant'; import { Participant } from '../entities/Participant';
import { ResponseObjectType } from '../enums/ResponseObjectType'; import { ResponseObjectType } from '../enums/ResponseObjectType';
@ -63,6 +63,14 @@ export abstract class ResponseParticipant implements IResponse {
@IsObject() @IsObject()
address?: Address; address?: Address;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseParticipant object from a participant. * Creates a ResponseParticipant object from a participant.
* @param participant The participant the response shall be build for. * @param participant The participant the response shall be build for.
@ -76,5 +84,7 @@ export abstract class ResponseParticipant implements IResponse {
this.phone = participant.phone; this.phone = participant.phone;
this.email = participant.email; this.email = participant.email;
this.address = participant.address; this.address = participant.address;
this.created_at = participant.created_at;
this.updated_at = participant.updated_at;
} }
} }

View File

@ -2,7 +2,8 @@ import {
IsEnum, IsEnum,
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsObject IsObject,
IsPositive
} from "class-validator"; } from "class-validator";
import { Permission } from '../entities/Permission'; import { Permission } from '../entities/Permission';
import { PermissionAction } from '../enums/PermissionAction'; import { PermissionAction } from '../enums/PermissionAction';
@ -48,6 +49,14 @@ export class ResponsePermission implements IResponse {
@IsEnum(PermissionAction) @IsEnum(PermissionAction)
action: PermissionAction; action: PermissionAction;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponsePermission object from a permission. * Creates a ResponsePermission object from a permission.
* @param permission The permission the response shall be build for. * @param permission The permission the response shall be build for.
@ -57,5 +66,7 @@ export class ResponsePermission implements IResponse {
this.principal = permission.principal.toResponse(); this.principal = permission.principal.toResponse();
this.target = permission.target; this.target = permission.target;
this.action = permission.action; this.action = permission.action;
this.created_at = permission.created_at;
this.updated_at = permission.updated_at;
} }
} }

View File

@ -1,5 +1,6 @@
import { import {
IsInt IsInt,
IsPositive
} from "class-validator"; } from "class-validator";
import { Principal } from '../entities/Principal'; import { Principal } from '../entities/Principal';
import { ResponseObjectType } from '../enums/ResponseObjectType'; import { ResponseObjectType } from '../enums/ResponseObjectType';
@ -22,11 +23,21 @@ export abstract class ResponsePrincipal implements IResponse {
@IsInt() @IsInt()
id: number; id: number;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponsePrincipal object from a principal. * Creates a ResponsePrincipal object from a principal.
* @param principal The principal the response shall be build for. * @param principal The principal the response shall be build for.
*/ */
public constructor(principal: Principal) { public constructor(principal: Principal) {
this.id = principal.id; this.id = principal.id;
this.created_at = principal.created_at;
this.updated_at = principal.updated_at;
} }
} }

View File

@ -1,4 +1,4 @@
import { IsBoolean, IsEAN, IsInt, IsNotEmpty, IsObject, IsString } from "class-validator"; import { IsBoolean, IsEAN, IsInt, IsNotEmpty, IsObject, IsPositive, IsString } from "class-validator";
import { RunnerCard } from '../entities/RunnerCard'; import { RunnerCard } from '../entities/RunnerCard';
import { ResponseObjectType } from '../enums/ResponseObjectType'; import { ResponseObjectType } from '../enums/ResponseObjectType';
import { IResponse } from './IResponse'; import { IResponse } from './IResponse';
@ -42,6 +42,14 @@ export class ResponseRunnerCard implements IResponse {
@IsBoolean() @IsBoolean()
enabled: boolean = true; enabled: boolean = true;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseRunnerCard object from a runner card. * Creates a ResponseRunnerCard object from a runner card.
* @param card The card the response shall be build for. * @param card The card the response shall be build for.
@ -57,5 +65,7 @@ export class ResponseRunnerCard implements IResponse {
} }
this.enabled = card.enabled; this.enabled = card.enabled;
this.created_at = card.created_at;
this.updated_at = card.updated_at;
} }
} }

View File

@ -1,4 +1,4 @@
import { IsInt, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString } from "class-validator"; import { IsInt, IsNotEmpty, IsNumber, IsObject, IsOptional, IsPositive, IsString } from "class-validator";
import { RunnerGroup } from '../entities/RunnerGroup'; import { RunnerGroup } from '../entities/RunnerGroup';
import { ResponseObjectType } from '../enums/ResponseObjectType'; import { ResponseObjectType } from '../enums/ResponseObjectType';
import { IResponse } from './IResponse'; import { IResponse } from './IResponse';
@ -40,6 +40,14 @@ export abstract class ResponseRunnerGroup implements IResponse {
@IsNumber() @IsNumber()
total_distance: number total_distance: number
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseRunnerGroup object from a runnerGroup. * Creates a ResponseRunnerGroup object from a runnerGroup.
* @param group The runnerGroup the response shall be build for. * @param group The runnerGroup the response shall be build for.
@ -49,5 +57,7 @@ export abstract class ResponseRunnerGroup implements IResponse {
this.name = group.name; this.name = group.name;
if (group.contact) { this.contact = group.contact.toResponse(); }; if (group.contact) { this.contact = group.contact.toResponse(); };
if (group.runners) { this.total_distance = group.runners.reduce((p, c) => p + c.distance, 0) } if (group.runners) { this.total_distance = group.runners.reduce((p, c) => p + c.distance, 0) }
this.created_at = group.created_at;
this.updated_at = group.updated_at;
} }
} }

View File

@ -41,6 +41,14 @@ export class ResponseScan implements IResponse {
@IsPositive() @IsPositive()
distance: number; distance: number;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseScan object from a scan. * Creates a ResponseScan object from a scan.
* @param scan The scan the response shall be build for. * @param scan The scan the response shall be build for.
@ -50,5 +58,7 @@ export class ResponseScan implements IResponse {
if (scan.runner) { this.runner = scan.runner.toResponse(); } if (scan.runner) { this.runner = scan.runner.toResponse(); }
this.distance = scan.distance; this.distance = scan.distance;
this.valid = scan.valid; this.valid = scan.valid;
this.created_at = scan.created_at;
this.updated_at = scan.updated_at;
} }
} }

View File

@ -1,5 +1,4 @@
import { import {
IsBoolean, IsBoolean,
IsInt, IsInt,
@ -8,6 +7,7 @@ import {
IsObject, IsObject,
IsOptional, IsOptional,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { ScanStation } from '../entities/ScanStation'; import { ScanStation } from '../entities/ScanStation';
@ -63,6 +63,14 @@ export class ResponseScanStation implements IResponse {
@IsBoolean() @IsBoolean()
enabled?: boolean = true; enabled?: boolean = true;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseStatsClient object from a statsClient. * Creates a ResponseStatsClient object from a statsClient.
* @param client The statsClient the response shall be build for. * @param client The statsClient the response shall be build for.
@ -74,5 +82,7 @@ export class ResponseScanStation implements IResponse {
this.key = "Only visible on creation."; this.key = "Only visible on creation.";
if (station.track) { this.track = station.track.toResponse(); } if (station.track) { this.track = station.track.toResponse(); }
this.enabled = station.enabled; this.enabled = station.enabled;
this.created_at = station.created_at;
this.updated_at = station.updated_at;
} }
} }

View File

@ -1,10 +1,10 @@
import { import {
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { StatsClient } from '../entities/StatsClient'; import { StatsClient } from '../entities/StatsClient';
@ -49,6 +49,14 @@ export class ResponseStatsClient implements IResponse {
@IsNotEmpty() @IsNotEmpty()
prefix: string; prefix: string;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseStatsClient object from a statsClient. * Creates a ResponseStatsClient object from a statsClient.
* @param client The statsClient the response shall be build for. * @param client The statsClient the response shall be build for.
@ -58,5 +66,7 @@ export class ResponseStatsClient implements IResponse {
this.description = client.description; this.description = client.description;
this.prefix = client.prefix; this.prefix = client.prefix;
this.key = "Only visible on creation."; this.key = "Only visible on creation.";
this.created_at = client.created_at;
this.updated_at = client.updated_at;
} }
} }

View File

@ -1,4 +1,4 @@
import { IsInt, IsOptional, IsString } from "class-validator"; import { IsInt, IsOptional, IsPositive, IsString } from "class-validator";
import { TrackLapTimeCantBeNegativeError } from '../../errors/TrackErrors'; import { TrackLapTimeCantBeNegativeError } from '../../errors/TrackErrors';
import { Track } from '../entities/Track'; import { Track } from '../entities/Track';
import { ResponseObjectType } from '../enums/ResponseObjectType'; import { ResponseObjectType } from '../enums/ResponseObjectType';
@ -40,6 +40,14 @@ export class ResponseTrack implements IResponse {
@IsOptional() @IsOptional()
minimumLapTime?: number; minimumLapTime?: number;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/** /**
* Creates a ResponseTrack object from a track. * Creates a ResponseTrack object from a track.
* @param track The track the response shall be build for. * @param track The track the response shall be build for.
@ -52,5 +60,7 @@ export class ResponseTrack implements IResponse {
if (this.minimumLapTime < 0) { if (this.minimumLapTime < 0) {
throw new TrackLapTimeCantBeNegativeError(); throw new TrackLapTimeCantBeNegativeError();
} }
this.created_at = track.created_at;
this.updated_at = track.updated_at;
} }
} }