diff --git a/.env.example b/.env.example index 076d8cd..ebf22c4 100644 --- a/.env.example +++ b/.env.example @@ -6,4 +6,5 @@ DB_USER=bla DB_PASSWORD=bla DB_NAME=bla NODE_ENV=production -POSTALCODE_COUNTRYCODE=DE \ No newline at end of file +POSTALCODE_COUNTRYCODE=DE +SEED_TEST_DATA=false \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index 580c90d..3bdcd27 100644 --- a/src/config.ts +++ b/src/config.ts @@ -9,7 +9,8 @@ export const config = { jwt_secret: process.env.JWT_SECRET || "secretjwtsecret", phone_validation_countrycode: getPhoneCodeLocale(), postalcode_validation_countrycode: getPostalCodeLocale(), - version: process.env.VERSION || require('../package.json').version + version: process.env.VERSION || require('../package.json').version, + seedTestData: getDataSeeding() } let errors = 0 if (typeof config.internal_port !== "number") { @@ -30,4 +31,11 @@ function getPostalCodeLocale(): any { return null; } } +function getDataSeeding(): Boolean { + try { + return JSON.parse(process.env.SEED_TEST_DATA); + } catch (error) { + return false; + } +} export let e = errors \ No newline at end of file diff --git a/src/loaders/database.ts b/src/loaders/database.ts index 9dda78d..0b4a16a 100644 --- a/src/loaders/database.ts +++ b/src/loaders/database.ts @@ -1,6 +1,9 @@ import { createConnection } from "typeorm"; import { runSeeder } from 'typeorm-seeding'; -import { User } from '../models/entities/User'; +import { config } from '../config'; +import { ConfigFlag } from '../models/entities/ConfigFlags'; +import SeedPublicOrg from '../seeds/SeedPublicOrg'; +import SeedTestRunners from '../seeds/SeedTestRunners'; import SeedUsers from '../seeds/SeedUsers'; /** * Loader for the database that creates the database connection and initializes the database tabels. @@ -9,8 +12,20 @@ import SeedUsers from '../seeds/SeedUsers'; export default async () => { const connection = await createConnection(); await connection.synchronize(); - if (await connection.getRepository(User).count() === 0) { + + //The data seeding part + if (!(await connection.getRepository(ConfigFlag).findOne({ option: "seeded:user", value: "true" }))) { await runSeeder(SeedUsers); + await connection.getRepository(ConfigFlag).save({ option: "seeded:user", value: "true" }); } + if (!(await connection.getRepository(ConfigFlag).findOne({ option: "seeded:citizenorg", value: "true" }))) { + await runSeeder(SeedPublicOrg); + await connection.getRepository(ConfigFlag).save({ option: "seeded:citizenorg", value: "true" }); + } + if (!(await connection.getRepository(ConfigFlag).findOne({ option: "seeded:testdata", value: "true" })) && config.seedTestData == true) { + await runSeeder(SeedTestRunners); + await connection.getRepository(ConfigFlag).save({ option: "seeded:testdata", value: "true" }); + } + return connection; }; \ No newline at end of file diff --git a/src/models/entities/ConfigFlags.ts b/src/models/entities/ConfigFlags.ts new file mode 100644 index 0000000..3dd6c69 --- /dev/null +++ b/src/models/entities/ConfigFlags.ts @@ -0,0 +1,27 @@ +import { + IsNotEmpty, + IsString +} from "class-validator"; +import { Column, Entity, PrimaryColumn } from "typeorm"; + +/** + * Defines the ConfigFlag entity. + * This entity can be used to set some flags on db init. +*/ +@Entity() +export class ConfigFlag { + /** + * The flag's name (primary). + */ + @PrimaryColumn() + @IsString() + option: string; + + /** + * The flag's value. + */ + @Column() + @IsString() + @IsNotEmpty() + value: string; +} diff --git a/src/seeds/SeedPublicOrg.ts b/src/seeds/SeedPublicOrg.ts new file mode 100644 index 0000000..57685f8 --- /dev/null +++ b/src/seeds/SeedPublicOrg.ts @@ -0,0 +1,15 @@ +import { Connection } from 'typeorm'; +import { Factory, Seeder } from 'typeorm-seeding'; +import { CreateRunnerOrganisation } from '../models/actions/create/CreateRunnerOrganisation'; +import { RunnerOrganisation } from '../models/entities/RunnerOrganisation'; + +/** + * Seeds the public runner org (named: "Citizen" by default). + */ +export default class SeedPublicOrg implements Seeder { + public async run(factory: Factory, connection: Connection): Promise { + let publicOrg = new CreateRunnerOrganisation(); + publicOrg.name = "Citizen"; + await connection.getRepository(RunnerOrganisation).save(await publicOrg.toEntity()); + } +} \ No newline at end of file diff --git a/src/seeds/SeedTestRunners.ts b/src/seeds/SeedTestRunners.ts new file mode 100644 index 0000000..14725c6 --- /dev/null +++ b/src/seeds/SeedTestRunners.ts @@ -0,0 +1,93 @@ +import { Connection } from 'typeorm'; +import { Factory, Seeder } from 'typeorm-seeding'; +import { CreateGroupContact } from '../models/actions/create/CreateGroupContact'; +import { CreateRunner } from '../models/actions/create/CreateRunner'; +import { CreateRunnerOrganisation } from '../models/actions/create/CreateRunnerOrganisation'; +import { CreateRunnerTeam } from '../models/actions/create/CreateRunnerTeam'; +import { Address } from '../models/entities/Address'; +import { GroupContact } from '../models/entities/GroupContact'; +import { Runner } from '../models/entities/Runner'; +import { RunnerGroup } from '../models/entities/RunnerGroup'; +import { RunnerOrganisation } from '../models/entities/RunnerOrganisation'; +import { RunnerTeam } from '../models/entities/RunnerTeam'; + +/** + * Seeds a test runner org with a test runner team ans some test runners. + * Usefull for testing or demo instances. + */ +export default class SeedTestRunners implements Seeder { + public async run(factory: Factory, connection: Connection): Promise { + let testOrg: RunnerOrganisation = await this.createTestOrg(connection); + let testTeam: RunnerTeam = await this.createTestTeam(connection, testOrg); + await this.createTestContact(connection, testOrg); + await this.createTestRunners(connection, testOrg); + await this.createTestRunners(connection, testTeam); + } + + public async createTestOrg(connection: Connection): Promise { + let testOrg = new CreateRunnerOrganisation(); + testOrg.name = "Test Org"; + + testOrg.address = new Address(); + testOrg.address.address1 = "Test street 1"; + testOrg.address.city = "Herzogenaurach"; + testOrg.address.country = "Germany"; + testOrg.address.postalcode = "90174"; + + return await connection.getRepository(RunnerOrganisation).save(await testOrg.toEntity()); + } + + public async createTestTeam(connection: Connection, org: RunnerOrganisation): Promise { + let testTeam = new CreateRunnerTeam(); + testTeam.name = "Test Team"; + testTeam.parentGroup = org.id; + + return await connection.getRepository(RunnerTeam).save(await testTeam.toEntity()); + } + + public async createTestRunners(connection: Connection, group: RunnerGroup) { + for (let first of this.firstnames) { + for (let last of this.lastnames) { + let runner = new CreateRunner; + runner.firstname = first; + runner.lastname = last; + runner.middlename = group.name; + runner.group = group.id; + await connection.getRepository(Runner).save(await runner.toEntity()); + } + } + } + + public async createTestContact(connection: Connection, group: RunnerGroup) { + let contact = new CreateGroupContact; + contact.firstname = "Test"; + contact.lastname = "Contact"; + contact.email = "test.contact@dev.lauf-fuer-kaya.de"; + contact.groups = group.id; + + contact.address = new Address(); + contact.address.address1 = "First Contact Street 100"; + contact.address.city = "Herzogenaurach"; + contact.address.country = "Germany"; + contact.address.postalcode = "90174"; + + await connection.getRepository(GroupContact).save(await contact.toEntity()); + } + + private firstnames = [ + "Peter", + "Matze", + "Tine", + "Uta", + "Fabian", + "Unicode:ÖÄ?✔⚠" + ] + + private lastnames = [ + "Muster", + "Example", + "Müller", + "Unicode:搆Ǩ>ÙՠƳ|" + ] + +} \ No newline at end of file