base schema

This commit is contained in:
Julian Krauser 2024-08-17 16:38:08 +02:00
parent 5704fe90f6
commit 2931e1a0ea
13 changed files with 4237 additions and 0 deletions

30
.gitignore vendored
View file

@ -130,3 +130,33 @@ dist
.yarn/install-state.gz
.pnp.*
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.env
.DS_Store
dist
dist-ssr
coverage
*.local
.npmrc
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

5
.prettierrc Normal file
View file

@ -0,0 +1,5 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"printWidth": 120
}

28
data-source.ts Normal file
View file

@ -0,0 +1,28 @@
import "dotenv/config";
import "reflect-metadata";
import { DataSource } from "typeorm";
import { member } from "./entities/member";
import { executive_position } from "./entities/executive_position";
import { qualification } from "./entities/qualification";
import { authentication } from "./entities/authentication";
import { session } from "./entities/session";
import { Initial1723905344553 } from "./migrations/1723905344553-initial";
const dataSource = new DataSource({
type: "mysql",
host: process.env.NODE_ENV || process.env.PKGMODE ? "localhost" : process.env.DB_HOST,
port: 3306,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: "members",
synchronize: false,
logging: process.env.NODE_ENV ? true : ["schema", "error", "warn", "log", "migration"],
bigNumberStrings: false,
entities: [member, executive_position, qualification, authentication, session],
migrations: [Initial1723905344553],
migrationsRun: true,
migrationsTransactionMode: "each",
subscribers: [],
});
export { dataSource };

View file

@ -0,0 +1,10 @@
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity()
export class authentication {
@PrimaryColumn({ type: "varchar", length: 36 })
username: string;
@Column({ type: "varchar", length: 255 })
secret: string;
}

View file

@ -0,0 +1,19 @@
import { Column, Entity, ManyToMany, PrimaryColumn } from "typeorm";
import { member } from "./member";
@Entity()
export class executive_position {
@PrimaryColumn({ generated: "uuid", type: "varchar", length: 36 })
id: string;
@Column({ type: "varchar", length: 255 })
postition: string;
@Column({ type: "int", default: 1 })
number_of_performers: string;
@ManyToMany(() => member, (member) => member.positions, {
onDelete: "RESTRICT",
})
members: member[];
}

63
entities/member.ts Normal file
View file

@ -0,0 +1,63 @@
import { Column, Entity, JoinTable, ManyToMany, PrimaryColumn, Unique } from "typeorm";
import { executive_position } from "./executive_position";
import { qualification } from "./qualification";
@Entity()
export class member {
@PrimaryColumn({ generated: "uuid", type: "varchar", length: 36 })
id: string;
@Column({ type: "varchar", length: 255, unique: true, nullable: true })
member_id: string;
@Column({ type: "varchar", length: 255 })
firstname: string;
@Column({ type: "varchar", length: 255 })
lastname: string;
@Column({ type: "varchar", length: 255 })
phone: string;
@Column({ type: "varchar", length: 255 })
mobile: string;
@Column({ type: "varchar", length: 255 })
email: string;
@Column({ type: "varchar", length: 255 })
postal_code: string;
@Column({ type: "varchar", length: 255 })
place: string;
@Column({ type: "varchar", length: 255 })
street: string;
@Column({ type: "date" })
birthdate: Date;
@Column({ type: "date" })
accession_date: Date;
@Column({ type: "date", nullable: true, default: null })
leaving_data: Date;
@Column({ type: "boolean", default: true })
active: boolean;
@Column({ type: "boolean", default: false })
push_alert: boolean;
@ManyToMany(() => executive_position, (executive_position) => executive_position.members, {
onDelete: "CASCADE",
})
@JoinTable({ name: "member_executive_position" })
positions: executive_position[];
@ManyToMany(() => qualification, (qualification) => qualification.members, {
onDelete: "CASCADE",
})
@JoinTable({ name: "member_qualification" })
qualifications: qualification[];
}

19
entities/qualification.ts Normal file
View file

@ -0,0 +1,19 @@
import { Column, Entity, ManyToMany, PrimaryColumn } from "typeorm";
import { member } from "./member";
@Entity()
export class qualification {
@PrimaryColumn({ generated: "uuid", type: "varchar", length: 36 })
id: string;
@Column({ type: "varchar", length: 255 })
qualification: string;
@Column({ type: "int", default: 1 })
number_of_performers: string;
@ManyToMany(() => member, (member) => member.positions, {
onDelete: "RESTRICT",
})
members: member[];
}

14
entities/session.ts Normal file
View file

@ -0,0 +1,14 @@
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm";
import { member } from "./member";
@Entity()
export class session {
@PrimaryColumn({ type: "varchar", length: 36 })
accessToken: string;
@Column({ type: "datetime" })
expiration: Date;
@ManyToOne(() => member)
member: member;
}

9
index.ts Normal file
View file

@ -0,0 +1,9 @@
import "dotenv/config";
import "reflect-metadata";
export { dataSource } from "./data-source";
export { member } from "./entities/member";
export { qualification } from "./entities/qualification";
export { executive_position } from "./entities/executive_position";
export { authentication } from "./entities/authentication";
export { session } from "./entities/session";

View file

@ -0,0 +1,41 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class Initial1723905344553 implements MigrationInterface {
name = 'Initial1723905344553'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE \`executive_position\` (\`id\` varchar(36) NOT NULL, \`postition\` varchar(255) NOT NULL, \`number_of_performers\` int NOT NULL DEFAULT '1', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
await queryRunner.query(`CREATE TABLE \`qualification\` (\`id\` varchar(36) NOT NULL, \`qualification\` varchar(255) NOT NULL, \`number_of_performers\` int NOT NULL DEFAULT '1', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
await queryRunner.query(`CREATE TABLE \`member\` (\`id\` varchar(36) NOT NULL, \`member_id\` varchar(255) NULL, \`firstname\` varchar(255) NOT NULL, \`lastname\` varchar(255) NOT NULL, \`phone\` varchar(255) NOT NULL, \`mobile\` varchar(255) NOT NULL, \`email\` varchar(255) NOT NULL, \`postal_code\` varchar(255) NOT NULL, \`place\` varchar(255) NOT NULL, \`street\` varchar(255) NOT NULL, \`birthdate\` date NOT NULL, \`accession_date\` date NOT NULL, \`leaving_data\` date NULL, \`active\` tinyint NOT NULL DEFAULT 1, \`push_alert\` tinyint NOT NULL DEFAULT 0, UNIQUE INDEX \`IDX_73e1828d94de0b2ddf89da0546\` (\`member_id\`), PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
await queryRunner.query(`CREATE TABLE \`authentication\` (\`username\` varchar(36) NOT NULL, \`secret\` varchar(255) NOT NULL, PRIMARY KEY (\`username\`)) ENGINE=InnoDB`);
await queryRunner.query(`CREATE TABLE \`session\` (\`accessToken\` varchar(36) NOT NULL, \`expiration\` datetime NOT NULL, \`memberId\` varchar(36) NULL, PRIMARY KEY (\`accessToken\`)) ENGINE=InnoDB`);
await queryRunner.query(`CREATE TABLE \`member_executive_position\` (\`memberId\` varchar(36) NOT NULL, \`executivePositionId\` varchar(36) NOT NULL, INDEX \`IDX_d624e879b218a815ba6280ee03\` (\`memberId\`), INDEX \`IDX_871ad125ada81704d0ff5f77fd\` (\`executivePositionId\`), PRIMARY KEY (\`memberId\`, \`executivePositionId\`)) ENGINE=InnoDB`);
await queryRunner.query(`CREATE TABLE \`member_qualification\` (\`memberId\` varchar(36) NOT NULL, \`qualificationId\` varchar(36) NOT NULL, INDEX \`IDX_6e044da7d52bc06dbe86451acd\` (\`memberId\`), INDEX \`IDX_0cd599d7a2617a381266258693\` (\`qualificationId\`), PRIMARY KEY (\`memberId\`, \`qualificationId\`)) ENGINE=InnoDB`);
await queryRunner.query(`ALTER TABLE \`session\` ADD CONSTRAINT \`FK_1f8d57f74fb4486a743d89d4820\` FOREIGN KEY (\`memberId\`) REFERENCES \`member\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE \`member_executive_position\` ADD CONSTRAINT \`FK_d624e879b218a815ba6280ee035\` FOREIGN KEY (\`memberId\`) REFERENCES \`member\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`);
await queryRunner.query(`ALTER TABLE \`member_executive_position\` ADD CONSTRAINT \`FK_871ad125ada81704d0ff5f77fda\` FOREIGN KEY (\`executivePositionId\`) REFERENCES \`executive_position\`(\`id\`) ON DELETE RESTRICT ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE \`member_qualification\` ADD CONSTRAINT \`FK_6e044da7d52bc06dbe86451acdc\` FOREIGN KEY (\`memberId\`) REFERENCES \`member\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`);
await queryRunner.query(`ALTER TABLE \`member_qualification\` ADD CONSTRAINT \`FK_0cd599d7a2617a3812662586930\` FOREIGN KEY (\`qualificationId\`) REFERENCES \`qualification\`(\`id\`) ON DELETE RESTRICT ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE \`member_qualification\` DROP FOREIGN KEY \`FK_0cd599d7a2617a3812662586930\``);
await queryRunner.query(`ALTER TABLE \`member_qualification\` DROP FOREIGN KEY \`FK_6e044da7d52bc06dbe86451acdc\``);
await queryRunner.query(`ALTER TABLE \`member_executive_position\` DROP FOREIGN KEY \`FK_871ad125ada81704d0ff5f77fda\``);
await queryRunner.query(`ALTER TABLE \`member_executive_position\` DROP FOREIGN KEY \`FK_d624e879b218a815ba6280ee035\``);
await queryRunner.query(`ALTER TABLE \`session\` DROP FOREIGN KEY \`FK_1f8d57f74fb4486a743d89d4820\``);
await queryRunner.query(`DROP INDEX \`IDX_0cd599d7a2617a381266258693\` ON \`member_qualification\``);
await queryRunner.query(`DROP INDEX \`IDX_6e044da7d52bc06dbe86451acd\` ON \`member_qualification\``);
await queryRunner.query(`DROP TABLE \`member_qualification\``);
await queryRunner.query(`DROP INDEX \`IDX_871ad125ada81704d0ff5f77fd\` ON \`member_executive_position\``);
await queryRunner.query(`DROP INDEX \`IDX_d624e879b218a815ba6280ee03\` ON \`member_executive_position\``);
await queryRunner.query(`DROP TABLE \`member_executive_position\``);
await queryRunner.query(`DROP TABLE \`session\``);
await queryRunner.query(`DROP TABLE \`authentication\``);
await queryRunner.query(`DROP INDEX \`IDX_73e1828d94de0b2ddf89da0546\` ON \`member\``);
await queryRunner.query(`DROP TABLE \`member\``);
await queryRunner.query(`DROP TABLE \`qualification\``);
await queryRunner.query(`DROP TABLE \`executive_position\``);
}
}

3944
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

39
package.json Normal file
View file

@ -0,0 +1,39 @@
{
"name": "@ehrenamt/members_database",
"version": "0.0.0",
"description": "database package across administration, webpage and fireportal",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"scripts": {
"migrate_": "npm run migrate --name=%npm_config_name%",
"migrate": "set PKGMODE=migration && npx typeorm-ts-node-commonjs migration:generate ./migrations/%npm_config_name% -d ./data-source.ts",
"update-database": "set PKGMODE=update-database && npx typeorm-ts-node-commonjs migration:run -d ./data-source.ts",
"build": "tsup index.ts --format cjs,esm --dts && npx fix-tsup-cjs",
"buildAndPublish": "npm run build && npm publish"
},
"repository": {
"type": "git",
"url": "git+https://forgejo.jk-effects.cloud/Ehrenamt/members-database.git"
},
"keywords": [
"Feuerwehr"
],
"author": "JK Effects",
"license": "GPL-3.0-only",
"dependencies": {
"mysql": "^2.18.1",
"reflect-metadata": "^0.2.2",
"typeorm": "^0.3.20"
},
"devDependencies": {
"@types/mysql": "^2.15.21",
"@types/node": "^16.18.41",
"ts-node": "10.7.0",
"tsup": "^7.2.0",
"typescript": "^4.5.2"
},
"publishConfig": {
"@ehrenamt:registry": "https://npm.registry.jk-effects.cloud"
}
}

16
tsconfig.json Normal file
View file

@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "esnext",
"module": "CommonJS",
"noEmit": true,
"esModuleInterop": true,
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true,
"noUncheckedIndexedAccess": true,
"skipLibCheck": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"include": ["./"],
"exclude": ["node_modules"]
}