|
@@ -0,0 +1,859 @@
|
|
|
+// router
|
|
|
+import express from "express";
|
|
|
+const router = express.Router();
|
|
|
+export default router;
|
|
|
+
|
|
|
+// db
|
|
|
+import { db } from "#db";
|
|
|
+import { ZDbShema } from "#db-shema";
|
|
|
+import { sql } from "slonik";
|
|
|
+
|
|
|
+// api
|
|
|
+import { EventManagerApi } from "#api/event-manager-api.ts";
|
|
|
+
|
|
|
+// error
|
|
|
+import { ApiError } from "#exceptions/api-error.ts";
|
|
|
+
|
|
|
+// dayjs
|
|
|
+import dayjs from "dayjs";
|
|
|
+import utc from "dayjs/plugin/utc.js";
|
|
|
+dayjs.extend(utc);
|
|
|
+import timezone from "dayjs/plugin/timezone.js";
|
|
|
+dayjs.extend(timezone);
|
|
|
+
|
|
|
+// other
|
|
|
+import { z } from "zod";
|
|
|
+
|
|
|
+import { v7 as uuidv7 } from "uuid";
|
|
|
+// import { logger } from "#logger";
|
|
|
+import { UserUtils } from "#utils/user-utils.js";
|
|
|
+
|
|
|
+dayjs.extend(utc);
|
|
|
+
|
|
|
+router.post("/create-event", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZCreateEvent.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { name, dates, timezone } = EventManagerApi.ZCreateEvent.req.parse(
|
|
|
+ req.body,
|
|
|
+ );
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ // если тз не указана, то ставим тз пользователя
|
|
|
+ let tz = timezone;
|
|
|
+ if (!tz) {
|
|
|
+ const userTz = (
|
|
|
+ await db.one(
|
|
|
+ sql.type(
|
|
|
+ z.object({ timezone: ZDbShema.users.user_profiles.timezone }),
|
|
|
+ )`select timezone from users.user_profiles where user_id = ${userId}`,
|
|
|
+ )
|
|
|
+ ).timezone;
|
|
|
+
|
|
|
+ tz = userTz;
|
|
|
+ }
|
|
|
+ //
|
|
|
+
|
|
|
+ const eventId = uuidv7();
|
|
|
+
|
|
|
+ // event
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ insert into event_manager.events
|
|
|
+ (event_id, local_name, timezone, dates)
|
|
|
+ values
|
|
|
+ (${eventId}, ${name}, ${tz}, ${JSON.stringify(dates)})`,
|
|
|
+ );
|
|
|
+
|
|
|
+ // permission
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ insert into event_manager.event_permissions
|
|
|
+ (event_id, user_id, permission)
|
|
|
+ values
|
|
|
+ (${eventId}, ${userId}, 'creator')`,
|
|
|
+ );
|
|
|
+
|
|
|
+ sendRes(200, { code: "success", event_id: eventId });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/get-event-list", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZGetEventList.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+ // TODO сделать проверку на юзера
|
|
|
+ // const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+ // const userTz = (
|
|
|
+ // await db.one(
|
|
|
+ // sql.type(
|
|
|
+ // z.object({ timezone: ZDbShema.users.user_profiles.timezone }),
|
|
|
+ // )`select timezone from users.user_profiles where user_id = ${userId}`,
|
|
|
+ // )
|
|
|
+ // ).timezone;
|
|
|
+
|
|
|
+ const nowWithUzerTz = dayjs.utc().startOf("day");
|
|
|
+
|
|
|
+ const DbEventsTypes = ZDbShema.event_manager.events;
|
|
|
+ const events = await db.any(
|
|
|
+ sql.type(
|
|
|
+ z.object({
|
|
|
+ event_id: DbEventsTypes.event_id,
|
|
|
+ local_name: DbEventsTypes.event_id,
|
|
|
+ timezone: DbEventsTypes.timezone,
|
|
|
+ dates: DbEventsTypes.dates,
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ event_id,
|
|
|
+ local_name,
|
|
|
+ timezone,
|
|
|
+ dates
|
|
|
+ from
|
|
|
+ event_manager.events
|
|
|
+ where
|
|
|
+ exists (
|
|
|
+ select
|
|
|
+ from
|
|
|
+ jsonb_array_elements_text(dates)
|
|
|
+ where
|
|
|
+ value::date >= ${nowWithUzerTz.toISOString()}
|
|
|
+ )
|
|
|
+ `,
|
|
|
+ );
|
|
|
+
|
|
|
+ sendRes(200, { code: "success", events: [...events] });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/get-event", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZGetEvent.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { eventId } = EventManagerApi.ZGetEvent.req.parse(req.body);
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+ await UserUtils.checkEventPermissions(eventId, userId, "viewer");
|
|
|
+
|
|
|
+ // event
|
|
|
+ const DbEventsTypes = ZDbShema.event_manager.events;
|
|
|
+ const event = await db.maybeOne(
|
|
|
+ sql.type(
|
|
|
+ z.object({
|
|
|
+ event_id: DbEventsTypes.event_id,
|
|
|
+ local_name: DbEventsTypes.local_name,
|
|
|
+ timezone: DbEventsTypes.timezone,
|
|
|
+ dates: DbEventsTypes.dates,
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ event_id,
|
|
|
+ local_name,
|
|
|
+ timezone,
|
|
|
+ dates
|
|
|
+ from
|
|
|
+ event_manager.events
|
|
|
+ where
|
|
|
+ event_id = ${eventId}
|
|
|
+ `,
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!event) throw ApiError.BadRequest("EventNotFound", "Ивент не найден");
|
|
|
+
|
|
|
+ // points
|
|
|
+ const DbPointsType = ZDbShema.event_manager.program_points;
|
|
|
+ const programPoints = await db.any(
|
|
|
+ sql.type(
|
|
|
+ z.object({
|
|
|
+ point_id: DbPointsType.point_id,
|
|
|
+ name: DbPointsType.name,
|
|
|
+ date_start: DbPointsType.date_start,
|
|
|
+ date_end: DbPointsType.date_end,
|
|
|
+ room_id: DbPointsType.room_id,
|
|
|
+ is_internal: DbPointsType.is_internal,
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ point_id,
|
|
|
+ name,
|
|
|
+ date_start,
|
|
|
+ date_end,
|
|
|
+ room_id,
|
|
|
+ is_internal
|
|
|
+ from
|
|
|
+ event_manager.program_points pp
|
|
|
+ where
|
|
|
+ pp.event_id = ${eventId}
|
|
|
+ `,
|
|
|
+ );
|
|
|
+
|
|
|
+ //
|
|
|
+ const eventRoomsIds = new Set<string>();
|
|
|
+
|
|
|
+ for (const point of programPoints) {
|
|
|
+ if (point.room_id) eventRoomsIds.add(point.room_id);
|
|
|
+ }
|
|
|
+ //
|
|
|
+ // rooms
|
|
|
+ const eventRoomsIdsArr = Array.from(eventRoomsIds);
|
|
|
+ let rooms: readonly {
|
|
|
+ name: string;
|
|
|
+ room_id: string;
|
|
|
+ }[] = [];
|
|
|
+
|
|
|
+ // TODO ошибка в in?
|
|
|
+ if (eventRoomsIdsArr.length > 0) {
|
|
|
+ console.log(1);
|
|
|
+
|
|
|
+ rooms = await db.any(
|
|
|
+ sql.type(
|
|
|
+ z.object({
|
|
|
+ room_id: ZDbShema.event_manager.rooms.room_id,
|
|
|
+ name: ZDbShema.event_manager.rooms.name,
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ room_id, name
|
|
|
+ from
|
|
|
+ event_manager.rooms
|
|
|
+ where
|
|
|
+ room_id in (${sql.join(eventRoomsIdsArr, sql.fragment`, `)})
|
|
|
+ `,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // res
|
|
|
+ sendRes(200, {
|
|
|
+ code: "success",
|
|
|
+ event: {
|
|
|
+ ...event,
|
|
|
+ programPoints: [...programPoints],
|
|
|
+ rooms: [...rooms],
|
|
|
+ },
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/add-program-point", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZAddProgramPoint.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { name, dateStart, dateEnd, eventId, roomId, isInternal } =
|
|
|
+ EventManagerApi.ZAddProgramPoint.req.parse(req.body);
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+ await UserUtils.checkEventPermissions(eventId, userId, "editor");
|
|
|
+
|
|
|
+ const pointId = uuidv7();
|
|
|
+
|
|
|
+ // event
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ insert into event_manager.program_points
|
|
|
+ (point_id, name, date_start, date_end, room_id, event_id, is_internal)
|
|
|
+ values
|
|
|
+ (${pointId}, ${name}, ${dateStart}, ${dateEnd}, ${roomId || null}, ${eventId}, ${isInternal})
|
|
|
+ `,
|
|
|
+ );
|
|
|
+
|
|
|
+ sendRes(200, { code: "success" });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/add-user-room", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZAddUserRoom.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { name } = EventManagerApi.ZAddUserRoom.req.parse(req.body);
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ const roomId = uuidv7();
|
|
|
+
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ insert into event_manager.rooms
|
|
|
+ (room_id, name)
|
|
|
+ values
|
|
|
+ (${roomId}, ${name})`,
|
|
|
+ );
|
|
|
+
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ insert into event_manager.room_user_permissions
|
|
|
+ (user_id, room_id, permission)
|
|
|
+ values
|
|
|
+ (${userId}, ${roomId}, 'creator')`,
|
|
|
+ );
|
|
|
+
|
|
|
+ sendRes(200, { code: "success" });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/get-user-rooms", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZGetUserRooms.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ // const { permission } = EventManagerApi.ZGetUserRooms.req.parse(req.body);
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ const permissions = ["viewer", "editor"];
|
|
|
+
|
|
|
+ const rooms = await db.any(
|
|
|
+ sql.type(
|
|
|
+ z.object({
|
|
|
+ room_id: ZDbShema.event_manager.rooms.room_id,
|
|
|
+ name: ZDbShema.event_manager.rooms.name,
|
|
|
+ permission: ZDbShema.event_manager.event_permissions.permission,
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ r.room_id,
|
|
|
+ r."name",
|
|
|
+ rup."permission"
|
|
|
+ from
|
|
|
+ event_manager.rooms r
|
|
|
+ join event_manager.room_user_permissions rup on
|
|
|
+ r.room_id = rup.room_id
|
|
|
+ where
|
|
|
+ rup.user_id = ${userId}
|
|
|
+ and rup.permission in (${sql.join(permissions, sql.fragment`, `)})
|
|
|
+ `,
|
|
|
+ );
|
|
|
+
|
|
|
+ // res
|
|
|
+ sendRes(200, {
|
|
|
+ code: "success",
|
|
|
+ rooms: [...rooms],
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/update-event", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZUpdateEvent.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { eventId, name, dates, timezone } =
|
|
|
+ EventManagerApi.ZUpdateEvent.req.parse(req.body);
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+ await UserUtils.checkEventPermissions(eventId, userId, "editor");
|
|
|
+
|
|
|
+ // event
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ update event_manager.events
|
|
|
+ set
|
|
|
+ local_name = ${name},
|
|
|
+ timezone = ${timezone},
|
|
|
+ dates = ${JSON.stringify(dates)}
|
|
|
+ where
|
|
|
+ event_id = ${eventId}`,
|
|
|
+ );
|
|
|
+
|
|
|
+ sendRes(200, { code: "success" });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/update-program-point", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZUpdateProgramPoint.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { pointId, name, dateStart, dateEnd, roomId } =
|
|
|
+ EventManagerApi.ZUpdateProgramPoint.req.parse(req.body);
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ const eventId = await db.maybeOneFirst(
|
|
|
+ sql.type(
|
|
|
+ z.object({
|
|
|
+ event_id: ZDbShema.event_manager.events.event_id,
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ event_id
|
|
|
+ from
|
|
|
+ event_manager.program_points
|
|
|
+ where
|
|
|
+ point_id = ${pointId}
|
|
|
+ `,
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!eventId) {
|
|
|
+ throw ApiError.BadRequest("Point not found", "Point not found");
|
|
|
+ }
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+ await UserUtils.checkEventPermissions(eventId, userId, "editor");
|
|
|
+
|
|
|
+ // point
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ update event_manager.program_points
|
|
|
+ set
|
|
|
+ name = ${name},
|
|
|
+ date_start = ${dateStart},
|
|
|
+ date_end = ${dateEnd},
|
|
|
+ room_id = ${roomId || null}
|
|
|
+ where
|
|
|
+ point_id = ${pointId}`,
|
|
|
+ );
|
|
|
+
|
|
|
+ sendRes(200, { code: "success" });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/add-task-block", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZAddTaskBlock.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { name, eventId } = EventManagerApi.ZAddTaskBlock.req.parse(req.body);
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+ await UserUtils.checkEventPermissions(eventId, userId, "editor");
|
|
|
+
|
|
|
+ const blockId = uuidv7();
|
|
|
+
|
|
|
+ // block
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ insert into task_manager.task_blocks
|
|
|
+ (task_block_id, name, event_id)
|
|
|
+ values
|
|
|
+ (${blockId}, ${name}, ${eventId})`,
|
|
|
+ );
|
|
|
+
|
|
|
+ sendRes(200, { code: "success" });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/update-task-block", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZUpdateTaskBlock.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { taskBlockId, name } = EventManagerApi.ZUpdateTaskBlock.req.parse(
|
|
|
+ req.body,
|
|
|
+ );
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ const eventId = await db.maybeOneFirst(
|
|
|
+ sql.type(
|
|
|
+ z.object({
|
|
|
+ event_id: ZDbShema.event_manager.events.event_id,
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ event_id
|
|
|
+ from
|
|
|
+ task_manager.task_blocks
|
|
|
+ where
|
|
|
+ task_block_id = ${taskBlockId}
|
|
|
+ `,
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!eventId) {
|
|
|
+ throw ApiError.BadRequest("Block not found", "Block not found");
|
|
|
+ }
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+ await UserUtils.checkEventPermissions(eventId, userId, "editor");
|
|
|
+
|
|
|
+ // block
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ update task_manager.task_blocks
|
|
|
+ set
|
|
|
+ name = ${name}
|
|
|
+ where
|
|
|
+ task_block_id = ${taskBlockId}`,
|
|
|
+ );
|
|
|
+
|
|
|
+ sendRes(200, { code: "success" });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/get-task-blocks", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZGetTaskBlocks.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { eventId } = EventManagerApi.ZGetTaskBlocks.req.parse(req.body);
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+ await UserUtils.checkEventPermissions(eventId, userId, "viewer");
|
|
|
+
|
|
|
+ const taskBlocks = await db.any(
|
|
|
+ sql.type(
|
|
|
+ z.object({
|
|
|
+ task_block_id: ZDbShema.task_manager.task_blocks.task_block_id,
|
|
|
+ name: ZDbShema.task_manager.task_blocks.name,
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ task_block_id,
|
|
|
+ name
|
|
|
+ from
|
|
|
+ task_manager.task_blocks
|
|
|
+ where
|
|
|
+ event_id = ${eventId}
|
|
|
+ `,
|
|
|
+ );
|
|
|
+
|
|
|
+ // res
|
|
|
+ sendRes(200, {
|
|
|
+ code: "success",
|
|
|
+ taskBlocks: [...taskBlocks],
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/add-task", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZAddTask.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const {
|
|
|
+ dateEnd,
|
|
|
+ dateStart,
|
|
|
+ isTodo,
|
|
|
+ name,
|
|
|
+ ownerId,
|
|
|
+ taskBlockId,
|
|
|
+ pointId,
|
|
|
+ executors,
|
|
|
+ roomId,
|
|
|
+ } = EventManagerApi.ZAddTask.req.parse(req.body);
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+
|
|
|
+ await UserUtils.checkTaskBlockPermissions(taskBlockId, userId, "editor");
|
|
|
+
|
|
|
+ const taskId = uuidv7();
|
|
|
+
|
|
|
+ // task
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ insert into task_manager.tasks
|
|
|
+ (task_id, name, date_start, date_end, owner_id, is_todo, task_block_id, point_id, room_id)
|
|
|
+ values
|
|
|
+ (${taskId}, ${name}, ${dateStart}, ${dateEnd}, ${ownerId}, ${isTodo}, ${taskBlockId}, ${pointId}, ${roomId})`,
|
|
|
+ );
|
|
|
+
|
|
|
+ // executors
|
|
|
+ const executorsWithId = executors.map((e) => ({
|
|
|
+ task_executor_id: uuidv7(),
|
|
|
+ task_id: taskId,
|
|
|
+ user_id: e,
|
|
|
+ }));
|
|
|
+
|
|
|
+ for (const executor of executorsWithId) {
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ insert into task_manager.task_executors
|
|
|
+ (task_executor_id, task_id, user_id)
|
|
|
+ values
|
|
|
+ (${executor.task_executor_id}, ${executor.task_id}, ${executor.user_id})`,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ sendRes(200, { code: "success" });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/update-task", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZUpdateTask.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const {
|
|
|
+ dateEnd,
|
|
|
+ dateStart,
|
|
|
+ isTodo,
|
|
|
+ name,
|
|
|
+ pointId,
|
|
|
+ taskBlockId,
|
|
|
+ executors,
|
|
|
+ taskId,
|
|
|
+ roomId,
|
|
|
+ } = EventManagerApi.ZUpdateTask.req.parse(req.body);
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+
|
|
|
+ await UserUtils.checkTaskBlockPermissions(taskBlockId, userId, "editor");
|
|
|
+
|
|
|
+ // task
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ update task_manager.tasks
|
|
|
+ set
|
|
|
+ name = ${name},
|
|
|
+ date_start = ${dateStart},
|
|
|
+ date_end = ${dateEnd},
|
|
|
+ is_todo = ${isTodo},
|
|
|
+ point_id = ${pointId},
|
|
|
+ room_id = ${roomId}
|
|
|
+ where
|
|
|
+ task_id = ${taskId}`,
|
|
|
+ );
|
|
|
+
|
|
|
+ // executors
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ delete from task_manager.task_executors
|
|
|
+ where
|
|
|
+ task_id = ${taskId}`,
|
|
|
+ );
|
|
|
+
|
|
|
+ const executorsWithId = executors.map((e) => ({
|
|
|
+ task_executor_id: uuidv7(),
|
|
|
+ task_id: taskId,
|
|
|
+ user_id: e,
|
|
|
+ }));
|
|
|
+
|
|
|
+ for (const executor of executorsWithId) {
|
|
|
+ await db.query(
|
|
|
+ sql.unsafe`
|
|
|
+ insert into task_manager.task_executors
|
|
|
+ (task_executor_id, task_id, user_id)
|
|
|
+ values
|
|
|
+ (${executor.task_executor_id}, ${executor.task_id}, ${executor.user_id})`,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ sendRes(200, { code: "success" });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+router.post("/get-block-tasks", async (req, res, next) => {
|
|
|
+ try {
|
|
|
+ // функция валидации ответа
|
|
|
+ const ZResType = EventManagerApi.ZGetBlockTasks.res; //change
|
|
|
+ const sendRes = (
|
|
|
+ status: 200 | 400 | 500,
|
|
|
+ resData: z.infer<typeof ZResType>,
|
|
|
+ ) => {
|
|
|
+ const response = ZResType.parse(resData);
|
|
|
+ res.status(status).json(response);
|
|
|
+ };
|
|
|
+ //
|
|
|
+
|
|
|
+ // валидация запроса
|
|
|
+ const { taskBlockId } = EventManagerApi.ZGetBlockTasks.req.parse(req.body);
|
|
|
+
|
|
|
+ const userId = UserUtils.getUserFromReq(req).userId;
|
|
|
+
|
|
|
+ // проверка прав
|
|
|
+
|
|
|
+ await UserUtils.checkTaskBlockPermissions(taskBlockId, userId, "viewer");
|
|
|
+
|
|
|
+ const tasks = await db.any(
|
|
|
+ sql.type(
|
|
|
+ z.object({
|
|
|
+ task_id: ZDbShema.task_manager.tasks.task_id,
|
|
|
+ name: ZDbShema.task_manager.tasks.name,
|
|
|
+ date_start: ZDbShema.task_manager.tasks.date_start,
|
|
|
+ date_end: ZDbShema.task_manager.tasks.date_end,
|
|
|
+ is_todo: ZDbShema.task_manager.tasks.is_todo,
|
|
|
+ owner_id: ZDbShema.task_manager.tasks.owner_id,
|
|
|
+ task_block_id: ZDbShema.task_manager.tasks.task_block_id,
|
|
|
+ point_id: ZDbShema.task_manager.tasks.point_id,
|
|
|
+ room_id: ZDbShema.task_manager.tasks.room_id,
|
|
|
+ executors: z.array(ZDbShema.task_manager.task_executors.user_id),
|
|
|
+ }),
|
|
|
+ )`
|
|
|
+ select
|
|
|
+ t.task_id,
|
|
|
+ t.name,
|
|
|
+ t.date_start,
|
|
|
+ t.date_end,
|
|
|
+ t.is_todo,
|
|
|
+ t.owner_id,
|
|
|
+ t.task_block_id,
|
|
|
+ t.point_id,
|
|
|
+ t.room_id,
|
|
|
+ array(
|
|
|
+ select
|
|
|
+ user_id
|
|
|
+ from
|
|
|
+ task_manager.task_executors e
|
|
|
+ where
|
|
|
+ e.task_id = t.task_id) as executors
|
|
|
+ from
|
|
|
+ task_manager.tasks t`,
|
|
|
+ );
|
|
|
+
|
|
|
+ // res
|
|
|
+ sendRes(200, {
|
|
|
+ code: "success",
|
|
|
+ tasks: [...tasks],
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ next(e);
|
|
|
+ }
|
|
|
+});
|