|
@@ -13,7 +13,10 @@ import { RouterUtils } from "#utils/router-utils.js";
|
|
|
|
|
|
import { Request, Response } from "express";
|
|
|
import sessionService from "#modules/users/auth/services/session-service.js";
|
|
|
-import { CustomFieldWithUserCopyValue } from "#api/v_0.1.0/types/pe-types.js";
|
|
|
+import {
|
|
|
+ CustomFieldWithUserCopyValue,
|
|
|
+ CustomFieldWithValue,
|
|
|
+} from "#api/v_0.1.0/types/pe-types.js";
|
|
|
import { ApiError } from "#exceptions/api-error.js";
|
|
|
import { v7 } from "uuid";
|
|
|
|
|
@@ -61,10 +64,10 @@ class ClientPeController {
|
|
|
const userId = user.userId;
|
|
|
const peType = await selPool.maybeOne(sql.type(
|
|
|
z.object({
|
|
|
- peTypeId: z.string(),
|
|
|
- code: z.string(),
|
|
|
- name: z.string(),
|
|
|
- eventInstId: z.string(),
|
|
|
+ peTypeId: DbSchema.act.peTypes.peTypeId,
|
|
|
+ code: DbSchema.act.peTypes.code,
|
|
|
+ name: DbSchema.act.peTypes.name,
|
|
|
+ eventInstId: DbSchema.act.peTypes.eventInstId,
|
|
|
fields: z.array(
|
|
|
CustomFieldWithUserCopyValue.extend({ isCopyUserValue: z.boolean() }),
|
|
|
),
|
|
@@ -75,7 +78,7 @@ class ClientPeController {
|
|
|
pt.code,
|
|
|
pt.name,
|
|
|
pt.event_inst_id as "eventInstId",
|
|
|
- coalesce(json_agg(jsonb_build_object(
|
|
|
+ coalesce(jsonb_agg(jsonb_build_object(
|
|
|
'fieldDefinitionId',
|
|
|
cfwv.field_definition_id,
|
|
|
'peFfId',
|
|
@@ -98,7 +101,7 @@ class ClientPeController {
|
|
|
cfwv.validators)) filter (
|
|
|
where
|
|
|
cfwv.field_definition_id is not null),
|
|
|
- '[]'::json) as fields
|
|
|
+ '[]'::jsonb) as fields
|
|
|
from
|
|
|
act.pe_types pt
|
|
|
-- необходимые поля
|
|
@@ -135,10 +138,10 @@ class ClientPeController {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- async createPeType(req: Request, res: Response) {
|
|
|
+ async createPe(req: Request, res: Response) {
|
|
|
const event = await sessionService.getCurrentEventFromReq(req);
|
|
|
const user = sessionService.getUserFromReq(req);
|
|
|
- const { form, peTypeId } = api.client.pe.POST_PartEntity.req.parse(
|
|
|
+ const { form, peTypeId, name } = api.client.pe.POST_PartEntity.req.parse(
|
|
|
req.body,
|
|
|
);
|
|
|
|
|
@@ -146,9 +149,9 @@ class ClientPeController {
|
|
|
const peId = v7();
|
|
|
await t.query(sql.unsafe`
|
|
|
insert into act.part_entities
|
|
|
- (pe_id, pe_type_id, event_inst_id, owner_id)
|
|
|
+ (pe_id, pe_type_id, event_inst_id, owner_id, name)
|
|
|
values
|
|
|
- (${peId}, ${peTypeId}, ${event.eventInstId}, ${user.userId})
|
|
|
+ (${peId}, ${peTypeId}, ${event.eventInstId}, ${user.userId}, ${name})
|
|
|
`);
|
|
|
|
|
|
for (const field of form) {
|
|
@@ -167,87 +170,230 @@ class ClientPeController {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- async getOwnerPe(req: Request, res: Response) {
|
|
|
+ async getMyPes(req: Request, res: Response) {
|
|
|
const user = sessionService.getUserFromReq(req);
|
|
|
- const { peId } = api.client.pe.GET_OwnerPartEntity.req.parse(req.body);
|
|
|
+ const event = await sessionService.getCurrentEventFromReq(req);
|
|
|
|
|
|
- // TODO: заменить типы бд
|
|
|
- const pe = await selPool.maybeOne(sql.type(
|
|
|
+ const ownerPes = await selPool.any(sql.type(
|
|
|
z.object({
|
|
|
- peTypeId: z.string().uuid(),
|
|
|
- code: z.string(),
|
|
|
- name: z.string(),
|
|
|
- eventInstId: z.string().uuid(),
|
|
|
- ownerId: z.string().uuid(),
|
|
|
- fields: z.array(
|
|
|
- CustomFieldWithUserCopyValue.extend({ isCopyUserValue: z.boolean() }),
|
|
|
- ),
|
|
|
+ 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,
|
|
|
+ eventInstId: DbSchema.act.partEntities.eventInstId,
|
|
|
+ ownerId: DbSchema.act.partEntities.ownerId,
|
|
|
+ name: DbSchema.act.partEntities.name,
|
|
|
}),
|
|
|
)`
|
|
|
select
|
|
|
- pt.pe_type_id as "peTypeId",
|
|
|
- pt.code,
|
|
|
- pt.name,
|
|
|
- pt.event_inst_id as "eventInstId",
|
|
|
- pe.owner_id as "ownerId",
|
|
|
- coalesce(json_agg(jsonb_build_object(
|
|
|
- 'fieldDefinitionId',
|
|
|
- cfwv.field_definition_id,
|
|
|
- 'peFfId',
|
|
|
- pff.pe_ff_id,
|
|
|
- 'isCopyUserValue',
|
|
|
- pff.is_copy_user_value,
|
|
|
- 'code',
|
|
|
- cfwv.code,
|
|
|
- 'value',
|
|
|
- pfv.value,
|
|
|
- 'fieldTypeCode',
|
|
|
- cfwv.field_type_code,
|
|
|
- 'title',
|
|
|
- COALESCE(pff.field_title_override, cfwv.title),
|
|
|
- 'mask',
|
|
|
- cfwv.mask,
|
|
|
- 'options',
|
|
|
- cfwv.options,
|
|
|
- 'validators',
|
|
|
- cfwv.validators)) filter (
|
|
|
- where
|
|
|
- cfwv.field_definition_id is not null),
|
|
|
- '[]'::json) as fields
|
|
|
+ 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.part_entities pe
|
|
|
+ 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
|
|
|
- -- необходимые поля
|
|
|
- left join act.pe_form_fields pff on
|
|
|
- pff.pe_type_id = pt.pe_type_id
|
|
|
- -- значения
|
|
|
- left join act.pe_field_values pfv on
|
|
|
- pff.pe_ff_id = pfv.pe_ff_id
|
|
|
- and
|
|
|
- pff.pe_type_id = pt.pe_type_id
|
|
|
- left join cf.custom_fields_with_validators cfwv on
|
|
|
- pff.field_definition_id = cfwv.field_definition_id
|
|
|
- where pe.pe_id = ${peId}
|
|
|
- group by
|
|
|
- pt.pe_type_id,
|
|
|
- pt.code,
|
|
|
- pt.name,
|
|
|
- pt.event_inst_id,
|
|
|
- pe.owner_id
|
|
|
+ pt.pe_type_id = pe.pe_type_id
|
|
|
+ where
|
|
|
+ pe.event_inst_id = ${event.eventInstId}
|
|
|
+ and pm.user_id = ${user.userId}
|
|
|
`);
|
|
|
|
|
|
- if (!pe)
|
|
|
- throw ApiError.BadRequest("peNotFound", "Сущность участия не найдена");
|
|
|
+ RouterUtils.validAndSendResponse(api.client.pe.GET_MyPes.res, res, {
|
|
|
+ code: "success",
|
|
|
+ owner: [...ownerPes],
|
|
|
+ memeber: [...memberPes],
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- RouterUtils.validAndSendResponse(
|
|
|
- api.client.pe.GET_OwnerPartEntity.res,
|
|
|
- res,
|
|
|
- {
|
|
|
+ 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 selPool.maybeOne(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,
|
|
|
+ name: DbSchema.act.partEntities.name,
|
|
|
+ ownerId: DbSchema.act.partEntities.ownerId,
|
|
|
+ fields: z.array(CustomFieldWithValue),
|
|
|
+ members: z.array(
|
|
|
+ z.object({
|
|
|
+ memberId: DbSchema.act.peMembers.peMemberId,
|
|
|
+ userId: DbSchema.act.peMembers.userId,
|
|
|
+ email: DbSchema.usr.users.email,
|
|
|
+ fields: z.array(CustomFieldWithValue),
|
|
|
+ }),
|
|
|
+ ),
|
|
|
+ invites: z.array(
|
|
|
+ z.object({
|
|
|
+ peInviteId: DbSchema.act.peInvites.peInviteId,
|
|
|
+ peInviteUuid: DbSchema.act.peInvites.peInviteUuid,
|
|
|
+ name: DbSchema.act.peInvites.name,
|
|
|
+ limitVal: DbSchema.act.peInvites.limitVal,
|
|
|
+ countVal: DbSchema.act.peInvites.countVal,
|
|
|
+ }),
|
|
|
+ ),
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ pe.pe_id "peId",
|
|
|
+ pe.pe_type_id "peTypeId",
|
|
|
+ pe.pe_type_code "peTypeCode",
|
|
|
+ pe.pe_type_name "peTypeName",
|
|
|
+ pe.event_inst_id "eventInstId",
|
|
|
+ pe.name,
|
|
|
+ pe.owner_id "ownerId",
|
|
|
+ pe.fields::jsonb,
|
|
|
+ pe.members::jsonb,
|
|
|
+ coalesce(jsonb_agg(jsonb_build_object(
|
|
|
+ 'peInviteId',
|
|
|
+ i.pe_invite_id,
|
|
|
+ 'peInviteUuid',
|
|
|
+ i.pe_invite_uuid,
|
|
|
+ 'name',
|
|
|
+ i."name",
|
|
|
+ 'limitVal',
|
|
|
+ i.limit_val,
|
|
|
+ 'countVal',
|
|
|
+ i.count_val
|
|
|
+ )) filter (
|
|
|
+ where
|
|
|
+ i.pe_id is not null),
|
|
|
+ '[]'::jsonb) as invites
|
|
|
+ from
|
|
|
+ act.pe_with_fields_and_members pe
|
|
|
+ left join act.pe_invites i on
|
|
|
+ i.pe_id = pe.pe_id
|
|
|
+ where
|
|
|
+ pe.pe_id = ${peId}
|
|
|
+ group by
|
|
|
+ pe.pe_id,
|
|
|
+ pe.pe_type_id,
|
|
|
+ pe.pe_type_code,
|
|
|
+ pe.pe_type_name,
|
|
|
+ pe.event_inst_id,
|
|
|
+ pe.name,
|
|
|
+ pe.owner_id,
|
|
|
+ pe.fields,
|
|
|
+ pe.members
|
|
|
+ `);
|
|
|
+
|
|
|
+ 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,
|
|
|
- },
|
|
|
+ pe: { ...pe, 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}
|
|
|
+ `,
|
|
|
);
|
|
|
+
|
|
|
+ if (!isMember) throw ApiError.ForbiddenError();
|
|
|
+
|
|
|
+ const pe = await selPool.maybeOne(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,
|
|
|
+ name: DbSchema.act.partEntities.name,
|
|
|
+ eventInstId: DbSchema.act.partEntities.eventInstId,
|
|
|
+ ownerId: DbSchema.act.partEntities.ownerId,
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ pm.pe_member_id "peMemberId",
|
|
|
+ pe.pe_id "peId",
|
|
|
+ pt.pe_type_id "peTypeId",
|
|
|
+ pt.code "peTypeCode",
|
|
|
+ pt.name "peTypeName",
|
|
|
+ pe.event_inst_id "eventInstId",
|
|
|
+ pe.owner_id "ownerId",
|
|
|
+ pe.name
|
|
|
+ from
|
|
|
+ act.pe_members pm
|
|
|
+ left join act.part_entities pe on
|
|
|
+ pe.pe_id = pm.pe_member_id
|
|
|
+ left join act.pe_types pt on
|
|
|
+ pt.pe_type_id = pe.pe_type_id
|
|
|
+ where
|
|
|
+ pe.pe_id = ${peId}
|
|
|
+ `);
|
|
|
+ if (!pe)
|
|
|
+ throw ApiError.BadRequest("peNotFound", "Сущность участия не найдена");
|
|
|
+
|
|
|
+ RouterUtils.validAndSendResponse(api.client.pe.GET_PartEntity.res, res, {
|
|
|
+ code: "success",
|
|
|
+ pe: { ...pe, userRole: "member" },
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
|