@blackcode_sa/metaestetics-api 1.12.65 → 1.12.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/dist/admin/index.d.mts +2 -0
  2. package/dist/admin/index.d.ts +2 -0
  3. package/dist/admin/index.js +45 -4
  4. package/dist/admin/index.mjs +45 -4
  5. package/dist/backoffice/index.d.mts +33 -0
  6. package/dist/backoffice/index.d.ts +33 -0
  7. package/dist/backoffice/index.js +63 -0
  8. package/dist/backoffice/index.mjs +63 -0
  9. package/dist/index.d.mts +35 -0
  10. package/dist/index.d.ts +35 -0
  11. package/dist/index.js +116 -11
  12. package/dist/index.mjs +116 -11
  13. package/package.json +119 -119
  14. package/src/__mocks__/firstore.ts +10 -10
  15. package/src/admin/aggregation/README.md +79 -79
  16. package/src/admin/aggregation/appointment/README.md +128 -128
  17. package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +1844 -1844
  18. package/src/admin/aggregation/appointment/index.ts +1 -1
  19. package/src/admin/aggregation/clinic/README.md +52 -52
  20. package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +703 -703
  21. package/src/admin/aggregation/clinic/index.ts +1 -1
  22. package/src/admin/aggregation/forms/README.md +13 -13
  23. package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +322 -322
  24. package/src/admin/aggregation/forms/index.ts +1 -1
  25. package/src/admin/aggregation/index.ts +8 -8
  26. package/src/admin/aggregation/patient/README.md +27 -27
  27. package/src/admin/aggregation/patient/index.ts +1 -1
  28. package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -141
  29. package/src/admin/aggregation/practitioner/README.md +42 -42
  30. package/src/admin/aggregation/practitioner/index.ts +1 -1
  31. package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -433
  32. package/src/admin/aggregation/practitioner-invite/index.ts +1 -1
  33. package/src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts +961 -961
  34. package/src/admin/aggregation/procedure/README.md +43 -43
  35. package/src/admin/aggregation/procedure/index.ts +1 -1
  36. package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +702 -702
  37. package/src/admin/aggregation/reviews/index.ts +1 -1
  38. package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +689 -641
  39. package/src/admin/booking/README.md +125 -125
  40. package/src/admin/booking/booking.admin.ts +1037 -1037
  41. package/src/admin/booking/booking.calculator.ts +712 -712
  42. package/src/admin/booking/booking.types.ts +59 -59
  43. package/src/admin/booking/index.ts +3 -3
  44. package/src/admin/booking/timezones-problem.md +185 -185
  45. package/src/admin/calendar/README.md +7 -7
  46. package/src/admin/calendar/calendar.admin.service.ts +345 -345
  47. package/src/admin/calendar/index.ts +1 -1
  48. package/src/admin/documentation-templates/document-manager.admin.ts +260 -260
  49. package/src/admin/documentation-templates/index.ts +1 -1
  50. package/src/admin/free-consultation/free-consultation-utils.admin.ts +148 -148
  51. package/src/admin/free-consultation/index.ts +1 -1
  52. package/src/admin/index.ts +75 -75
  53. package/src/admin/logger/index.ts +78 -78
  54. package/src/admin/mailing/README.md +95 -95
  55. package/src/admin/mailing/appointment/appointment.mailing.service.ts +732 -732
  56. package/src/admin/mailing/appointment/index.ts +1 -1
  57. package/src/admin/mailing/appointment/templates/patient/appointment-confirmed.html +40 -40
  58. package/src/admin/mailing/base.mailing.service.ts +208 -208
  59. package/src/admin/mailing/index.ts +3 -3
  60. package/src/admin/mailing/practitionerInvite/existing-practitioner-invite.mailing.ts +611 -611
  61. package/src/admin/mailing/practitionerInvite/index.ts +2 -2
  62. package/src/admin/mailing/practitionerInvite/practitionerInvite.mailing.ts +395 -395
  63. package/src/admin/mailing/practitionerInvite/templates/existing-practitioner-invitation.template.ts +155 -155
  64. package/src/admin/mailing/practitionerInvite/templates/invitation.template.ts +101 -101
  65. package/src/admin/mailing/practitionerInvite/templates/invite-accepted-notification.template.ts +228 -228
  66. package/src/admin/mailing/practitionerInvite/templates/invite-rejected-notification.template.ts +242 -242
  67. package/src/admin/notifications/index.ts +1 -1
  68. package/src/admin/notifications/notifications.admin.ts +710 -710
  69. package/src/admin/requirements/README.md +128 -128
  70. package/src/admin/requirements/index.ts +1 -1
  71. package/src/admin/requirements/patient-requirements.admin.service.ts +475 -475
  72. package/src/admin/users/index.ts +1 -1
  73. package/src/admin/users/user-profile.admin.ts +405 -405
  74. package/src/backoffice/constants/certification.constants.ts +13 -13
  75. package/src/backoffice/constants/index.ts +1 -1
  76. package/src/backoffice/errors/backoffice.errors.ts +181 -181
  77. package/src/backoffice/errors/index.ts +1 -1
  78. package/src/backoffice/expo-safe/README.md +26 -26
  79. package/src/backoffice/expo-safe/index.ts +41 -41
  80. package/src/backoffice/index.ts +5 -5
  81. package/src/backoffice/services/FIXES_README.md +102 -102
  82. package/src/backoffice/services/README.md +40 -40
  83. package/src/backoffice/services/brand.service.ts +256 -256
  84. package/src/backoffice/services/category.service.ts +341 -318
  85. package/src/backoffice/services/constants.service.ts +385 -385
  86. package/src/backoffice/services/documentation-template.service.ts +202 -202
  87. package/src/backoffice/services/index.ts +10 -10
  88. package/src/backoffice/services/migrate-products.ts +116 -116
  89. package/src/backoffice/services/product.service.ts +553 -553
  90. package/src/backoffice/services/requirement.service.ts +235 -235
  91. package/src/backoffice/services/subcategory.service.ts +417 -395
  92. package/src/backoffice/services/technology.service.ts +1104 -1083
  93. package/src/backoffice/types/README.md +12 -12
  94. package/src/backoffice/types/admin-constants.types.ts +69 -69
  95. package/src/backoffice/types/brand.types.ts +29 -29
  96. package/src/backoffice/types/category.types.ts +67 -62
  97. package/src/backoffice/types/documentation-templates.types.ts +28 -28
  98. package/src/backoffice/types/index.ts +10 -10
  99. package/src/backoffice/types/procedure-product.types.ts +38 -38
  100. package/src/backoffice/types/product.types.ts +240 -240
  101. package/src/backoffice/types/requirement.types.ts +63 -63
  102. package/src/backoffice/types/static/README.md +18 -18
  103. package/src/backoffice/types/static/blocking-condition.types.ts +21 -21
  104. package/src/backoffice/types/static/certification.types.ts +37 -37
  105. package/src/backoffice/types/static/contraindication.types.ts +19 -19
  106. package/src/backoffice/types/static/index.ts +6 -6
  107. package/src/backoffice/types/static/pricing.types.ts +16 -16
  108. package/src/backoffice/types/static/procedure-family.types.ts +14 -14
  109. package/src/backoffice/types/static/treatment-benefit.types.ts +22 -22
  110. package/src/backoffice/types/subcategory.types.ts +34 -34
  111. package/src/backoffice/types/technology.types.ts +168 -163
  112. package/src/backoffice/validations/index.ts +1 -1
  113. package/src/backoffice/validations/schemas.ts +164 -164
  114. package/src/config/__mocks__/firebase.ts +99 -99
  115. package/src/config/firebase.ts +78 -78
  116. package/src/config/index.ts +9 -9
  117. package/src/errors/auth.error.ts +6 -6
  118. package/src/errors/auth.errors.ts +200 -200
  119. package/src/errors/clinic.errors.ts +32 -32
  120. package/src/errors/firebase.errors.ts +47 -47
  121. package/src/errors/user.errors.ts +99 -99
  122. package/src/index.backup.ts +407 -407
  123. package/src/index.ts +6 -6
  124. package/src/locales/en.ts +31 -31
  125. package/src/recommender/admin/index.ts +1 -1
  126. package/src/recommender/admin/services/recommender.service.admin.ts +5 -5
  127. package/src/recommender/front/index.ts +1 -1
  128. package/src/recommender/front/services/onboarding.service.ts +5 -5
  129. package/src/recommender/front/services/recommender.service.ts +3 -3
  130. package/src/recommender/index.ts +1 -1
  131. package/src/services/PATIENTAUTH.MD +197 -197
  132. package/src/services/README.md +106 -106
  133. package/src/services/__tests__/auth/auth.mock.test.ts +17 -17
  134. package/src/services/__tests__/auth/auth.setup.ts +293 -293
  135. package/src/services/__tests__/auth.service.test.ts +346 -346
  136. package/src/services/__tests__/base.service.test.ts +77 -77
  137. package/src/services/__tests__/user.service.test.ts +528 -528
  138. package/src/services/appointment/README.md +17 -17
  139. package/src/services/appointment/appointment.service.ts +2505 -2505
  140. package/src/services/appointment/index.ts +1 -1
  141. package/src/services/appointment/utils/appointment.utils.ts +552 -552
  142. package/src/services/appointment/utils/extended-procedure.utils.ts +314 -314
  143. package/src/services/appointment/utils/form-initialization.utils.ts +225 -225
  144. package/src/services/appointment/utils/recommended-procedure.utils.ts +195 -195
  145. package/src/services/appointment/utils/zone-management.utils.ts +353 -353
  146. package/src/services/appointment/utils/zone-photo.utils.ts +152 -152
  147. package/src/services/auth/auth.service.ts +989 -989
  148. package/src/services/auth/auth.v2.service.ts +961 -961
  149. package/src/services/auth/index.ts +7 -7
  150. package/src/services/auth/utils/error.utils.ts +90 -90
  151. package/src/services/auth/utils/firebase.utils.ts +49 -49
  152. package/src/services/auth/utils/index.ts +21 -21
  153. package/src/services/auth/utils/practitioner.utils.ts +125 -125
  154. package/src/services/base.service.ts +41 -41
  155. package/src/services/calendar/calendar.service.ts +1077 -1077
  156. package/src/services/calendar/calendar.v2.service.ts +1683 -1683
  157. package/src/services/calendar/calendar.v3.service.ts +313 -313
  158. package/src/services/calendar/externalCalendar.service.ts +178 -178
  159. package/src/services/calendar/index.ts +5 -5
  160. package/src/services/calendar/synced-calendars.service.ts +743 -743
  161. package/src/services/calendar/utils/appointment.utils.ts +265 -265
  162. package/src/services/calendar/utils/calendar-event.utils.ts +646 -646
  163. package/src/services/calendar/utils/clinic.utils.ts +237 -237
  164. package/src/services/calendar/utils/docs.utils.ts +157 -157
  165. package/src/services/calendar/utils/google-calendar.utils.ts +697 -697
  166. package/src/services/calendar/utils/index.ts +8 -8
  167. package/src/services/calendar/utils/patient.utils.ts +198 -198
  168. package/src/services/calendar/utils/practitioner.utils.ts +221 -221
  169. package/src/services/calendar/utils/synced-calendar.utils.ts +472 -472
  170. package/src/services/clinic/README.md +204 -204
  171. package/src/services/clinic/__tests__/clinic-admin.service.test.ts +287 -287
  172. package/src/services/clinic/__tests__/clinic-group.service.test.ts +352 -352
  173. package/src/services/clinic/__tests__/clinic.service.test.ts +354 -354
  174. package/src/services/clinic/billing-transactions.service.ts +217 -217
  175. package/src/services/clinic/clinic-admin.service.ts +202 -202
  176. package/src/services/clinic/clinic-group.service.ts +310 -310
  177. package/src/services/clinic/clinic.service.ts +708 -708
  178. package/src/services/clinic/index.ts +5 -5
  179. package/src/services/clinic/practitioner-invite.service.ts +519 -519
  180. package/src/services/clinic/utils/admin.utils.ts +551 -551
  181. package/src/services/clinic/utils/clinic-group.utils.ts +646 -646
  182. package/src/services/clinic/utils/clinic.utils.ts +949 -949
  183. package/src/services/clinic/utils/filter.utils.d.ts +23 -23
  184. package/src/services/clinic/utils/filter.utils.ts +446 -446
  185. package/src/services/clinic/utils/index.ts +11 -11
  186. package/src/services/clinic/utils/photos.utils.ts +188 -188
  187. package/src/services/clinic/utils/search.utils.ts +84 -84
  188. package/src/services/clinic/utils/tag.utils.ts +124 -124
  189. package/src/services/documentation-templates/documentation-template.service.ts +537 -537
  190. package/src/services/documentation-templates/filled-document.service.ts +587 -587
  191. package/src/services/documentation-templates/index.ts +2 -2
  192. package/src/services/index.ts +13 -13
  193. package/src/services/media/index.ts +1 -1
  194. package/src/services/media/media.service.ts +418 -418
  195. package/src/services/notifications/__tests__/notification.service.test.ts +242 -242
  196. package/src/services/notifications/index.ts +1 -1
  197. package/src/services/notifications/notification.service.ts +215 -215
  198. package/src/services/patient/README.md +48 -48
  199. package/src/services/patient/To-Do.md +43 -43
  200. package/src/services/patient/__tests__/patient.service.test.ts +294 -294
  201. package/src/services/patient/index.ts +2 -2
  202. package/src/services/patient/patient.service.ts +883 -883
  203. package/src/services/patient/patientRequirements.service.ts +285 -285
  204. package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -176
  205. package/src/services/patient/utils/clinic.utils.ts +80 -80
  206. package/src/services/patient/utils/docs.utils.ts +142 -142
  207. package/src/services/patient/utils/index.ts +9 -9
  208. package/src/services/patient/utils/location.utils.ts +126 -126
  209. package/src/services/patient/utils/medical-stuff.utils.ts +143 -143
  210. package/src/services/patient/utils/medical.utils.ts +458 -458
  211. package/src/services/patient/utils/practitioner.utils.ts +260 -260
  212. package/src/services/patient/utils/profile.utils.ts +510 -510
  213. package/src/services/patient/utils/sensitive.utils.ts +260 -260
  214. package/src/services/patient/utils/token.utils.ts +211 -211
  215. package/src/services/practitioner/README.md +145 -145
  216. package/src/services/practitioner/index.ts +1 -1
  217. package/src/services/practitioner/practitioner.service.ts +1742 -1742
  218. package/src/services/procedure/README.md +163 -163
  219. package/src/services/procedure/index.ts +1 -1
  220. package/src/services/procedure/procedure.service.ts +1715 -1715
  221. package/src/services/reviews/index.ts +1 -1
  222. package/src/services/reviews/reviews.service.ts +683 -636
  223. package/src/services/user/index.ts +1 -1
  224. package/src/services/user/user.service.ts +489 -489
  225. package/src/services/user/user.v2.service.ts +466 -466
  226. package/src/types/appointment/index.ts +480 -480
  227. package/src/types/calendar/index.ts +258 -258
  228. package/src/types/calendar/synced-calendar.types.ts +66 -66
  229. package/src/types/clinic/index.ts +489 -489
  230. package/src/types/clinic/practitioner-invite.types.ts +91 -91
  231. package/src/types/clinic/preferences.types.ts +159 -159
  232. package/src/types/clinic/to-do +3 -3
  233. package/src/types/documentation-templates/index.ts +308 -308
  234. package/src/types/index.ts +44 -44
  235. package/src/types/notifications/README.md +77 -77
  236. package/src/types/notifications/index.ts +265 -265
  237. package/src/types/patient/aesthetic-analysis.types.ts +66 -66
  238. package/src/types/patient/allergies.ts +58 -58
  239. package/src/types/patient/index.ts +275 -275
  240. package/src/types/patient/medical-info.types.ts +152 -152
  241. package/src/types/patient/patient-requirements.ts +92 -92
  242. package/src/types/patient/token.types.ts +61 -61
  243. package/src/types/practitioner/index.ts +206 -206
  244. package/src/types/procedure/index.ts +181 -181
  245. package/src/types/profile/index.ts +39 -39
  246. package/src/types/reviews/index.ts +132 -130
  247. package/src/types/tz-lookup.d.ts +4 -4
  248. package/src/types/user/index.ts +38 -38
  249. package/src/utils/TIMESTAMPS.md +176 -176
  250. package/src/utils/TimestampUtils.ts +241 -241
  251. package/src/utils/index.ts +1 -1
  252. package/src/validations/appointment.schema.ts +574 -574
  253. package/src/validations/calendar.schema.ts +225 -225
  254. package/src/validations/clinic.schema.ts +493 -493
  255. package/src/validations/common.schema.ts +25 -25
  256. package/src/validations/documentation-templates/index.ts +1 -1
  257. package/src/validations/documentation-templates/template.schema.ts +220 -220
  258. package/src/validations/documentation-templates.schema.ts +10 -10
  259. package/src/validations/index.ts +20 -20
  260. package/src/validations/media.schema.ts +10 -10
  261. package/src/validations/notification.schema.ts +90 -90
  262. package/src/validations/patient/aesthetic-analysis.schema.ts +55 -55
  263. package/src/validations/patient/medical-info.schema.ts +125 -125
  264. package/src/validations/patient/patient-requirements.schema.ts +84 -84
  265. package/src/validations/patient/token.schema.ts +29 -29
  266. package/src/validations/patient.schema.ts +217 -217
  267. package/src/validations/practitioner.schema.ts +222 -222
  268. package/src/validations/procedure-product.schema.ts +41 -41
  269. package/src/validations/procedure.schema.ts +124 -124
  270. package/src/validations/profile-info.schema.ts +41 -41
  271. package/src/validations/reviews.schema.ts +195 -189
  272. package/src/validations/schemas.ts +104 -104
  273. package/src/validations/shared.schema.ts +78 -78
@@ -70,6 +70,7 @@ interface PractitionerReview extends BaseReview {
70
70
  /**
71
71
  * Procedure review interface
72
72
  * @description Full review for a medical procedure
73
+ * Used for both main and extended procedures
73
74
  */
74
75
  interface ProcedureReview extends BaseReview {
75
76
  procedureId: string;
@@ -138,6 +139,7 @@ interface Review {
138
139
  clinicReview?: ClinicReview;
139
140
  practitionerReview?: PractitionerReview;
140
141
  procedureReview?: ProcedureReview;
142
+ extendedProcedureReviews?: ProcedureReview[];
141
143
  overallComment: string;
142
144
  overallRating: number;
143
145
  }
@@ -70,6 +70,7 @@ interface PractitionerReview extends BaseReview {
70
70
  /**
71
71
  * Procedure review interface
72
72
  * @description Full review for a medical procedure
73
+ * Used for both main and extended procedures
73
74
  */
74
75
  interface ProcedureReview extends BaseReview {
75
76
  procedureId: string;
@@ -138,6 +139,7 @@ interface Review {
138
139
  clinicReview?: ClinicReview;
139
140
  practitionerReview?: PractitionerReview;
140
141
  procedureReview?: ProcedureReview;
142
+ extendedProcedureReviews?: ProcedureReview[];
141
143
  overallComment: string;
142
144
  overallRating: number;
143
145
  }
@@ -6375,6 +6375,16 @@ var ReviewsAggregationService = class {
6375
6375
  this.updateProcedureReviewInfo(review.procedureReview.procedureId)
6376
6376
  );
6377
6377
  }
6378
+ if (review.extendedProcedureReviews && review.extendedProcedureReviews.length > 0) {
6379
+ console.log(
6380
+ `[ReviewsAggregationService] Processing ${review.extendedProcedureReviews.length} extended procedure reviews`
6381
+ );
6382
+ review.extendedProcedureReviews.forEach((extendedReview) => {
6383
+ updatePromises.push(
6384
+ this.updateProcedureReviewInfo(extendedReview.procedureId)
6385
+ );
6386
+ });
6387
+ }
6378
6388
  await Promise.all(updatePromises);
6379
6389
  console.log(
6380
6390
  `[ReviewsAggregationService] Successfully processed review: ${review.id}`
@@ -6417,6 +6427,20 @@ var ReviewsAggregationService = class {
6417
6427
  )
6418
6428
  );
6419
6429
  }
6430
+ if (review.extendedProcedureReviews && review.extendedProcedureReviews.length > 0) {
6431
+ console.log(
6432
+ `[ReviewsAggregationService] Processing deletion of ${review.extendedProcedureReviews.length} extended procedure reviews`
6433
+ );
6434
+ review.extendedProcedureReviews.forEach((extendedReview) => {
6435
+ updatePromises.push(
6436
+ this.updateProcedureReviewInfo(
6437
+ extendedReview.procedureId,
6438
+ extendedReview,
6439
+ true
6440
+ )
6441
+ );
6442
+ });
6443
+ }
6420
6444
  await Promise.all(updatePromises);
6421
6445
  console.log(
6422
6446
  `[ReviewsAggregationService] Successfully processed deleted review: ${review.id}`
@@ -6634,8 +6658,21 @@ var ReviewsAggregationService = class {
6634
6658
  valueForMoney: 0,
6635
6659
  recommendationPercentage: 0
6636
6660
  };
6637
- const reviewsQuery = await this.db.collection(REVIEWS_COLLECTION).where("procedureReview.procedureId", "==", procedureId).get();
6638
- if (isRemoval && reviewsQuery.size <= 1 || reviewsQuery.empty) {
6661
+ const allReviewsQuery = await this.db.collection(REVIEWS_COLLECTION).get();
6662
+ const reviews = allReviewsQuery.docs.map((doc) => doc.data());
6663
+ const procedureReviews = [];
6664
+ reviews.forEach((review) => {
6665
+ if (review.procedureReview && review.procedureReview.procedureId === procedureId) {
6666
+ procedureReviews.push(review.procedureReview);
6667
+ }
6668
+ if (review.extendedProcedureReviews && review.extendedProcedureReviews.length > 0) {
6669
+ const matchingExtended = review.extendedProcedureReviews.filter(
6670
+ (extReview) => extReview.procedureId === procedureId
6671
+ );
6672
+ procedureReviews.push(...matchingExtended);
6673
+ }
6674
+ });
6675
+ if (procedureReviews.length === 0) {
6639
6676
  const updatedReviewInfo2 = {
6640
6677
  totalReviews: 0,
6641
6678
  averageRating: 0,
@@ -6655,8 +6692,6 @@ var ReviewsAggregationService = class {
6655
6692
  );
6656
6693
  return updatedReviewInfo2;
6657
6694
  }
6658
- const reviews = reviewsQuery.docs.map((doc) => doc.data());
6659
- const procedureReviews = reviews.map((review) => review.procedureReview).filter((review) => review !== void 0);
6660
6695
  let totalRating = 0;
6661
6696
  let totalEffectivenessOfTreatment = 0;
6662
6697
  let totalOutcomeExplanation = 0;
@@ -6750,10 +6785,16 @@ var ReviewsAggregationService = class {
6750
6785
  if (review.procedureReview) {
6751
6786
  review.procedureReview.isVerified = true;
6752
6787
  }
6788
+ if (review.extendedProcedureReviews && review.extendedProcedureReviews.length > 0) {
6789
+ review.extendedProcedureReviews.forEach((extReview) => {
6790
+ extReview.isVerified = true;
6791
+ });
6792
+ }
6753
6793
  batch.update(reviewRef, {
6754
6794
  clinicReview: review.clinicReview,
6755
6795
  practitionerReview: review.practitionerReview,
6756
6796
  procedureReview: review.procedureReview,
6797
+ extendedProcedureReviews: review.extendedProcedureReviews,
6757
6798
  updatedAt: admin13.firestore.FieldValue.serverTimestamp()
6758
6799
  });
6759
6800
  await batch.commit();
@@ -6313,6 +6313,16 @@ var ReviewsAggregationService = class {
6313
6313
  this.updateProcedureReviewInfo(review.procedureReview.procedureId)
6314
6314
  );
6315
6315
  }
6316
+ if (review.extendedProcedureReviews && review.extendedProcedureReviews.length > 0) {
6317
+ console.log(
6318
+ `[ReviewsAggregationService] Processing ${review.extendedProcedureReviews.length} extended procedure reviews`
6319
+ );
6320
+ review.extendedProcedureReviews.forEach((extendedReview) => {
6321
+ updatePromises.push(
6322
+ this.updateProcedureReviewInfo(extendedReview.procedureId)
6323
+ );
6324
+ });
6325
+ }
6316
6326
  await Promise.all(updatePromises);
6317
6327
  console.log(
6318
6328
  `[ReviewsAggregationService] Successfully processed review: ${review.id}`
@@ -6355,6 +6365,20 @@ var ReviewsAggregationService = class {
6355
6365
  )
6356
6366
  );
6357
6367
  }
6368
+ if (review.extendedProcedureReviews && review.extendedProcedureReviews.length > 0) {
6369
+ console.log(
6370
+ `[ReviewsAggregationService] Processing deletion of ${review.extendedProcedureReviews.length} extended procedure reviews`
6371
+ );
6372
+ review.extendedProcedureReviews.forEach((extendedReview) => {
6373
+ updatePromises.push(
6374
+ this.updateProcedureReviewInfo(
6375
+ extendedReview.procedureId,
6376
+ extendedReview,
6377
+ true
6378
+ )
6379
+ );
6380
+ });
6381
+ }
6358
6382
  await Promise.all(updatePromises);
6359
6383
  console.log(
6360
6384
  `[ReviewsAggregationService] Successfully processed deleted review: ${review.id}`
@@ -6572,8 +6596,21 @@ var ReviewsAggregationService = class {
6572
6596
  valueForMoney: 0,
6573
6597
  recommendationPercentage: 0
6574
6598
  };
6575
- const reviewsQuery = await this.db.collection(REVIEWS_COLLECTION).where("procedureReview.procedureId", "==", procedureId).get();
6576
- if (isRemoval && reviewsQuery.size <= 1 || reviewsQuery.empty) {
6599
+ const allReviewsQuery = await this.db.collection(REVIEWS_COLLECTION).get();
6600
+ const reviews = allReviewsQuery.docs.map((doc) => doc.data());
6601
+ const procedureReviews = [];
6602
+ reviews.forEach((review) => {
6603
+ if (review.procedureReview && review.procedureReview.procedureId === procedureId) {
6604
+ procedureReviews.push(review.procedureReview);
6605
+ }
6606
+ if (review.extendedProcedureReviews && review.extendedProcedureReviews.length > 0) {
6607
+ const matchingExtended = review.extendedProcedureReviews.filter(
6608
+ (extReview) => extReview.procedureId === procedureId
6609
+ );
6610
+ procedureReviews.push(...matchingExtended);
6611
+ }
6612
+ });
6613
+ if (procedureReviews.length === 0) {
6577
6614
  const updatedReviewInfo2 = {
6578
6615
  totalReviews: 0,
6579
6616
  averageRating: 0,
@@ -6593,8 +6630,6 @@ var ReviewsAggregationService = class {
6593
6630
  );
6594
6631
  return updatedReviewInfo2;
6595
6632
  }
6596
- const reviews = reviewsQuery.docs.map((doc) => doc.data());
6597
- const procedureReviews = reviews.map((review) => review.procedureReview).filter((review) => review !== void 0);
6598
6633
  let totalRating = 0;
6599
6634
  let totalEffectivenessOfTreatment = 0;
6600
6635
  let totalOutcomeExplanation = 0;
@@ -6688,10 +6723,16 @@ var ReviewsAggregationService = class {
6688
6723
  if (review.procedureReview) {
6689
6724
  review.procedureReview.isVerified = true;
6690
6725
  }
6726
+ if (review.extendedProcedureReviews && review.extendedProcedureReviews.length > 0) {
6727
+ review.extendedProcedureReviews.forEach((extReview) => {
6728
+ extReview.isVerified = true;
6729
+ });
6730
+ }
6691
6731
  batch.update(reviewRef, {
6692
6732
  clinicReview: review.clinicReview,
6693
6733
  practitionerReview: review.practitionerReview,
6694
6734
  procedureReview: review.procedureReview,
6735
+ extendedProcedureReviews: review.extendedProcedureReviews,
6695
6736
  updatedAt: admin13.firestore.FieldValue.serverTimestamp()
6696
6737
  });
6697
6738
  await batch.commit();
@@ -188,6 +188,11 @@ interface ICategoryService {
188
188
  delete(id: string): Promise<void>;
189
189
  reactivate(id: string): Promise<void>;
190
190
  getById(id: string): Promise<Category | null>;
191
+ findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
192
+ exportToCsv(options?: {
193
+ includeInactive?: boolean;
194
+ includeBom?: boolean;
195
+ }): Promise<string>;
191
196
  }
192
197
 
193
198
  /**
@@ -289,6 +294,14 @@ declare class CategoryService extends BaseService implements ICategoryService {
289
294
  * @returns Kategorija ili null ako ne postoji
290
295
  */
291
296
  getById(id: string): Promise<Category | null>;
297
+ /**
298
+ * Finds a category by exact name match within a specific family.
299
+ * Used for CSV import matching.
300
+ * @param name - Exact name of the category to find
301
+ * @param family - Procedure family to search within
302
+ * @returns Category if found, null otherwise
303
+ */
304
+ findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
292
305
  /**
293
306
  * Exports categories to CSV string, suitable for Excel/Sheets.
294
307
  * Includes headers and optional UTF-8 BOM.
@@ -1077,6 +1090,11 @@ interface ITechnologyService {
1077
1090
  getAllForFilterBySubcategory(subcategoryId: string): Promise<Technology[]>;
1078
1091
  getAllForFilterBySubcategoryId(categoryId: string, subcategoryId: string): Promise<Technology[]>;
1079
1092
  getAllForFilter(): Promise<Technology[]>;
1093
+ findByName(name: string): Promise<Technology | null>;
1094
+ exportToCsv(options?: {
1095
+ includeInactive?: boolean;
1096
+ includeBom?: boolean;
1097
+ }): Promise<string>;
1080
1098
  }
1081
1099
 
1082
1100
  /**
@@ -1976,6 +1994,14 @@ declare class SubcategoryService extends BaseService {
1976
1994
  * @returns Podkategorija ili null ako ne postoji
1977
1995
  */
1978
1996
  getById(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
1997
+ /**
1998
+ * Finds a subcategory by exact name match within a specific category.
1999
+ * Used for CSV import matching.
2000
+ * @param name - Exact name of the subcategory to find
2001
+ * @param categoryId - ID of the category to search within
2002
+ * @returns Subcategory if found, null otherwise
2003
+ */
2004
+ findByNameAndCategory(name: string, categoryId: string): Promise<Subcategory | null>;
1979
2005
  /**
1980
2006
  * Exports subcategories to CSV string, suitable for Excel/Sheets.
1981
2007
  * Includes headers and optional UTF-8 BOM.
@@ -2101,6 +2127,13 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2101
2127
  * @returns The technology or null if it doesn't exist.
2102
2128
  */
2103
2129
  getById(id: string): Promise<Technology | null>;
2130
+ /**
2131
+ * Finds a technology by exact name match.
2132
+ * Used for CSV import duplicate detection.
2133
+ * @param name - Exact name of the technology to find
2134
+ * @returns Technology if found, null otherwise
2135
+ */
2136
+ findByName(name: string): Promise<Technology | null>;
2104
2137
  /**
2105
2138
  * Dodaje novi zahtev tehnologiji
2106
2139
  * @param technologyId - ID tehnologije
@@ -188,6 +188,11 @@ interface ICategoryService {
188
188
  delete(id: string): Promise<void>;
189
189
  reactivate(id: string): Promise<void>;
190
190
  getById(id: string): Promise<Category | null>;
191
+ findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
192
+ exportToCsv(options?: {
193
+ includeInactive?: boolean;
194
+ includeBom?: boolean;
195
+ }): Promise<string>;
191
196
  }
192
197
 
193
198
  /**
@@ -289,6 +294,14 @@ declare class CategoryService extends BaseService implements ICategoryService {
289
294
  * @returns Kategorija ili null ako ne postoji
290
295
  */
291
296
  getById(id: string): Promise<Category | null>;
297
+ /**
298
+ * Finds a category by exact name match within a specific family.
299
+ * Used for CSV import matching.
300
+ * @param name - Exact name of the category to find
301
+ * @param family - Procedure family to search within
302
+ * @returns Category if found, null otherwise
303
+ */
304
+ findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
292
305
  /**
293
306
  * Exports categories to CSV string, suitable for Excel/Sheets.
294
307
  * Includes headers and optional UTF-8 BOM.
@@ -1077,6 +1090,11 @@ interface ITechnologyService {
1077
1090
  getAllForFilterBySubcategory(subcategoryId: string): Promise<Technology[]>;
1078
1091
  getAllForFilterBySubcategoryId(categoryId: string, subcategoryId: string): Promise<Technology[]>;
1079
1092
  getAllForFilter(): Promise<Technology[]>;
1093
+ findByName(name: string): Promise<Technology | null>;
1094
+ exportToCsv(options?: {
1095
+ includeInactive?: boolean;
1096
+ includeBom?: boolean;
1097
+ }): Promise<string>;
1080
1098
  }
1081
1099
 
1082
1100
  /**
@@ -1976,6 +1994,14 @@ declare class SubcategoryService extends BaseService {
1976
1994
  * @returns Podkategorija ili null ako ne postoji
1977
1995
  */
1978
1996
  getById(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
1997
+ /**
1998
+ * Finds a subcategory by exact name match within a specific category.
1999
+ * Used for CSV import matching.
2000
+ * @param name - Exact name of the subcategory to find
2001
+ * @param categoryId - ID of the category to search within
2002
+ * @returns Subcategory if found, null otherwise
2003
+ */
2004
+ findByNameAndCategory(name: string, categoryId: string): Promise<Subcategory | null>;
1979
2005
  /**
1980
2006
  * Exports subcategories to CSV string, suitable for Excel/Sheets.
1981
2007
  * Includes headers and optional UTF-8 BOM.
@@ -2101,6 +2127,13 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2101
2127
  * @returns The technology or null if it doesn't exist.
2102
2128
  */
2103
2129
  getById(id: string): Promise<Technology | null>;
2130
+ /**
2131
+ * Finds a technology by exact name match.
2132
+ * Used for CSV import duplicate detection.
2133
+ * @param name - Exact name of the technology to find
2134
+ * @returns Technology if found, null otherwise
2135
+ */
2136
+ findByName(name: string): Promise<Technology | null>;
2104
2137
  /**
2105
2138
  * Dodaje novi zahtev tehnologiji
2106
2139
  * @param technologyId - ID tehnologije
@@ -515,6 +515,28 @@ var CategoryService = class extends BaseService {
515
515
  ...docSnap.data()
516
516
  };
517
517
  }
518
+ /**
519
+ * Finds a category by exact name match within a specific family.
520
+ * Used for CSV import matching.
521
+ * @param name - Exact name of the category to find
522
+ * @param family - Procedure family to search within
523
+ * @returns Category if found, null otherwise
524
+ */
525
+ async findByNameAndFamily(name, family) {
526
+ const q = (0, import_firestore2.query)(
527
+ this.categoriesRef,
528
+ (0, import_firestore2.where)("name", "==", name),
529
+ (0, import_firestore2.where)("family", "==", family),
530
+ (0, import_firestore2.where)("isActive", "==", true)
531
+ );
532
+ const snapshot = await (0, import_firestore2.getDocs)(q);
533
+ if (snapshot.empty) return null;
534
+ const doc11 = snapshot.docs[0];
535
+ return {
536
+ id: doc11.id,
537
+ ...doc11.data()
538
+ };
539
+ }
518
540
  /**
519
541
  * Exports categories to CSV string, suitable for Excel/Sheets.
520
542
  * Includes headers and optional UTF-8 BOM.
@@ -2445,6 +2467,27 @@ var SubcategoryService = class extends BaseService {
2445
2467
  ...docSnap.data()
2446
2468
  };
2447
2469
  }
2470
+ /**
2471
+ * Finds a subcategory by exact name match within a specific category.
2472
+ * Used for CSV import matching.
2473
+ * @param name - Exact name of the subcategory to find
2474
+ * @param categoryId - ID of the category to search within
2475
+ * @returns Subcategory if found, null otherwise
2476
+ */
2477
+ async findByNameAndCategory(name, categoryId) {
2478
+ const q = (0, import_firestore10.query)(
2479
+ this.getSubcategoriesRef(categoryId),
2480
+ (0, import_firestore10.where)("name", "==", name),
2481
+ (0, import_firestore10.where)("isActive", "==", true)
2482
+ );
2483
+ const querySnapshot = await (0, import_firestore10.getDocs)(q);
2484
+ if (querySnapshot.empty) return null;
2485
+ const doc11 = querySnapshot.docs[0];
2486
+ return {
2487
+ id: doc11.id,
2488
+ ...doc11.data()
2489
+ };
2490
+ }
2448
2491
  /**
2449
2492
  * Exports subcategories to CSV string, suitable for Excel/Sheets.
2450
2493
  * Includes headers and optional UTF-8 BOM.
@@ -2756,6 +2799,26 @@ var TechnologyService = class extends BaseService {
2756
2799
  ...docSnap.data()
2757
2800
  };
2758
2801
  }
2802
+ /**
2803
+ * Finds a technology by exact name match.
2804
+ * Used for CSV import duplicate detection.
2805
+ * @param name - Exact name of the technology to find
2806
+ * @returns Technology if found, null otherwise
2807
+ */
2808
+ async findByName(name) {
2809
+ const q = (0, import_firestore11.query)(
2810
+ this.technologiesRef,
2811
+ (0, import_firestore11.where)("name", "==", name),
2812
+ (0, import_firestore11.where)("isActive", "==", true)
2813
+ );
2814
+ const snapshot = await (0, import_firestore11.getDocs)(q);
2815
+ if (snapshot.empty) return null;
2816
+ const doc11 = snapshot.docs[0];
2817
+ return {
2818
+ id: doc11.id,
2819
+ ...doc11.data()
2820
+ };
2821
+ }
2759
2822
  /**
2760
2823
  * Dodaje novi zahtev tehnologiji
2761
2824
  * @param technologyId - ID tehnologije
@@ -434,6 +434,28 @@ var CategoryService = class extends BaseService {
434
434
  ...docSnap.data()
435
435
  };
436
436
  }
437
+ /**
438
+ * Finds a category by exact name match within a specific family.
439
+ * Used for CSV import matching.
440
+ * @param name - Exact name of the category to find
441
+ * @param family - Procedure family to search within
442
+ * @returns Category if found, null otherwise
443
+ */
444
+ async findByNameAndFamily(name, family) {
445
+ const q = query2(
446
+ this.categoriesRef,
447
+ where2("name", "==", name),
448
+ where2("family", "==", family),
449
+ where2("isActive", "==", true)
450
+ );
451
+ const snapshot = await getDocs2(q);
452
+ if (snapshot.empty) return null;
453
+ const doc11 = snapshot.docs[0];
454
+ return {
455
+ id: doc11.id,
456
+ ...doc11.data()
457
+ };
458
+ }
437
459
  /**
438
460
  * Exports categories to CSV string, suitable for Excel/Sheets.
439
461
  * Includes headers and optional UTF-8 BOM.
@@ -2448,6 +2470,27 @@ var SubcategoryService = class extends BaseService {
2448
2470
  ...docSnap.data()
2449
2471
  };
2450
2472
  }
2473
+ /**
2474
+ * Finds a subcategory by exact name match within a specific category.
2475
+ * Used for CSV import matching.
2476
+ * @param name - Exact name of the subcategory to find
2477
+ * @param categoryId - ID of the category to search within
2478
+ * @returns Subcategory if found, null otherwise
2479
+ */
2480
+ async findByNameAndCategory(name, categoryId) {
2481
+ const q = query8(
2482
+ this.getSubcategoriesRef(categoryId),
2483
+ where8("name", "==", name),
2484
+ where8("isActive", "==", true)
2485
+ );
2486
+ const querySnapshot = await getDocs8(q);
2487
+ if (querySnapshot.empty) return null;
2488
+ const doc11 = querySnapshot.docs[0];
2489
+ return {
2490
+ id: doc11.id,
2491
+ ...doc11.data()
2492
+ };
2493
+ }
2451
2494
  /**
2452
2495
  * Exports subcategories to CSV string, suitable for Excel/Sheets.
2453
2496
  * Includes headers and optional UTF-8 BOM.
@@ -2774,6 +2817,26 @@ var TechnologyService = class extends BaseService {
2774
2817
  ...docSnap.data()
2775
2818
  };
2776
2819
  }
2820
+ /**
2821
+ * Finds a technology by exact name match.
2822
+ * Used for CSV import duplicate detection.
2823
+ * @param name - Exact name of the technology to find
2824
+ * @returns Technology if found, null otherwise
2825
+ */
2826
+ async findByName(name) {
2827
+ const q = query9(
2828
+ this.technologiesRef,
2829
+ where9("name", "==", name),
2830
+ where9("isActive", "==", true)
2831
+ );
2832
+ const snapshot = await getDocs9(q);
2833
+ if (snapshot.empty) return null;
2834
+ const doc11 = snapshot.docs[0];
2835
+ return {
2836
+ id: doc11.id,
2837
+ ...doc11.data()
2838
+ };
2839
+ }
2777
2840
  /**
2778
2841
  * Dodaje novi zahtev tehnologiji
2779
2842
  * @param technologyId - ID tehnologije
package/dist/index.d.mts CHANGED
@@ -70,6 +70,7 @@ interface PractitionerReview extends BaseReview {
70
70
  /**
71
71
  * Procedure review interface
72
72
  * @description Full review for a medical procedure
73
+ * Used for both main and extended procedures
73
74
  */
74
75
  interface ProcedureReview extends BaseReview {
75
76
  procedureId: string;
@@ -138,6 +139,7 @@ interface Review {
138
139
  clinicReview?: ClinicReview;
139
140
  practitionerReview?: PractitionerReview;
140
141
  procedureReview?: ProcedureReview;
142
+ extendedProcedureReviews?: ProcedureReview[];
141
143
  overallComment: string;
142
144
  overallRating: number;
143
145
  }
@@ -286,6 +288,11 @@ interface ICategoryService {
286
288
  delete(id: string): Promise<void>;
287
289
  reactivate(id: string): Promise<void>;
288
290
  getById(id: string): Promise<Category | null>;
291
+ findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
292
+ exportToCsv(options?: {
293
+ includeInactive?: boolean;
294
+ includeBom?: boolean;
295
+ }): Promise<string>;
289
296
  }
290
297
 
291
298
  /**
@@ -1012,6 +1019,11 @@ interface ITechnologyService {
1012
1019
  getAllForFilterBySubcategory(subcategoryId: string): Promise<Technology[]>;
1013
1020
  getAllForFilterBySubcategoryId(categoryId: string, subcategoryId: string): Promise<Technology[]>;
1014
1021
  getAllForFilter(): Promise<Technology[]>;
1022
+ findByName(name: string): Promise<Technology | null>;
1023
+ exportToCsv(options?: {
1024
+ includeInactive?: boolean;
1025
+ includeBom?: boolean;
1026
+ }): Promise<string>;
1015
1027
  }
1016
1028
 
1017
1029
  /**
@@ -1298,6 +1310,14 @@ declare class CategoryService extends BaseService implements ICategoryService {
1298
1310
  * @returns Kategorija ili null ako ne postoji
1299
1311
  */
1300
1312
  getById(id: string): Promise<Category | null>;
1313
+ /**
1314
+ * Finds a category by exact name match within a specific family.
1315
+ * Used for CSV import matching.
1316
+ * @param name - Exact name of the category to find
1317
+ * @param family - Procedure family to search within
1318
+ * @returns Category if found, null otherwise
1319
+ */
1320
+ findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
1301
1321
  /**
1302
1322
  * Exports categories to CSV string, suitable for Excel/Sheets.
1303
1323
  * Includes headers and optional UTF-8 BOM.
@@ -1820,6 +1840,14 @@ declare class SubcategoryService extends BaseService {
1820
1840
  * @returns Podkategorija ili null ako ne postoji
1821
1841
  */
1822
1842
  getById(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
1843
+ /**
1844
+ * Finds a subcategory by exact name match within a specific category.
1845
+ * Used for CSV import matching.
1846
+ * @param name - Exact name of the subcategory to find
1847
+ * @param categoryId - ID of the category to search within
1848
+ * @returns Subcategory if found, null otherwise
1849
+ */
1850
+ findByNameAndCategory(name: string, categoryId: string): Promise<Subcategory | null>;
1823
1851
  /**
1824
1852
  * Exports subcategories to CSV string, suitable for Excel/Sheets.
1825
1853
  * Includes headers and optional UTF-8 BOM.
@@ -2246,6 +2274,13 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2246
2274
  * @returns The technology or null if it doesn't exist.
2247
2275
  */
2248
2276
  getById(id: string): Promise<Technology | null>;
2277
+ /**
2278
+ * Finds a technology by exact name match.
2279
+ * Used for CSV import duplicate detection.
2280
+ * @param name - Exact name of the technology to find
2281
+ * @returns Technology if found, null otherwise
2282
+ */
2283
+ findByName(name: string): Promise<Technology | null>;
2249
2284
  /**
2250
2285
  * Dodaje novi zahtev tehnologiji
2251
2286
  * @param technologyId - ID tehnologije
package/dist/index.d.ts CHANGED
@@ -70,6 +70,7 @@ interface PractitionerReview extends BaseReview {
70
70
  /**
71
71
  * Procedure review interface
72
72
  * @description Full review for a medical procedure
73
+ * Used for both main and extended procedures
73
74
  */
74
75
  interface ProcedureReview extends BaseReview {
75
76
  procedureId: string;
@@ -138,6 +139,7 @@ interface Review {
138
139
  clinicReview?: ClinicReview;
139
140
  practitionerReview?: PractitionerReview;
140
141
  procedureReview?: ProcedureReview;
142
+ extendedProcedureReviews?: ProcedureReview[];
141
143
  overallComment: string;
142
144
  overallRating: number;
143
145
  }
@@ -286,6 +288,11 @@ interface ICategoryService {
286
288
  delete(id: string): Promise<void>;
287
289
  reactivate(id: string): Promise<void>;
288
290
  getById(id: string): Promise<Category | null>;
291
+ findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
292
+ exportToCsv(options?: {
293
+ includeInactive?: boolean;
294
+ includeBom?: boolean;
295
+ }): Promise<string>;
289
296
  }
290
297
 
291
298
  /**
@@ -1012,6 +1019,11 @@ interface ITechnologyService {
1012
1019
  getAllForFilterBySubcategory(subcategoryId: string): Promise<Technology[]>;
1013
1020
  getAllForFilterBySubcategoryId(categoryId: string, subcategoryId: string): Promise<Technology[]>;
1014
1021
  getAllForFilter(): Promise<Technology[]>;
1022
+ findByName(name: string): Promise<Technology | null>;
1023
+ exportToCsv(options?: {
1024
+ includeInactive?: boolean;
1025
+ includeBom?: boolean;
1026
+ }): Promise<string>;
1015
1027
  }
1016
1028
 
1017
1029
  /**
@@ -1298,6 +1310,14 @@ declare class CategoryService extends BaseService implements ICategoryService {
1298
1310
  * @returns Kategorija ili null ako ne postoji
1299
1311
  */
1300
1312
  getById(id: string): Promise<Category | null>;
1313
+ /**
1314
+ * Finds a category by exact name match within a specific family.
1315
+ * Used for CSV import matching.
1316
+ * @param name - Exact name of the category to find
1317
+ * @param family - Procedure family to search within
1318
+ * @returns Category if found, null otherwise
1319
+ */
1320
+ findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
1301
1321
  /**
1302
1322
  * Exports categories to CSV string, suitable for Excel/Sheets.
1303
1323
  * Includes headers and optional UTF-8 BOM.
@@ -1820,6 +1840,14 @@ declare class SubcategoryService extends BaseService {
1820
1840
  * @returns Podkategorija ili null ako ne postoji
1821
1841
  */
1822
1842
  getById(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
1843
+ /**
1844
+ * Finds a subcategory by exact name match within a specific category.
1845
+ * Used for CSV import matching.
1846
+ * @param name - Exact name of the subcategory to find
1847
+ * @param categoryId - ID of the category to search within
1848
+ * @returns Subcategory if found, null otherwise
1849
+ */
1850
+ findByNameAndCategory(name: string, categoryId: string): Promise<Subcategory | null>;
1823
1851
  /**
1824
1852
  * Exports subcategories to CSV string, suitable for Excel/Sheets.
1825
1853
  * Includes headers and optional UTF-8 BOM.
@@ -2246,6 +2274,13 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2246
2274
  * @returns The technology or null if it doesn't exist.
2247
2275
  */
2248
2276
  getById(id: string): Promise<Technology | null>;
2277
+ /**
2278
+ * Finds a technology by exact name match.
2279
+ * Used for CSV import duplicate detection.
2280
+ * @param name - Exact name of the technology to find
2281
+ * @returns Technology if found, null otherwise
2282
+ */
2283
+ findByName(name: string): Promise<Technology | null>;
2249
2284
  /**
2250
2285
  * Dodaje novi zahtev tehnologiji
2251
2286
  * @param technologyId - ID tehnologije