locations-router.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // router
  2. import express from "express";
  3. const router = express.Router();
  4. export default router;
  5. // db
  6. import { db } from "#db";
  7. import { ZDbShema } from "#db-shema";
  8. import { sql } from "slonik";
  9. // error
  10. // import { ApiError } from "#exceptions/api-error.ts";
  11. // dayjs
  12. import dayjs from "dayjs";
  13. import utc from "dayjs/plugin/utc.js";
  14. dayjs.extend(utc);
  15. import timezone from "dayjs/plugin/timezone.js";
  16. dayjs.extend(timezone);
  17. // other
  18. import { z } from "zod";
  19. import { v7 as uuidv7 } from "uuid";
  20. // import { logger } from "#logger";
  21. import { UserUtils } from "#utils/user-utils.js";
  22. import { LocationsManagementApi } from "#api/locations-management-api.js";
  23. import { CheckPermissionsService } from "#modules/permissions-management/check-permissions-service.js";
  24. import { RouterUtils } from "#utils/router-utils.js";
  25. dayjs.extend(utc);
  26. router.post("/create-location", async (req, res, next) => {
  27. try {
  28. // валидация запроса
  29. const { name, eventId, rooms } =
  30. LocationsManagementApi.ZCreateLocation.req.parse(req.body);
  31. const userId = UserUtils.getUserFromReq(req).userId;
  32. await CheckPermissionsService.checkEntityPermission(
  33. eventId,
  34. userId,
  35. "edit_event",
  36. "edit_event_true",
  37. );
  38. const locationId = uuidv7();
  39. // location
  40. await db.query(
  41. sql.unsafe`
  42. insert into locations_management.locations
  43. (location_id, name, event_id)
  44. values
  45. (${locationId}, ${name}, ${eventId})`,
  46. );
  47. // rooms
  48. for (const room of rooms) {
  49. const roomId = uuidv7();
  50. await db.query(
  51. sql.unsafe`
  52. insert into locations_management.rooms
  53. (room_id, location_id, name, parent_id)
  54. values
  55. (${roomId}, ${locationId}, ${room.name}, ${room.parentId})
  56. `,
  57. );
  58. }
  59. RouterUtils.validAndSendResponse(
  60. LocationsManagementApi.ZCreateLocation.res,
  61. res,
  62. {
  63. code: "success",
  64. },
  65. );
  66. } catch (e) {
  67. next(e);
  68. }
  69. });
  70. router.post("/get-event-locations", async (req, res, next) => {
  71. try {
  72. // валидация запроса
  73. const { eventId } = LocationsManagementApi.ZGetEventLocations.req.parse(
  74. req.body,
  75. );
  76. const userId = UserUtils.getUserFromReq(req).userId;
  77. await CheckPermissionsService.checkEntityPermission(
  78. eventId,
  79. userId,
  80. "edit_event",
  81. "edit_event_true",
  82. );
  83. const locations = await db.any(
  84. sql.type(
  85. z.object({
  86. location_id: ZDbShema.locations_management.locations.location_id,
  87. name: ZDbShema.locations_management.locations.name,
  88. rooms: z.array(
  89. z.object({
  90. room_id: ZDbShema.locations_management.rooms.room_id,
  91. name: ZDbShema.locations_management.rooms.name,
  92. parent_id: ZDbShema.locations_management.rooms.parent_id,
  93. }),
  94. ),
  95. }),
  96. )`
  97. SELECT
  98. l.location_id,
  99. l.name,
  100. COALESCE(
  101. json_agg(
  102. jsonb_build_object(
  103. 'room_id', r.room_id,
  104. 'name', r.name,
  105. 'parent_id', r.parent_id
  106. )
  107. ) FILTER (WHERE r.room_id IS NOT NULL),
  108. '[]'::json
  109. ) AS rooms
  110. FROM locations_management.locations l
  111. LEFT JOIN locations_management.rooms r ON l.location_id = r.location_id
  112. WHERE l.event_id = ${eventId}
  113. GROUP BY l.location_id, l.name;
  114. `,
  115. );
  116. RouterUtils.validAndSendResponse(
  117. LocationsManagementApi.ZGetEventLocations.res,
  118. res,
  119. {
  120. code: "success",
  121. locations: [...locations],
  122. },
  123. );
  124. } catch (e) {
  125. next(e);
  126. }
  127. });