Compare commits

..

No commits in common. "dev" and "1.3.8" have entirely different histories.
dev ... 1.3.8

40 changed files with 53 additions and 701 deletions

View File

@ -2,93 +2,9 @@
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 May 2025
- 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 May 2025
- fix(donations): Fixed creation bug [`07a0195`](https://git.odit.services/lfk/backend/commit/07a0195f125519f239d255a0cc081ddbde8f1da3)
- chore(release): 1.4.2 [`f4747c5`](https://git.odit.services/lfk/backend/commit/f4747c51de71d9b28cca1b00a91de3cfd6f0f56e)
#### [1.4.1](https://git.odit.services/lfk/backend/compare/1.4.0...1.4.1)
> 28 April 2025
- chore(release): 1.4.1 [`7ac9822`](https://git.odit.services/lfk/backend/commit/7ac98229d17e7cb019d5dcc5402870490a97f910)
- refactor(auth): Increased token timeouts to 24hrs/7days [`dd5b538`](https://git.odit.services/lfk/backend/commit/dd5b538783f9c806f0c883cd391754fb5c842ec8)
#### [1.4.0](https://git.odit.services/lfk/backend/compare/1.3.12...1.4.0)
> 28 April 2025
- feat(donations): Implement response type to indicate possible missing donor [`f4bf309`](https://git.odit.services/lfk/backend/commit/f4bf309821c140f2bc0ae8b6d96c7458fcc80978)
- wip [`9875b4f`](https://git.odit.services/lfk/backend/commit/9875b4f3926e04b502e7af64c17f54fd3c1d8e3e)
- refactor(donations): Make anon prepaid [`02b1cb9`](https://git.odit.services/lfk/backend/commit/02b1cb9904cc593faeac025ae302a8684f650f5e)
- chore(release): 1.4.0 [`8e6d674`](https://git.odit.services/lfk/backend/commit/8e6d67428c85b6ee504a379ff13a3a951f7b9543)
- fix(donations): Move donor over to the types that need it [`7697acf`](https://git.odit.services/lfk/backend/commit/7697acff82b23d0c05dbbd17fee6e70eb1b7061c)
#### [1.3.12](https://git.odit.services/lfk/backend/compare/1.3.11...1.3.12)
> 28 April 2025
- chore(release): 1.3.12 [`bacfc43`](https://git.odit.services/lfk/backend/commit/bacfc437f97cac6a20c32b79ae2d6391466f78a6)
- refactor: make Donation.donor optional [`2ab6e98`](https://git.odit.services/lfk/backend/commit/2ab6e985e356f0f3d8637d81630d191cc11b8806)
- refactor(config): improve consola error logs [`ce9b765`](https://git.odit.services/lfk/backend/commit/ce9b765b81b014623e79ce64d8d835f1f86cecf3)
#### [1.3.11](https://git.odit.services/lfk/backend/compare/1.3.10...1.3.11)
> 17 April 2025
- feat(RunnerController): add selfservice_links parameter to getRunners method [`a50d72f`](https://git.odit.services/lfk/backend/commit/a50d72f2f5281b8c28ca64a0970161a35a7af95a)
- chore(release): 1.3.11 [`d06f6a4`](https://git.odit.services/lfk/backend/commit/d06f6a44072971d1853411b255f9b49eb423b3a2)
#### [1.3.10](https://git.odit.services/lfk/backend/compare/1.3.9...1.3.10)
> 11 April 2025
- chore(release): 1.3.10 [`4723d97`](https://git.odit.services/lfk/backend/commit/4723d9738eacd63fb41f23c628fbe4181bd126de)
- feat(RunnerController.getAll): debug created_via query param filter [`1a478bd`](https://git.odit.services/lfk/backend/commit/1a478bd784e01b9d5a1c6635d1004a9535c9a0e9)
#### [1.3.9](https://git.odit.services/lfk/backend/compare/1.3.8...1.3.9)
> 9 April 2025
- feat(RunnerController.getAll): add created_via query param filter [`6e63c57`](https://git.odit.services/lfk/backend/commit/6e63c57936f06a29da5f1a94b1141d51b75df5f0)
- chore(release): 1.3.9 [`284cb0f`](https://git.odit.services/lfk/backend/commit/284cb0f8b3955d0d65c2b36d2ec427a39752ffe7)
#### [1.3.8](https://git.odit.services/lfk/backend/compare/1.3.7...1.3.8) #### [1.3.8](https://git.odit.services/lfk/backend/compare/1.3.7...1.3.8)
> 9 April 2025
- feat(RunnerCardController): putByCode [`8237d5f`](https://git.odit.services/lfk/backend/commit/8237d5f21067c0872a7eff7c8d1506edf44ec10c) - feat(RunnerCardController): putByCode [`8237d5f`](https://git.odit.services/lfk/backend/commit/8237d5f21067c0872a7eff7c8d1506edf44ec10c)
- chore(release): 1.3.8 [`30b61db`](https://git.odit.services/lfk/backend/commit/30b61db2c160c019bac381f26cefdc6524ea465e)
#### [1.3.7](https://git.odit.services/lfk/backend/compare/1.3.6...1.3.7) #### [1.3.7](https://git.odit.services/lfk/backend/compare/1.3.6...1.3.7)

View File

@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-backend", "name": "@odit/lfk-backend",
"version": "1.5.2", "version": "1.3.8",
"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

@ -1,4 +1,3 @@
import consola from 'consola';
import { config as configDotenv } from 'dotenv'; import { config as configDotenv } from 'dotenv';
import { CountryCode } from 'libphonenumber-js'; import { CountryCode } from 'libphonenumber-js';
import ValidatorJS from 'validator'; import ValidatorJS from 'validator';
@ -21,15 +20,12 @@ export const config = {
} }
let errors = 0 let errors = 0
if (typeof config.internal_port !== "number") { if (typeof config.internal_port !== "number") {
consola.error("Error: APP_PORT is not a number")
errors++ errors++
} }
if (typeof config.development !== "boolean") { if (typeof config.development !== "boolean") {
consola.error("Error: NODE_ENV is not a boolean")
errors++ errors++
} }
if (config.mailer_url == "" || config.mailer_key == "") { if (config.mailer_url == "" || config.mailer_key == "") {
consola.error("Error: invalid mailer config")
errors++; errors++;
} }
function getPhoneCodeLocale(): CountryCode { function getPhoneCodeLocale(): CountryCode {

View File

@ -4,7 +4,6 @@ import { Repository, getConnectionManager } from 'typeorm';
import { DonationIdsNotMatchingError, DonationNotFoundError } from '../errors/DonationErrors'; import { DonationIdsNotMatchingError, DonationNotFoundError } from '../errors/DonationErrors';
import { DonorNotFoundError } from '../errors/DonorErrors'; import { DonorNotFoundError } from '../errors/DonorErrors';
import { RunnerNotFoundError } from '../errors/RunnerErrors'; import { RunnerNotFoundError } from '../errors/RunnerErrors';
import { CreateAnonymousDonation } from '../models/actions/create/CreateAnonymousDonation';
import { CreateDistanceDonation } from '../models/actions/create/CreateDistanceDonation'; import { CreateDistanceDonation } from '../models/actions/create/CreateDistanceDonation';
import { CreateFixedDonation } from '../models/actions/create/CreateFixedDonation'; import { CreateFixedDonation } from '../models/actions/create/CreateFixedDonation';
import { UpdateDistanceDonation } from '../models/actions/update/UpdateDistanceDonation'; import { UpdateDistanceDonation } from '../models/actions/update/UpdateDistanceDonation';
@ -12,7 +11,6 @@ import { UpdateFixedDonation } from '../models/actions/update/UpdateFixedDonatio
import { DistanceDonation } from '../models/entities/DistanceDonation'; import { DistanceDonation } from '../models/entities/DistanceDonation';
import { Donation } from '../models/entities/Donation'; import { Donation } from '../models/entities/Donation';
import { FixedDonation } from '../models/entities/FixedDonation'; import { FixedDonation } from '../models/entities/FixedDonation';
import { ResponseAnonymousDonation } from '../models/responses/ResponseAnonymousDonation';
import { ResponseDistanceDonation } from '../models/responses/ResponseDistanceDonation'; import { ResponseDistanceDonation } from '../models/responses/ResponseDistanceDonation';
import { ResponseDonation } from '../models/responses/ResponseDonation'; import { ResponseDonation } from '../models/responses/ResponseDonation';
import { ResponseEmpty } from '../models/responses/ResponseEmpty'; import { ResponseEmpty } from '../models/responses/ResponseEmpty';
@ -37,7 +35,6 @@ export class DonationController {
@Authorized("DONATION:GET") @Authorized("DONATION:GET")
@ResponseSchema(ResponseDonation, { isArray: true }) @ResponseSchema(ResponseDonation, { isArray: true })
@ResponseSchema(ResponseDistanceDonation, { isArray: true }) @ResponseSchema(ResponseDistanceDonation, { isArray: true })
@ResponseSchema(ResponseAnonymousDonation, { isArray: true })
@OpenAPI({ description: 'Lists all donations (fixed or distance based) from all donors. <br> This includes the donations\'s runner\'s distance ran(if distance donation).' }) @OpenAPI({ description: 'Lists all donations (fixed or distance based) from all donors. <br> This includes the donations\'s runner\'s distance ran(if distance donation).' })
async getAll(@QueryParam("page", { required: false }) page: number, @QueryParam("page_size", { required: false }) page_size: number = 100) { async getAll(@QueryParam("page", { required: false }) page: number, @QueryParam("page_size", { required: false }) page_size: number = 100) {
let responseDonations: ResponseDonation[] = new Array<ResponseDonation>(); let responseDonations: ResponseDonation[] = new Array<ResponseDonation>();
@ -59,7 +56,6 @@ export class DonationController {
@Authorized("DONATION:GET") @Authorized("DONATION:GET")
@ResponseSchema(ResponseDonation) @ResponseSchema(ResponseDonation)
@ResponseSchema(ResponseDistanceDonation) @ResponseSchema(ResponseDistanceDonation)
@ResponseSchema(ResponseAnonymousDonation)
@ResponseSchema(DonationNotFoundError, { statusCode: 404 }) @ResponseSchema(DonationNotFoundError, { statusCode: 404 })
@OnUndefined(DonationNotFoundError) @OnUndefined(DonationNotFoundError)
@OpenAPI({ description: 'Lists all information about the donation whose id got provided. This includes the donation\'s runner\'s distance ran (if distance donation).' }) @OpenAPI({ description: 'Lists all information about the donation whose id got provided. This includes the donation\'s runner\'s distance ran (if distance donation).' })
@ -80,17 +76,6 @@ export class DonationController {
return (await this.donationRepository.findOne({ id: donation.id }, { relations: ['donor'] })).toResponse(); return (await this.donationRepository.findOne({ id: donation.id }, { relations: ['donor'] })).toResponse();
} }
@Post('/anonymous')
@Authorized("DONATION:CREATE")
@ResponseSchema(ResponseDonation)
@ResponseSchema(DonorNotFoundError, { statusCode: 404 })
@OpenAPI({ description: 'Create a anonymous donation' })
async postAnonymous(@Body({ validate: true }) createDonation: CreateAnonymousDonation) {
let donation = await createDonation.toEntity();
donation = await this.fixedDonationRepository.save(donation);
return (await this.donationRepository.findOne({ id: donation.id })).toResponse();
}
@Post('/distance') @Post('/distance')
@Authorized("DONATION:CREATE") @Authorized("DONATION:CREATE")
@ResponseSchema(ResponseDistanceDonation) @ResponseSchema(ResponseDistanceDonation)

View File

@ -30,11 +30,10 @@ export class RunnerController {
@Authorized("RUNNER:GET") @Authorized("RUNNER:GET")
@ResponseSchema(ResponseRunner, { isArray: true }) @ResponseSchema(ResponseRunner, { isArray: true })
@OpenAPI({ description: 'Lists all runners from all teams/orgs. <br> This includes the runner\'s group and distance ran.' }) @OpenAPI({ description: 'Lists all runners from all teams/orgs. <br> This includes the runner\'s group and distance ran.' })
async getAll(@QueryParam("page", { required: false }) page: number, @QueryParam("page_size", { required: false }) page_size: number = 100, @QueryParam("created_via", { required: false }) created_via: string = "all", @QueryParam("selfservice_links", { required: false }) selfservice_links: boolean = false) { async getAll(@QueryParam("page", { required: false }) page: number, @QueryParam("page_size", { required: false }) page_size: number = 100, @QueryParam("selfservice_links", { required: false }) selfservice_links: boolean = false) {
let responseRunners: ResponseRunner[] = new Array<ResponseRunner>(); let responseRunners: ResponseRunner[] = new Array<ResponseRunner>();
let runners: Array<Runner>; let runners: Array<Runner>;
console.log("call to RunnerController.getAll() with page: " + page + " and page_size: " + page_size + " and created_via: " + created_via + " and selfservice_links: " + selfservice_links);
if (page != undefined) { if (page != undefined) {
runners = await this.runnerRepository.find({ relations: ['scans', 'group', 'group.parentGroup', 'scans.track'], skip: page * page_size, take: page_size }); runners = await this.runnerRepository.find({ relations: ['scans', 'group', 'group.parentGroup', 'scans.track'], skip: page * page_size, take: page_size });
} else { } else {
@ -42,13 +41,7 @@ export class RunnerController {
} }
runners.forEach(runner => { runners.forEach(runner => {
if (created_via === "all") { responseRunners.push(new ResponseRunner(runner, selfservice_links));
responseRunners.push(new ResponseRunner(runner, selfservice_links));
} else {
if (runner.created_via === created_via) {
responseRunners.push(new ResponseRunner(runner, selfservice_links));
}
}
}); });
return responseRunners; return responseRunners;
} }
@ -60,7 +53,7 @@ export class RunnerController {
@OnUndefined(RunnerNotFoundError) @OnUndefined(RunnerNotFoundError)
@OpenAPI({ description: 'Lists all information about the runner whose id got provided.' }) @OpenAPI({ description: 'Lists all information about the runner whose id got provided.' })
async getOne(@Param('id') id: number) { async getOne(@Param('id') id: number) {
let runner = await this.runnerRepository.findOne({ id: id }, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards', 'distanceDonations'] }) let runner = await this.runnerRepository.findOne({ id: id }, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards'] })
if (!runner) { throw new RunnerNotFoundError(); } if (!runner) { throw new RunnerNotFoundError(); }
return new ResponseRunner(runner, true); return new ResponseRunner(runner, true);
} }

View File

@ -62,13 +62,13 @@ export class RunnerOrganizationController {
@ResponseSchema(ResponseRunner, { isArray: true }) @ResponseSchema(ResponseRunner, { isArray: true })
@ResponseSchema(RunnerOrganizationNotFoundError, { statusCode: 404 }) @ResponseSchema(RunnerOrganizationNotFoundError, { statusCode: 404 })
@OpenAPI({ description: 'Lists all runners from this org and it\'s teams (if you don\'t provide the ?onlyDirect=true param). <br> This includes the runner\'s group and distance ran.' }) @OpenAPI({ description: 'Lists all runners from this org and it\'s teams (if you don\'t provide the ?onlyDirect=true param). <br> This includes the runner\'s group and distance ran.' })
async getRunners(@Param('id') id: number, @QueryParam('onlyDirect') onlyDirect: boolean, @QueryParam("selfservice_links", { required: false }) selfservice_links: boolean = false) { async getRunners(@Param('id') id: number, @QueryParam('onlyDirect') onlyDirect: boolean) {
let responseRunners: ResponseRunner[] = new Array<ResponseRunner>(); let responseRunners: ResponseRunner[] = new Array<ResponseRunner>();
let runners: Runner[]; let runners: Runner[];
if (!onlyDirect) { runners = (await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['runners', 'runners.group', 'runners.group.parentGroup', 'runners.scans', 'runners.scans.track', 'teams', 'teams.runners', 'teams.runners.group', 'teams.runners.group.parentGroup', 'teams.runners.scans', 'teams.runners.scans.track'] })).allRunners; } if (!onlyDirect) { runners = (await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['runners', 'runners.group', 'runners.group.parentGroup', 'runners.scans', 'runners.scans.track', 'teams', 'teams.runners', 'teams.runners.group', 'teams.runners.group.parentGroup', 'teams.runners.scans', 'teams.runners.scans.track'] })).allRunners; }
else { runners = (await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['runners', 'runners.group', 'runners.group.parentGroup', 'runners.scans', 'runners.scans.track'] })).runners; } else { runners = (await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['runners', 'runners.group', 'runners.group.parentGroup', 'runners.scans', 'runners.scans.track'] })).runners; }
runners.forEach(runner => { runners.forEach(runner => {
responseRunners.push(new ResponseRunner(runner, selfservice_links)); responseRunners.push(new ResponseRunner(runner));
}); });
return responseRunners; return responseRunners;
} }

View File

@ -60,11 +60,11 @@ export class RunnerTeamController {
@ResponseSchema(ResponseRunner, { isArray: true }) @ResponseSchema(ResponseRunner, { isArray: true })
@ResponseSchema(RunnerTeamNotFoundError, { statusCode: 404 }) @ResponseSchema(RunnerTeamNotFoundError, { statusCode: 404 })
@OpenAPI({ description: 'Lists all runners from this team. <br> This includes the runner\'s group and distance ran.' }) @OpenAPI({ description: 'Lists all runners from this team. <br> This includes the runner\'s group and distance ran.' })
async getRunners(@Param('id') id: number, @QueryParam("selfservice_links", { required: false }) selfservice_links: boolean = false) { async getRunners(@Param('id') id: number) {
let responseRunners: ResponseRunner[] = new Array<ResponseRunner>(); let responseRunners: ResponseRunner[] = new Array<ResponseRunner>();
const runners = (await this.runnerTeamRepository.findOne({ id: id }, { relations: ['runners', 'runners.group', 'runners.group.parentGroup', 'runners.scans', 'runners.scans.track'] })).runners; const runners = (await this.runnerTeamRepository.findOne({ id: id }, { relations: ['runners', 'runners.group', 'runners.group.parentGroup', 'runners.scans', 'runners.scans.track'] })).runners;
runners.forEach(runner => { runners.forEach(runner => {
responseRunners.push(new ResponseRunner(runner, selfservice_links)); responseRunners.push(new ResponseRunner(runner));
}); });
return responseRunners; return responseRunners;
} }

View File

@ -76,21 +76,6 @@ 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`,
@ -111,7 +96,6 @@ 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,29 +0,0 @@
import { IsInt, IsPositive } from 'class-validator';
import { FixedDonation } from '../../entities/FixedDonation';
import { CreateDonation } from './CreateDonation';
/**
* This class is used to create a new FixedDonation entity from a json body (post request).
*/
export class CreateAnonymousDonation extends CreateDonation {
/**
* The donation's amount.
* The unit is your currency's smallest unit (default: euro cent).
*/
@IsInt()
@IsPositive()
amount: number;
/**
* Creates a new FixedDonation entity from this.
*/
public async toEntity(): Promise<FixedDonation> {
let newDonation = new FixedDonation;
newDonation.amount = this.amount;
newDonation.paidAmount = this.amount;
return newDonation;
}
}

View File

@ -61,11 +61,11 @@ export class CreateAuth {
} }
//Create the access token //Create the access token
const timestamp_accesstoken_expiry = Math.floor(Date.now() / 1000) + 24 * 60 * 60 const timestamp_accesstoken_expiry = Math.floor(Date.now() / 1000) + 5 * 60
newAuth.access_token = JwtCreator.createAccess(found_user, timestamp_accesstoken_expiry); newAuth.access_token = JwtCreator.createAccess(found_user, timestamp_accesstoken_expiry);
newAuth.access_token_expires_at = timestamp_accesstoken_expiry newAuth.access_token_expires_at = timestamp_accesstoken_expiry
//Create the refresh token //Create the refresh token
const timestamp_refresh_expiry = Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60 const timestamp_refresh_expiry = Math.floor(Date.now() / 1000) + 10 * 36000
newAuth.refresh_token = JwtCreator.createRefresh(found_user, timestamp_refresh_expiry); newAuth.refresh_token = JwtCreator.createRefresh(found_user, timestamp_refresh_expiry);
newAuth.refresh_token_expires_at = timestamp_refresh_expiry newAuth.refresh_token_expires_at = timestamp_refresh_expiry
return newAuth; return newAuth;

View File

@ -1,4 +1,4 @@
import { IsInt, IsOptional, IsPositive } from 'class-validator'; import { IsInt, IsPositive } from 'class-validator';
import { getConnection } from 'typeorm'; import { getConnection } from 'typeorm';
import { RunnerNotFoundError } from '../../../errors/RunnerErrors'; import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
import { DistanceDonation } from '../../entities/DistanceDonation'; import { DistanceDonation } from '../../entities/DistanceDonation';
@ -10,21 +10,6 @@ import { CreateDonation } from './CreateDonation';
*/ */
export class CreateDistanceDonation extends CreateDonation { export class CreateDistanceDonation extends CreateDonation {
/**
* The donation's associated donor's id.
* This is important to link donations to donors.
*/
@IsInt()
@IsPositive()
donor: number;
/**
* The donation's paid amount in the smalles unit of your currency (default: euro cent).
*/
@IsInt()
@IsOptional()
paidAmount?: number;
/** /**
* The donation's associated runner's id. * The donation's associated runner's id.
* This is important to link the runner's distance ran to the donation. * This is important to link the runner's distance ran to the donation.

View File

@ -1,5 +1,6 @@
import { IsInt, IsOptional } from 'class-validator'; import { IsInt, IsOptional, IsPositive } from 'class-validator';
import { getConnection } from 'typeorm'; import { getConnection } from 'typeorm';
import { DonorNotFoundError } from '../../../errors/DonorErrors';
import { Donation } from '../../entities/Donation'; import { Donation } from '../../entities/Donation';
import { Donor } from '../../entities/Donor'; import { Donor } from '../../entities/Donor';
@ -7,10 +8,17 @@ import { Donor } from '../../entities/Donor';
* This class is used to create a new Donation entity from a json body (post request). * This class is used to create a new Donation entity from a json body (post request).
*/ */
export abstract class CreateDonation { export abstract class CreateDonation {
/**
* The donation's associated donor's id.
* This is important to link donations to donors.
*/
@IsInt() @IsInt()
@IsOptional() @IsPositive()
donor: number; donor: number;
/**
* The donation's paid amount in the smalles unit of your currency (default: euro cent).
*/
@IsInt() @IsInt()
@IsOptional() @IsOptional()
paidAmount?: number; paidAmount?: number;
@ -25,6 +33,9 @@ export abstract class CreateDonation {
*/ */
public async getDonor(): Promise<Donor> { public async getDonor(): Promise<Donor> {
const donor = await getConnection().getRepository(Donor).findOne({ id: this.donor }); const donor = await getConnection().getRepository(Donor).findOne({ id: this.donor });
if (!donor) {
throw new DonorNotFoundError();
}
return donor; return donor;
} }
} }

View File

@ -6,21 +6,6 @@ import { CreateDonation } from './CreateDonation';
* This class is used to create a new FixedDonation entity from a json body (post request). * This class is used to create a new FixedDonation entity from a json body (post request).
*/ */
export class CreateFixedDonation extends CreateDonation { export class CreateFixedDonation extends CreateDonation {
/**
* The donation's associated donor's id.
* This is important to link donations to donors.
*/
@IsInt()
@IsPositive()
donor: number;
/**
* The donation's paid amount in the smalles unit of your currency (default: euro cent).
*/
@IsInt()
paidAmount?: number;
/** /**
* The donation's amount. * The donation's amount.
* The unit is your currency's smallest unit (default: euro cent). * The unit is your currency's smallest unit (default: euro cent).

View File

@ -1,10 +1,8 @@
import { import {
IsInt,
IsNotEmpty, IsNotEmpty,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryColumn } from "typeorm"; import { Column, Entity, PrimaryColumn } from "typeorm";
/** /**
* Defines the ConfigFlag entity. * Defines the ConfigFlag entity.
@ -26,25 +24,4 @@ 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,8 +1,8 @@
import { import {
IsInt, IsInt,
IsPositive IsNotEmpty
} from "class-validator"; } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { 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';
@ -24,6 +24,7 @@ export abstract class Donation {
/** /**
* The donations's donor. * The donations's donor.
*/ */
@IsNotEmpty()
@ManyToOne(() => Donor, donor => donor.donations) @ManyToOne(() => Donor, donor => donor.donations)
donor: Donor; donor: Donor;
@ -41,27 +42,6 @@ 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,11 +5,9 @@ import {
IsOptional, IsOptional,
IsPhoneNumber, IsPhoneNumber,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { 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";
@ -83,27 +81,6 @@ 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,11 +5,9 @@ import {
IsOptional, IsOptional,
IsPhoneNumber, IsPhoneNumber,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { 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";
@ -85,27 +83,6 @@ 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,10 +1,9 @@
import { import {
IsEnum, IsEnum,
IsInt, IsInt,
IsNotEmpty, IsNotEmpty
IsPositive
} from "class-validator"; } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; import { 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';
@ -46,27 +45,6 @@ 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, IsPositive } from 'class-validator'; import { IsInt } from 'class-validator';
import { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn, TableInheritance } from 'typeorm'; import { 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,27 +23,6 @@ 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

@ -84,6 +84,6 @@ export class Runner extends Participant {
* Turns this entity into it's response class. * Turns this entity into it's response class.
*/ */
public toResponse(): ResponseRunner { public toResponse(): ResponseRunner {
return new ResponseRunner(this, true); return new ResponseRunner(this);
} }
} }

View File

@ -3,10 +3,9 @@ import {
IsInt, IsInt,
IsOptional, IsOptional
IsPositive
} from "class-validator"; } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { 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";
@ -49,27 +48,6 @@ 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,10 +2,9 @@ import {
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { 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";
@ -47,27 +46,6 @@ 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 { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { 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,27 +40,6 @@ 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,10 +3,9 @@ import {
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { 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";
@ -79,27 +78,6 @@ 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, IsPositive, IsString } from "class-validator"; import { IsInt, IsOptional, IsString } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryGeneratedColumn } from "typeorm"; import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import { ResponseStatsClient } from '../responses/ResponseStatsClient'; import { ResponseStatsClient } from '../responses/ResponseStatsClient';
/** /**
* Defines the StatsClient entity. * Defines the StatsClient entity.
@ -47,27 +47,6 @@ 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 { BeforeInsert, BeforeUpdate, Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { 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,27 +63,6 @@ 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,10 +3,9 @@ import {
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
IsPositive,
IsString IsString
} from "class-validator"; } from "class-validator";
import { BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
import { PermissionAction } from '../enums/PermissionAction'; import { PermissionAction } from '../enums/PermissionAction';
import { User } from './User'; import { User } from './User';
@ -54,27 +53,6 @@ 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

@ -1,68 +0,0 @@
import { IsInt, IsPositive } from "class-validator";
import { Donation } from '../entities/Donation';
import { DonationStatus } from '../enums/DonationStatus';
import { ResponseObjectType } from '../enums/ResponseObjectType';
import { IResponse } from './IResponse';
/**
* Defines the donation response.
*/
export class ResponseAnonymousDonation implements IResponse {
/**
* The responseType.
* This contains the type of class/entity this response contains.
*/
responseType: ResponseObjectType = ResponseObjectType.DONATION;
/**
* The donation's payment status.
* Provides you with a quick indicator of it's payment status.
*/
status: DonationStatus;
/**
* The donation's id.
*/
@IsInt()
@IsPositive()
id: number;
/**
* The donation's amount in the smalles unit of your currency (default: euro cent).
*/
@IsInt()
amount: number;
/**
* The donation's paid amount in the smalles unit of your currency (default: euro cent).
*/
@IsInt()
paidAmount: number;
@IsInt()
@IsPositive()
created_at: number;
@IsInt()
@IsPositive()
updated_at: number;
/**
* Creates a ResponseDonation object from a scan.
* @param donation The donation the response shall be build for.
*/
public constructor(donation: Donation) {
this.id = donation.id;
this.amount = donation.amount;
this.paidAmount = donation.paidAmount || 0;
if (this.paidAmount < this.amount) {
this.status = DonationStatus.OPEN;
}
else {
this.status = DonationStatus.PAID;
}
this.created_at = donation.created_at;
this.updated_at = donation.updated_at;
}
}

View File

@ -47,14 +47,6 @@ 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.
@ -72,7 +64,5 @@ 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, IsPositive, IsString } from "class-validator"; import { IsInt, IsObject, 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,14 +64,6 @@ 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.
@ -90,7 +82,5 @@ 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, IsPositive, IsString } from "class-validator"; import { IsInt, IsObject, IsOptional, 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,14 +63,6 @@ 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.
@ -84,7 +76,5 @@ 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,8 +2,7 @@ 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';
@ -49,14 +48,6 @@ 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.
@ -66,7 +57,5 @@ 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,6 +1,5 @@
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';
@ -23,21 +22,11 @@ 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

@ -27,13 +27,6 @@ export class ResponseRunner extends ResponseParticipant implements IResponse {
@IsInt() @IsInt()
distance: number; distance: number;
/**
* The runner's current donation amount based on distance.
* Only available for queries for single runners.
*/
@IsInt()
donationAmount: number;
/** /**
* The runner's group. * The runner's group.
*/ */
@ -57,10 +50,6 @@ export class ResponseRunner extends ResponseParticipant implements IResponse {
else { this.distance = runner.validScans.reduce((sum, current) => sum + current.distance, 0); } else { this.distance = runner.validScans.reduce((sum, current) => sum + current.distance, 0); }
if (runner.group) { this.group = runner.group.toResponse(); } if (runner.group) { this.group = runner.group.toResponse(); }
if (runner.distanceDonations) {
this.donationAmount = runner.distanceDonations.reduce((sum, current) => sum + (current.amountPerDistance * runner.distance / 1000), 0);
}
if (generateSelfServiceLink) { if (generateSelfServiceLink) {
const token = JwtCreator.createSelfService(runner); const token = JwtCreator.createSelfService(runner);
this.selfserviceLink = `${process.env.SELFSERVICE_URL}/profile/${token}`; this.selfserviceLink = `${process.env.SELFSERVICE_URL}/profile/${token}`;

View File

@ -1,4 +1,4 @@
import { IsBoolean, IsEAN, IsInt, IsNotEmpty, IsObject, IsPositive, IsString } from "class-validator"; import { IsBoolean, IsEAN, IsInt, IsNotEmpty, IsObject, 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,14 +42,6 @@ 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.
@ -65,7 +57,5 @@ 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, IsPositive, IsString } from "class-validator"; import { IsInt, IsNotEmpty, IsNumber, IsObject, IsOptional, 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,14 +40,6 @@ 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.
@ -57,7 +49,5 @@ 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,14 +41,6 @@ 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.
@ -58,7 +50,5 @@ 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,4 +1,5 @@
import { import {
IsBoolean, IsBoolean,
IsInt, IsInt,
@ -7,7 +8,6 @@ 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,14 +63,6 @@ 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.
@ -82,7 +74,5 @@ 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,14 +49,6 @@ 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.
@ -66,7 +58,5 @@ 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, IsPositive, IsString } from "class-validator"; import { IsInt, IsOptional, 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,14 +40,6 @@ 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.
@ -60,7 +52,5 @@ 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;
} }
} }