123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842 |
- // db
- import { selPool, updPool } from "#db";
- import { DbSchema } from "#db-schema";
- import { sql } from "slonik";
- // api
- import { api, apiTypes } from "#api";
- // other
- import { z } from "zod";
- import { RouterUtils } from "#utils/router-utils.js";
- import { Request, Response } from "express";
- import sessionService from "#modules/users/auth/services/session-service.js";
- import { ApiError } from "#exceptions/api-error.js";
- import { v4, v7 } from "uuid";
- import { cPeService } from "./c-pe-service.js";
- import { cCustomFieldsValidateService } from "#modules/client/custom-fields/c-cf-validate-service.js";
- import dayjs from "dayjs";
- import { cActService } from "../c-act-service.js";
- class ClientPeController {
- async getEventPeTypes(
- req: Request,
- res: Response,
- // next: NextFunction
- ) {
- const event = await sessionService.getCurrentEventFromReq(req);
- const peTypes = await selPool.any(sql.type(
- z.object({
- peTypeId: DbSchema.act.peTypes.peTypeId,
- code: DbSchema.act.peTypes.code,
- name: DbSchema.act.peTypes.name,
- }),
- )`
- select
- pe_type_id as "peTypeId",
- code,
- "name"
- from
- act.pe_types pt
- where
- pt.event_inst_id = ${event.eventInstId}
- `);
- RouterUtils.validAndSendResponse(api.client.pe.GET_EventPeTypes.res, res, {
- code: "success",
- peTypes: [...peTypes],
- });
- }
- async getPeTypeForCreate(
- req: Request,
- res: Response,
- // next: NextFunction
- ) {
- const event = await sessionService.getCurrentEventFromReq(req);
- const user = sessionService.getUserFromReq(req);
- const { peTypeCode } = api.client.pe.GET_PeType.req.parse(req.params);
- const eventId = event.eventId;
- const userId = user.userId;
- const peType = await cPeService.getPeTypeWithFieldsAndUserCopyValues(
- userId,
- peTypeCode,
- eventId,
- );
- if (!peType)
- throw ApiError.BadRequest(
- "peTypeNotFound",
- "Тип сущности участия не найден",
- );
- RouterUtils.validAndSendResponse(api.client.pe.GET_PeType.res, res, {
- code: "success",
- peType: peType,
- });
- }
- async createPe(req: Request, res: Response) {
- const event = await sessionService.getCurrentEventFromReq(req);
- const user = sessionService.getUserFromReq(req);
- const { fields, peTypeCode, name } =
- api.client.pe.POST_PartEntity.req.formData.body.parse(
- JSON.parse(req.body.body),
- );
- const files = req.files;
- const peType = await cPeService.getPeTypeWithFields(peTypeCode);
- if (!peType)
- throw ApiError.BadRequest(
- "peTypeNotFound",
- "Тип сущности участия не найден",
- );
- const refFields = peType.fields.map((f) => ({
- ...f,
- idKey: "peFfId",
- }));
- // валидация
- const validationResult =
- await cCustomFieldsValidateService.processAndValidateFields({
- inputFields: fields,
- referenceFields: refFields,
- files,
- idKey: "peFfId",
- addOldValue: false,
- });
- if (!validationResult.isValid)
- throw ApiError.BadRequest(
- "fieldsValidationFailed",
- JSON.stringify(validationResult.messages),
- );
- const validatedFields = validationResult.checkedfields;
- //
- //
- // вставляем в базу и сохраняем файлы
- const peId = v7();
- await updPool.transaction(async (tr) => {
- await tr.query(sql.unsafe`
- insert into act.part_entities
- (pe_id, pe_type_id, event_inst_id, owner_id, name)
- values
- (${peId}, ${peType.peTypeId}, ${event.eventInstId}, ${user.userId}, ${name})
- `);
- if (peType.isJoinAfterCreate) {
- await tr.query(sql.unsafe`
- insert into act.pe_members
- (pe_member_id, pe_id, user_id)
- values
- (${v7()}, ${peId}, ${user.userId})
- `);
- }
- await cCustomFieldsValidateService.saveCustomFieldValuesInTransaction({
- tr,
- parentId: peId,
- action: "peCreate",
- inputFields: validatedFields,
- files,
- isDeleteBefore: false,
- });
- });
- RouterUtils.validAndSendResponse(api.client.pe.POST_PartEntity.res, res, {
- code: "success",
- peId,
- });
- }
- async getPeForPatch(req: Request, res: Response) {
- const { peId } = api.client.pe.GET_PeForPatch.req.parse(req.params);
- const user = sessionService.getUserFromReq(req);
- const pe = await cPeService.getPeWithValidatorsAndValues(peId);
- if (!pe)
- throw ApiError.BadRequest("peNotFound", "Сущность участия не найдена");
- if (pe.ownerId !== user.userId) throw ApiError.ForbiddenError();
- RouterUtils.validAndSendResponse(api.client.pe.GET_PeForPatch.res, res, {
- code: "success",
- pe: pe,
- });
- }
- async patchPe(req: Request, res: Response) {
- const { peId } = api.client.pe.PATCH_PartEntity.req.params.parse(
- req.params,
- );
- const { name, fields } =
- api.client.pe.PATCH_PartEntity.req.formData.body.parse(
- JSON.parse(req.body.body),
- );
- const files = req.files;
- const user = sessionService.getUserFromReq(req);
- const peType = await cPeService.getPeWithValidatorsAndValues(peId);
- if (!peType)
- throw ApiError.BadRequest(
- "peTypeNotFound",
- "Тип сущности участия не найден",
- );
- // проверка доступа
- if (peType.ownerId !== user.userId) throw ApiError.ForbiddenError();
- const refFields = peType.fields
- .map((f) => ({
- ...f,
- idKey: "peFfId",
- }))
- // только изменяемые
- .filter((f) => fields.some((ff) => ff.peFfId === f.peFfId));
- // валидация
- const validationResult =
- await cCustomFieldsValidateService.processAndValidateFields({
- inputFields: fields,
- referenceFields: refFields,
- files,
- idKey: "peFfId",
- addOldValue: true,
- });
- if (!validationResult.isValid)
- throw ApiError.BadRequest(
- "fieldsValidationFailed",
- JSON.stringify(validationResult.messages),
- );
- const validatedFields = validationResult.checkedfields;
- //
- //
- // вставляем в базу и сохраняем файлы
- await updPool.transaction(async (tr) => {
- if (name) {
- await tr.query(sql.unsafe`
- update act.part_entities
- set
- name = ${name}
- where
- pe_id = ${peId}
- `);
- }
- await cCustomFieldsValidateService.saveCustomFieldValuesInTransaction({
- tr,
- parentId: peId,
- action: "peCreate",
- inputFields: validatedFields,
- files,
- isDeleteBefore: true,
- });
- });
- RouterUtils.validAndSendResponse(api.client.pe.PATCH_PartEntity.res, res, {
- code: "success",
- });
- }
- async getMyPes(req: Request, res: Response) {
- const user = sessionService.getUserFromReq(req);
- const event = await sessionService.getCurrentEventFromReq(req);
- const ownerPes = await selPool.any(sql.type(
- z.object({
- peId: DbSchema.act.partEntities.peId,
- peTypeId: DbSchema.act.partEntities.peTypeId,
- peTypeCode: DbSchema.act.peTypes.code,
- peTypeName: DbSchema.act.peTypes.name,
- eventInstId: DbSchema.act.partEntities.eventInstId,
- ownerId: DbSchema.act.partEntities.ownerId,
- name: DbSchema.act.partEntities.name,
- }),
- )`
- select
- pe.pe_id "peId",
- pe.event_inst_id "eventInstId",
- pe.owner_id "ownerId",
- pe.pe_type_id "peTypeId",
- pt.code "peTypeCode",
- pt."name" "peTypeName",
- pe."name"
- from
- act.part_entities pe
- join act.pe_types pt on
- pt.pe_type_id = pe.pe_type_id
- where
- pe.event_inst_id = ${event.eventInstId}
- and pe.owner_id = ${user.userId}
- `);
- const memberPes = await selPool.any(sql.type(
- z.object({
- peMemberId: DbSchema.act.peMembers.peMemberId,
- peId: DbSchema.act.partEntities.peId,
- peTypeId: DbSchema.act.partEntities.peTypeId,
- peTypeCode: DbSchema.act.peTypes.code,
- peTypeName: DbSchema.act.peTypes.name,
- ownerId: DbSchema.act.partEntities.ownerId,
- name: DbSchema.act.partEntities.name,
- }),
- )`
- select
- pm.pe_member_id "peMemberId",
- pe.pe_id "peId",
- pe.event_inst_id "peInstId",
- pe.owner_id "ownerId",
- pe.pe_type_id "peTypeId",
- pt.code "peTypeCode",
- pt."name" "peTypeName",
- pe."name"
- from
- act.pe_members pm
- join act.part_entities pe on
- pe.pe_id = pm.pe_id
- join act.pe_types pt on
- pt.pe_type_id = pe.pe_type_id
- where
- pe.event_inst_id = ${event.eventInstId}
- and pm.user_id = ${user.userId}
- and pm.is_active = true
- `);
- RouterUtils.validAndSendResponse(api.client.pe.GET_MyPes.res, res, {
- code: "success",
- owner: [...ownerPes],
- memeber: [...memberPes],
- });
- }
- async getPe(req: Request, res: Response) {
- const user = sessionService.getUserFromReq(req);
- const { peId } = api.client.pe.GET_PartEntity.req.parse(req.params);
- const isOwner = await selPool.exists(
- sql.unsafe`
- select
- pe_id
- from
- act.part_entities pe
- where
- pe.owner_id = ${user.userId}
- and pe.pe_id = ${peId}
- `,
- );
- // валделец
- if (isOwner) {
- const pe = await cPeService.getPeWithValues(peId);
- const members = await cPeService.getPeMembersWithFields(peId);
- const invites = await cPeService.getInvites(peId);
- const peMembersRequests = await cPeService.getPeMembersRequests(peId);
- if (!pe)
- throw ApiError.BadRequest("peNotFound", "Сущность участия не найдена");
- if (pe.ownerId !== user.userId) throw ApiError.ForbiddenError();
- RouterUtils.validAndSendResponse(api.client.pe.GET_PartEntity.res, res, {
- code: "success",
- pe: {
- ...pe,
- members: [...members],
- invites: [...invites],
- peMembersRequests: [...peMembersRequests],
- userRole: "owner",
- },
- });
- return;
- }
- // участник
- const isMember = await selPool.exists(
- sql.unsafe`
- select
- pm.pe_id
- from
- act.pe_members pm
- where
- pm.user_id = ${user.userId}
- and pm.pe_id = ${peId}
- and pm.is_active = true
- `,
- );
- if (!isMember) throw ApiError.ForbiddenError();
- const pe = await cPeService.getPeForMember(peId);
- if (!pe)
- throw ApiError.BadRequest("peNotFound", "Сущность участия не найдена");
- RouterUtils.validAndSendResponse(api.client.pe.GET_PartEntity.res, res, {
- code: "success",
- pe: { ...pe, userRole: "member" },
- });
- }
- async joinToPe(req: Request, res: Response) {
- const user = sessionService.getUserFromReq(req);
- const { peId } = api.client.pe.POST_JoinToPe.req.params.parse(req.params);
- const isOwner = await cPeService.checkPeOwner(user.userId, peId);
- if (!isOwner) throw ApiError.ForbiddenError();
- const peMember = await selPool.maybeOne(sql.type(
- z.object({
- isActive: DbSchema.act.peMembers.isActive,
- peMemberId: DbSchema.act.peMembers.peMemberId,
- }),
- )`
- select
- pm.pe_member_id "peMemberId",
- pm.is_active "isActive"
- from
- act.pe_members pm
- where
- pm.pe_id = ${peId} and
- pm.user_id = ${user.userId}
- `);
- if (peMember && peMember.isActive) {
- throw ApiError.BadRequest(
- "peMemberAlreadyExists",
- "Участник уже в сущности участия",
- );
- }
- const memberId = v7();
- await updPool.transaction(async (tr) => {
- if (peMember) {
- await tr.query(sql.unsafe`
- update act.pe_members
- set
- is_active = true
- where
- pe_member_id = ${peMember.peMemberId}
- `);
- } else {
- await tr.query(sql.unsafe`
- insert into act.pe_members
- (pe_member_id, pe_id, user_id, is_active)
- values
- (${memberId}, ${peId}, ${user.userId}, true)
- `);
- }
- await cPeService.updateAllActRegStatusByPe(peId);
- });
- RouterUtils.validAndSendResponse(api.client.pe.POST_JoinToPe.res, res, {
- code: "success",
- memberId,
- });
- }
- async createInvite(req: Request, res: Response) {
- const user = sessionService.getUserFromReq(req);
- const { name, limitVal, expirationDate } =
- api.client.pe.POST_Invite.req.body.parse(req.body);
- const { peId } = api.client.pe.POST_Invite.req.params.parse(req.params);
- const isOwner = await cPeService.checkPeOwner(user.userId, peId);
- if (!isOwner) throw ApiError.ForbiddenError();
- const peInviteId = v7();
- const peInviteUuid = v4();
- await updPool.transaction(async (t) => {
- await t.query(sql.unsafe`
- insert into act.pe_invites
- (pe_invite_id, pe_invite_uuid, pe_id, limit_val, name, expiration_date)
- values
- (${peInviteId}, ${peInviteUuid}, ${peId}, ${limitVal}, ${name}, ${expirationDate})
- `);
- });
- RouterUtils.validAndSendResponse(api.client.pe.POST_Invite.res, res, {
- code: "success",
- peInviteId,
- });
- }
- async getInvites(req: Request, res: Response) {
- const user = sessionService.getUserFromReq(req);
- const { peId } = api.client.pe.GET_Invites.req.parse(req.params);
- const isOwner = await cPeService.checkPeOwner(user.userId, peId);
- if (!isOwner) throw ApiError.ForbiddenError();
- const invites = await cPeService.getInvites(peId);
- RouterUtils.validAndSendResponse(api.client.pe.GET_Invites.res, res, {
- code: "success",
- invites: [...invites],
- });
- }
- async getInviteInfo(req: Request, res: Response) {
- const { peInviteUuid } = api.client.pe.GET_InviteInfo.req.params.parse(
- req.params,
- );
- const user = sessionService.getUserFromReq(req);
- const invite = await cPeService.getInviteInfo(peInviteUuid);
- if (!invite)
- throw ApiError.BadRequest("inviteNotFound", "Приглашение не найдено");
- const request = await cPeService.checkPeMemberInvite({
- peInviteId: invite.peInviteId,
- userId: user.userId,
- });
- if (dayjs(invite.expirationDate).isBefore(dayjs()))
- throw ApiError.BadRequest("inviteExpired", "Приглашение истекло");
- if (request)
- throw ApiError.BadRequest("requestAlreadyExists", "Запрос уже отправлен");
- RouterUtils.validAndSendResponse(api.client.pe.GET_InviteInfo.res, res, {
- code: "success",
- invite,
- });
- }
- async acceptInvite(req: Request, res: Response) {
- const user = sessionService.getUserFromReq(req);
- const { peInviteUuid } = api.client.pe.POST_AcceptInvite.req.params.parse(
- req.params,
- );
- const invite = await cPeService.getInviteInfo(peInviteUuid);
- // приглашение не найдено
- if (!invite) {
- RouterUtils.validAndSendResponse(
- api.client.pe.POST_AcceptInvite.res,
- res,
- {
- code: "inviteNotFound",
- },
- 400,
- );
- return;
- }
- const pe = await selPool.maybeOne(sql.unsafe`
- select
- pe.pe_id,
- pt.max_members,
- members."membersCount"
- from
- act.part_entities pe
- left join act.pe_types pt on
- pt.pe_type_id = pe.pe_type_id
- left join (
- select
- pe_id,
- count(*) as "membersCount"
- from
- act.pe_members
- where
- is_active = true
- group by
- pe_id
- ) members on
- members.pe_id = pe.pe_id
- where
- pe.pe_id = ${invite.peId}
- `);
- if (!pe) {
- throw ApiError.BadRequest("peNotFound", "Сущность участия не найдена");
- }
- // лимит превышен
- if (
- (invite.limitVal && invite.countVal >= invite.limitVal) ||
- (pe.maxMembers !== null && pe.membersCount >= pe.maxMembers)
- ) {
- RouterUtils.validAndSendResponse(
- api.client.pe.POST_AcceptInvite.res,
- res,
- {
- code: "inviteLimitExceeded",
- },
- 400,
- );
- return;
- }
- // приглашение истекло
- if (
- invite.expirationDate &&
- dayjs(invite.expirationDate).isBefore(dayjs())
- ) {
- RouterUtils.validAndSendResponse(
- api.client.pe.POST_AcceptInvite.res,
- res,
- {
- code: "inviteExpired",
- },
- 400,
- );
- return;
- }
- // TODO: много лишних данных
- // участник уже в pe
- const peMembers = await cPeService.getPeMembersWithFields(invite.peId);
- const isFound = peMembers.find((m) => m.userId === user.userId);
- if (isFound) {
- RouterUtils.validAndSendResponse(
- api.client.pe.POST_AcceptInvite.res,
- res,
- {
- code: "peMemberAlreadyExists",
- },
- 400,
- );
- return;
- }
- // запрос уже отправлен
- const isPending = await cPeService.checkPeMemberInvite({
- peInviteId: invite.peInviteId,
- userId: user.userId,
- });
- if (isPending) {
- RouterUtils.validAndSendResponse(
- api.client.pe.POST_AcceptInvite.res,
- res,
- {
- code: "peMemberInviteAlreadyExists",
- },
- 400,
- );
- return;
- }
- await updPool.transaction(async (t) => {
- const id = v7();
- await t.query(sql.unsafe`
- insert into act.pe_members_requests
- (pe_member_request_id, pe_invite_id, user_id, status)
- values
- (${id}, ${invite.peInviteId}, ${user.userId}, 'PENDING')
- `);
- await t.query(sql.unsafe`
- update act.pe_invites
- set
- count_val = count_val + 1
- where
- pe_id = ${invite.peId}
- `);
- });
- RouterUtils.validAndSendResponse(api.client.pe.POST_AcceptInvite.res, res, {
- code: "success",
- peId: invite.peId,
- });
- }
- async patchPeMembersRequests(req: Request, res: Response) {
- const requests = api.client.pe.PATCH_PeMembersRequests.req.body.parse(
- req.body,
- );
- const user = sessionService.getUserFromReq(req);
- const peIdsToRecheck: Set<string> = new Set();
- await updPool.transaction(async (t) => {
- for (const r of requests) {
- const request = await cPeService.getPeMemberRequest(
- r.peMemberRequestId,
- );
- if (!request)
- throw ApiError.BadRequest("requestNotFound", "Запрос не найден");
- const pe = await cPeService.getPeForMember(request.peId);
- if (!pe)
- throw ApiError.BadRequest(
- "peNotFound",
- "Сущность участия не найдена",
- );
- if (pe.ownerId !== user.userId) throw ApiError.ForbiddenError();
- // участник уже в pe
- const peMembers = await cPeService.getPeMembersWithFields(pe.peId);
- const isFound = peMembers.find((m) => m.userId === request.userId);
- if (isFound)
- throw ApiError.BadRequest(
- "memberAlreadyInPe",
- "Участник уже добавлен",
- );
- peIdsToRecheck.add(pe.peId);
- await t.query(sql.unsafe`
- update act.pe_members_requests
- set
- status = ${r.status}
- where
- pe_member_request_id = ${r.peMemberRequestId}
- `);
- if (r.status === "ACCEPTED") {
- await t.query(sql.unsafe`
- insert into act.pe_members
- (pe_id, user_id)
- values
- (${pe.peId}, ${request.userId})
- `);
- }
- }
- });
- for (const peId of peIdsToRecheck) {
- await cPeService.updateAllActRegStatusByPe(peId);
- }
- RouterUtils.validAndSendResponse(
- api.client.pe.PATCH_PeMembersRequests.res,
- res,
- {
- code: "success",
- },
- );
- }
- async getMyPesForActivity(req: Request, res: Response) {
- const user = sessionService.getUserFromReq(req);
- const event = await sessionService.getCurrentEventFromReq(req);
- const pes = await selPool.any(sql.type(apiTypes.activities.PeForActivity)`
- select
- pe.pe_id "peId",
- pe.event_inst_id "eventInstId",
- pe.owner_id "ownerId",
- pe.pe_type_id "peTypeId",
- pt.code "peTypeCode",
- pt."name" "peTypeName",
- pe."name",
- coalesce(m.members, '[]'::jsonb) members,
- v.fields
- from
- act.part_entities pe
- join act.pe_types pt on
- pt.pe_type_id = pe.pe_type_id
- -- members
- left join lateral (
- select
- jsonb_agg(jsonb_build_object(
- 'peMemberId', m.pe_member_id,
- 'userId', m.user_id,
- 'email', m.email,
- 'fields', m.fields
- )) as members
- from
- act.pe_members_with_fields_and_values m
- where
- m.pe_id = pe.pe_id
- ) m on
- true
- -- fields
- left join act.pe_with_fields_and_values v on
- v.pe_id = pe.pe_id
- where
- pe.event_inst_id = ${event.eventInstId}
- and pe.owner_id = ${user.userId}
- `);
- RouterUtils.validAndSendResponse(
- api.client.pe.GET_MyPesForActivity.res,
- res,
- {
- code: "success",
- pes: [...pes],
- },
- );
- }
- async excludeMemberFromPe(req: Request, res: Response) {
- const user = sessionService.getUserFromReq(req);
- const { peMemberId } = api.client.pe.DELETE_PeMember.req.params.parse(
- req.params,
- );
- const peMember = await cPeService.getPeMember(peMemberId);
- if (!peMember)
- throw ApiError.BadRequest("peMemberNotFound", "Участник не найден");
- const pe = await cPeService.getPeForMember(peMember.peId);
- if (!pe)
- throw ApiError.BadRequest("peNotFound", "Сущность участия не найдена");
- if (pe.ownerId !== user.userId) throw ApiError.ForbiddenError();
- await updPool.transaction(async (t) => {
- await cActService.refundByPeMemberId({
- peMemberId,
- peId: pe.peId,
- userId: user.userId,
- });
- await t.query(sql.unsafe`
- update act.pe_members
- set
- is_active = false
- where
- pe_member_id = ${peMemberId}
- `);
- });
- RouterUtils.validAndSendResponse(api.client.pe.DELETE_PeMember.res, res, {
- code: "success",
- });
- }
- async getRelatedActivityRegsToPe(req: Request, res: Response) {
- const user = sessionService.getUserFromReq(req);
- const { peId } = api.client.pe.GET_RelatedActivityRegsToPe.req.params.parse(
- req.params,
- );
- const pe = await cPeService.getPeForMember(peId);
- if (!pe)
- throw ApiError.BadRequest("peNotFound", "Сущность участия не найдена");
- if (pe.ownerId !== user.userId) throw ApiError.ForbiddenError();
- const activityRegs = await cActService.getActivityRegsByPeId(peId);
- RouterUtils.validAndSendResponse(
- api.client.pe.GET_RelatedActivityRegsToPe.res,
- res,
- {
- code: "success",
- activityRegs: [...activityRegs],
- },
- );
- }
- }
- export const clientPeController = new ClientPeController();
|