Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
bacfc437f9
|
|||
|
ce9b765b81
|
|||
|
2ab6e985e3
|
|||
|
d06f6a4407
|
|||
|
a50d72f2f5
|
|||
|
4723d9738e
|
|||
|
1a478bd784
|
|||
|
284cb0f8b3
|
|||
|
6e63c57936
|
|||
|
30b61db2c1
|
|||
|
8237d5f210
|
36
CHANGELOG.md
36
CHANGELOG.md
@@ -2,9 +2,45 @@
|
|||||||
|
|
||||||
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.3.12](https://git.odit.services/lfk/backend/compare/1.3.11...1.3.12)
|
||||||
|
|
||||||
|
- 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)
|
||||||
|
|
||||||
|
> 9 April 2025
|
||||||
|
|
||||||
|
- 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)
|
||||||
|
|
||||||
|
> 8 April 2025
|
||||||
|
|
||||||
- feat(stats): Publish runners by kiosk stat [`a6afba9`](https://git.odit.services/lfk/backend/commit/a6afba93e243ca419c282a16cad023d06d864e0e)
|
- feat(stats): Publish runners by kiosk stat [`a6afba9`](https://git.odit.services/lfk/backend/commit/a6afba93e243ca419c282a16cad023d06d864e0e)
|
||||||
|
- chore(release): 1.3.7 [`03e0a29`](https://git.odit.services/lfk/backend/commit/03e0a290965648579956ac1f8e8542c97a667ed8)
|
||||||
|
|
||||||
#### [1.3.6](https://git.odit.services/lfk/backend/compare/1.3.5...1.3.6)
|
#### [1.3.6](https://git.odit.services/lfk/backend/compare/1.3.5...1.3.6)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@odit/lfk-backend",
|
"name": "@odit/lfk-backend",
|
||||||
"version": "1.3.7",
|
"version": "1.3.12",
|
||||||
"main": "src/app.ts",
|
"main": "src/app.ts",
|
||||||
"repository": "https://git.odit.services/lfk/backend",
|
"repository": "https://git.odit.services/lfk/backend",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
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';
|
||||||
@@ -20,12 +21,15 @@ 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 {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { RunnerCardHasScansError, RunnerCardIdsNotMatchingError, RunnerCardNotFo
|
|||||||
import { RunnerNotFoundError } from '../errors/RunnerErrors';
|
import { RunnerNotFoundError } from '../errors/RunnerErrors';
|
||||||
import { CreateRunnerCard } from '../models/actions/create/CreateRunnerCard';
|
import { CreateRunnerCard } from '../models/actions/create/CreateRunnerCard';
|
||||||
import { UpdateRunnerCard } from '../models/actions/update/UpdateRunnerCard';
|
import { UpdateRunnerCard } from '../models/actions/update/UpdateRunnerCard';
|
||||||
|
import { UpdateRunnerCardByCode } from '../models/actions/update/UpdateRunnerCardByCode';
|
||||||
import { RunnerCard } from '../models/entities/RunnerCard';
|
import { RunnerCard } from '../models/entities/RunnerCard';
|
||||||
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
||||||
import { ResponseRunnerCard } from '../models/responses/ResponseRunnerCard';
|
import { ResponseRunnerCard } from '../models/responses/ResponseRunnerCard';
|
||||||
@@ -112,6 +113,28 @@ export class RunnerCardController {
|
|||||||
return (await this.cardRepository.findOne({ id: id }, { relations: ['runner', 'runner.group', 'runner.group.parentGroup'] })).toResponse();
|
return (await this.cardRepository.findOne({ id: id }, { relations: ['runner', 'runner.group', 'runner.group.parentGroup'] })).toResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Put('/:code')
|
||||||
|
@Authorized("CARD:UPDATE")
|
||||||
|
@ResponseSchema(ResponseRunnerCard)
|
||||||
|
@ResponseSchema(RunnerCardNotFoundError, { statusCode: 404 })
|
||||||
|
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
|
||||||
|
@ResponseSchema(RunnerCardIdsNotMatchingError, { statusCode: 406 })
|
||||||
|
@OpenAPI({ description: "Update the card whose code you provided." })
|
||||||
|
async putByCode(@Param('code') code: string, @Body({ validate: true }) card: UpdateRunnerCardByCode) {
|
||||||
|
let oldCard = await this.cardRepository.findOne({ code: code });
|
||||||
|
|
||||||
|
if (!oldCard) {
|
||||||
|
throw new RunnerCardNotFoundError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldCard.code != card.code) {
|
||||||
|
throw new RunnerCardIdsNotMatchingError();
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.cardRepository.save(await card.update(oldCard));
|
||||||
|
return (await this.cardRepository.findOne({ code: code }, { relations: ['runner', 'runner.group', 'runner.group.parentGroup'] })).toResponse();
|
||||||
|
}
|
||||||
|
|
||||||
@Delete('/:id')
|
@Delete('/:id')
|
||||||
@Authorized("CARD:DELETE")
|
@Authorized("CARD:DELETE")
|
||||||
@ResponseSchema(ResponseRunnerCard)
|
@ResponseSchema(ResponseRunnerCard)
|
||||||
|
|||||||
@@ -30,10 +30,11 @@ 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("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("created_via", { required: false }) created_via: string = "all", @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 {
|
||||||
@@ -41,7 +42,13 @@ export class RunnerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runners.forEach(runner => {
|
runners.forEach(runner => {
|
||||||
responseRunners.push(new ResponseRunner(runner, selfservice_links));
|
if (created_via === "all") {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
async getRunners(@Param('id') id: number, @QueryParam('onlyDirect') onlyDirect: boolean, @QueryParam("selfservice_links", { required: false }) selfservice_links: boolean = false) {
|
||||||
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));
|
responseRunners.push(new ResponseRunner(runner, selfservice_links));
|
||||||
});
|
});
|
||||||
return responseRunners;
|
return responseRunners;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
async getRunners(@Param('id') id: number, @QueryParam("selfservice_links", { required: false }) selfservice_links: boolean = false) {
|
||||||
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));
|
responseRunners.push(new ResponseRunner(runner, selfservice_links));
|
||||||
});
|
});
|
||||||
return responseRunners;
|
return responseRunners;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { IsInt, IsOptional, IsPositive } 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';
|
||||||
|
|
||||||
@@ -14,6 +13,7 @@ export abstract class CreateDonation {
|
|||||||
*/
|
*/
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@IsPositive()
|
@IsPositive()
|
||||||
|
@IsOptional()
|
||||||
donor: number;
|
donor: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,9 +33,6 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
50
src/models/actions/update/UpdateRunnerCardByCode.ts
Normal file
50
src/models/actions/update/UpdateRunnerCardByCode.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { IsBoolean, IsInt, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||||
|
import { getConnection } from 'typeorm';
|
||||||
|
import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
|
||||||
|
import { Runner } from '../../entities/Runner';
|
||||||
|
import { RunnerCard } from '../../entities/RunnerCard';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to update a RunnerCard entity (via put request).
|
||||||
|
*/
|
||||||
|
export class UpdateRunnerCardByCode {
|
||||||
|
/**
|
||||||
|
* The card's code.
|
||||||
|
*/
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
code?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The runner's id.
|
||||||
|
*/
|
||||||
|
@IsInt()
|
||||||
|
@IsOptional()
|
||||||
|
runner?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the updated card enabled (for fraud reasons)?
|
||||||
|
* Default: true
|
||||||
|
*/
|
||||||
|
@IsBoolean()
|
||||||
|
enabled: boolean = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new RunnerCard entity from this.
|
||||||
|
*/
|
||||||
|
public async update(card: RunnerCard): Promise<RunnerCard> {
|
||||||
|
card.enabled = this.enabled;
|
||||||
|
card.runner = await this.getRunner();
|
||||||
|
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getRunner(): Promise<Runner> {
|
||||||
|
if (!this.runner) { return null; }
|
||||||
|
const runner = await getConnection().getRepository(Runner).findOne({ id: this.runner });
|
||||||
|
if (!runner) {
|
||||||
|
throw new RunnerNotFoundError();
|
||||||
|
}
|
||||||
|
return runner;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
IsInt,
|
IsInt
|
||||||
IsNotEmpty
|
|
||||||
} from "class-validator";
|
} from "class-validator";
|
||||||
import { 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';
|
||||||
@@ -24,7 +23,6 @@ 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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
return new ResponseRunner(this, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user