parent
a03f1a438d
commit
d20d738218
|
@ -10,7 +10,8 @@ import { Participant } from "./Participant";
|
|||
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()
|
||||
export class Address {
|
||||
|
@ -23,6 +24,7 @@ export class Address {
|
|||
|
||||
/**
|
||||
* The address's description.
|
||||
* Optional and mostly for UX.
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsString()
|
||||
|
@ -49,6 +51,8 @@ export class Address {
|
|||
|
||||
/**
|
||||
* The address's postal code.
|
||||
* This will get checked against the postal code syntax for the configured country.
|
||||
* TODO: Implement the config option.
|
||||
*/
|
||||
@Column()
|
||||
@IsString()
|
||||
|
|
|
@ -4,19 +4,21 @@ import { Donation } from "./Donation";
|
|||
import { Runner } from "./Runner";
|
||||
|
||||
/**
|
||||
* Defines a distance based donation.
|
||||
* Here people donate a certain amout per kilometer
|
||||
* Defines the DistanceDonation entity.
|
||||
* For distanceDonations a donor pledges to donate a certain amount for each kilometer ran by a runner.
|
||||
*/
|
||||
@ChildEntity()
|
||||
export class DistanceDonation extends Donation {
|
||||
/**
|
||||
* The runner associated.
|
||||
* The donation's associated runner.
|
||||
* Used as the source of the donation's distance.
|
||||
*/
|
||||
@IsNotEmpty()
|
||||
@ManyToOne(() => Runner, runner => runner.distanceDonations)
|
||||
runner: Runner;
|
||||
|
||||
/**
|
||||
* The donation's amount donated per distance.
|
||||
* The amount the donor set to be donated per kilometer that the runner ran.
|
||||
*/
|
||||
@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 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 {
|
||||
let calculatedAmount = -1;
|
||||
try {
|
||||
calculatedAmount = this.amountPerDistance * this.runner.distance;
|
||||
calculatedAmount = this.amountPerDistance * (this.runner.distance / 1000);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ import { Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typ
|
|||
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()
|
||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
|
||||
|
|
|
@ -3,13 +3,13 @@ import { ChildEntity, Column } from "typeorm";
|
|||
import { Participant } from "./Participant";
|
||||
|
||||
/**
|
||||
* Defines a donor.
|
||||
* Defines the Donor entity.
|
||||
*/
|
||||
@ChildEntity()
|
||||
export class Donor extends Participant {
|
||||
/**
|
||||
* Does this donor need a receipt?.
|
||||
* Default: false
|
||||
* Does this donor need a receipt?
|
||||
* Will later be used to automaticly generate donation receipts.
|
||||
*/
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
|
|
|
@ -3,7 +3,8 @@ import { ChildEntity, Column } from "typeorm";
|
|||
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()
|
||||
export class FixedDonation extends Donation {
|
||||
|
|
|
@ -13,13 +13,14 @@ import { Address } from "./Address";
|
|||
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()
|
||||
export class GroupContact {
|
||||
/**
|
||||
* Autogenerated unique id (primary key).
|
||||
*/
|
||||
* Autogenerated unique id (primary key).
|
||||
*/
|
||||
@PrimaryGeneratedColumn()
|
||||
@IsInt()
|
||||
id: number;
|
||||
|
@ -34,7 +35,6 @@ export class GroupContact {
|
|||
|
||||
/**
|
||||
* The contact's middle name.
|
||||
* Optional
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsOptional()
|
||||
|
@ -51,7 +51,7 @@ export class GroupContact {
|
|||
|
||||
/**
|
||||
* The contact's address.
|
||||
* Optional
|
||||
* This is a address object to prevent any formatting differences.
|
||||
*/
|
||||
@IsOptional()
|
||||
@ManyToOne(() => Address, address => address.participants, { nullable: true })
|
||||
|
@ -59,7 +59,7 @@ export class GroupContact {
|
|||
|
||||
/**
|
||||
* The contact's phone number.
|
||||
* Optional
|
||||
* This will be validated against the configured country phone numer syntax (default: international).
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsOptional()
|
||||
|
@ -68,7 +68,7 @@ export class GroupContact {
|
|||
|
||||
/**
|
||||
* The contact's email address.
|
||||
* Optional
|
||||
* Could later be used to automaticly send mails concerning the contact's associated groups.
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsOptional()
|
||||
|
|
|
@ -13,7 +13,8 @@ import { Address } from "./Address";
|
|||
import { Donation } from "./Donation";
|
||||
|
||||
/**
|
||||
* Defines the participant interface.
|
||||
* Defines the Participant entity.
|
||||
* Participans can donate and therefor be associated with donation entities.
|
||||
*/
|
||||
@Entity()
|
||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
|
||||
|
@ -35,7 +36,6 @@ export abstract class Participant {
|
|||
|
||||
/**
|
||||
* The participant's middle name.
|
||||
* Optional
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsOptional()
|
||||
|
@ -52,14 +52,14 @@ export abstract class Participant {
|
|||
|
||||
/**
|
||||
* The participant's address.
|
||||
* Optional
|
||||
* This is a address object to prevent any formatting differences.
|
||||
*/
|
||||
@ManyToOne(() => Address, address => address.participants, { nullable: true })
|
||||
address?: Address;
|
||||
|
||||
/**
|
||||
* The participant's phone number.
|
||||
* Optional
|
||||
* This will be validated against the configured country phone numer syntax (default: international).
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsOptional()
|
||||
|
@ -68,7 +68,7 @@ export abstract class Participant {
|
|||
|
||||
/**
|
||||
* The participant's email address.
|
||||
* Optional
|
||||
* Can be used to contact the participant.
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsOptional()
|
||||
|
@ -77,6 +77,7 @@ export abstract class Participant {
|
|||
|
||||
/**
|
||||
* 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 })
|
||||
donations: Donation[];
|
||||
|
|
|
@ -8,7 +8,9 @@ import { PermissionAction } from '../enums/PermissionAction';
|
|||
import { PermissionTarget } from '../enums/PermissionTargets';
|
||||
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()
|
||||
export class Permission {
|
||||
|
@ -20,13 +22,14 @@ export class Permission {
|
|||
id: number;
|
||||
|
||||
/**
|
||||
* The permissions principal
|
||||
* The permission's principal.
|
||||
*/
|
||||
@ManyToOne(() => Principal, principal => principal.permissions)
|
||||
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' })
|
||||
@IsNotEmpty()
|
||||
|
@ -34,14 +37,16 @@ export class Permission {
|
|||
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' })
|
||||
@IsEnum(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 {
|
||||
return this.target + ":" + this.action;
|
||||
|
|
|
@ -4,23 +4,27 @@ import { ResponsePrincipal } from '../responses/ResponsePrincipal';
|
|||
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()
|
||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
|
||||
export abstract class Principal {
|
||||
/**
|
||||
* autogenerated unique id (primary key).
|
||||
* Autogenerated unique id (primary key).
|
||||
*/
|
||||
@PrimaryGeneratedColumn()
|
||||
@IsInt()
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* permissions
|
||||
*/
|
||||
* The participant's permissions.
|
||||
*/
|
||||
@OneToMany(() => Permission, permission => permission.principal, { nullable: true })
|
||||
permissions: Permission[];
|
||||
|
||||
/**
|
||||
* Turns this entity into it's response class.
|
||||
*/
|
||||
public abstract toResponse(): ResponsePrincipal;
|
||||
}
|
|
@ -7,44 +7,52 @@ import { RunnerGroup } from "./RunnerGroup";
|
|||
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()
|
||||
export class Runner extends Participant {
|
||||
/**
|
||||
* The runner's associated group.
|
||||
* Can be a runner team or organisation.
|
||||
*/
|
||||
@IsNotEmpty()
|
||||
@ManyToOne(() => RunnerGroup, group => group.runners, { nullable: false })
|
||||
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 })
|
||||
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 })
|
||||
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 })
|
||||
scans: Scan[];
|
||||
|
||||
/**
|
||||
* Returns all valid scans associated with this runner.
|
||||
* This is implemented here to avoid duplicate code in other files.
|
||||
*/
|
||||
public get validScans(): Scan[] {
|
||||
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()
|
||||
public get distance(): number {
|
||||
|
|
|
@ -11,7 +11,9 @@ import { Runner } from "./Runner";
|
|||
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()
|
||||
export class RunnerCard {
|
||||
|
@ -23,7 +25,8 @@ export class RunnerCard {
|
|||
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()
|
||||
@ManyToOne(() => Runner, runner => runner.cards, { nullable: true })
|
||||
|
@ -32,7 +35,7 @@ export class RunnerCard {
|
|||
/**
|
||||
* The card's code.
|
||||
* This has to be able to being converted to something barcode compatible.
|
||||
* could theoretically be autogenerated
|
||||
* Will get automaticlly generated (not implemented yet).
|
||||
*/
|
||||
@Column()
|
||||
@IsEAN()
|
||||
|
@ -49,7 +52,8 @@ export class RunnerCard {
|
|||
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 })
|
||||
scans: TrackScan[];
|
||||
|
|
|
@ -9,7 +9,8 @@ import { GroupContact } from "./GroupContact";
|
|||
import { Runner } from "./Runner";
|
||||
|
||||
/**
|
||||
* Defines the runnerGroup interface.
|
||||
* Defines the RunnerGroup entity.
|
||||
* This is used to group runners together (as the name suggests).
|
||||
*/
|
||||
@Entity()
|
||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
|
||||
|
@ -31,13 +32,14 @@ export abstract class RunnerGroup {
|
|||
|
||||
/**
|
||||
* The group's contact.
|
||||
* Optional
|
||||
* This is mostly a feature for the group managers and public relations.
|
||||
*/
|
||||
@IsOptional()
|
||||
@ManyToOne(() => GroupContact, contact => contact.groups, { nullable: true })
|
||||
contact?: GroupContact;
|
||||
|
||||
/**
|
||||
* The group's associated runners.
|
||||
* Used to link runners to a runner group.
|
||||
*/
|
||||
@OneToMany(() => Runner, runner => runner.group, { nullable: true })
|
||||
|
|
|
@ -5,22 +5,23 @@ import { RunnerGroup } from "./RunnerGroup";
|
|||
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()
|
||||
export class RunnerOrganisation extends RunnerGroup {
|
||||
|
||||
/**
|
||||
* The organisations's address.
|
||||
* Optional
|
||||
*/
|
||||
@IsOptional()
|
||||
@ManyToOne(() => Address, address => address.groups, { nullable: true })
|
||||
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 })
|
||||
teams: RunnerTeam[];
|
||||
}
|
|
@ -4,14 +4,15 @@ import { RunnerGroup } from "./RunnerGroup";
|
|||
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()
|
||||
export class RunnerTeam extends RunnerGroup {
|
||||
|
||||
/**
|
||||
* The team's parent group.
|
||||
* Optional
|
||||
* Every team has to be part of a runnerOrganisation - this get's checked on creation and update.
|
||||
*/
|
||||
@IsNotEmpty()
|
||||
@ManyToOne(() => RunnerOrganisation, org => org.teams, { nullable: true })
|
||||
|
|
|
@ -9,7 +9,8 @@ import { Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } f
|
|||
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()
|
||||
@TableInheritance({ column: { name: "type", type: "varchar" } })
|
||||
|
@ -22,7 +23,8 @@ export abstract class Scan {
|
|||
id: number;
|
||||
|
||||
/**
|
||||
* The associated runner.
|
||||
* The scan's associated runner.
|
||||
* This is important to link ran distances to runners.
|
||||
*/
|
||||
@IsNotEmpty()
|
||||
@ManyToOne(() => Runner, runner => runner.scans, { nullable: false })
|
||||
|
@ -30,15 +32,17 @@ export abstract class Scan {
|
|||
|
||||
/**
|
||||
* The scan's distance in meters.
|
||||
* Can be set manually or derived from another object.
|
||||
*/
|
||||
@IsInt()
|
||||
@IsPositive()
|
||||
abstract distance: number;
|
||||
|
||||
/**
|
||||
* Is the scan valid (for fraud reasons).
|
||||
* Default: true
|
||||
*/
|
||||
* Is the scan valid (for fraud reasons).
|
||||
* The determination of validity will work differently for every child class.
|
||||
* Default: true
|
||||
*/
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
valid: boolean = true;
|
||||
|
|
|
@ -10,7 +10,8 @@ import { Track } from "./Track";
|
|||
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()
|
||||
export class ScanStation {
|
||||
|
@ -23,6 +24,7 @@ export class ScanStation {
|
|||
|
||||
/**
|
||||
* The station's description.
|
||||
* Mostly for better UX when traceing back stuff.
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsOptional()
|
||||
|
@ -31,6 +33,7 @@ export class ScanStation {
|
|||
|
||||
/**
|
||||
* The track this station is associated with.
|
||||
* All scans created by this station will also be associated with this track.
|
||||
*/
|
||||
@IsNotEmpty()
|
||||
@ManyToOne(() => Track, track => track.stations, { nullable: false })
|
||||
|
@ -38,6 +41,7 @@ export class ScanStation {
|
|||
|
||||
/**
|
||||
* The station's api key.
|
||||
* This is used to authorize a station against the api (not implemented yet).
|
||||
*/
|
||||
@Column()
|
||||
@IsNotEmpty()
|
||||
|
@ -45,7 +49,7 @@ export class ScanStation {
|
|||
key: string;
|
||||
|
||||
/**
|
||||
* Is the station enabled (for fraud reasons)?
|
||||
* Is the station enabled (for fraud and setup reasons)?
|
||||
* Default: true
|
||||
*/
|
||||
@Column()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import {
|
||||
IsInt,
|
||||
IsNotEmpty,
|
||||
|
||||
IsPositive,
|
||||
IsString
|
||||
} from "class-validator";
|
||||
|
@ -10,7 +9,7 @@ import { ScanStation } from "./ScanStation";
|
|||
import { TrackScan } from "./TrackScan";
|
||||
|
||||
/**
|
||||
* Defines a track of given length.
|
||||
* Defines the Track entity.
|
||||
*/
|
||||
@Entity()
|
||||
export class Track {
|
||||
|
@ -23,6 +22,7 @@ export class Track {
|
|||
|
||||
/**
|
||||
* The track's name.
|
||||
* Mainly here for UX.
|
||||
*/
|
||||
@Column()
|
||||
@IsString()
|
||||
|
@ -31,6 +31,7 @@ export class Track {
|
|||
|
||||
/**
|
||||
* The track's length/distance in meters.
|
||||
* Will be used to calculate runner's ran distances.
|
||||
*/
|
||||
@Column()
|
||||
@IsInt()
|
||||
|
@ -38,13 +39,15 @@ export class Track {
|
|||
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 })
|
||||
stations: ScanStation[];
|
||||
|
||||
/**
|
||||
* 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 })
|
||||
scans: TrackScan[];
|
||||
|
|
|
@ -12,26 +12,30 @@ import { ScanStation } from "./ScanStation";
|
|||
import { Track } from "./Track";
|
||||
|
||||
/**
|
||||
* Defines the scan interface.
|
||||
* Defines the TrackScan entity.
|
||||
* A track scan usaually get's generated by a scan station.
|
||||
*/
|
||||
@ChildEntity()
|
||||
export class TrackScan extends Scan {
|
||||
/**
|
||||
* The associated track.
|
||||
* The scan's associated track.
|
||||
* This is used to determine the scan's distance.
|
||||
*/
|
||||
@IsNotEmpty()
|
||||
@ManyToOne(() => Track, track => track.scans, { nullable: true })
|
||||
track: Track;
|
||||
|
||||
/**
|
||||
* The associated card.
|
||||
* The runnerCard associated with the scan.
|
||||
* This get's saved for documentation and management purposes.
|
||||
*/
|
||||
@IsNotEmpty()
|
||||
@ManyToOne(() => RunnerCard, card => card.scans, { nullable: true })
|
||||
card: RunnerCard;
|
||||
|
||||
/**
|
||||
* The scanning station.
|
||||
* The scanning station that created the scan.
|
||||
* Mainly used for logging and traceing back scans (or errors)
|
||||
*/
|
||||
@IsNotEmpty()
|
||||
@ManyToOne(() => ScanStation, station => station.scans, { nullable: true })
|
||||
|
@ -39,6 +43,7 @@ export class TrackScan extends Scan {
|
|||
|
||||
/**
|
||||
* The scan's distance in meters.
|
||||
* This just get's loaded from it's track.
|
||||
*/
|
||||
@IsInt()
|
||||
@IsPositive()
|
||||
|
@ -48,6 +53,7 @@ export class TrackScan extends Scan {
|
|||
|
||||
/**
|
||||
* The scan's creation timestamp.
|
||||
* Will be used to implement fraud detection.
|
||||
*/
|
||||
@Column()
|
||||
@IsDateString()
|
||||
|
|
|
@ -8,26 +8,29 @@ import { UserAction } from './UserAction';
|
|||
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()
|
||||
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 })
|
||||
@IsUUID(4)
|
||||
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 })
|
||||
@IsEmail()
|
||||
email?: string;
|
||||
|
||||
/**
|
||||
* user phone
|
||||
* The user's phone number.
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsOptional()
|
||||
|
@ -35,14 +38,15 @@ export class User extends Principal {
|
|||
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 })
|
||||
@IsString()
|
||||
username?: string;
|
||||
|
||||
/**
|
||||
* firstname
|
||||
* The user's first name.
|
||||
*/
|
||||
@Column()
|
||||
@IsString()
|
||||
|
@ -50,7 +54,7 @@ export class User extends Principal {
|
|||
firstname: string;
|
||||
|
||||
/**
|
||||
* middlename
|
||||
* The user's middle name.
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
@IsString()
|
||||
|
@ -58,7 +62,7 @@ export class User extends Principal {
|
|||
middlename?: string;
|
||||
|
||||
/**
|
||||
* lastname
|
||||
* The user's last name.
|
||||
*/
|
||||
@Column()
|
||||
@IsString()
|
||||
|
@ -66,7 +70,8 @@ export class User extends Principal {
|
|||
lastname: string;
|
||||
|
||||
/**
|
||||
* password
|
||||
* The user's password.
|
||||
* This is a argon2 hash salted with the user's uuid.
|
||||
*/
|
||||
@Column()
|
||||
@IsString()
|
||||
|
@ -74,7 +79,8 @@ export class User extends Principal {
|
|||
password: string;
|
||||
|
||||
/**
|
||||
* groups
|
||||
* The groups this user is a part of.
|
||||
* The user will inherit the groups permissions (without overwriting his own).
|
||||
*/
|
||||
@IsOptional()
|
||||
@ManyToMany(() => UserGroup, { nullable: true })
|
||||
|
@ -82,21 +88,23 @@ export class User extends Principal {
|
|||
groups: UserGroup[];
|
||||
|
||||
/**
|
||||
* is user enabled?
|
||||
* Is this user enabled?
|
||||
*/
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
enabled: boolean = true;
|
||||
|
||||
/**
|
||||
* jwt refresh count
|
||||
* The user's jwt refresh token count.
|
||||
* Used to invalidate jwts.
|
||||
*/
|
||||
@IsInt()
|
||||
@Column({ default: 1 })
|
||||
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 })
|
||||
@IsString()
|
||||
|
@ -104,14 +112,15 @@ export class User extends Principal {
|
|||
profilePic?: string;
|
||||
|
||||
/**
|
||||
* actions
|
||||
* The actions performed by this user.
|
||||
* For documentation purposes only, will be implemented later.
|
||||
*/
|
||||
@IsOptional()
|
||||
@OneToMany(() => UserAction, action => action.user, { nullable: true })
|
||||
actions: UserAction[]
|
||||
|
||||
/**
|
||||
* Turn this into a response.
|
||||
* Turns this entity into it's response class.
|
||||
*/
|
||||
public toResponse(): ResponsePrincipal {
|
||||
return new ResponseUser(this);
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
import {
|
||||
IsEnum,
|
||||
IsInt,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString
|
||||
} from "class-validator";
|
||||
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { PermissionAction } from '../enums/PermissionAction';
|
||||
import { User } from './User';
|
||||
|
||||
/**
|
||||
* Defines the UserAction interface.
|
||||
* Defines the UserAction entity.
|
||||
* Will later be used to document a user's actions.
|
||||
*/
|
||||
@Entity()
|
||||
export class UserAction {
|
||||
|
@ -20,7 +23,7 @@ export class UserAction {
|
|||
id: number;
|
||||
|
||||
/**
|
||||
* user
|
||||
* The user that performed the action.
|
||||
*/
|
||||
@ManyToOne(() => User, user => user.actions)
|
||||
user: User
|
||||
|
@ -34,15 +37,16 @@ export class UserAction {
|
|||
target: string;
|
||||
|
||||
/**
|
||||
* The actions's action (e.g. UPDATE)
|
||||
* The actions's action (e.g. UPDATE).
|
||||
* Directly pulled from the PermissionAction Enum.
|
||||
*/
|
||||
@Column()
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
action: string;
|
||||
@Column({ type: 'varchar' })
|
||||
@IsEnum(PermissionAction)
|
||||
action: PermissionAction;
|
||||
|
||||
/**
|
||||
* 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 })
|
||||
@IsOptional()
|
||||
|
|
|
@ -9,7 +9,8 @@ import { ResponseUserGroup } from '../responses/ResponseUserGroup';
|
|||
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()
|
||||
export class UserGroup extends Principal {
|
||||
|
@ -30,6 +31,9 @@ export class UserGroup extends Principal {
|
|||
@IsString()
|
||||
description?: string;
|
||||
|
||||
/**
|
||||
* Turns this entity into it's response class.
|
||||
*/
|
||||
public toResponse(): ResponsePrincipal {
|
||||
return new ResponseUserGroup(this);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue