Compare commits

...

22 Commits

Author SHA1 Message Date
a54cb287a4 🚀Bumped version to v1.1.4 2024-11-20 19:00:19 +01:00
74d334f9b7 fix(dependencies): Switch back to previous class-validator version to produce a working build 2024-11-20 18:59:50 +01:00
cd3cd81360 fix(deps): Bump sqlite3
All checks were successful
ci/woodpecker/push/build Pipeline was successful
2023-11-06 20:32:05 +01:00
cf48c00ddb fix(deps): Bumped argon2 to latest version for arm support
Some checks failed
ci/woodpecker/push/build Pipeline failed
2023-11-06 20:23:32 +01:00
3192365793 feat(ci)!: Switch to woodpecker
Some checks failed
ci/woodpecker/push/build Pipeline failed
2023-11-06 20:15:44 +01:00
075d484f11 ci: drop lfk-client-node 2023-11-06 18:09:31 +01:00
5082b1b8b1 fix: updated README for pnpm, typos 2023-11-06 18:04:32 +01:00
50dd703a1b build: package lock 2023-11-06 18:01:15 +01:00
057a8ee699 🚀Bumped version to v1.1.3
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-10 13:38:14 +02:00
8d9418635d feat(orgs): Also resolve child-teams' distances and add them to org total 2023-05-10 13:37:54 +02:00
f2832a2dae fix(orgs): Removed unused log 2023-05-10 13:36:05 +02:00
0d21596e2b 🚀Bumped version to v1.1.2
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-10 13:16:33 +02:00
245827e9c6 feat(groups): Resolve the total group distance on group get single (aka get org and get team) 2023-05-10 13:15:59 +02:00
4608a36df6 chore(package): Formatting 2023-05-10 13:15:21 +02:00
cb1305aa77 🚀Bumped version to v1.1.1
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 18:10:52 +02:00
12a9ae2493 feat(donors): Resolve donations with donors via pagination 2023-04-19 18:10:26 +02:00
b9fe9f1c24 🚀Bumped version to v1.1.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 15:48:16 +02:00
b25b0db760 Added hints 2023-04-19 15:47:54 +02:00
fe59e3a557 Added average donation per distance to stats 2023-04-19 15:46:50 +02:00
42c23a5883 Formatting 2023-04-19 15:45:34 +02:00
6ee5328dbc Added calls to controller 2023-04-19 15:41:49 +02:00
6f39ac42da feat(stats): Added donation count and donor count to stats 2023-04-19 15:41:43 +02:00
19 changed files with 7944 additions and 208 deletions

View File

@@ -1,180 +0,0 @@
---
kind: secret
name: docker_username
get:
path: odit-registry-builder
name: username
---
kind: secret
name: docker_password
get:
path: odit-registry-builder
name: password
---
kind: secret
name: git_ssh
get:
path: odit-git-bot
name: sshkey
---
kind: secret
name: ci_token
get:
path: odit-ci-bot
name: apikey
---
kind: secret
name: npm_url
get:
path: odit-npm-cache
name: url
---
kind: pipeline
type: kubernetes
name: tests:node
clone:
disable: true
steps:
- name: checkout pr
image: alpine/git
commands:
- git clone $DRONE_REMOTE_URL .
- git checkout $DRONE_SOURCE_BRANCH
- name: run tests
image: registry.odit.services/hub/library/node:19.5.0-alpine3.16
commands:
- npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8
- pnpm i
- pnpm test:ci
environment:
NPM_REGISTRY_URL:
from_secret: npm_url
trigger:
event:
- pull_request
---
kind: pipeline
type: kubernetes
name: build:dev
clone:
disable: true
steps:
- name: clone
image: alpine/git
commands:
- git clone $DRONE_REMOTE_URL .
- git checkout dev
- name: build dev
depends_on: ["clone"]
image: registry.odit.services/library/drone-kaniko
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
build_args:
- NPM_REGISTRY_URL:
from_secret: npm_url
repo: lfk/backend
tags:
- dev
cache: true
registry: registry.odit.services
trigger:
branch:
- dev
event:
- push
---
kind: pipeline
type: kubernetes
name: build:latest
clone:
disable: true
steps:
- name: clone
image: alpine/git
commands:
- git clone $DRONE_REMOTE_URL .
- git checkout dev
- git merge main
- git checkout main
- name: build latest
depends_on: ["clone"]
image: registry.odit.services/library/drone-kaniko
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
build_args:
- NPM_REGISTRY_URL:
from_secret: npm_url
repo: lfk/backend
tags:
- latest
cache: true
registry: registry.odit.services
- name: push merge to repo
depends_on: ["clone"]
image: appleboy/drone-git-push
settings:
branch: dev
commit: false
remote: git@git.odit.services:lfk/backend.git
ssh_key:
from_secret: git_ssh
trigger:
branch:
- main
event:
- push
---
kind: pipeline
type: kubernetes
name: build:tags
steps:
- name: build $DRONE_TAG
depends_on: ["clone"]
image: registry.odit.services/library/drone-kaniko
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
build_args:
- NPM_REGISTRY_URL:
from_secret: npm_url
repo: lfk/backend
tags:
- "${DRONE_TAG}"
cache: true
registry: registry.odit.services
- name: trigger node lib build
image: idcooldi/drone-webhook
settings:
urls: https://ci.odit.services/api/repos/lfk/lfk-client-node/builds?SOURCE_TAG=${DRONE_TAG}
bearer:
from_secret: ci_token
- name: trigger js lib build
image: idcooldi/drone-webhook
settings:
urls: https://ci.odit.services/api/repos/lfk/lfk-client-js/builds?SOURCE_TAG=${DRONE_TAG}
bearer:
from_secret: ci_token
trigger:
event:
- tag

1
.gitignore vendored
View File

@@ -136,4 +136,3 @@ build
lib lib
/oss-attribution /oss-attribution
*.tmp *.tmp
pnpm-lock.yaml

39
.woodpecker/build.yml Normal file
View File

@@ -0,0 +1,39 @@
steps:
- name: build latest
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/backend
tags:
- latest
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/backend:latest
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
secrets:
- source: odit-npm-cache-url
target: NPM_REGISTRY_URL
when:
branch: main
- name: build dev
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/backend
tags:
- dev
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/backend:dev
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
secrets:
- source: odit-npm-cache-url
target: NPM_REGISTRY_URL
when:
branch: dev
when:
event: push

29
.woodpecker/release.yml Normal file
View File

@@ -0,0 +1,29 @@
steps:
- name: build tag
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/backend
tags:
- "${CI_COMMIT_TAG}"
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/backend:latest
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
secrets:
- source: odit-npm-cache-url
target: NPM_REGISTRY_URL
- name: trigger js lib build
image: woodpeckerci/plugin-trigger
settings:
repositories:
- lfk/lfk-client-js
params:
- "SOURCE_TAG=${CI_COMMIT_TAG}"
token:
from_secret: odit-ci-bot-apikey
when:
event: tag

13
.woodpecker/testpr.yml Normal file
View File

@@ -0,0 +1,13 @@
steps:
- name: playwright tests
image: registry.odit.services/hub/library/node:19.5.0-alpine3.16
commands:
- npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8
- pnpm i
- pnpm test:ci
secrets:
- source: odit-npm-cache-url
target: NPM_REGISTRY_URL
when:
event:
- pull_request

View File

@@ -2,9 +2,56 @@
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.
#### [v1.1.4](https://git.odit.services/lfk/backend/compare/v1.1.3...v1.1.4)
- build: package lock [`50dd703`](https://git.odit.services/lfk/backend/commit/50dd703a1bd276a607cc10a087c7e90fd880847a)
- fix(deps): Bump sqlite3 [`cd3cd81`](https://git.odit.services/lfk/backend/commit/cd3cd81360777e8bc4d78e861354e58c8da79cc7)
- feat(ci)!: Switch to woodpecker [`3192365`](https://git.odit.services/lfk/backend/commit/3192365793fae59f2b89e3231db298654f0a28e9)
- fix(deps): Bumped argon2 to latest version for arm support [`cf48c00`](https://git.odit.services/lfk/backend/commit/cf48c00ddb2ac33263549876928db50ae152c12d)
- fix: updated README for pnpm, typos [`5082b1b`](https://git.odit.services/lfk/backend/commit/5082b1b8b1c0ae9e8ffa9c71c4d7923fd9223c87)
- ci: drop lfk-client-node [`075d484`](https://git.odit.services/lfk/backend/commit/075d484f1169bfc5c5b68cb9712116b0e270b471)
- fix(dependencies): Switch back to previous class-validator version to produce a working build [`74d334f`](https://git.odit.services/lfk/backend/commit/74d334f9b747a77115bd9b97729ef1120822e128)
#### [v1.1.3](https://git.odit.services/lfk/backend/compare/v1.1.2...v1.1.3)
> 10 May 2023
- 🚀Bumped version to v1.1.3 [`057a8ee`](https://git.odit.services/lfk/backend/commit/057a8ee699d08c0e4a80cb50a8820f819569c9ac)
- feat(orgs): Also resolve child-teams' distances and add them to org total [`8d94186`](https://git.odit.services/lfk/backend/commit/8d9418635d3e381c0f55a2521a3334ba497c169a)
- fix(orgs): Removed unused log [`f2832a2`](https://git.odit.services/lfk/backend/commit/f2832a2daecc7bc7bbee4d4fceeab8db194730cf)
#### [v1.1.2](https://git.odit.services/lfk/backend/compare/v1.1.1...v1.1.2)
> 10 May 2023
- 🚀Bumped version to v1.1.2 [`0d21596`](https://git.odit.services/lfk/backend/commit/0d21596e2b64a99258d4925ae2ad627d5cdbd984)
- feat(groups): Resolve the total group distance on group get single (aka get org and get team) [`245827e`](https://git.odit.services/lfk/backend/commit/245827e9c659cf76183dc33ab253becc22ddf032)
- chore(package): Formatting [`4608a36`](https://git.odit.services/lfk/backend/commit/4608a36df6b187520ca0c331b8dce615205257be)
#### [v1.1.1](https://git.odit.services/lfk/backend/compare/v1.1.0...v1.1.1)
> 19 April 2023
- feat(donors): Resolve donations with donors via pagination [`12a9ae2`](https://git.odit.services/lfk/backend/commit/12a9ae24933117acb3ff9815a7d72abca5eea7a7)
- 🚀Bumped version to v1.1.1 [`cb1305a`](https://git.odit.services/lfk/backend/commit/cb1305aa77c36aa9d7900f09e7413bc6d45f2c89)
#### [v1.1.0](https://git.odit.services/lfk/backend/compare/v1.0.1...v1.1.0)
> 19 April 2023
- feat(stats): Added donation count and donor count to stats [`6f39ac4`](https://git.odit.services/lfk/backend/commit/6f39ac42dafc2a589bbb2256b0417f3e774ae174)
- 🚀Bumped version to v1.1.0 [`b9fe9f1`](https://git.odit.services/lfk/backend/commit/b9fe9f1c24653b91255a6dbbdc32c30b1b411eeb)
- Added average donation per distance to stats [`fe59e3a`](https://git.odit.services/lfk/backend/commit/fe59e3a557903cf555d4c50098e935c49ca1fac4)
- Added hints [`b25b0db`](https://git.odit.services/lfk/backend/commit/b25b0db76071ef8d50cc60e950a399dc060a2a9f)
- Added calls to controller [`6ee5328`](https://git.odit.services/lfk/backend/commit/6ee5328dbc404603d19db3a5173ae4def560a9c9)
- Formatting [`42c23a5`](https://git.odit.services/lfk/backend/commit/42c23a5883dacda4e0147842d448b3ad35b197b1)
#### [v1.0.1](https://git.odit.services/lfk/backend/compare/v1.0.0...v1.0.1) #### [v1.0.1](https://git.odit.services/lfk/backend/compare/v1.0.0...v1.0.1)
> 18 April 2023
- fix(pagination) page=0 resulted in false thx JS [`fcee390`](https://git.odit.services/lfk/backend/commit/fcee3909f4c4664115cc7ecb94f30e0dd8e78ce0) - fix(pagination) page=0 resulted in false thx JS [`fcee390`](https://git.odit.services/lfk/backend/commit/fcee3909f4c4664115cc7ecb94f30e0dd8e78ce0)
- 🚀Bumped version to v1.0.1 [`301f334`](https://git.odit.services/lfk/backend/commit/301f33467489a8533bdac11fbd10efd1b791f5e3)
### [v1.0.0](https://git.odit.services/lfk/backend/compare/v0.15.4...v1.0.0) ### [v1.0.0](https://git.odit.services/lfk/backend/compare/v0.15.4...v1.0.0)

View File

@@ -1,5 +1,5 @@
# Typescript Build # Typescript Build
FROM registry.odit.services/hub/library/node:19.5.0-alpine3.16 as build FROM registry.odit.services/hub/library/node:21.1.0-alpine3.18 as build
ARG NPM_REGISTRY_URL=https://registry.npmjs.org ARG NPM_REGISTRY_URL=https://registry.npmjs.org
WORKDIR /app WORKDIR /app
@@ -14,7 +14,7 @@ RUN pnpm run build \
&& pnpm i --production --prefer-offline && pnpm i --production --prefer-offline
# final image # final image
FROM registry.odit.services/hub/library/node:19.5.0-alpine3.16 as final FROM registry.odit.services/hub/library/node:21.1.0-alpine3.18 as final
WORKDIR /app WORKDIR /app
COPY --from=build /app/package.json /app/package.json COPY --from=build /app/package.json /app/package.json
COPY --from=build /app/ormconfig.js /app/ormconfig.js COPY --from=build /app/ormconfig.js /app/ormconfig.js

View File

@@ -16,23 +16,23 @@ Backend Server
1. Rename the .env.example file to .env (you can adjust app port and other settings, if needed) 1. Rename the .env.example file to .env (you can adjust app port and other settings, if needed)
2. Install Dependencies 2. Install Dependencies
```bash ```bash
yarn pnpm i
``` ```
3. Start the server 3. Start the server
```bash ```bash
yarn dev pnpm dev
``` ```
### Run Tests ### Run Tests
```bash ```bash
# Run tests once (server has to run) # Run tests once (server has to run)
yarn test pnpm test
# Run test in watch mode (reruns on change) # Run test in watch mode (reruns on change)
yarn test:watch pnpm test:watch
# Run test in ci mode (automaticly starts the dev server) # Run test in ci mode (automaticly starts the dev server)
yarn test:ci pnpm test:ci
``` ```
### Use your own mail templates ### Use your own mail templates
@@ -44,7 +44,7 @@ Currently the following templates exist:
### Generate Docs ### Generate Docs
```bash ```bash
yarn docs pnpm docs
``` ```
## ENV Vars ## ENV Vars
@@ -90,5 +90,5 @@ yarn docs
* The dev tag of the docker image get's build from this * The dev tag of the docker image get's build from this
* Only push minor changes to this branch! * Only push minor changes to this branch!
* To merge a feature branch into this please create a pull request * To merge a feature branch into this please create a pull request
* feature/xyz: Feature branches - nameing scheme: `feature/issueid-title` * feature/xyz: Feature branches - naming scheme: `feature/issueid-title`
* bugfix/xyz: Branches for bugfixes - nameing scheme:`bugfix/issueid-title` * bugfix/xyz: Branches for bugfixes - naming scheme:`bugfix/issueid-title`

View File

@@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-backend", "name": "@odit/lfk-backend",
"version": "1.0.1", "version": "1.1.4",
"main": "src/app.ts", "main": "src/app.ts",
"repository": "https://git.odit.services/lfk/backend", "repository": "https://git.odit.services/lfk/backend",
"engines": { "engines": {
@@ -26,12 +26,12 @@
"license": "CC-BY-NC-SA-4.0", "license": "CC-BY-NC-SA-4.0",
"dependencies": { "dependencies": {
"@odit/class-validator-jsonschema": "2.1.1", "@odit/class-validator-jsonschema": "2.1.1",
"argon2": "0.27.1", "argon2": "0.31.2",
"axios": "0.21.1", "axios": "0.21.1",
"body-parser": "1.19.0", "body-parser": "1.19.0",
"check-password-strength": "2.0.2", "check-password-strength": "2.0.2",
"class-transformer": "0.3.1", "class-transformer": "0.3.1",
"class-validator": "0.13.1", "class-validator": "0.13.0",
"consola": "2.15.0", "consola": "2.15.0",
"cookie": "0.4.1", "cookie": "0.4.1",
"cookie-parser": "1.4.5", "cookie-parser": "1.4.5",
@@ -46,7 +46,7 @@
"reflect-metadata": "0.1.13", "reflect-metadata": "0.1.13",
"routing-controllers": "0.9.0-alpha.6", "routing-controllers": "0.9.0-alpha.6",
"routing-controllers-openapi": "2.2.0", "routing-controllers-openapi": "2.2.0",
"sqlite3": "5.0.0", "sqlite3": "5.1.6",
"typeorm": "0.2.30", "typeorm": "0.2.30",
"typeorm-routing-controllers-extensions": "0.2.0", "typeorm-routing-controllers-extensions": "0.2.0",
"typeorm-seeding": "1.6.1", "typeorm-seeding": "1.6.1",
@@ -54,7 +54,7 @@
"validator": "13.5.2" "validator": "13.5.2"
}, },
"devDependencies": { "devDependencies": {
"@faker-js/faker": "^7.6.0", "@faker-js/faker": "7.6.0",
"@odit/license-exporter": "0.0.9", "@odit/license-exporter": "0.0.9",
"@types/cors": "2.8.9", "@types/cors": "2.8.9",
"@types/csvtojson": "1.1.5", "@types/csvtojson": "1.1.5",
@@ -63,7 +63,7 @@
"@types/jsonwebtoken": "8.5.0", "@types/jsonwebtoken": "8.5.0",
"@types/node": "14.14.22", "@types/node": "14.14.22",
"@types/uuid": "8.3.0", "@types/uuid": "8.3.0",
"auto-changelog": "^2.4.0", "auto-changelog": "2.4.0",
"cp-cli": "2.0.0", "cp-cli": "2.0.0",
"jest": "26.6.3", "jest": "26.6.3",
"nodemon": "2.0.7", "nodemon": "2.0.7",

7744
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -52,7 +52,7 @@ export class RunnerOrganizationController {
@OnUndefined(RunnerOrganizationNotFoundError) @OnUndefined(RunnerOrganizationNotFoundError)
@OpenAPI({ description: 'Lists all information about the organization whose id got provided.' }) @OpenAPI({ description: 'Lists all information about the organization whose id got provided.' })
async getOne(@Param('id') id: number) { async getOne(@Param('id') id: number) {
let runnerOrg = await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['contact', 'teams'] }); let runnerOrg = await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['contact', 'teams', 'teams.runners', 'teams.runners.scans', 'teams.runners.scans.track', 'runners', 'runners.scans', 'runners.scans.track'] });
if (!runnerOrg) { throw new RunnerOrganizationNotFoundError(); } if (!runnerOrg) { throw new RunnerOrganizationNotFoundError(); }
return new ResponseRunnerOrganization(runnerOrg); return new ResponseRunnerOrganization(runnerOrg);
} }

View File

@@ -50,7 +50,7 @@ export class RunnerTeamController {
@OnUndefined(RunnerTeamNotFoundError) @OnUndefined(RunnerTeamNotFoundError)
@OpenAPI({ description: 'Lists all information about the team whose id got provided.' }) @OpenAPI({ description: 'Lists all information about the team whose id got provided.' })
async getOne(@Param('id') id: number) { async getOne(@Param('id') id: number) {
let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact'] }); let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact', 'runners', 'runners.scans', 'runners.scans.track'] });
if (!runnerTeam) { throw new RunnerTeamNotFoundError(); } if (!runnerTeam) { throw new RunnerTeamNotFoundError(); }
return new ResponseRunnerTeam(runnerTeam); return new ResponseRunnerTeam(runnerTeam);
} }

View File

@@ -3,6 +3,7 @@ import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnection } from 'typeorm'; import { getConnection } from 'typeorm';
import StatsAuth from '../middlewares/StatsAuth'; import StatsAuth from '../middlewares/StatsAuth';
import { Donation } from '../models/entities/Donation'; import { Donation } from '../models/entities/Donation';
import { Donor } from '../models/entities/Donor';
import { Runner } from '../models/entities/Runner'; import { Runner } from '../models/entities/Runner';
import { RunnerOrganization } from '../models/entities/RunnerOrganization'; import { RunnerOrganization } from '../models/entities/RunnerOrganization';
import { RunnerTeam } from '../models/entities/RunnerTeam'; import { RunnerTeam } from '../models/entities/RunnerTeam';
@@ -27,6 +28,7 @@ export class StatsController {
const orgs = await connection.getRepository(RunnerOrganization).count(); const orgs = await connection.getRepository(RunnerOrganization).count();
const users = await connection.getRepository(User).count(); const users = await connection.getRepository(User).count();
const scans = await connection.getRepository(Scan).count({ where: { valid: true } }); const scans = await connection.getRepository(Scan).count({ where: { valid: true } });
const distance_query = await connection.getRepository(Scan).createQueryBuilder('scan') const distance_query = await connection.getRepository(Scan).createQueryBuilder('scan')
.leftJoinAndSelect("scan.track", "track").where("scan.valid = TRUE") .leftJoinAndSelect("scan.track", "track").where("scan.valid = TRUE")
.select("SUM(track.distance)", "sum_track").addSelect("SUM(_distance)", "sum_distance") .select("SUM(track.distance)", "sum_track").addSelect("SUM(_distance)", "sum_distance")
@@ -35,8 +37,11 @@ export class StatsController {
if (distance_query.sum_distance) { if (distance_query.sum_distance) {
distace += parseInt(distance_query.sum_distance) distace += parseInt(distance_query.sum_distance)
} }
let donations = await connection.getRepository(Donation).find({ relations: ['runner', 'runner.scans', 'runner.scans.track'] }); let donations = await connection.getRepository(Donation).find({ relations: ['runner', 'runner.scans', 'runner.scans.track'] });
return new ResponseStats(runners, teams, orgs, users, scans, donations, distace) const donors = await connection.getRepository(Donor).count();
return new ResponseStats(runners, teams, orgs, users, scans, donations, distace, donors)
} }
@Get("/runners/distance") @Get("/runners/distance")

View File

@@ -53,7 +53,9 @@ export class ResponseDonation implements IResponse {
*/ */
public constructor(donation: Donation) { public constructor(donation: Donation) {
this.id = donation.id; this.id = donation.id;
if (donation.donor) {
this.donor = donation.donor.toResponse(); this.donor = donation.donor.toResponse();
}
this.amount = donation.amount; this.amount = donation.amount;
this.paidAmount = donation.paidAmount || 0; this.paidAmount = donation.paidAmount || 0;
if (this.paidAmount < this.amount) { if (this.paidAmount < this.amount) {

View File

@@ -4,6 +4,7 @@ import {
import { Donor } from '../entities/Donor'; import { Donor } from '../entities/Donor';
import { ResponseObjectType } from '../enums/ResponseObjectType'; import { ResponseObjectType } from '../enums/ResponseObjectType';
import { IResponse } from './IResponse'; import { IResponse } from './IResponse';
import { ResponseDonation } from './ResponseDonation';
import { ResponseParticipant } from './ResponseParticipant'; import { ResponseParticipant } from './ResponseParticipant';
/** /**
@@ -34,6 +35,8 @@ export class ResponseDonor extends ResponseParticipant implements IResponse {
@IsInt() @IsInt()
paidDonationAmount: number; paidDonationAmount: number;
donations: Array<ResponseDonation>;
/** /**
* Creates a ResponseRunner object from a runner. * Creates a ResponseRunner object from a runner.
* @param runner The user the response shall be build for. * @param runner The user the response shall be build for.
@@ -43,5 +46,11 @@ export class ResponseDonor extends ResponseParticipant implements IResponse {
this.receiptNeeded = donor.receiptNeeded; this.receiptNeeded = donor.receiptNeeded;
this.donationAmount = donor.donationAmount; this.donationAmount = donor.donationAmount;
this.paidDonationAmount = donor.paidDonationAmount; this.paidDonationAmount = donor.paidDonationAmount;
this.donations = new Array<ResponseDonation>();
if (donor.donations?.length > 0) {
for (const donation of donor.donations) {
this.donations.push(donation.toResponse())
}
}
} }
} }

View File

@@ -1,4 +1,4 @@
import { IsInt, IsNotEmpty, IsObject, IsOptional, 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';
@@ -36,6 +36,10 @@ export abstract class ResponseRunnerGroup implements IResponse {
@IsOptional() @IsOptional()
contact?: ResponseGroupContact; contact?: ResponseGroupContact;
@IsOptional()
@IsNumber()
total_distance: 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.
@@ -44,5 +48,6 @@ export abstract class ResponseRunnerGroup implements IResponse {
this.id = group.id; this.id = group.id;
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) }
} }
} }

View File

@@ -67,6 +67,9 @@ export class ResponseRunnerOrganization extends ResponseRunnerGroup implements I
for (let team of org.teams) { for (let team of org.teams) {
this.teams.push(team.toResponse()); this.teams.push(team.toResponse());
} }
for (const team of this.teams) {
this.total_distance += team.total_distance;
}
} }
if (!org.key) { this.registrationEnabled = false; } if (!org.key) { this.registrationEnabled = false; }

View File

@@ -58,12 +58,30 @@ export class ResponseStats implements IResponse {
@IsInt() @IsInt()
total_donation: number; total_donation: number;
/**
* The total donation count (cent).
*/
@IsInt()
total_donations: number;
/**
* The total donor count.
*/
@IsInt()
total_donors: number;
/** /**
* The average distance ran per runner. * The average distance ran per runner.
*/ */
@IsInt() @IsInt()
average_distance: number; average_distance: number;
/**
* The average donation per distance (cent).
*/
@IsInt()
average_donation: number;
/** /**
* Creates a new stats response containing some basic statistics for a dashboard or public display. * Creates a new stats response containing some basic statistics for a dashboard or public display.
* @param runners Array containing all runners - the following relations have to be resolved: scans, scans.track * @param runners Array containing all runners - the following relations have to be resolved: scans, scans.track
@@ -73,7 +91,7 @@ export class ResponseStats implements IResponse {
* @param scans Array containing all scans - no relations have to be resolved. * @param scans Array containing all scans - no relations have to be resolved.
* @param donations Array containing all donations - the following relations have to be resolved: runner, runner.scans, runner.scans.track * @param donations Array containing all donations - the following relations have to be resolved: runner, runner.scans, runner.scans.track
*/ */
public constructor(runners: number, teams: number, orgs: number, users: number, scans: number, donations: Donation[], distance: number) { public constructor(runners: number, teams: number, orgs: number, users: number, scans: number, donations: Donation[], distance: number, donors: number) {
this.total_runners = runners; this.total_runners = runners;
this.total_teams = teams; this.total_teams = teams;
this.total_orgs = orgs; this.total_orgs = orgs;
@@ -81,6 +99,9 @@ export class ResponseStats implements IResponse {
this.total_scans = scans; this.total_scans = scans;
this.total_distance = distance; this.total_distance = distance;
this.total_donation = donations.reduce((sum, current) => sum + current.amount, 0); this.total_donation = donations.reduce((sum, current) => sum + current.amount, 0);
this.total_donations = donations.length;
this.average_donation = this.total_donation / this.total_donations
this.total_donors = donors;
this.average_distance = this.total_distance / this.total_runners; this.average_distance = this.total_distance / this.total_runners;
} }
} }

View File

@@ -11,7 +11,7 @@ import { PermissionAction } from '../models/enums/PermissionAction';
import { PermissionTarget } from '../models/enums/PermissionTargets'; import { PermissionTarget } from '../models/enums/PermissionTargets';
/** /**
* Seeds a admin group with a demo user into the database for initial setup and auto recovery. * Seeds a admin group with a demo user into the database for initial setup and auto recovery.
* We know that the nameing isn't perfectly fitting. Feel free to change it. * We know that the naming isn't perfectly fitting. Feel free to change it.
*/ */
export default class SeedUsers implements Seeder { export default class SeedUsers implements Seeder {
public async run(factory: Factory, connection: Connection): Promise<any> { public async run(factory: Factory, connection: Connection): Promise<any> {