#5-intelligent-groups #23
8 changed files with 314 additions and 2 deletions
|
@ -46,6 +46,11 @@ import { SMSAlarming1732696919191 } from "./migrations/1732696919191-SMSAlarming
|
||||||
import { SecuringCalendarType1733249553766 } from "./migrations/1733249553766-securingCalendarType";
|
import { SecuringCalendarType1733249553766 } from "./migrations/1733249553766-securingCalendarType";
|
||||||
import { query } from "./entity/query";
|
import { query } from "./entity/query";
|
||||||
import { QueryStore1734187754677 } from "./migrations/1734187754677-queryStore";
|
import { QueryStore1734187754677 } from "./migrations/1734187754677-queryStore";
|
||||||
|
import { memberView } from "./views/memberView";
|
||||||
|
import { memberExecutivePositionsView } from "./views/memberExecutivePositionView";
|
||||||
|
import { memberQualificationsView } from "./views/memberQualificationsView";
|
||||||
|
import { membershipView } from "./views/membershipsView";
|
||||||
|
import { MemberDataViews1734520998539 } from "./migrations/1734520998539-memberDataViews";
|
||||||
|
|
||||||
const dataSource = new DataSource({
|
const dataSource = new DataSource({
|
||||||
type: DB_TYPE as any,
|
type: DB_TYPE as any,
|
||||||
|
@ -85,6 +90,10 @@ const dataSource = new DataSource({
|
||||||
calendar,
|
calendar,
|
||||||
calendarType,
|
calendarType,
|
||||||
query,
|
query,
|
||||||
|
memberView,
|
||||||
|
memberExecutivePositionsView,
|
||||||
|
memberQualificationsView,
|
||||||
|
membershipView,
|
||||||
],
|
],
|
||||||
migrations: [
|
migrations: [
|
||||||
Initial1724317398939,
|
Initial1724317398939,
|
||||||
|
@ -102,6 +111,7 @@ const dataSource = new DataSource({
|
||||||
SMSAlarming1732696919191,
|
SMSAlarming1732696919191,
|
||||||
SecuringCalendarType1733249553766,
|
SecuringCalendarType1733249553766,
|
||||||
QueryStore1734187754677,
|
QueryStore1734187754677,
|
||||||
|
MemberDataViews1734520998539,
|
||||||
],
|
],
|
||||||
migrationsRun: true,
|
migrationsRun: true,
|
||||||
migrationsTransactionMode: "each",
|
migrationsTransactionMode: "each",
|
||||||
|
|
|
@ -16,6 +16,10 @@ export default abstract class DynamicQueryBuilder {
|
||||||
"memberExecutivePositions",
|
"memberExecutivePositions",
|
||||||
"memberQualifications",
|
"memberQualifications",
|
||||||
"membership",
|
"membership",
|
||||||
|
"memberView",
|
||||||
|
"memberExecutivePositionsView",
|
||||||
|
"memberQualificationsView",
|
||||||
|
"membershipView",
|
||||||
];
|
];
|
||||||
|
|
||||||
public static getTableMeta(tableName: string): TableMeta {
|
public static getTableMeta(tableName: string): TableMeta {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import express from "express";
|
||||||
import { configCheck, SERVER_PORT } from "./env.defaults";
|
import { configCheck, SERVER_PORT } from "./env.defaults";
|
||||||
configCheck();
|
configCheck();
|
||||||
|
|
||||||
|
import { PermissionObject } from "./type/permissionTypes";
|
||||||
declare global {
|
declare global {
|
||||||
namespace Express {
|
namespace Express {
|
||||||
export interface Request {
|
export interface Request {
|
||||||
|
@ -16,12 +17,10 @@ declare global {
|
||||||
}
|
}
|
||||||
|
|
||||||
import { dataSource } from "./data-source";
|
import { dataSource } from "./data-source";
|
||||||
|
|
||||||
dataSource.initialize();
|
dataSource.initialize();
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
import router from "./routes/index";
|
import router from "./routes/index";
|
||||||
import { PermissionObject } from "./type/permissionTypes";
|
|
||||||
router(app);
|
router(app);
|
||||||
app.listen(process.env.NODE_ENV ? SERVER_PORT : 5000, () => {
|
app.listen(process.env.NODE_ENV ? SERVER_PORT : 5000, () => {
|
||||||
console.log(`listening on *:${SERVER_PORT}`);
|
console.log(`listening on *:${SERVER_PORT}`);
|
||||||
|
|
106
src/migrations/1734520998539-memberDataViews.ts
Normal file
106
src/migrations/1734520998539-memberDataViews.ts
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
import { DataSource, MigrationInterface, QueryRunner, View } from "typeorm";
|
||||||
|
import { member } from "../entity/member";
|
||||||
|
import { memberExecutivePositions } from "../entity/memberExecutivePositions";
|
||||||
|
import { memberQualifications } from "../entity/memberQualifications";
|
||||||
|
import { membership } from "../entity/membership";
|
||||||
|
|
||||||
|
export class MemberDataViews1734520998539 implements MigrationInterface {
|
||||||
|
name = "MemberDataViews1734520998539";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createView(
|
||||||
|
new View({
|
||||||
|
name: "member_view",
|
||||||
|
expression: (datasource: DataSource) =>
|
||||||
|
datasource
|
||||||
|
.getRepository(member)
|
||||||
|
.createQueryBuilder("member")
|
||||||
|
.addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge")
|
||||||
|
.addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear"),
|
||||||
|
}),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
await queryRunner.createView(
|
||||||
|
new View({
|
||||||
|
name: "member_executive_positions_view",
|
||||||
|
expression: (datasource: DataSource) =>
|
||||||
|
datasource
|
||||||
|
.getRepository(memberExecutivePositions)
|
||||||
|
.createQueryBuilder("memberExecutivePositions")
|
||||||
|
.select("executivePosition.id", "positionId")
|
||||||
|
.addSelect("executivePosition.position", "position")
|
||||||
|
.addSelect("member.id", "memberId")
|
||||||
|
.addSelect("member.salutation", "memberSalutation")
|
||||||
|
.addSelect("member.firstname", "memberFirstname")
|
||||||
|
.addSelect("member.lastname", "memberLastname")
|
||||||
|
.addSelect("member.nameaffix", "memberNameaffix")
|
||||||
|
.addSelect("member.birthdate", "memberBirthdate")
|
||||||
|
.addSelect(
|
||||||
|
"SUM(TIMESTAMPDIFF(DAY, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURRENT_DATE)))",
|
||||||
|
"durationInDays"
|
||||||
|
)
|
||||||
|
.leftJoin("memberExecutivePositions.executivePosition", "executivePosition")
|
||||||
|
.leftJoin("memberExecutivePositions.member", "member")
|
||||||
|
.groupBy("executivePosition.id"),
|
||||||
|
}),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
await queryRunner.createView(
|
||||||
|
new View({
|
||||||
|
name: "member_qualifications_view",
|
||||||
|
expression: (datasource: DataSource) =>
|
||||||
|
datasource
|
||||||
|
.getRepository(memberQualifications)
|
||||||
|
.createQueryBuilder("memberQualifications")
|
||||||
|
.select("qualification.id", "qualificationId")
|
||||||
|
.addSelect("qualification.qualification", "qualification")
|
||||||
|
.addSelect("member.id", "memberId")
|
||||||
|
.addSelect("member.salutation", "memberSalutation")
|
||||||
|
.addSelect("member.firstname", "memberFirstname")
|
||||||
|
.addSelect("member.lastname", "memberLastname")
|
||||||
|
.addSelect("member.nameaffix", "memberNameaffix")
|
||||||
|
.addSelect("member.birthdate", "memberBirthdate")
|
||||||
|
.addSelect(
|
||||||
|
"SUM(TIMESTAMPDIFF(DAY, memberQualifications.start, COALESCE(memberQualifications.end, CURRENT_DATE)))",
|
||||||
|
"durationInDays"
|
||||||
|
)
|
||||||
|
.leftJoin("memberQualifications.qualification", "qualification")
|
||||||
|
.leftJoin("memberQualifications.member", "member")
|
||||||
|
.groupBy("qualification.id"),
|
||||||
|
}),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
await queryRunner.createView(
|
||||||
|
new View({
|
||||||
|
name: "membership_view",
|
||||||
|
expression: (datasource: DataSource) =>
|
||||||
|
datasource
|
||||||
|
.getRepository(membership)
|
||||||
|
.createQueryBuilder("membership")
|
||||||
|
.select("status.id", "statusId")
|
||||||
|
.addSelect("status.status", "status")
|
||||||
|
.addSelect("member.id", "memberId")
|
||||||
|
.addSelect("member.salutation", "memberSalutation")
|
||||||
|
.addSelect("member.firstname", "memberFirstname")
|
||||||
|
.addSelect("member.lastname", "memberLastname")
|
||||||
|
.addSelect("member.nameaffix", "memberNameaffix")
|
||||||
|
.addSelect("member.birthdate", "memberBirthdate")
|
||||||
|
.addSelect(
|
||||||
|
"SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))",
|
||||||
|
"durationInDays"
|
||||||
|
)
|
||||||
|
.leftJoin("membership.status", "status")
|
||||||
|
.leftJoin("membership.member", "member")
|
||||||
|
.groupBy("status.id"),
|
||||||
|
}),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropView("membership_view");
|
||||||
|
await queryRunner.dropView("member_qualifications_view");
|
||||||
|
await queryRunner.dropView("member_executive_positions_view");
|
||||||
|
await queryRunner.dropView("member_view");
|
||||||
|
}
|
||||||
|
}
|
53
src/views/memberExecutivePositionView.ts
Normal file
53
src/views/memberExecutivePositionView.ts
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import { DataSource, ViewColumn, ViewEntity } from "typeorm";
|
||||||
|
import { memberExecutivePositions } from "../entity/memberExecutivePositions";
|
||||||
|
import { Salutation } from "../enums/salutation";
|
||||||
|
|
||||||
|
@ViewEntity({
|
||||||
|
expression: (datasource: DataSource) =>
|
||||||
|
datasource
|
||||||
|
.getRepository(memberExecutivePositions)
|
||||||
|
.createQueryBuilder("memberExecutivePositions")
|
||||||
|
.select("executivePosition.id", "positionId")
|
||||||
|
.addSelect("executivePosition.position", "position")
|
||||||
|
.addSelect("member.id", "memberId")
|
||||||
|
.addSelect("member.salutation", "memberSalutation")
|
||||||
|
.addSelect("member.firstname", "memberFirstname")
|
||||||
|
.addSelect("member.lastname", "memberLastname")
|
||||||
|
.addSelect("member.nameaffix", "memberNameaffix")
|
||||||
|
.addSelect("member.birthdate", "memberBirthdate")
|
||||||
|
.addSelect(
|
||||||
|
"SUM(TIMESTAMPDIFF(DAY, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURRENT_DATE)))",
|
||||||
|
"durationInDays"
|
||||||
|
)
|
||||||
|
.leftJoin("memberExecutivePositions.executivePosition", "executivePosition")
|
||||||
|
.leftJoin("memberExecutivePositions.member", "member")
|
||||||
|
.groupBy("executivePosition.id"),
|
||||||
|
})
|
||||||
|
export class memberExecutivePositionsView {
|
||||||
|
@ViewColumn()
|
||||||
|
durationInDays: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
position: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
positionId: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberId: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberSalutation: Salutation;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberFirstname: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberLastname: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberNameaffix: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberBirthdate: Date;
|
||||||
|
}
|
53
src/views/memberQualificationsView.ts
Normal file
53
src/views/memberQualificationsView.ts
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import { DataSource, ViewColumn, ViewEntity } from "typeorm";
|
||||||
|
import { memberQualifications } from "../entity/memberQualifications";
|
||||||
|
import { Salutation } from "../enums/salutation";
|
||||||
|
|
||||||
|
@ViewEntity({
|
||||||
|
expression: (datasource: DataSource) =>
|
||||||
|
datasource
|
||||||
|
.getRepository(memberQualifications)
|
||||||
|
.createQueryBuilder("memberQualifications")
|
||||||
|
.select("qualification.id", "qualificationId")
|
||||||
|
.addSelect("qualification.qualification", "qualification")
|
||||||
|
.addSelect("member.id", "memberId")
|
||||||
|
.addSelect("member.salutation", "memberSalutation")
|
||||||
|
.addSelect("member.firstname", "memberFirstname")
|
||||||
|
.addSelect("member.lastname", "memberLastname")
|
||||||
|
.addSelect("member.nameaffix", "memberNameaffix")
|
||||||
|
.addSelect("member.birthdate", "memberBirthdate")
|
||||||
|
.addSelect(
|
||||||
|
"SUM(TIMESTAMPDIFF(DAY, memberQualifications.start, COALESCE(memberQualifications.end, CURRENT_DATE)))",
|
||||||
|
"durationInDays"
|
||||||
|
)
|
||||||
|
.leftJoin("memberQualifications.qualification", "qualification")
|
||||||
|
.leftJoin("memberQualifications.member", "member")
|
||||||
|
.groupBy("qualification.id"),
|
||||||
|
})
|
||||||
|
export class memberQualificationsView {
|
||||||
|
@ViewColumn()
|
||||||
|
durationInDays: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
qualification: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
qualificationId: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberId: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberSalutation: Salutation;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberFirstname: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberLastname: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberNameaffix: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberBirthdate: Date;
|
||||||
|
}
|
37
src/views/memberView.ts
Normal file
37
src/views/memberView.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { DataSource, ViewColumn, ViewEntity } from "typeorm";
|
||||||
|
import { member } from "../entity/member";
|
||||||
|
import { Salutation } from "../enums/salutation";
|
||||||
|
|
||||||
|
@ViewEntity({
|
||||||
|
expression: (datasource: DataSource) =>
|
||||||
|
datasource
|
||||||
|
.getRepository(member)
|
||||||
|
.createQueryBuilder("member")
|
||||||
|
.addSelect("TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE())", "todayAge")
|
||||||
|
.addSelect("YEAR(CURDATE()) - YEAR(member.birthdate)", "ageThisYear"),
|
||||||
|
})
|
||||||
|
export class memberView {
|
||||||
|
@ViewColumn()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
salutation: Salutation;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
firstname: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
lastname: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
nameaffix: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
birthdate: Date;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
todayAge: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
ageThisYear: number;
|
||||||
|
}
|
50
src/views/membershipsView.ts
Normal file
50
src/views/membershipsView.ts
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { DataSource, ViewColumn, ViewEntity } from "typeorm";
|
||||||
|
import { membership } from "../entity/membership";
|
||||||
|
import { Salutation } from "../enums/salutation";
|
||||||
|
|
||||||
|
@ViewEntity({
|
||||||
|
expression: (datasource: DataSource) =>
|
||||||
|
datasource
|
||||||
|
.getRepository(membership)
|
||||||
|
.createQueryBuilder("membership")
|
||||||
|
.select("status.id", "statusId")
|
||||||
|
.addSelect("status.status", "status")
|
||||||
|
.addSelect("member.id", "memberId")
|
||||||
|
.addSelect("member.salutation", "memberSalutation")
|
||||||
|
.addSelect("member.firstname", "memberFirstname")
|
||||||
|
.addSelect("member.lastname", "memberLastname")
|
||||||
|
.addSelect("member.nameaffix", "memberNameaffix")
|
||||||
|
.addSelect("member.birthdate", "memberBirthdate")
|
||||||
|
.addSelect("SUM(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURRENT_DATE)))", "durationInDays")
|
||||||
|
.leftJoin("membership.status", "status")
|
||||||
|
.leftJoin("membership.member", "member")
|
||||||
|
.groupBy("status.id"),
|
||||||
|
})
|
||||||
|
export class membershipView {
|
||||||
|
@ViewColumn()
|
||||||
|
durationInDays: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
status: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
statusId: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberId: number;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberSalutation: Salutation;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberFirstname: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberLastname: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberNameaffix: string;
|
||||||
|
|
||||||
|
@ViewColumn()
|
||||||
|
memberBirthdate: Date;
|
||||||
|
}
|
Loading…
Reference in a new issue