children-controller.ts 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. import { api } from "#api/current-api.js";
  2. import { Request, Response } from "express";
  3. import sessionService from "./auth/services/session-service.js";
  4. import { cCustomFieldsValidateService } from "../custom-fields/c-cf-validate-service.js";
  5. import { cUsersService } from "./c-users-service.js";
  6. import { ApiError } from "#exceptions/api-error.js";
  7. import { v7 as uuidv7 } from "uuid";
  8. import { updPool } from "#db";
  9. import { sql } from "slonik";
  10. import { RouterUtils } from "#utils/router-utils.js";
  11. class ChildrenController {
  12. async createChild(req: Request, res: Response) {
  13. const { fields } = api.client.users.POST_Child.req.formData.body.parse(
  14. JSON.parse(req.body.body),
  15. );
  16. const event = await sessionService.getCurrentEventFromReq(req);
  17. const files = req.files;
  18. const user = sessionService.getUserFromReq(req);
  19. // поля пользователя
  20. const userData = await cUsersService.getUserEventFieldsWithValidators(
  21. event.eventId,
  22. );
  23. const refFields = userData.map((f) => {
  24. // TODO: костылёк для возраста ребенка
  25. if (f.code === "birth-date") {
  26. return {
  27. ...f,
  28. idKey: "userEfId",
  29. validators: f.validators.filter((v) => v.code !== "minAge"),
  30. };
  31. }
  32. return {
  33. ...f,
  34. idKey: "userEfId",
  35. };
  36. });
  37. // валидация полей
  38. const validationResult =
  39. await cCustomFieldsValidateService.processAndValidateFields({
  40. inputFields: fields,
  41. referenceFields: refFields,
  42. files,
  43. idKey: "userEfId",
  44. addOldValue: false,
  45. });
  46. if (!validationResult.isValid)
  47. throw ApiError.BadRequest(
  48. "fieldsValidationFailed",
  49. JSON.stringify(validationResult.messages),
  50. );
  51. const validatedFields = validationResult.checkedfields;
  52. // вставляем в базу и сохраняем файлы
  53. const childId = uuidv7();
  54. await updPool.transaction(async (tr) => {
  55. await tr.query(
  56. sql.unsafe`
  57. insert into usr.users
  58. (user_id, is_child, parent_id)
  59. values
  60. (${childId}, true, ${user.userId})`,
  61. );
  62. await cCustomFieldsValidateService.saveCustomFieldValuesInTransaction({
  63. tr,
  64. parentId: childId,
  65. action: "userProfile",
  66. inputFields: validatedFields,
  67. files,
  68. isDeleteBefore: false,
  69. });
  70. });
  71. RouterUtils.validAndSendResponse(api.client.users.POST_Child.res, res, {
  72. code: "success",
  73. childId: childId,
  74. });
  75. }
  76. async patchChild(req: Request, res: Response) {
  77. const user = sessionService.getUserFromReq(req);
  78. const { fields } = api.client.users.PATCH_Child.req.formData.body.parse(
  79. JSON.parse(req.body.body),
  80. );
  81. const childId = api.client.users.PATCH_Child.req.params.childId.parse(
  82. req.params.childId,
  83. );
  84. const event = await sessionService.getCurrentEventFromReq(req);
  85. const files = req.files;
  86. const isChildParent = await cUsersService.checkChildParent({
  87. userId: user.userId,
  88. childId,
  89. });
  90. if (!isChildParent) {
  91. throw ApiError.ForbiddenError();
  92. }
  93. const userData =
  94. await cUsersService.getUserEventFieldsWithValuesAndValidators(
  95. event.eventId,
  96. childId,
  97. );
  98. const refFields = userData
  99. .map((f) => {
  100. // TODO: костылёк для возраста ребенка
  101. if (f.code === "birth-date") {
  102. return {
  103. ...f,
  104. idKey: "userEfId",
  105. validators: f.validators.filter((v) => v.code !== "minAge"),
  106. };
  107. }
  108. return {
  109. ...f,
  110. idKey: "userEfId",
  111. };
  112. })
  113. // только изменяемые
  114. .filter((f) => fields.some((ff) => ff.userEfId === f.userEfId));
  115. // валидация
  116. const validationResult =
  117. await cCustomFieldsValidateService.processAndValidateFields({
  118. inputFields: fields,
  119. referenceFields: refFields,
  120. files,
  121. idKey: "userEfId",
  122. addOldValue: true,
  123. });
  124. if (!validationResult.isValid)
  125. throw ApiError.BadRequest(
  126. "fieldsValidationFailed",
  127. JSON.stringify(validationResult.messages),
  128. );
  129. const validatedFields = validationResult.checkedfields;
  130. //
  131. //
  132. // вставляем в базу и сохраняем файлы
  133. await updPool.transaction(async (tr) => {
  134. await cCustomFieldsValidateService.saveCustomFieldValuesInTransaction({
  135. tr,
  136. parentId: childId,
  137. action: "userProfile",
  138. inputFields: validatedFields,
  139. files,
  140. isDeleteBefore: true,
  141. });
  142. });
  143. RouterUtils.validAndSendResponse(
  144. api.client.users.PATCH_UserEventData.res,
  145. res,
  146. { code: "success" },
  147. );
  148. }
  149. async getChildren(req: Request, res: Response) {
  150. const user = sessionService.getUserFromReq(req);
  151. const children = await cUsersService.getChildrens(user.userId);
  152. RouterUtils.validAndSendResponse(api.client.users.GET_Children.res, res, {
  153. code: "success",
  154. children: [...children],
  155. });
  156. }
  157. async getChild(req: Request, res: Response) {
  158. const user = sessionService.getUserFromReq(req);
  159. const event = await sessionService.getCurrentEventFromReq(req);
  160. const { childId } = api.client.users.GET_Child.req.params.parse(req.params);
  161. const isChildParent = await cUsersService.checkChildParent({
  162. userId: user.userId,
  163. childId,
  164. });
  165. if (!isChildParent) {
  166. throw ApiError.ForbiddenError();
  167. }
  168. const childFields = await cUsersService.getUserEventFieldsWithValues(
  169. event.eventId,
  170. childId,
  171. );
  172. RouterUtils.validAndSendResponse(api.client.users.GET_Child.res, res, {
  173. code: "success",
  174. userData: {
  175. fields: [...childFields],
  176. },
  177. });
  178. }
  179. async getChildForPatch(req: Request, res: Response) {
  180. const user = sessionService.getUserFromReq(req);
  181. const event = await sessionService.getCurrentEventFromReq(req);
  182. const childId = api.client.users.GET_ChildForPatch.req.params.childId.parse(
  183. req.params.childId,
  184. );
  185. const isChildParent = await cUsersService.checkChildParent({
  186. userId: user.userId,
  187. childId,
  188. });
  189. if (!isChildParent) {
  190. throw ApiError.ForbiddenError();
  191. }
  192. const childFields =
  193. await cUsersService.getUserEventFieldsWithValuesAndValidators(
  194. event.eventId,
  195. childId,
  196. );
  197. RouterUtils.validAndSendResponse(
  198. api.client.users.GET_ChildForPatch.res,
  199. res,
  200. {
  201. code: "success",
  202. userData: {
  203. fields: [...childFields],
  204. },
  205. },
  206. );
  207. }
  208. }
  209. export const childrenController = new ChildrenController();