diff --git a/src/command/protocolAgendaCommandHandler.ts b/src/command/protocolAgendaCommandHandler.ts index d132558..91c7dea 100644 --- a/src/command/protocolAgendaCommandHandler.ts +++ b/src/command/protocolAgendaCommandHandler.ts @@ -4,6 +4,30 @@ import InternalException from "../exceptions/internalException"; import { SynchronizeProtocolAgendaCommand } from "./protocolAgendaCommand"; export default abstract class ProtocolAgendaCommandHandler { + /** + * @description create protocolAgenda + * @param {number} + * @returns {Promise} + */ + static async create(protocolId: number): Promise { + return await dataSource + .createQueryBuilder() + .insert() + .into(protocolAgenda) + .values({ + topic: "", + context: "", + protocolId, + }) + .execute() + .then((result) => { + return result.identifiers[0].id; + }) + .catch((err) => { + throw new InternalException("Failed creating protocol", err); + }); + } + /** * @description sync protocolAgenda * @param {Array} diff --git a/src/command/protocolDecisionCommandHandler.ts b/src/command/protocolDecisionCommandHandler.ts index 3925884..750a40e 100644 --- a/src/command/protocolDecisionCommandHandler.ts +++ b/src/command/protocolDecisionCommandHandler.ts @@ -4,6 +4,29 @@ import InternalException from "../exceptions/internalException"; import { SynchronizeProtocolDecisionCommand } from "./protocolDecisionCommand"; export default abstract class ProtocolDecisionCommandHandler { + /** + * @description create protocolDecision + * @param {number} + * @returns {Promise} + */ + static async create(protocolId: number): Promise { + return await dataSource + .createQueryBuilder() + .insert() + .into(protocolDecision) + .values({ + topic: "", + context: "", + protocolId, + }) + .execute() + .then((result) => { + return result.identifiers[0].id; + }) + .catch((err) => { + throw new InternalException("Failed creating protocol", err); + }); + } /** * @description sync protocolDecision * @param {Array} diff --git a/src/command/protocolPresenceCommandHandler.ts b/src/command/protocolPresenceCommandHandler.ts index 7d7a5f7..b773cc6 100644 --- a/src/command/protocolPresenceCommandHandler.ts +++ b/src/command/protocolPresenceCommandHandler.ts @@ -21,13 +21,17 @@ export default abstract class ProtocolPresenceCommandHandler { let newMembers = syncProtocolPresences.memberIds.filter((r) => !currentPresence.includes(r)); let removeMembers = currentPresence.filter((r) => !syncProtocolPresences.memberIds.includes(r)); - await this.syncPresenceAdd(manager, syncProtocolPresences.protocolId, newMembers); + if (newMembers.length != 0) { + await this.syncPresenceAdd(manager, syncProtocolPresences.protocolId, newMembers); + } - await this.syncPresenceRemove(manager, syncProtocolPresences.protocolId, removeMembers); + if (removeMembers.length != 0) { + await this.syncPresenceRemove(manager, syncProtocolPresences.protocolId, removeMembers); + } }) .then(() => {}) .catch((err) => { - throw new InternalException("Failed saving user roles", err); + throw new InternalException("Failed saving protocol presence", err); }); } @@ -43,7 +47,7 @@ export default abstract class ProtocolPresenceCommandHandler { .values( memberIds.map((m) => ({ protocolId, - memberIds: m, + memberId: m, })) ) .execute(); @@ -59,7 +63,7 @@ export default abstract class ProtocolPresenceCommandHandler { .delete() .from(protocolPresence) .where("memberId IN (:...ids)", { ids: memberIds }) - .andWhere("protcolId = :protocolId", { protocolId }) + .andWhere("protocolId = :protocolId", { protocolId }) .execute(); } } diff --git a/src/command/protocolVotingCommandHandler.ts b/src/command/protocolVotingCommandHandler.ts index 6ade2f1..bbc9660 100644 --- a/src/command/protocolVotingCommandHandler.ts +++ b/src/command/protocolVotingCommandHandler.ts @@ -4,6 +4,29 @@ import InternalException from "../exceptions/internalException"; import { SynchronizeProtocolVotingCommand } from "./protocolVotingCommand"; export default abstract class ProtocolVotingCommandHandler { + /** + * @description create protocolVoting + * @param {number} + * @returns {Promise} + */ + static async create(protocolId: number): Promise { + return await dataSource + .createQueryBuilder() + .insert() + .into(protocolVoting) + .values({ + topic: "", + context: "", + protocolId, + }) + .execute() + .then((result) => { + return result.identifiers[0].id; + }) + .catch((err) => { + throw new InternalException("Failed creating protocol", err); + }); + } /** * @description sync protocolVoting * @param {Array} diff --git a/src/controller/admin/protocolController.ts b/src/controller/admin/protocolController.ts index 51bf599..3316ec8 100644 --- a/src/controller/admin/protocolController.ts +++ b/src/controller/admin/protocolController.ts @@ -21,6 +21,7 @@ import { SynchronizeProtocolPresenceCommand } from "../../command/protocolPresen import { SynchronizeProtocolDecisionCommand } from "../../command/protocolDecisionCommand"; import { SynchronizeProtocolVotingCommand } from "../../command/protocolVotingCommand"; import { ProtocolVotingViewModel } from "../../viewmodel/admin/protocolVoting.models"; +import ProtocolVotingCommandHandler from "../../command/protocolVotingCommandHandler"; /** * @description get all protocols @@ -129,6 +130,48 @@ export async function createProtocol(req: Request, res: Response): Promise res.send(id); } +/** + * @description create protocol agenda by id + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function createProtocolAgendaById(req: Request, res: Response): Promise { + let protocolId = parseInt(req.params.protocolId); + + let agenda = await ProtocolAgendaCommandHandler.create(protocolId); + + res.send(agenda); +} + +/** + * @description create protocol decisions by id + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function createProtocolDecisonsById(req: Request, res: Response): Promise { + let protocolId = parseInt(req.params.protocolId); + + let decision = await ProtocolDecisionCommandHandler.create(protocolId); + + res.send(decision); +} + +/** + * @description create protocol votings by id + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function createProtocolVotingsById(req: Request, res: Response): Promise { + let protocolId = parseInt(req.params.protocolId); + + let voting = await ProtocolVotingCommandHandler.create(protocolId); + + res.send(voting); +} + /** * @description synchronize protocol by id * @param req {Request} Express req object @@ -202,25 +245,6 @@ export async function synchronizeProtocolDecisonsById(req: Request, res: Respons res.sendStatus(204); } -/** - * @description synchronize protocol precense by id - * @param req {Request} Express req object - * @param res {Response} Express res object - * @returns {Promise<*>} - */ -export async function synchronizeProtocolPrecenseById(req: Request, res: Response): Promise { - let protocolId = parseInt(req.params.protocolId); - let presence = req.body.precense as Array; - - let syncPresence: SynchronizeProtocolPresenceCommand = { - memberIds: presence, - protocolId, - }; - await ProtocolPresenceCommandHandler.sync(syncPresence); - - res.sendStatus(204); -} - /** * @description synchronize protocol votings by id * @param req {Request} Express req object @@ -242,7 +266,26 @@ export async function synchronizeProtocolVotingsById(req: Request, res: Response protocolId, }) ); - await ProtocolDecisionCommandHandler.sync(syncDecision); + await ProtocolVotingCommandHandler.sync(syncDecision); + + res.sendStatus(204); +} + +/** + * @description synchronize protocol precense by id + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function synchronizeProtocolPrecenseById(req: Request, res: Response): Promise { + let protocolId = parseInt(req.params.protocolId); + let presence = req.body.presence as Array; + + let syncPresence: SynchronizeProtocolPresenceCommand = { + memberIds: presence, + protocolId, + }; + await ProtocolPresenceCommandHandler.sync(syncPresence); res.sendStatus(204); } diff --git a/src/data-source.ts b/src/data-source.ts index f08af33..5a1c1f3 100644 --- a/src/data-source.ts +++ b/src/data-source.ts @@ -38,6 +38,7 @@ import { protocolPresence } from "./entity/protocolPresence"; import { protocolVoting } from "./entity/protocolVoting"; import { ProtocolTables1728563204766 } from "./migrations/1728563204766-protocolTables"; import { ProtocolTableRename1728645611919 } from "./migrations/1728645611919-protocolTableRename"; +import { ProtocolTableTypes1728999487170 } from "./migrations/1728999487170-protocolTableTypes"; const dataSource = new DataSource({ type: DB_TYPE as any, @@ -86,6 +87,7 @@ const dataSource = new DataSource({ ProtocolBase1728037129072, ProtocolTables1728563204766, ProtocolTableRename1728645611919, + ProtocolTableTypes1728999487170, ], migrationsRun: true, migrationsTransactionMode: "each", diff --git a/src/entity/protocolAgenda.ts b/src/entity/protocolAgenda.ts index dcfbde4..7ce7556 100644 --- a/src/entity/protocolAgenda.ts +++ b/src/entity/protocolAgenda.ts @@ -9,9 +9,12 @@ export class protocolAgenda { @Column({ type: "varchar", length: 255 }) topic: string; - @Column({ type: "varchar", length: 255, default: "" }) + @Column({ type: "text", default: "" }) context: string; + @Column() + protocolId: number; + @ManyToOne(() => protocol, { nullable: false, onDelete: "CASCADE", diff --git a/src/entity/protocolDecision.ts b/src/entity/protocolDecision.ts index b40d3aa..4978d17 100644 --- a/src/entity/protocolDecision.ts +++ b/src/entity/protocolDecision.ts @@ -9,9 +9,12 @@ export class protocolDecision { @Column({ type: "varchar", length: 255 }) topic: string; - @Column({ type: "varchar", length: 255, default: "" }) + @Column({ type: "text", default: "" }) context: string; + @Column() + protocolId: number; + @ManyToOne(() => protocol, { nullable: false, onDelete: "CASCADE", diff --git a/src/entity/protocolVoting.ts b/src/entity/protocolVoting.ts index 4f3b461..8e8f7a1 100644 --- a/src/entity/protocolVoting.ts +++ b/src/entity/protocolVoting.ts @@ -9,7 +9,7 @@ export class protocolVoting { @Column({ type: "varchar", length: 255 }) topic: string; - @Column({ type: "varchar", length: 255, default: "" }) + @Column({ type: "text", default: "" }) context: string; @Column({ type: "int", default: 0 }) @@ -21,6 +21,9 @@ export class protocolVoting { @Column({ type: "int", default: 0 }) against: number; + @Column() + protocolId: number; + @ManyToOne(() => protocol, { nullable: false, onDelete: "CASCADE", diff --git a/src/factory/admin/protocolAgenda.ts b/src/factory/admin/protocolAgenda.ts index d48c0ef..432c479 100644 --- a/src/factory/admin/protocolAgenda.ts +++ b/src/factory/admin/protocolAgenda.ts @@ -12,7 +12,7 @@ export default abstract class ProtocolAgendaFactory { id: record.id, topic: record.topic, context: record.context, - protocolId: record.protocol.id, + protocolId: record.protocolId, }; } diff --git a/src/factory/admin/protocolDecision.ts b/src/factory/admin/protocolDecision.ts index a23f524..3e33823 100644 --- a/src/factory/admin/protocolDecision.ts +++ b/src/factory/admin/protocolDecision.ts @@ -12,7 +12,7 @@ export default abstract class ProtocolDecisionFactory { id: record.id, topic: record.topic, context: record.context, - protocolId: record.protocol.id, + protocolId: record.protocolId, }; } diff --git a/src/factory/admin/protocolPresence.ts b/src/factory/admin/protocolPresence.ts index 3772be8..59a70ad 100644 --- a/src/factory/admin/protocolPresence.ts +++ b/src/factory/admin/protocolPresence.ts @@ -12,7 +12,7 @@ export default abstract class ProtocolPresenceFactory { return { memberId: record.member.id, member: MemberFactory.mapToSingle(record.member), - protocolId: record.protocol.id, + protocolId: record.protocolId, }; } diff --git a/src/factory/admin/protocolVoting.ts b/src/factory/admin/protocolVoting.ts index 076fe59..19865fb 100644 --- a/src/factory/admin/protocolVoting.ts +++ b/src/factory/admin/protocolVoting.ts @@ -15,7 +15,7 @@ export default abstract class ProtocolVotingFactory { favour: record.favour, abstain: record.abstain, against: record.against, - protocolId: record.protocol.id, + protocolId: record.protocolId, }; } diff --git a/src/migrations/1728999487170-protocolTableTypes.ts b/src/migrations/1728999487170-protocolTableTypes.ts new file mode 100644 index 0000000..ef739f0 --- /dev/null +++ b/src/migrations/1728999487170-protocolTableTypes.ts @@ -0,0 +1,101 @@ +import { MigrationInterface, QueryRunner, TableColumn } from "typeorm"; + +export class ProtocolTableTypes1728999487170 implements MigrationInterface { + name = "ProtocolTableTypes1728999487170"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.changeColumn( + "protocol", + "summary", + new TableColumn({ + name: "summary", + type: "text", + default: "''", + isNullable: false, + }) + ); + + await queryRunner.changeColumn( + "protocol_agenda", + "context", + new TableColumn({ + name: "context", + type: "text", + default: "''", + isNullable: false, + }) + ); + + await queryRunner.changeColumn( + "protocol_decision", + "context", + new TableColumn({ + name: "context", + type: "text", + default: "''", + isNullable: false, + }) + ); + + await queryRunner.changeColumn( + "protocol_voting", + "context", + new TableColumn({ + name: "context", + type: "text", + default: "''", + isNullable: false, + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.changeColumn( + "protocol", + "summary", + new TableColumn({ + name: "summary", + type: "varchar", + length: "255", + default: "''", + isNullable: false, + }) + ); + + await queryRunner.changeColumn( + "protocol_agenda", + "context", + new TableColumn({ + name: "context", + type: "varchar", + length: "255", + default: "''", + isNullable: false, + }) + ); + + await queryRunner.changeColumn( + "protocol_decision", + "context", + new TableColumn({ + name: "context", + type: "varchar", + length: "255", + default: "''", + isNullable: false, + }) + ); + + await queryRunner.changeColumn( + "protocol_voting", + "context", + new TableColumn({ + name: "context", + type: "varchar", + length: "255", + default: "''", + isNullable: false, + }) + ); + } +} diff --git a/src/routes/admin/protocol.ts b/src/routes/admin/protocol.ts index 5edbeee..f7ed9b6 100644 --- a/src/routes/admin/protocol.ts +++ b/src/routes/admin/protocol.ts @@ -1,6 +1,9 @@ import express, { Request, Response } from "express"; import { createProtocol, + createProtocolAgendaById, + createProtocolDecisonsById, + createProtocolVotingsById, getAllProtocols, getProtocolAgendaById, getProtocolById, @@ -44,24 +47,36 @@ router.post("/", async (req: Request, res: Response) => { await createProtocol(req, res); }); -router.put("/:id/synchronize", async (req: Request, res: Response) => { +router.post("/:protocolId/agenda", async (req: Request, res: Response) => { + await createProtocolAgendaById(req, res); +}); + +router.post("/:protocolId/decision", async (req: Request, res: Response) => { + await createProtocolDecisonsById(req, res); +}); + +router.post("/:protocolId/voting", async (req: Request, res: Response) => { + await createProtocolVotingsById(req, res); +}); + +router.patch("/:id/synchronize", async (req: Request, res: Response) => { await synchronizeProtocolById(req, res); }); -router.put("/:protocolId/synchronize/agenda", async (req: Request, res: Response) => { +router.patch("/:protocolId/synchronize/agenda", async (req: Request, res: Response) => { await synchronizeProtocolAgendaById(req, res); }); -router.put("/:protocolId/synchronize/decisions", async (req: Request, res: Response) => { +router.patch("/:protocolId/synchronize/decisions", async (req: Request, res: Response) => { await synchronizeProtocolDecisonsById(req, res); }); +router.patch("/:protocolId/synchronize/votings", async (req: Request, res: Response) => { + await synchronizeProtocolVotingsById(req, res); +}); + router.put("/:protocolId/synchronize/presence", async (req: Request, res: Response) => { await synchronizeProtocolPrecenseById(req, res); }); -router.put("/:protocolId/synchronize/votings", async (req: Request, res: Response) => { - await synchronizeProtocolVotingsById(req, res); -}); - export default router; diff --git a/src/service/protocolPrecenseService.ts b/src/service/protocolPrecenseService.ts index e66c946..c8840c3 100644 --- a/src/service/protocolPrecenseService.ts +++ b/src/service/protocolPrecenseService.ts @@ -11,6 +11,7 @@ export default abstract class ProtocolPresenceService { return await dataSource .getRepository(protocolPresence) .createQueryBuilder("protocolPresence") + .leftJoinAndSelect("protocolPresence.member", "member") .where("protocolPresence.protocolId = :protocolId", { protocolId }) .getMany() .then((res) => { @@ -29,6 +30,7 @@ export default abstract class ProtocolPresenceService { return await dataSource .getRepository(protocolPresence) .createQueryBuilder("protocolPresence") + .leftJoinAndSelect("protocolPresence.member", "member") .where("protocolPresence.id = :id", { id: id }) .getOneOrFail() .then((res) => {