From 774860075b0835b066427604afb41c6701c0b039 Mon Sep 17 00:00:00 2001 From: Alex Zhang Date: Mon, 23 Dec 2024 17:25:02 -0800 Subject: [PATCH] Add TypeORM Response table --- server/models/ResponseModel.ts | 30 +++++++++++++++++++++++ server/models/UserModel.ts | 11 ++++++--- server/models/index.ts | 3 ++- server/repositories/ResponseRepository.ts | 21 ++++++++++++++++ server/repositories/index.ts | 5 ++++ server/services/ResponseService.ts | 21 ++++++++++++++++ server/types/Enums.ts | 4 +++ 7 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 server/models/ResponseModel.ts create mode 100644 server/repositories/ResponseRepository.ts create mode 100644 server/services/ResponseService.ts diff --git a/server/models/ResponseModel.ts b/server/models/ResponseModel.ts new file mode 100644 index 0000000..fd6d28a --- /dev/null +++ b/server/models/ResponseModel.ts @@ -0,0 +1,30 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm"; +import { UserModel } from "./UserModel"; +import { FormType } from "../types/Enums"; +import { Uuid } from "../types/Internal"; + +@Entity('Response') +export class ResponseModel extends BaseEntity { + @PrimaryGeneratedColumn('uuid') + uuid: Uuid; + + @ManyToOne((type) => UserModel, (user) => user.response, { onDelete: 'CASCADE' }) + @JoinColumn({ name: 'user' }) + @Index('response_by_user_index') + user: UserModel; + + @CreateDateColumn() + createdAt: Date; + + @UpdateDateColumn() + updatedAt: Date; + + @Column({ + type: 'enum', + enum: FormType, + }) + formType: FormType; + + @Column({type: 'json'}) + data: object; +} \ No newline at end of file diff --git a/server/models/UserModel.ts b/server/models/UserModel.ts index e8a5ae3..d44f2f8 100644 --- a/server/models/UserModel.ts +++ b/server/models/UserModel.ts @@ -1,10 +1,12 @@ -import { Column, Entity, PrimaryColumn } from 'typeorm'; +import { Column, Entity, OneToMany, PrimaryColumn } from 'typeorm'; import { ApplicationStatus, UserAccessType } from '../types/Enums'; +import { ResponseModel } from './ResponseModel'; +import { Uid } from '../types/Internal'; -@Entity() +@Entity('User') export class UserModel { @PrimaryColumn() - uid: string; + uid: Uid; @Column() email: string; @@ -29,6 +31,9 @@ export class UserModel { }) applicationStatus: ApplicationStatus; + @OneToMany((type) => ResponseModel, (response) => response.user, { cascade: true }) + response: ResponseModel; + public isRestricted(): boolean { return this.accessType === UserAccessType.RESTRICTED; } diff --git a/server/models/index.ts b/server/models/index.ts index 322ea07..b05839e 100644 --- a/server/models/index.ts +++ b/server/models/index.ts @@ -1,3 +1,4 @@ import { UserModel } from './UserModel'; +import { ResponseModel } from './ResponseModel'; -export const models = [UserModel]; +export const models = [UserModel, ResponseModel]; diff --git a/server/repositories/ResponseRepository.ts b/server/repositories/ResponseRepository.ts new file mode 100644 index 0000000..d46c013 --- /dev/null +++ b/server/repositories/ResponseRepository.ts @@ -0,0 +1,21 @@ +import Container from 'typedi'; +import { DataSource, EntityRepository, In, SelectQueryBuilder } from 'typeorm'; +import { UserModel } from '../models/UserModel'; +import { Uuid } from '../types/Internal'; +import { ResponseModel } from '../models/ResponseModel'; + +export const ResponseRepository = Container.get(DataSource) + .getRepository(ResponseModel) + .extend({ + async findAll(): Promise { + return this.find(); + }, + + async findByUuid(uuid: Uuid): Promise { + return this.findOneBy({ uuid }); + }, + + async findResponsesForUser(user: UserModel): Promise { + return this.findBy({ user }) + } + }); diff --git a/server/repositories/index.ts b/server/repositories/index.ts index e560572..e5899c0 100644 --- a/server/repositories/index.ts +++ b/server/repositories/index.ts @@ -1,11 +1,16 @@ import { Service } from 'typedi'; import { DataSource, EntityManager } from 'typeorm'; import { UserRepository } from './UserRepository'; +import { ResponseRepository } from './ResponseRepository'; export class Repositories { public static user(entityManager: EntityManager) { return entityManager.withRepository(UserRepository); } + + public static response(entityManager: EntityManager) { + return entityManager.withRepository(ResponseRepository) + } } @Service() diff --git a/server/services/ResponseService.ts b/server/services/ResponseService.ts new file mode 100644 index 0000000..1028557 --- /dev/null +++ b/server/services/ResponseService.ts @@ -0,0 +1,21 @@ +import { Service } from 'typedi'; +import { Repositories, TransactionsManager } from '../repositories'; +import { Uuid } from '../types/Internal'; +import { ResponseModel } from '../models/ResponseModel'; + +@Service() +export class ResponseService { + private transactionsManager: TransactionsManager; + + constructor(transactionsManager: TransactionsManager) { + this.transactionsManager = transactionsManager; + } + + public async findByUuid(uuid: Uuid): Promise { + const response = await this.transactionsManager.readOnly( + async (entityManager) => Repositories.response(entityManager).findByUuid(uuid), + ); + if (!response) throw new Error('Response not found'); + return response; + } +} diff --git a/server/types/Enums.ts b/server/types/Enums.ts index 012e4b6..d183903 100644 --- a/server/types/Enums.ts +++ b/server/types/Enums.ts @@ -13,3 +13,7 @@ export enum ApplicationStatus { REJECTED = 'REJECTED', ALL_DONE = 'ALL_DONE', } + +export enum FormType { + APPLICATION = 'APPLICATION' +} \ No newline at end of file