@blackcode_sa/metaestetics-api 1.12.66 → 1.12.68

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.
@@ -243,7 +243,6 @@ import {
243
243
  addDoc as addDoc2,
244
244
  collection as collection2,
245
245
  doc as doc2,
246
- getCountFromServer as getCountFromServer2,
247
246
  getDoc as getDoc2,
248
247
  getDocs as getDocs2,
249
248
  limit as limit2,
@@ -265,7 +264,16 @@ var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
265
264
  })(ProcedureFamily || {});
266
265
 
267
266
  // src/backoffice/services/category.service.ts
267
+ var EXCLUDED_CATEGORY_ID = "consultation";
268
268
  var CategoryService = class extends BaseService {
269
+ /**
270
+ * Filters out excluded categories from a list.
271
+ * @param categories - List of categories to filter
272
+ * @returns Filtered list without excluded categories
273
+ */
274
+ filterExcludedCategories(categories) {
275
+ return categories.filter((cat) => cat.id !== EXCLUDED_CATEGORY_ID);
276
+ }
269
277
  /**
270
278
  * Referenca na Firestore kolekciju kategorija
271
279
  */
@@ -302,8 +310,9 @@ var CategoryService = class extends BaseService {
302
310
  where2("family", "==", family),
303
311
  where2("isActive", "==", active)
304
312
  );
305
- const snapshot = await getCountFromServer2(q);
306
- counts[family] = snapshot.data().count;
313
+ const snapshot = await getDocs2(q);
314
+ const filteredDocs = snapshot.docs.filter((doc11) => doc11.id !== EXCLUDED_CATEGORY_ID);
315
+ counts[family] = filteredDocs.length;
307
316
  }
308
317
  return counts;
309
318
  }
@@ -314,12 +323,13 @@ var CategoryService = class extends BaseService {
314
323
  async getAllForFilter() {
315
324
  const q = query2(this.categoriesRef, where2("isActive", "==", true));
316
325
  const snapshot = await getDocs2(q);
317
- return snapshot.docs.map(
326
+ const categories = snapshot.docs.map(
318
327
  (doc11) => ({
319
328
  id: doc11.id,
320
329
  ...doc11.data()
321
330
  })
322
331
  );
332
+ return this.filterExcludedCategories(categories);
323
333
  }
324
334
  /**
325
335
  * Vraća sve kategorije za određenu familiju za potrebe filtera (bez paginacije)
@@ -334,12 +344,13 @@ var CategoryService = class extends BaseService {
334
344
  orderBy2("name")
335
345
  );
336
346
  const snapshot = await getDocs2(q);
337
- return snapshot.docs.map(
347
+ const categories = snapshot.docs.map(
338
348
  (doc11) => ({
339
349
  id: doc11.id,
340
350
  ...doc11.data()
341
351
  })
342
352
  );
353
+ return this.filterExcludedCategories(categories);
343
354
  }
344
355
  /**
345
356
  * Vraća sve kategorije sa paginacijom
@@ -362,8 +373,9 @@ var CategoryService = class extends BaseService {
362
373
  ...doc11.data()
363
374
  })
364
375
  );
376
+ const filteredCategories = this.filterExcludedCategories(categories);
365
377
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
366
- return { categories, lastVisible: newLastVisible };
378
+ return { categories: filteredCategories, lastVisible: newLastVisible };
367
379
  }
368
380
  /**
369
381
  * Vraća sve aktivne kategorije za određenu familiju procedura sa paginacijom
@@ -388,8 +400,9 @@ var CategoryService = class extends BaseService {
388
400
  ...doc11.data()
389
401
  })
390
402
  );
403
+ const filteredCategories = this.filterExcludedCategories(categories);
391
404
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
392
- return { categories, lastVisible: newLastVisible };
405
+ return { categories: filteredCategories, lastVisible: newLastVisible };
393
406
  }
394
407
  /**
395
408
  * Ažurira postojeću kategoriju
@@ -426,6 +439,7 @@ var CategoryService = class extends BaseService {
426
439
  * @returns Kategorija ili null ako ne postoji
427
440
  */
428
441
  async getById(id) {
442
+ if (id === EXCLUDED_CATEGORY_ID) return null;
429
443
  const docRef = doc2(this.categoriesRef, id);
430
444
  const docSnap = await getDoc2(docRef);
431
445
  if (!docSnap.exists()) return null;
@@ -434,6 +448,44 @@ var CategoryService = class extends BaseService {
434
448
  ...docSnap.data()
435
449
  };
436
450
  }
451
+ /**
452
+ * Internal method to get category by ID without filtering.
453
+ * Used internally for consultation procedures.
454
+ * @param id - ID of the category to get
455
+ * @returns Category or null if not found
456
+ */
457
+ async getByIdInternal(id) {
458
+ const docRef = doc2(this.categoriesRef, id);
459
+ const docSnap = await getDoc2(docRef);
460
+ if (!docSnap.exists()) return null;
461
+ return {
462
+ id: docSnap.id,
463
+ ...docSnap.data()
464
+ };
465
+ }
466
+ /**
467
+ * Finds a category by exact name match within a specific family.
468
+ * Used for CSV import matching.
469
+ * @param name - Exact name of the category to find
470
+ * @param family - Procedure family to search within
471
+ * @returns Category if found, null otherwise
472
+ */
473
+ async findByNameAndFamily(name, family) {
474
+ const q = query2(
475
+ this.categoriesRef,
476
+ where2("name", "==", name),
477
+ where2("family", "==", family),
478
+ where2("isActive", "==", true)
479
+ );
480
+ const snapshot = await getDocs2(q);
481
+ if (snapshot.empty) return null;
482
+ const doc11 = snapshot.docs[0];
483
+ if (doc11.id === EXCLUDED_CATEGORY_ID) return null;
484
+ return {
485
+ id: doc11.id,
486
+ ...doc11.data()
487
+ };
488
+ }
437
489
  /**
438
490
  * Exports categories to CSV string, suitable for Excel/Sheets.
439
491
  * Includes headers and optional UTF-8 BOM.
@@ -466,6 +518,7 @@ var CategoryService = class extends BaseService {
466
518
  const snapshot = await getDocs2(q);
467
519
  if (snapshot.empty) break;
468
520
  for (const d of snapshot.docs) {
521
+ if (d.id === EXCLUDED_CATEGORY_ID) continue;
469
522
  const category = { id: d.id, ...d.data() };
470
523
  rows.push(this.categoryToCsvRow(category));
471
524
  }
@@ -2214,7 +2267,6 @@ import {
2214
2267
  collectionGroup as collectionGroup2,
2215
2268
  deleteDoc as deleteDoc3,
2216
2269
  doc as doc8,
2217
- getCountFromServer as getCountFromServer5,
2218
2270
  getDoc as getDoc8,
2219
2271
  getDocs as getDocs8,
2220
2272
  limit as limit7,
@@ -2230,7 +2282,16 @@ import {
2230
2282
  var SUBCATEGORIES_COLLECTION = "subcategories";
2231
2283
 
2232
2284
  // src/backoffice/services/subcategory.service.ts
2285
+ var EXCLUDED_SUBCATEGORY_ID = "free-consultation";
2233
2286
  var SubcategoryService = class extends BaseService {
2287
+ /**
2288
+ * Filters out excluded subcategories from a list.
2289
+ * @param subcategories - List of subcategories to filter
2290
+ * @returns Filtered list without excluded subcategories
2291
+ */
2292
+ filterExcludedSubcategories(subcategories) {
2293
+ return subcategories.filter((sub) => sub.id !== EXCLUDED_SUBCATEGORY_ID);
2294
+ }
2234
2295
  /**
2235
2296
  * Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
2236
2297
  * @param categoryId - ID roditeljske kategorije
@@ -2277,8 +2338,9 @@ var SubcategoryService = class extends BaseService {
2277
2338
  const categoryId = categoryDoc.id;
2278
2339
  const subcategoriesRef = this.getSubcategoriesRef(categoryId);
2279
2340
  const q = query8(subcategoriesRef, where8("isActive", "==", active));
2280
- const snapshot = await getCountFromServer5(q);
2281
- counts[categoryId] = snapshot.data().count;
2341
+ const snapshot = await getDocs8(q);
2342
+ const filteredDocs = snapshot.docs.filter((doc11) => doc11.id !== EXCLUDED_SUBCATEGORY_ID);
2343
+ counts[categoryId] = filteredDocs.length;
2282
2344
  }
2283
2345
  return counts;
2284
2346
  }
@@ -2304,8 +2366,9 @@ var SubcategoryService = class extends BaseService {
2304
2366
  ...doc11.data()
2305
2367
  })
2306
2368
  );
2369
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
2307
2370
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
2308
- return { subcategories, lastVisible: newLastVisible };
2371
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
2309
2372
  }
2310
2373
  /**
2311
2374
  * Vraća sve podkategorije sa paginacijom koristeći collection group query.
@@ -2334,8 +2397,9 @@ var SubcategoryService = class extends BaseService {
2334
2397
  ...doc11.data()
2335
2398
  })
2336
2399
  );
2400
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
2337
2401
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
2338
- return { subcategories, lastVisible: newLastVisible };
2402
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
2339
2403
  }
2340
2404
  /**
2341
2405
  * Vraća sve subkategorije za određenu kategoriju za potrebe filtera (bez paginacije)
@@ -2348,12 +2412,13 @@ var SubcategoryService = class extends BaseService {
2348
2412
  where8("isActive", "==", true)
2349
2413
  );
2350
2414
  const querySnapshot = await getDocs8(q);
2351
- return querySnapshot.docs.map(
2415
+ const subcategories = querySnapshot.docs.map(
2352
2416
  (doc11) => ({
2353
2417
  id: doc11.id,
2354
2418
  ...doc11.data()
2355
2419
  })
2356
2420
  );
2421
+ return this.filterExcludedSubcategories(subcategories);
2357
2422
  }
2358
2423
  /**
2359
2424
  * Vraća sve subkategorije za potrebe filtera (bez paginacije)
@@ -2365,12 +2430,13 @@ var SubcategoryService = class extends BaseService {
2365
2430
  where8("isActive", "==", true)
2366
2431
  );
2367
2432
  const querySnapshot = await getDocs8(q);
2368
- return querySnapshot.docs.map(
2433
+ const subcategories = querySnapshot.docs.map(
2369
2434
  (doc11) => ({
2370
2435
  id: doc11.id,
2371
2436
  ...doc11.data()
2372
2437
  })
2373
2438
  );
2439
+ return this.filterExcludedSubcategories(subcategories);
2374
2440
  }
2375
2441
  /**
2376
2442
  * Ažurira postojeću podkategoriju
@@ -2440,6 +2506,7 @@ var SubcategoryService = class extends BaseService {
2440
2506
  * @returns Podkategorija ili null ako ne postoji
2441
2507
  */
2442
2508
  async getById(categoryId, subcategoryId) {
2509
+ if (subcategoryId === EXCLUDED_SUBCATEGORY_ID) return null;
2443
2510
  const docRef = doc8(this.getSubcategoriesRef(categoryId), subcategoryId);
2444
2511
  const docSnap = await getDoc8(docRef);
2445
2512
  if (!docSnap.exists()) return null;
@@ -2448,6 +2515,44 @@ var SubcategoryService = class extends BaseService {
2448
2515
  ...docSnap.data()
2449
2516
  };
2450
2517
  }
2518
+ /**
2519
+ * Internal method to get subcategory by ID without filtering.
2520
+ * Used internally for consultation procedures.
2521
+ * @param categoryId - ID of the category
2522
+ * @param subcategoryId - ID of the subcategory to get
2523
+ * @returns Subcategory or null if not found
2524
+ */
2525
+ async getByIdInternal(categoryId, subcategoryId) {
2526
+ const docRef = doc8(this.getSubcategoriesRef(categoryId), subcategoryId);
2527
+ const docSnap = await getDoc8(docRef);
2528
+ if (!docSnap.exists()) return null;
2529
+ return {
2530
+ id: docSnap.id,
2531
+ ...docSnap.data()
2532
+ };
2533
+ }
2534
+ /**
2535
+ * Finds a subcategory by exact name match within a specific category.
2536
+ * Used for CSV import matching.
2537
+ * @param name - Exact name of the subcategory to find
2538
+ * @param categoryId - ID of the category to search within
2539
+ * @returns Subcategory if found, null otherwise
2540
+ */
2541
+ async findByNameAndCategory(name, categoryId) {
2542
+ const q = query8(
2543
+ this.getSubcategoriesRef(categoryId),
2544
+ where8("name", "==", name),
2545
+ where8("isActive", "==", true)
2546
+ );
2547
+ const querySnapshot = await getDocs8(q);
2548
+ if (querySnapshot.empty) return null;
2549
+ const doc11 = querySnapshot.docs[0];
2550
+ if (doc11.id === EXCLUDED_SUBCATEGORY_ID) return null;
2551
+ return {
2552
+ id: doc11.id,
2553
+ ...doc11.data()
2554
+ };
2555
+ }
2451
2556
  /**
2452
2557
  * Exports subcategories to CSV string, suitable for Excel/Sheets.
2453
2558
  * Includes headers and optional UTF-8 BOM.
@@ -2483,6 +2588,7 @@ var SubcategoryService = class extends BaseService {
2483
2588
  const snapshot = await getDocs8(q);
2484
2589
  if (snapshot.empty) break;
2485
2590
  for (const d of snapshot.docs) {
2591
+ if (d.id === EXCLUDED_SUBCATEGORY_ID) continue;
2486
2592
  const subcategory = { id: d.id, ...d.data() };
2487
2593
  rows.push(this.subcategoryToCsvRow(subcategory));
2488
2594
  }
@@ -2561,11 +2667,20 @@ var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
2561
2667
  })(CertificationSpecialty || {});
2562
2668
 
2563
2669
  // src/backoffice/services/technology.service.ts
2670
+ var EXCLUDED_TECHNOLOGY_ID = "free-consultation-tech";
2564
2671
  var DEFAULT_CERTIFICATION_REQUIREMENT = {
2565
2672
  minimumLevel: "aesthetician" /* AESTHETICIAN */,
2566
2673
  requiredSpecialties: []
2567
2674
  };
2568
2675
  var TechnologyService = class extends BaseService {
2676
+ /**
2677
+ * Filters out excluded technologies from a list.
2678
+ * @param technologies - List of technologies to filter
2679
+ * @returns Filtered list without excluded technologies
2680
+ */
2681
+ filterExcludedTechnologies(technologies) {
2682
+ return technologies.filter((tech) => tech.id !== EXCLUDED_TECHNOLOGY_ID);
2683
+ }
2569
2684
  /**
2570
2685
  * Reference to the Firestore collection of technologies.
2571
2686
  */
@@ -2614,6 +2729,7 @@ var TechnologyService = class extends BaseService {
2614
2729
  const snapshot = await getDocs9(q);
2615
2730
  const counts = {};
2616
2731
  snapshot.docs.forEach((doc11) => {
2732
+ if (doc11.id === EXCLUDED_TECHNOLOGY_ID) return;
2617
2733
  const tech = doc11.data();
2618
2734
  counts[tech.subcategoryId] = (counts[tech.subcategoryId] || 0) + 1;
2619
2735
  });
@@ -2629,6 +2745,7 @@ var TechnologyService = class extends BaseService {
2629
2745
  const snapshot = await getDocs9(q);
2630
2746
  const counts = {};
2631
2747
  snapshot.docs.forEach((doc11) => {
2748
+ if (doc11.id === EXCLUDED_TECHNOLOGY_ID) return;
2632
2749
  const tech = doc11.data();
2633
2750
  counts[tech.categoryId] = (counts[tech.categoryId] || 0) + 1;
2634
2751
  });
@@ -2655,8 +2772,9 @@ var TechnologyService = class extends BaseService {
2655
2772
  ...doc11.data()
2656
2773
  })
2657
2774
  );
2775
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
2658
2776
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
2659
- return { technologies, lastVisible: newLastVisible };
2777
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
2660
2778
  }
2661
2779
  /**
2662
2780
  * Returns all technologies for a specific category with pagination.
@@ -2681,8 +2799,9 @@ var TechnologyService = class extends BaseService {
2681
2799
  ...doc11.data()
2682
2800
  })
2683
2801
  );
2802
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
2684
2803
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
2685
- return { technologies, lastVisible: newLastVisible };
2804
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
2686
2805
  }
2687
2806
  /**
2688
2807
  * Returns all technologies for a specific subcategory with pagination.
@@ -2707,8 +2826,9 @@ var TechnologyService = class extends BaseService {
2707
2826
  ...doc11.data()
2708
2827
  })
2709
2828
  );
2829
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
2710
2830
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
2711
- return { technologies, lastVisible: newLastVisible };
2831
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
2712
2832
  }
2713
2833
  /**
2714
2834
  * Updates an existing technology.
@@ -2766,6 +2886,22 @@ var TechnologyService = class extends BaseService {
2766
2886
  * @returns The technology or null if it doesn't exist.
2767
2887
  */
2768
2888
  async getById(id) {
2889
+ if (id === EXCLUDED_TECHNOLOGY_ID) return null;
2890
+ const docRef = doc9(this.technologiesRef, id);
2891
+ const docSnap = await getDoc9(docRef);
2892
+ if (!docSnap.exists()) return null;
2893
+ return {
2894
+ id: docSnap.id,
2895
+ ...docSnap.data()
2896
+ };
2897
+ }
2898
+ /**
2899
+ * Internal method to get technology by ID without filtering.
2900
+ * Used internally for consultation procedures.
2901
+ * @param id - The ID of the requested technology
2902
+ * @returns The technology or null if it doesn't exist
2903
+ */
2904
+ async getByIdInternal(id) {
2769
2905
  const docRef = doc9(this.technologiesRef, id);
2770
2906
  const docSnap = await getDoc9(docRef);
2771
2907
  if (!docSnap.exists()) return null;
@@ -2774,6 +2910,27 @@ var TechnologyService = class extends BaseService {
2774
2910
  ...docSnap.data()
2775
2911
  };
2776
2912
  }
2913
+ /**
2914
+ * Finds a technology by exact name match.
2915
+ * Used for CSV import duplicate detection.
2916
+ * @param name - Exact name of the technology to find
2917
+ * @returns Technology if found, null otherwise
2918
+ */
2919
+ async findByName(name) {
2920
+ const q = query9(
2921
+ this.technologiesRef,
2922
+ where9("name", "==", name),
2923
+ where9("isActive", "==", true)
2924
+ );
2925
+ const snapshot = await getDocs9(q);
2926
+ if (snapshot.empty) return null;
2927
+ const doc11 = snapshot.docs[0];
2928
+ if (doc11.id === EXCLUDED_TECHNOLOGY_ID) return null;
2929
+ return {
2930
+ id: doc11.id,
2931
+ ...doc11.data()
2932
+ };
2933
+ }
2777
2934
  /**
2778
2935
  * Dodaje novi zahtev tehnologiji
2779
2936
  * @param technologyId - ID tehnologije
@@ -3134,12 +3291,13 @@ var TechnologyService = class extends BaseService {
3134
3291
  orderBy9("name")
3135
3292
  );
3136
3293
  const snapshot = await getDocs9(q);
3137
- return snapshot.docs.map(
3294
+ const technologies = snapshot.docs.map(
3138
3295
  (doc11) => ({
3139
3296
  id: doc11.id,
3140
3297
  ...doc11.data()
3141
3298
  })
3142
3299
  );
3300
+ return this.filterExcludedTechnologies(technologies);
3143
3301
  }
3144
3302
  /**
3145
3303
  * Gets all active technologies for a subcategory for filter dropdowns.
@@ -3155,12 +3313,13 @@ var TechnologyService = class extends BaseService {
3155
3313
  orderBy9("name")
3156
3314
  );
3157
3315
  const snapshot = await getDocs9(q);
3158
- return snapshot.docs.map(
3316
+ const technologies = snapshot.docs.map(
3159
3317
  (doc11) => ({
3160
3318
  id: doc11.id,
3161
3319
  ...doc11.data()
3162
3320
  })
3163
3321
  );
3322
+ return this.filterExcludedTechnologies(technologies);
3164
3323
  }
3165
3324
  /**
3166
3325
  * Gets all active technologies for filter dropdowns.
@@ -3172,12 +3331,13 @@ var TechnologyService = class extends BaseService {
3172
3331
  orderBy9("name")
3173
3332
  );
3174
3333
  const snapshot = await getDocs9(q);
3175
- return snapshot.docs.map(
3334
+ const technologies = snapshot.docs.map(
3176
3335
  (doc11) => ({
3177
3336
  id: doc11.id,
3178
3337
  ...doc11.data()
3179
3338
  })
3180
3339
  );
3340
+ return this.filterExcludedTechnologies(technologies);
3181
3341
  }
3182
3342
  // ==========================================
3183
3343
  // NEW METHODS: Product assignment management
@@ -3343,6 +3503,7 @@ var TechnologyService = class extends BaseService {
3343
3503
  const snapshot = await getDocs9(q);
3344
3504
  if (snapshot.empty) break;
3345
3505
  for (const d of snapshot.docs) {
3506
+ if (d.id === EXCLUDED_TECHNOLOGY_ID) continue;
3346
3507
  const technology = { id: d.id, ...d.data() };
3347
3508
  const productNames = await this.getProductNamesForTechnology(technology.id);
3348
3509
  rows.push(this.technologyToCsvRow(technology, productNames));
package/dist/index.d.mts CHANGED
@@ -288,6 +288,11 @@ interface ICategoryService {
288
288
  delete(id: string): Promise<void>;
289
289
  reactivate(id: string): Promise<void>;
290
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>;
291
296
  }
292
297
 
293
298
  /**
@@ -1014,6 +1019,11 @@ interface ITechnologyService {
1014
1019
  getAllForFilterBySubcategory(subcategoryId: string): Promise<Technology[]>;
1015
1020
  getAllForFilterBySubcategoryId(categoryId: string, subcategoryId: string): Promise<Technology[]>;
1016
1021
  getAllForFilter(): Promise<Technology[]>;
1022
+ findByName(name: string): Promise<Technology | null>;
1023
+ exportToCsv(options?: {
1024
+ includeInactive?: boolean;
1025
+ includeBom?: boolean;
1026
+ }): Promise<string>;
1017
1027
  }
1018
1028
 
1019
1029
  /**
@@ -1215,6 +1225,12 @@ declare class BrandService extends BaseService {
1215
1225
  * });
1216
1226
  */
1217
1227
  declare class CategoryService extends BaseService implements ICategoryService {
1228
+ /**
1229
+ * Filters out excluded categories from a list.
1230
+ * @param categories - List of categories to filter
1231
+ * @returns Filtered list without excluded categories
1232
+ */
1233
+ private filterExcludedCategories;
1218
1234
  /**
1219
1235
  * Referenca na Firestore kolekciju kategorija
1220
1236
  */
@@ -1300,6 +1316,21 @@ declare class CategoryService extends BaseService implements ICategoryService {
1300
1316
  * @returns Kategorija ili null ako ne postoji
1301
1317
  */
1302
1318
  getById(id: string): Promise<Category | null>;
1319
+ /**
1320
+ * Internal method to get category by ID without filtering.
1321
+ * Used internally for consultation procedures.
1322
+ * @param id - ID of the category to get
1323
+ * @returns Category or null if not found
1324
+ */
1325
+ getByIdInternal(id: string): Promise<Category | null>;
1326
+ /**
1327
+ * Finds a category by exact name match within a specific family.
1328
+ * Used for CSV import matching.
1329
+ * @param name - Exact name of the category to find
1330
+ * @param family - Procedure family to search within
1331
+ * @returns Category if found, null otherwise
1332
+ */
1333
+ findByNameAndFamily(name: string, family: ProcedureFamily): Promise<Category | null>;
1303
1334
  /**
1304
1335
  * Exports categories to CSV string, suitable for Excel/Sheets.
1305
1336
  * Includes headers and optional UTF-8 BOM.
@@ -1728,6 +1759,12 @@ declare class ProductService extends BaseService implements IProductService {
1728
1759
  * });
1729
1760
  */
1730
1761
  declare class SubcategoryService extends BaseService {
1762
+ /**
1763
+ * Filters out excluded subcategories from a list.
1764
+ * @param subcategories - List of subcategories to filter
1765
+ * @returns Filtered list without excluded subcategories
1766
+ */
1767
+ private filterExcludedSubcategories;
1731
1768
  /**
1732
1769
  * Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
1733
1770
  * @param categoryId - ID roditeljske kategorije
@@ -1822,6 +1859,22 @@ declare class SubcategoryService extends BaseService {
1822
1859
  * @returns Podkategorija ili null ako ne postoji
1823
1860
  */
1824
1861
  getById(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
1862
+ /**
1863
+ * Internal method to get subcategory by ID without filtering.
1864
+ * Used internally for consultation procedures.
1865
+ * @param categoryId - ID of the category
1866
+ * @param subcategoryId - ID of the subcategory to get
1867
+ * @returns Subcategory or null if not found
1868
+ */
1869
+ getByIdInternal(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
1870
+ /**
1871
+ * Finds a subcategory by exact name match within a specific category.
1872
+ * Used for CSV import matching.
1873
+ * @param name - Exact name of the subcategory to find
1874
+ * @param categoryId - ID of the category to search within
1875
+ * @returns Subcategory if found, null otherwise
1876
+ */
1877
+ findByNameAndCategory(name: string, categoryId: string): Promise<Subcategory | null>;
1825
1878
  /**
1826
1879
  * Exports subcategories to CSV string, suitable for Excel/Sheets.
1827
1880
  * Includes headers and optional UTF-8 BOM.
@@ -2141,6 +2194,12 @@ interface CreatePractitionerTokenData {
2141
2194
  * Service for managing technologies.
2142
2195
  */
2143
2196
  declare class TechnologyService extends BaseService implements ITechnologyService {
2197
+ /**
2198
+ * Filters out excluded technologies from a list.
2199
+ * @param technologies - List of technologies to filter
2200
+ * @returns Filtered list without excluded technologies
2201
+ */
2202
+ private filterExcludedTechnologies;
2144
2203
  /**
2145
2204
  * Reference to the Firestore collection of technologies.
2146
2205
  */
@@ -2248,6 +2307,20 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2248
2307
  * @returns The technology or null if it doesn't exist.
2249
2308
  */
2250
2309
  getById(id: string): Promise<Technology | null>;
2310
+ /**
2311
+ * Internal method to get technology by ID without filtering.
2312
+ * Used internally for consultation procedures.
2313
+ * @param id - The ID of the requested technology
2314
+ * @returns The technology or null if it doesn't exist
2315
+ */
2316
+ getByIdInternal(id: string): Promise<Technology | null>;
2317
+ /**
2318
+ * Finds a technology by exact name match.
2319
+ * Used for CSV import duplicate detection.
2320
+ * @param name - Exact name of the technology to find
2321
+ * @returns Technology if found, null otherwise
2322
+ */
2323
+ findByName(name: string): Promise<Technology | null>;
2251
2324
  /**
2252
2325
  * Dodaje novi zahtev tehnologiji
2253
2326
  * @param technologyId - ID tehnologije