@@ -10,7 +10,8 @@ import { Participant } from "./Participant";
 | 
				
			|||||||
import { RunnerOrganisation } from "./RunnerOrganisation";
 | 
					import { RunnerOrganisation } from "./RunnerOrganisation";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a address (to be used for contact information).
 | 
					 * Defines the Address entity.
 | 
				
			||||||
 | 
					 * Implemented this way to prevent any formatting differences.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
export class Address {
 | 
					export class Address {
 | 
				
			||||||
@@ -23,6 +24,7 @@ export class Address {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The address's description.
 | 
					   * The address's description.
 | 
				
			||||||
 | 
					   * Optional and mostly for UX.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
@@ -49,6 +51,8 @@ export class Address {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The address's postal code.
 | 
					   * The address's postal code.
 | 
				
			||||||
 | 
					   * This will get checked against the postal code syntax for the configured country.
 | 
				
			||||||
 | 
					   * TODO: Implement the config option. 
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,19 +4,21 @@ import { Donation } from "./Donation";
 | 
				
			|||||||
import { Runner } from "./Runner";
 | 
					import { Runner } from "./Runner";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a distance based donation.
 | 
					 * Defines the DistanceDonation entity.
 | 
				
			||||||
 * Here people donate a certain amout per kilometer
 | 
					 * For distanceDonations a donor pledges to donate a certain amount for each kilometer ran by a runner.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ChildEntity()
 | 
					@ChildEntity()
 | 
				
			||||||
export class DistanceDonation extends Donation {
 | 
					export class DistanceDonation extends Donation {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The runner associated.
 | 
					   * The donation's associated runner.
 | 
				
			||||||
 | 
					   * Used as the source of the donation's distance.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
  @ManyToOne(() => Runner, runner => runner.distanceDonations)
 | 
					  @ManyToOne(() => Runner, runner => runner.distanceDonations)
 | 
				
			||||||
  runner: Runner;
 | 
					  runner: Runner;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
 | 
					   * The donation's amount donated per distance.
 | 
				
			||||||
   * The amount the donor set to be donated per kilometer that the runner ran.
 | 
					   * The amount the donor set to be donated per kilometer that the runner ran.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
@@ -26,12 +28,12 @@ export class DistanceDonation extends Donation {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The donation's amount in cents (or whatever your currency's smallest unit is.).
 | 
					   * The donation's amount in cents (or whatever your currency's smallest unit is.).
 | 
				
			||||||
   * The exact implementation may differ for each type of donation.
 | 
					   * Get's calculated from the runner's distance ran and the amount donated per kilometer.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public get amount(): number {
 | 
					  public get amount(): number {
 | 
				
			||||||
    let calculatedAmount = -1;
 | 
					    let calculatedAmount = -1;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      calculatedAmount = this.amountPerDistance * this.runner.distance;
 | 
					      calculatedAmount = this.amountPerDistance * (this.runner.distance / 1000);
 | 
				
			||||||
    } catch (error) {
 | 
					    } catch (error) {
 | 
				
			||||||
      throw error;
 | 
					      throw error;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,9 @@ import { Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typ
 | 
				
			|||||||
import { Participant } from "./Participant";
 | 
					import { Participant } from "./Participant";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines the donation interface.
 | 
					 * Defines the Donation entity.
 | 
				
			||||||
 | 
					 * A donation just associates a donor with a donation amount.
 | 
				
			||||||
 | 
					 * The specifics of the amoun's determination has to be implemented in child classes.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
					@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,13 +3,13 @@ import { ChildEntity, Column } from "typeorm";
 | 
				
			|||||||
import { Participant } from "./Participant";
 | 
					import { Participant } from "./Participant";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a donor.
 | 
					 * Defines the Donor entity.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ChildEntity()
 | 
					@ChildEntity()
 | 
				
			||||||
export class Donor extends Participant {
 | 
					export class Donor extends Participant {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Does this donor need a receipt?.
 | 
					   * Does this donor need a receipt?
 | 
				
			||||||
   * Default: false
 | 
					   * Will later be used to automaticly generate donation receipts.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsBoolean()
 | 
					  @IsBoolean()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,8 @@ import { ChildEntity, Column } from "typeorm";
 | 
				
			|||||||
import { Donation } from "./Donation";
 | 
					import { Donation } from "./Donation";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a fixed donation.
 | 
					 * Defines the FixedDonation entity.
 | 
				
			||||||
 | 
					 * In the past there was no easy way to track fixed donations (eg. for creating donation receipts).
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ChildEntity()
 | 
					@ChildEntity()
 | 
				
			||||||
export class FixedDonation extends Donation {
 | 
					export class FixedDonation extends Donation {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,8 @@ import { Address } from "./Address";
 | 
				
			|||||||
import { RunnerGroup } from "./RunnerGroup";
 | 
					import { RunnerGroup } from "./RunnerGroup";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a group's contact.
 | 
					 * Defines the GroupContact entity.
 | 
				
			||||||
 | 
					 * Mainly it's own class to reduce duplicate code and enable contact's to be associated with multiple groups.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
export class GroupContact {
 | 
					export class GroupContact {
 | 
				
			||||||
@@ -34,7 +35,6 @@ export class GroupContact {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The contact's middle name.
 | 
					   * The contact's middle name.
 | 
				
			||||||
   * Optional
 | 
					 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
@@ -51,7 +51,7 @@ export class GroupContact {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The contact's address.
 | 
					   * The contact's address.
 | 
				
			||||||
   * Optional
 | 
					   * This is a address object to prevent any formatting differences.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
  @ManyToOne(() => Address, address => address.participants, { nullable: true })
 | 
					  @ManyToOne(() => Address, address => address.participants, { nullable: true })
 | 
				
			||||||
@@ -59,7 +59,7 @@ export class GroupContact {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The contact's phone number.
 | 
					   * The contact's phone number.
 | 
				
			||||||
   * Optional
 | 
					   * This will be validated against the configured country phone numer syntax (default: international).
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
@@ -68,7 +68,7 @@ export class GroupContact {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The contact's email address.
 | 
					   * The contact's email address.
 | 
				
			||||||
   * Optional
 | 
					   * Could later be used to automaticly send mails concerning the contact's associated groups.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,8 @@ import { Address } from "./Address";
 | 
				
			|||||||
import { Donation } from "./Donation";
 | 
					import { Donation } from "./Donation";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines the participant interface.
 | 
					 * Defines the Participant entity.
 | 
				
			||||||
 | 
					 * Participans can donate and therefor be associated with donation entities.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
					@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
				
			||||||
@@ -35,7 +36,6 @@ export abstract class Participant {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The participant's middle name.
 | 
					   * The participant's middle name.
 | 
				
			||||||
   * Optional
 | 
					 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
@@ -52,14 +52,14 @@ export abstract class Participant {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The participant's address.
 | 
					   * The participant's address.
 | 
				
			||||||
   * Optional
 | 
					   * This is a address object to prevent any formatting differences.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @ManyToOne(() => Address, address => address.participants, { nullable: true })
 | 
					  @ManyToOne(() => Address, address => address.participants, { nullable: true })
 | 
				
			||||||
  address?: Address;
 | 
					  address?: Address;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The participant's phone number.
 | 
					   * The participant's phone number.
 | 
				
			||||||
   * Optional
 | 
					   * This will be validated against the configured country phone numer syntax (default: international).
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
@@ -68,7 +68,7 @@ export abstract class Participant {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The participant's email address.
 | 
					   * The participant's email address.
 | 
				
			||||||
   * Optional
 | 
					   * Can be used to contact the participant.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
@@ -77,6 +77,7 @@ export abstract class Participant {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Used to link the participant as the donor of a donation.
 | 
					   * Used to link the participant as the donor of a donation.
 | 
				
			||||||
 | 
					   * Attention: Only runner's can be associated as a distanceDonations distance source.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @OneToMany(() => Donation, donation => donation.donor, { nullable: true })
 | 
					  @OneToMany(() => Donation, donation => donation.donor, { nullable: true })
 | 
				
			||||||
  donations: Donation[];
 | 
					  donations: Donation[];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,9 @@ import { PermissionAction } from '../enums/PermissionAction';
 | 
				
			|||||||
import { PermissionTarget } from '../enums/PermissionTargets';
 | 
					import { PermissionTarget } from '../enums/PermissionTargets';
 | 
				
			||||||
import { Principal } from './Principal';
 | 
					import { Principal } from './Principal';
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines the Permission interface.
 | 
					 * Defines the Permission entity.
 | 
				
			||||||
 | 
					 * Permissions can be granted to principals.
 | 
				
			||||||
 | 
					 * The permissions possible targets and actions are defined in enums.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
export class Permission {
 | 
					export class Permission {
 | 
				
			||||||
@@ -20,13 +22,14 @@ export class Permission {
 | 
				
			|||||||
  id: number;
 | 
					  id: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The permissions principal
 | 
					   * The permission's principal.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @ManyToOne(() => Principal, principal => principal.permissions)
 | 
					  @ManyToOne(() => Principal, principal => principal.permissions)
 | 
				
			||||||
  principal: Principal;
 | 
					  principal: Principal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The target
 | 
					   * The permission's target.
 | 
				
			||||||
 | 
					   * This get's stored as the enum value's string representation for compatability reasons.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ type: 'varchar' })
 | 
					  @Column({ type: 'varchar' })
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
@@ -34,14 +37,16 @@ export class Permission {
 | 
				
			|||||||
  target: PermissionTarget;
 | 
					  target: PermissionTarget;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The action type
 | 
					   * The permission's action.
 | 
				
			||||||
 | 
					   * This get's stored as the enum value's string representation for compatability reasons.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ type: 'varchar' })
 | 
					  @Column({ type: 'varchar' })
 | 
				
			||||||
  @IsEnum(PermissionAction)
 | 
					  @IsEnum(PermissionAction)
 | 
				
			||||||
  action: PermissionAction;
 | 
					  action: PermissionAction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * 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).
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public toString(): string {
 | 
					  public toString(): string {
 | 
				
			||||||
    return this.target + ":" + this.action;
 | 
					    return this.target + ":" + this.action;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,23 +4,27 @@ import { ResponsePrincipal } from '../responses/ResponsePrincipal';
 | 
				
			|||||||
import { Permission } from './Permission';
 | 
					import { Permission } from './Permission';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a admin user.
 | 
					 * Defines the principal entity.
 | 
				
			||||||
 | 
					 * A principal basicly is any entity that can receive permissions for the api (users and their groups).
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
					@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
				
			||||||
export abstract class Principal {
 | 
					export abstract class Principal {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * autogenerated unique id (primary key).
 | 
					  * Autogenerated unique id (primary key).
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @PrimaryGeneratedColumn()
 | 
					  @PrimaryGeneratedColumn()
 | 
				
			||||||
  @IsInt()
 | 
					  @IsInt()
 | 
				
			||||||
  id: number;
 | 
					  id: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
* permissions
 | 
					  * The participant's permissions.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @OneToMany(() => Permission, permission => permission.principal, { nullable: true })
 | 
					  @OneToMany(() => Permission, permission => permission.principal, { nullable: true })
 | 
				
			||||||
  permissions: Permission[];
 | 
					  permissions: Permission[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Turns this entity into it's response class.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  public abstract toResponse(): ResponsePrincipal;
 | 
					  public abstract toResponse(): ResponsePrincipal;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -7,44 +7,52 @@ import { RunnerGroup } from "./RunnerGroup";
 | 
				
			|||||||
import { Scan } from "./Scan";
 | 
					import { Scan } from "./Scan";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a runner.
 | 
					 * Defines the runner entity.
 | 
				
			||||||
 | 
					 * Runners differ from participants in being able to actually accumulate a ran distance through scans.
 | 
				
			||||||
 | 
					 * Runner's get organized in groups.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ChildEntity()
 | 
					@ChildEntity()
 | 
				
			||||||
export class Runner extends Participant {
 | 
					export class Runner extends Participant {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The runner's associated group.
 | 
					   * The runner's associated group.
 | 
				
			||||||
 | 
					   * Can be a runner team or organisation.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
  @ManyToOne(() => RunnerGroup, group => group.runners, { nullable: false })
 | 
					  @ManyToOne(() => RunnerGroup, group => group.runners, { nullable: false })
 | 
				
			||||||
  group: RunnerGroup;
 | 
					  group: RunnerGroup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Used to link runners to donations.
 | 
					   * The runner's associated distanceDonations.
 | 
				
			||||||
 | 
					   * Used to link runners to distanceDonations in order to calculate the donation's amount based on the distance the runner ran.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @OneToMany(() => DistanceDonation, distanceDonation => distanceDonation.runner, { nullable: true })
 | 
					  @OneToMany(() => DistanceDonation, distanceDonation => distanceDonation.runner, { nullable: true })
 | 
				
			||||||
  distanceDonations: DistanceDonation[];
 | 
					  distanceDonations: DistanceDonation[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Used to link runners to cards.
 | 
					   * The runner's associated cards.
 | 
				
			||||||
 | 
					   * Used to link runners to cards - yes a runner be associated with multiple cards this came in handy in the past.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @OneToMany(() => RunnerCard, card => card.runner, { nullable: true })
 | 
					  @OneToMany(() => RunnerCard, card => card.runner, { nullable: true })
 | 
				
			||||||
  cards: RunnerCard[];
 | 
					  cards: RunnerCard[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Used to link runners to a scans
 | 
					   * The runner's associated scans.
 | 
				
			||||||
 | 
					   * Used to link runners to scans (valid and fraudulant).
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @OneToMany(() => Scan, scan => scan.runner, { nullable: true })
 | 
					  @OneToMany(() => Scan, scan => scan.runner, { nullable: true })
 | 
				
			||||||
  scans: Scan[];
 | 
					  scans: Scan[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Returns all valid scans associated with this runner.
 | 
					   * Returns all valid scans associated with this runner.
 | 
				
			||||||
 | 
					   * This is implemented here to avoid duplicate code in other files.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public get validScans(): Scan[] {
 | 
					  public get validScans(): Scan[] {
 | 
				
			||||||
    return this.scans.filter(scan => { scan.valid === true });
 | 
					    return this.scans.filter(scan => { scan.valid === true });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Returns the total distance ran by this runner.
 | 
					   * Returns the total distance ran by this runner based on all his valid scans.
 | 
				
			||||||
 | 
					   * This is implemented here to avoid duplicate code in other files.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @IsInt()
 | 
					  @IsInt()
 | 
				
			||||||
  public get distance(): number {
 | 
					  public get distance(): number {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,9 @@ import { Runner } from "./Runner";
 | 
				
			|||||||
import { TrackScan } from "./TrackScan";
 | 
					import { TrackScan } from "./TrackScan";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a card that can be scanned via a scanner station.
 | 
					 * Defines the RunnerCard entity.
 | 
				
			||||||
 | 
					 * A runnerCard is a physical representation for a runner.
 | 
				
			||||||
 | 
					 * It can be associated with a runner to create scans via the scan station's.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
export class RunnerCard {
 | 
					export class RunnerCard {
 | 
				
			||||||
@@ -23,7 +25,8 @@ export class RunnerCard {
 | 
				
			|||||||
  id: number;
 | 
					  id: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The runner that is currently associated with this card.
 | 
					   * The card's currently associated runner.
 | 
				
			||||||
 | 
					   * To increase reusability a card can be reassigned.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
  @ManyToOne(() => Runner, runner => runner.cards, { nullable: true })
 | 
					  @ManyToOne(() => Runner, runner => runner.cards, { nullable: true })
 | 
				
			||||||
@@ -32,7 +35,7 @@ export class RunnerCard {
 | 
				
			|||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The card's code.
 | 
					   * The card's code.
 | 
				
			||||||
   * This has to be able to being converted to something barcode compatible.
 | 
					   * This has to be able to being converted to something barcode compatible.
 | 
				
			||||||
   * could theoretically be autogenerated
 | 
					   * Will get automaticlly generated (not implemented yet).
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsEAN()
 | 
					  @IsEAN()
 | 
				
			||||||
@@ -49,7 +52,8 @@ export class RunnerCard {
 | 
				
			|||||||
  enabled: boolean = true;
 | 
					  enabled: boolean = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Used to link cards to a track scans.
 | 
					   * The card's associated scans.
 | 
				
			||||||
 | 
					   * Used to link cards to track scans.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @OneToMany(() => TrackScan, scan => scan.track, { nullable: true })
 | 
					  @OneToMany(() => TrackScan, scan => scan.track, { nullable: true })
 | 
				
			||||||
  scans: TrackScan[];
 | 
					  scans: TrackScan[];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,8 @@ import { GroupContact } from "./GroupContact";
 | 
				
			|||||||
import { Runner } from "./Runner";
 | 
					import { Runner } from "./Runner";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines the runnerGroup interface.
 | 
					 * Defines the RunnerGroup entity.
 | 
				
			||||||
 | 
					 * This is used to group runners together (as the name suggests).
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
					@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
				
			||||||
@@ -31,13 +32,14 @@ export abstract class RunnerGroup {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The group's contact.
 | 
					   * The group's contact.
 | 
				
			||||||
   * Optional
 | 
					   * This is mostly a feature for the group managers and public relations.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
  @ManyToOne(() => GroupContact, contact => contact.groups, { nullable: true })
 | 
					  @ManyToOne(() => GroupContact, contact => contact.groups, { nullable: true })
 | 
				
			||||||
  contact?: GroupContact;
 | 
					  contact?: GroupContact;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
 | 
					   * The group's associated runners.
 | 
				
			||||||
   * Used to link runners to a runner group.
 | 
					   * Used to link runners to a runner group.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @OneToMany(() => Runner, runner => runner.group, { nullable: true })
 | 
					  @OneToMany(() => Runner, runner => runner.group, { nullable: true })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,21 +5,22 @@ import { RunnerGroup } from "./RunnerGroup";
 | 
				
			|||||||
import { RunnerTeam } from "./RunnerTeam";
 | 
					import { RunnerTeam } from "./RunnerTeam";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a runner organisation (business or school for example).
 | 
					 * Defines the RunnerOrganisation entity.
 | 
				
			||||||
 | 
					 * This usually is a school, club or company.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ChildEntity()
 | 
					@ChildEntity()
 | 
				
			||||||
export class RunnerOrganisation extends RunnerGroup {
 | 
					export class RunnerOrganisation extends RunnerGroup {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The organisations's address.
 | 
					   * The organisations's address.
 | 
				
			||||||
   * Optional
 | 
					 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
  @ManyToOne(() => Address, address => address.groups, { nullable: true })
 | 
					  @ManyToOne(() => Address, address => address.groups, { nullable: true })
 | 
				
			||||||
  address?: Address;
 | 
					  address?: Address;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
 * Used to link teams to runner groups.
 | 
					   * The organisation's teams.
 | 
				
			||||||
 | 
					   * Used to link teams to a organisation.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @OneToMany(() => RunnerTeam, team => team.parentGroup, { nullable: true })
 | 
					  @OneToMany(() => RunnerTeam, team => team.parentGroup, { nullable: true })
 | 
				
			||||||
  teams: RunnerTeam[];
 | 
					  teams: RunnerTeam[];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,14 +4,15 @@ import { RunnerGroup } from "./RunnerGroup";
 | 
				
			|||||||
import { RunnerOrganisation } from "./RunnerOrganisation";
 | 
					import { RunnerOrganisation } from "./RunnerOrganisation";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a runner team (class or deparment for example).
 | 
					 * Defines the RunnerTeam entity.
 | 
				
			||||||
 | 
					 * This usually is a school class or department in a company.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ChildEntity()
 | 
					@ChildEntity()
 | 
				
			||||||
export class RunnerTeam extends RunnerGroup {
 | 
					export class RunnerTeam extends RunnerGroup {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The team's parent group.
 | 
					   * The team's parent group.
 | 
				
			||||||
   * Optional
 | 
					   * Every team has to be part of a runnerOrganisation - this get's checked on creation and update.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
  @ManyToOne(() => RunnerOrganisation, org => org.teams, { nullable: true })
 | 
					  @ManyToOne(() => RunnerOrganisation, org => org.teams, { nullable: true })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,8 @@ import { Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } f
 | 
				
			|||||||
import { Runner } from "./Runner";
 | 
					import { Runner } from "./Runner";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines the scan interface.
 | 
					 * Defines the Scan entity.
 | 
				
			||||||
 | 
					 * A scan basicly adds a certain distance to a runner's total ran distance.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
					@TableInheritance({ column: { name: "type", type: "varchar" } })
 | 
				
			||||||
@@ -22,7 +23,8 @@ export abstract class Scan {
 | 
				
			|||||||
  id: number;
 | 
					  id: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The associated runner.
 | 
					   * The scan's associated runner.
 | 
				
			||||||
 | 
					   * This is important to link ran distances to runners.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
  @ManyToOne(() => Runner, runner => runner.scans, { nullable: false })
 | 
					  @ManyToOne(() => Runner, runner => runner.scans, { nullable: false })
 | 
				
			||||||
@@ -30,6 +32,7 @@ export abstract class Scan {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The scan's distance in meters.
 | 
					   * The scan's distance in meters.
 | 
				
			||||||
 | 
					   * Can be set manually or derived from another object.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsInt()
 | 
					  @IsInt()
 | 
				
			||||||
  @IsPositive()
 | 
					  @IsPositive()
 | 
				
			||||||
@@ -37,6 +40,7 @@ export abstract class Scan {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Is the scan valid (for fraud reasons).
 | 
					   * Is the scan valid (for fraud reasons).
 | 
				
			||||||
 | 
					   * The determination of validity will work differently for every child class.
 | 
				
			||||||
   * Default: true
 | 
					   * Default: true
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,8 @@ import { Track } from "./Track";
 | 
				
			|||||||
import { TrackScan } from "./TrackScan";
 | 
					import { TrackScan } from "./TrackScan";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * ScannerStations have the ability to create scans for specific tracks.
 | 
					 * Defines the ScanStation entity.
 | 
				
			||||||
 | 
					 * ScanStations get used to create TrackScans for runners based on a scan of their runnerCard.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
export class ScanStation {
 | 
					export class ScanStation {
 | 
				
			||||||
@@ -23,6 +24,7 @@ export class ScanStation {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The station's description.
 | 
					   * The station's description.
 | 
				
			||||||
 | 
					   * Mostly for better UX when traceing back stuff.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
@@ -31,6 +33,7 @@ export class ScanStation {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The track this station is associated with.
 | 
					   * The track this station is associated with.
 | 
				
			||||||
 | 
					   * All scans created by this station will also be associated with this track.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
  @ManyToOne(() => Track, track => track.stations, { nullable: false })
 | 
					  @ManyToOne(() => Track, track => track.stations, { nullable: false })
 | 
				
			||||||
@@ -38,6 +41,7 @@ export class ScanStation {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The station's api key.
 | 
					   * The station's api key.
 | 
				
			||||||
 | 
					   * This is used to authorize a station against the api (not implemented yet).
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
@@ -45,7 +49,7 @@ export class ScanStation {
 | 
				
			|||||||
  key: string;
 | 
					  key: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Is the station enabled (for fraud reasons)?
 | 
					   * Is the station enabled (for fraud and setup reasons)?
 | 
				
			||||||
   * Default: true
 | 
					   * Default: true
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,6 @@
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
  IsInt,
 | 
					  IsInt,
 | 
				
			||||||
  IsNotEmpty,
 | 
					  IsNotEmpty,
 | 
				
			||||||
 | 
					 | 
				
			||||||
  IsPositive,
 | 
					  IsPositive,
 | 
				
			||||||
  IsString
 | 
					  IsString
 | 
				
			||||||
} from "class-validator";
 | 
					} from "class-validator";
 | 
				
			||||||
@@ -10,7 +9,7 @@ import { ScanStation } from "./ScanStation";
 | 
				
			|||||||
import { TrackScan } from "./TrackScan";
 | 
					import { TrackScan } from "./TrackScan";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a track of given length.
 | 
					 * Defines the Track entity.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
export class Track {
 | 
					export class Track {
 | 
				
			||||||
@@ -23,6 +22,7 @@ export class Track {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The track's name.
 | 
					   * The track's name.
 | 
				
			||||||
 | 
					   * Mainly here for UX.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
@@ -31,6 +31,7 @@ export class Track {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The track's length/distance in meters.
 | 
					   * The track's length/distance in meters.
 | 
				
			||||||
 | 
					   * Will be used to calculate runner's ran distances.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsInt()
 | 
					  @IsInt()
 | 
				
			||||||
@@ -38,13 +39,15 @@ export class Track {
 | 
				
			|||||||
  distance: number;
 | 
					  distance: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Used to link scan stations to track.
 | 
					   * Used to link scan stations to a certain track.
 | 
				
			||||||
 | 
					   * This makes the configuration of the scan stations easier.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @OneToMany(() => ScanStation, station => station.track, { nullable: true })
 | 
					  @OneToMany(() => ScanStation, station => station.track, { nullable: true })
 | 
				
			||||||
  stations: ScanStation[];
 | 
					  stations: ScanStation[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Used to link track scans to a track.
 | 
					   * Used to link track scans to a track.
 | 
				
			||||||
 | 
					   * The scan will derive it's distance from the track's distance.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @OneToMany(() => TrackScan, scan => scan.track, { nullable: true })
 | 
					  @OneToMany(() => TrackScan, scan => scan.track, { nullable: true })
 | 
				
			||||||
  scans: TrackScan[];
 | 
					  scans: TrackScan[];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,26 +12,30 @@ import { ScanStation } from "./ScanStation";
 | 
				
			|||||||
import { Track } from "./Track";
 | 
					import { Track } from "./Track";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines the scan interface.
 | 
					 * Defines the TrackScan entity.
 | 
				
			||||||
 | 
					 * A track scan usaually get's generated by a scan station.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ChildEntity()
 | 
					@ChildEntity()
 | 
				
			||||||
export class TrackScan extends Scan {
 | 
					export class TrackScan extends Scan {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The associated track.
 | 
					   * The scan's associated track.
 | 
				
			||||||
 | 
					   * This is used to determine the scan's distance.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
  @ManyToOne(() => Track, track => track.scans, { nullable: true })
 | 
					  @ManyToOne(() => Track, track => track.scans, { nullable: true })
 | 
				
			||||||
  track: Track;
 | 
					  track: Track;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The associated card.
 | 
					   * The runnerCard associated with the scan.
 | 
				
			||||||
 | 
					   * This get's saved for documentation and management purposes.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
  @ManyToOne(() => RunnerCard, card => card.scans, { nullable: true })
 | 
					  @ManyToOne(() => RunnerCard, card => card.scans, { nullable: true })
 | 
				
			||||||
  card: RunnerCard;
 | 
					  card: RunnerCard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The scanning station.
 | 
					   * The scanning station that created the scan.
 | 
				
			||||||
 | 
					   * Mainly used for logging and traceing back scans (or errors)
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsNotEmpty()
 | 
				
			||||||
  @ManyToOne(() => ScanStation, station => station.scans, { nullable: true })
 | 
					  @ManyToOne(() => ScanStation, station => station.scans, { nullable: true })
 | 
				
			||||||
@@ -39,6 +43,7 @@ export class TrackScan extends Scan {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The scan's distance in meters.
 | 
					   * The scan's distance in meters.
 | 
				
			||||||
 | 
					   * This just get's loaded from it's track.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsInt()
 | 
					  @IsInt()
 | 
				
			||||||
  @IsPositive()
 | 
					  @IsPositive()
 | 
				
			||||||
@@ -48,6 +53,7 @@ export class TrackScan extends Scan {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The scan's creation timestamp.
 | 
					   * The scan's creation timestamp.
 | 
				
			||||||
 | 
					   * Will be used to implement fraud detection.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsDateString()
 | 
					  @IsDateString()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,26 +8,29 @@ import { UserAction } from './UserAction';
 | 
				
			|||||||
import { UserGroup } from './UserGroup';
 | 
					import { UserGroup } from './UserGroup';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines a admin user.
 | 
					 * Defines the User entity.
 | 
				
			||||||
 | 
					 * Users are the ones that can use the "admin" webui and do stuff in the backend.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ChildEntity()
 | 
					@ChildEntity()
 | 
				
			||||||
export class User extends Principal {
 | 
					export class User extends Principal {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * uuid
 | 
					  * The user's uuid.
 | 
				
			||||||
 | 
					  * Mainly gets used as a per-user salt for the password hash.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column({ unique: true })
 | 
					  @Column({ unique: true })
 | 
				
			||||||
  @IsUUID(4)
 | 
					  @IsUUID(4)
 | 
				
			||||||
  uuid: string;
 | 
					  uuid: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * user email
 | 
					  * The user's e-mail address.
 | 
				
			||||||
 | 
					  * Either username or email has to be set (otherwise the user couldn't log in).
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column({ nullable: true, unique: true })
 | 
					  @Column({ nullable: true, unique: true })
 | 
				
			||||||
  @IsEmail()
 | 
					  @IsEmail()
 | 
				
			||||||
  email?: string;
 | 
					  email?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * user phone
 | 
					  * The user's phone number.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
@@ -35,14 +38,15 @@ export class User extends Principal {
 | 
				
			|||||||
  phone?: string;
 | 
					  phone?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * username
 | 
					  * The user's username.
 | 
				
			||||||
 | 
					  * Either username or email has to be set (otherwise the user couldn't log in).
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column({ nullable: true, unique: true })
 | 
					  @Column({ nullable: true, unique: true })
 | 
				
			||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
  username?: string;
 | 
					  username?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * firstname
 | 
					  * The user's first name.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
@@ -50,7 +54,7 @@ export class User extends Principal {
 | 
				
			|||||||
  firstname: string;
 | 
					  firstname: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * middlename
 | 
					  * The user's middle name.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
@@ -58,7 +62,7 @@ export class User extends Principal {
 | 
				
			|||||||
  middlename?: string;
 | 
					  middlename?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * lastname
 | 
					  * The user's last name.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
@@ -66,7 +70,8 @@ export class User extends Principal {
 | 
				
			|||||||
  lastname: string;
 | 
					  lastname: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * password
 | 
					  * The user's password.
 | 
				
			||||||
 | 
					  * This is a argon2 hash salted with the user's uuid.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
@@ -74,7 +79,8 @@ export class User extends Principal {
 | 
				
			|||||||
  password: string;
 | 
					  password: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * groups
 | 
					  * The groups this user is a part of.
 | 
				
			||||||
 | 
					  * The user will inherit the groups permissions (without overwriting his own).
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
  @ManyToMany(() => UserGroup, { nullable: true })
 | 
					  @ManyToMany(() => UserGroup, { nullable: true })
 | 
				
			||||||
@@ -82,21 +88,23 @@ export class User extends Principal {
 | 
				
			|||||||
  groups: UserGroup[];
 | 
					  groups: UserGroup[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * is user enabled?
 | 
					  * Is this user enabled?
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column()
 | 
					  @Column()
 | 
				
			||||||
  @IsBoolean()
 | 
					  @IsBoolean()
 | 
				
			||||||
  enabled: boolean = true;
 | 
					  enabled: boolean = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * jwt refresh count
 | 
					  * The user's jwt refresh token count.
 | 
				
			||||||
 | 
					  * Used to invalidate jwts.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @IsInt()
 | 
					  @IsInt()
 | 
				
			||||||
  @Column({ default: 1 })
 | 
					  @Column({ default: 1 })
 | 
				
			||||||
  refreshTokenCount?: number;
 | 
					  refreshTokenCount?: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  * profilepic
 | 
					  * The user's profile picture.
 | 
				
			||||||
 | 
					  * We haven't decided yet if this will be a bas64 encoded image or just a link to the profile picture.
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  @Column({ nullable: true, unique: true })
 | 
					  @Column({ nullable: true, unique: true })
 | 
				
			||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
@@ -104,14 +112,15 @@ export class User extends Principal {
 | 
				
			|||||||
  profilePic?: string;
 | 
					  profilePic?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * actions
 | 
					   * The actions performed by this user.
 | 
				
			||||||
 | 
					   * For documentation purposes only, will be implemented later.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
  @OneToMany(() => UserAction, action => action.user, { nullable: true })
 | 
					  @OneToMany(() => UserAction, action => action.user, { nullable: true })
 | 
				
			||||||
  actions: UserAction[]
 | 
					  actions: UserAction[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Turn this into a response.
 | 
					   * Turns this entity into it's response class.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public toResponse(): ResponsePrincipal {
 | 
					  public toResponse(): ResponsePrincipal {
 | 
				
			||||||
    return new ResponseUser(this);
 | 
					    return new ResponseUser(this);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,17 @@
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					  IsEnum,
 | 
				
			||||||
  IsInt,
 | 
					  IsInt,
 | 
				
			||||||
  IsNotEmpty,
 | 
					  IsNotEmpty,
 | 
				
			||||||
  IsOptional,
 | 
					  IsOptional,
 | 
				
			||||||
  IsString
 | 
					  IsString
 | 
				
			||||||
} from "class-validator";
 | 
					} from "class-validator";
 | 
				
			||||||
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
 | 
					import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
 | 
				
			||||||
 | 
					import { PermissionAction } from '../enums/PermissionAction';
 | 
				
			||||||
import { User } from './User';
 | 
					import { User } from './User';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines the UserAction interface.
 | 
					 * Defines the UserAction entity.
 | 
				
			||||||
 | 
					 * Will later be used to document a user's actions.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@Entity()
 | 
					@Entity()
 | 
				
			||||||
export class UserAction {
 | 
					export class UserAction {
 | 
				
			||||||
@@ -20,7 +23,7 @@ export class UserAction {
 | 
				
			|||||||
  id: number;
 | 
					  id: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * user
 | 
					   * The user that performed the action.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @ManyToOne(() => User, user => user.actions)
 | 
					  @ManyToOne(() => User, user => user.actions)
 | 
				
			||||||
  user: User
 | 
					  user: User
 | 
				
			||||||
@@ -34,15 +37,16 @@ export class UserAction {
 | 
				
			|||||||
  target: string;
 | 
					  target: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The actions's action (e.g. UPDATE)
 | 
					   * The actions's action (e.g. UPDATE).
 | 
				
			||||||
 | 
					   * Directly pulled from the PermissionAction Enum.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column()
 | 
					  @Column({ type: 'varchar' })
 | 
				
			||||||
  @IsNotEmpty()
 | 
					  @IsEnum(PermissionAction)
 | 
				
			||||||
  @IsString()
 | 
					  action: PermissionAction;
 | 
				
			||||||
  action: string;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * The description of change (before-> after; e.g. distance:15->17)
 | 
					   * The description of the change (before-> after; e.g. distance:15->17).
 | 
				
			||||||
 | 
					   * Will later be defined in more detail.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @Column({ nullable: true })
 | 
					  @Column({ nullable: true })
 | 
				
			||||||
  @IsOptional()
 | 
					  @IsOptional()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,8 @@ import { ResponseUserGroup } from '../responses/ResponseUserGroup';
 | 
				
			|||||||
import { Principal } from './Principal';
 | 
					import { Principal } from './Principal';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Defines the UserGroup interface.
 | 
					 * Defines the UserGroup entity.
 | 
				
			||||||
 | 
					 * This entity describes a group of users with a set of permissions.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@ChildEntity()
 | 
					@ChildEntity()
 | 
				
			||||||
export class UserGroup extends Principal {
 | 
					export class UserGroup extends Principal {
 | 
				
			||||||
@@ -30,6 +31,9 @@ export class UserGroup extends Principal {
 | 
				
			|||||||
  @IsString()
 | 
					  @IsString()
 | 
				
			||||||
  description?: string;
 | 
					  description?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Turns this entity into it's response class.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  public toResponse(): ResponsePrincipal {
 | 
					  public toResponse(): ResponsePrincipal {
 | 
				
			||||||
    return new ResponseUserGroup(this);
 | 
					    return new ResponseUserGroup(this);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user