@blackcode_sa/metaestetics-api 1.12.67 → 1.13.0

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 (47) hide show
  1. package/dist/admin/index.d.mts +801 -2
  2. package/dist/admin/index.d.ts +801 -2
  3. package/dist/admin/index.js +2332 -153
  4. package/dist/admin/index.mjs +2321 -153
  5. package/dist/backoffice/index.d.mts +40 -0
  6. package/dist/backoffice/index.d.ts +40 -0
  7. package/dist/backoffice/index.js +118 -18
  8. package/dist/backoffice/index.mjs +118 -20
  9. package/dist/index.d.mts +1097 -2
  10. package/dist/index.d.ts +1097 -2
  11. package/dist/index.js +4224 -2091
  12. package/dist/index.mjs +3941 -1821
  13. package/package.json +1 -1
  14. package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +140 -0
  15. package/src/admin/analytics/analytics.admin.service.ts +278 -0
  16. package/src/admin/analytics/index.ts +2 -0
  17. package/src/admin/index.ts +6 -0
  18. package/src/backoffice/services/README.md +17 -0
  19. package/src/backoffice/services/analytics.service.proposal.md +863 -0
  20. package/src/backoffice/services/analytics.service.summary.md +143 -0
  21. package/src/backoffice/services/category.service.ts +49 -6
  22. package/src/backoffice/services/subcategory.service.ts +50 -6
  23. package/src/backoffice/services/technology.service.ts +53 -6
  24. package/src/services/analytics/ARCHITECTURE.md +199 -0
  25. package/src/services/analytics/CLOUD_FUNCTIONS.md +225 -0
  26. package/src/services/analytics/GROUPED_ANALYTICS.md +501 -0
  27. package/src/services/analytics/QUICK_START.md +393 -0
  28. package/src/services/analytics/README.md +287 -0
  29. package/src/services/analytics/SUMMARY.md +141 -0
  30. package/src/services/analytics/USAGE_GUIDE.md +518 -0
  31. package/src/services/analytics/analytics-cloud.service.ts +222 -0
  32. package/src/services/analytics/analytics.service.ts +1632 -0
  33. package/src/services/analytics/index.ts +3 -0
  34. package/src/services/analytics/utils/appointment-filtering.utils.ts +138 -0
  35. package/src/services/analytics/utils/cost-calculation.utils.ts +154 -0
  36. package/src/services/analytics/utils/grouping.utils.ts +394 -0
  37. package/src/services/analytics/utils/stored-analytics.utils.ts +347 -0
  38. package/src/services/analytics/utils/time-calculation.utils.ts +186 -0
  39. package/src/services/appointment/appointment.service.ts +50 -6
  40. package/src/services/index.ts +1 -0
  41. package/src/services/procedure/procedure.service.ts +3 -3
  42. package/src/types/analytics/analytics.types.ts +500 -0
  43. package/src/types/analytics/grouped-analytics.types.ts +148 -0
  44. package/src/types/analytics/index.ts +4 -0
  45. package/src/types/analytics/stored-analytics.types.ts +137 -0
  46. package/src/types/index.ts +3 -0
  47. package/src/types/notifications/index.ts +21 -0
@@ -209,6 +209,12 @@ interface ICategoryService {
209
209
  * });
210
210
  */
211
211
  declare class CategoryService extends BaseService implements ICategoryService {
212
+ /**
213
+ * Filters out excluded categories from a list.
214
+ * @param categories - List of categories to filter
215
+ * @returns Filtered list without excluded categories
216
+ */
217
+ private filterExcludedCategories;
212
218
  /**
213
219
  * Referenca na Firestore kolekciju kategorija
214
220
  */
@@ -294,6 +300,13 @@ declare class CategoryService extends BaseService implements ICategoryService {
294
300
  * @returns Kategorija ili null ako ne postoji
295
301
  */
296
302
  getById(id: string): Promise<Category | null>;
303
+ /**
304
+ * Internal method to get category by ID without filtering.
305
+ * Used internally for consultation procedures.
306
+ * @param id - ID of the category to get
307
+ * @returns Category or null if not found
308
+ */
309
+ getByIdInternal(id: string): Promise<Category | null>;
297
310
  /**
298
311
  * Finds a category by exact name match within a specific family.
299
312
  * Used for CSV import matching.
@@ -1900,6 +1913,12 @@ declare class RequirementService extends BaseService {
1900
1913
  * });
1901
1914
  */
1902
1915
  declare class SubcategoryService extends BaseService {
1916
+ /**
1917
+ * Filters out excluded subcategories from a list.
1918
+ * @param subcategories - List of subcategories to filter
1919
+ * @returns Filtered list without excluded subcategories
1920
+ */
1921
+ private filterExcludedSubcategories;
1903
1922
  /**
1904
1923
  * Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
1905
1924
  * @param categoryId - ID roditeljske kategorije
@@ -1994,6 +2013,14 @@ declare class SubcategoryService extends BaseService {
1994
2013
  * @returns Podkategorija ili null ako ne postoji
1995
2014
  */
1996
2015
  getById(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
2016
+ /**
2017
+ * Internal method to get subcategory by ID without filtering.
2018
+ * Used internally for consultation procedures.
2019
+ * @param categoryId - ID of the category
2020
+ * @param subcategoryId - ID of the subcategory to get
2021
+ * @returns Subcategory or null if not found
2022
+ */
2023
+ getByIdInternal(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
1997
2024
  /**
1998
2025
  * Finds a subcategory by exact name match within a specific category.
1999
2026
  * Used for CSV import matching.
@@ -2020,6 +2047,12 @@ declare class SubcategoryService extends BaseService {
2020
2047
  * Service for managing technologies.
2021
2048
  */
2022
2049
  declare class TechnologyService extends BaseService implements ITechnologyService {
2050
+ /**
2051
+ * Filters out excluded technologies from a list.
2052
+ * @param technologies - List of technologies to filter
2053
+ * @returns Filtered list without excluded technologies
2054
+ */
2055
+ private filterExcludedTechnologies;
2023
2056
  /**
2024
2057
  * Reference to the Firestore collection of technologies.
2025
2058
  */
@@ -2127,6 +2160,13 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2127
2160
  * @returns The technology or null if it doesn't exist.
2128
2161
  */
2129
2162
  getById(id: string): Promise<Technology | null>;
2163
+ /**
2164
+ * Internal method to get technology by ID without filtering.
2165
+ * Used internally for consultation procedures.
2166
+ * @param id - The ID of the requested technology
2167
+ * @returns The technology or null if it doesn't exist
2168
+ */
2169
+ getByIdInternal(id: string): Promise<Technology | null>;
2130
2170
  /**
2131
2171
  * Finds a technology by exact name match.
2132
2172
  * Used for CSV import duplicate detection.
@@ -209,6 +209,12 @@ interface ICategoryService {
209
209
  * });
210
210
  */
211
211
  declare class CategoryService extends BaseService implements ICategoryService {
212
+ /**
213
+ * Filters out excluded categories from a list.
214
+ * @param categories - List of categories to filter
215
+ * @returns Filtered list without excluded categories
216
+ */
217
+ private filterExcludedCategories;
212
218
  /**
213
219
  * Referenca na Firestore kolekciju kategorija
214
220
  */
@@ -294,6 +300,13 @@ declare class CategoryService extends BaseService implements ICategoryService {
294
300
  * @returns Kategorija ili null ako ne postoji
295
301
  */
296
302
  getById(id: string): Promise<Category | null>;
303
+ /**
304
+ * Internal method to get category by ID without filtering.
305
+ * Used internally for consultation procedures.
306
+ * @param id - ID of the category to get
307
+ * @returns Category or null if not found
308
+ */
309
+ getByIdInternal(id: string): Promise<Category | null>;
297
310
  /**
298
311
  * Finds a category by exact name match within a specific family.
299
312
  * Used for CSV import matching.
@@ -1900,6 +1913,12 @@ declare class RequirementService extends BaseService {
1900
1913
  * });
1901
1914
  */
1902
1915
  declare class SubcategoryService extends BaseService {
1916
+ /**
1917
+ * Filters out excluded subcategories from a list.
1918
+ * @param subcategories - List of subcategories to filter
1919
+ * @returns Filtered list without excluded subcategories
1920
+ */
1921
+ private filterExcludedSubcategories;
1903
1922
  /**
1904
1923
  * Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
1905
1924
  * @param categoryId - ID roditeljske kategorije
@@ -1994,6 +2013,14 @@ declare class SubcategoryService extends BaseService {
1994
2013
  * @returns Podkategorija ili null ako ne postoji
1995
2014
  */
1996
2015
  getById(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
2016
+ /**
2017
+ * Internal method to get subcategory by ID without filtering.
2018
+ * Used internally for consultation procedures.
2019
+ * @param categoryId - ID of the category
2020
+ * @param subcategoryId - ID of the subcategory to get
2021
+ * @returns Subcategory or null if not found
2022
+ */
2023
+ getByIdInternal(categoryId: string, subcategoryId: string): Promise<Subcategory | null>;
1997
2024
  /**
1998
2025
  * Finds a subcategory by exact name match within a specific category.
1999
2026
  * Used for CSV import matching.
@@ -2020,6 +2047,12 @@ declare class SubcategoryService extends BaseService {
2020
2047
  * Service for managing technologies.
2021
2048
  */
2022
2049
  declare class TechnologyService extends BaseService implements ITechnologyService {
2050
+ /**
2051
+ * Filters out excluded technologies from a list.
2052
+ * @param technologies - List of technologies to filter
2053
+ * @returns Filtered list without excluded technologies
2054
+ */
2055
+ private filterExcludedTechnologies;
2023
2056
  /**
2024
2057
  * Reference to the Firestore collection of technologies.
2025
2058
  */
@@ -2127,6 +2160,13 @@ declare class TechnologyService extends BaseService implements ITechnologyServic
2127
2160
  * @returns The technology or null if it doesn't exist.
2128
2161
  */
2129
2162
  getById(id: string): Promise<Technology | null>;
2163
+ /**
2164
+ * Internal method to get technology by ID without filtering.
2165
+ * Used internally for consultation procedures.
2166
+ * @param id - The ID of the requested technology
2167
+ * @returns The technology or null if it doesn't exist
2168
+ */
2169
+ getByIdInternal(id: string): Promise<Technology | null>;
2130
2170
  /**
2131
2171
  * Finds a technology by exact name match.
2132
2172
  * Used for CSV import duplicate detection.
@@ -346,7 +346,16 @@ var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
346
346
  })(ProcedureFamily || {});
347
347
 
348
348
  // src/backoffice/services/category.service.ts
349
+ var EXCLUDED_CATEGORY_ID = "consultation";
349
350
  var CategoryService = class extends BaseService {
351
+ /**
352
+ * Filters out excluded categories from a list.
353
+ * @param categories - List of categories to filter
354
+ * @returns Filtered list without excluded categories
355
+ */
356
+ filterExcludedCategories(categories) {
357
+ return categories.filter((cat) => cat.id !== EXCLUDED_CATEGORY_ID);
358
+ }
350
359
  /**
351
360
  * Referenca na Firestore kolekciju kategorija
352
361
  */
@@ -383,8 +392,9 @@ var CategoryService = class extends BaseService {
383
392
  (0, import_firestore2.where)("family", "==", family),
384
393
  (0, import_firestore2.where)("isActive", "==", active)
385
394
  );
386
- const snapshot = await (0, import_firestore2.getCountFromServer)(q);
387
- counts[family] = snapshot.data().count;
395
+ const snapshot = await (0, import_firestore2.getDocs)(q);
396
+ const filteredDocs = snapshot.docs.filter((doc11) => doc11.id !== EXCLUDED_CATEGORY_ID);
397
+ counts[family] = filteredDocs.length;
388
398
  }
389
399
  return counts;
390
400
  }
@@ -395,12 +405,13 @@ var CategoryService = class extends BaseService {
395
405
  async getAllForFilter() {
396
406
  const q = (0, import_firestore2.query)(this.categoriesRef, (0, import_firestore2.where)("isActive", "==", true));
397
407
  const snapshot = await (0, import_firestore2.getDocs)(q);
398
- return snapshot.docs.map(
408
+ const categories = snapshot.docs.map(
399
409
  (doc11) => ({
400
410
  id: doc11.id,
401
411
  ...doc11.data()
402
412
  })
403
413
  );
414
+ return this.filterExcludedCategories(categories);
404
415
  }
405
416
  /**
406
417
  * Vraća sve kategorije za određenu familiju za potrebe filtera (bez paginacije)
@@ -415,12 +426,13 @@ var CategoryService = class extends BaseService {
415
426
  (0, import_firestore2.orderBy)("name")
416
427
  );
417
428
  const snapshot = await (0, import_firestore2.getDocs)(q);
418
- return snapshot.docs.map(
429
+ const categories = snapshot.docs.map(
419
430
  (doc11) => ({
420
431
  id: doc11.id,
421
432
  ...doc11.data()
422
433
  })
423
434
  );
435
+ return this.filterExcludedCategories(categories);
424
436
  }
425
437
  /**
426
438
  * Vraća sve kategorije sa paginacijom
@@ -443,8 +455,9 @@ var CategoryService = class extends BaseService {
443
455
  ...doc11.data()
444
456
  })
445
457
  );
458
+ const filteredCategories = this.filterExcludedCategories(categories);
446
459
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
447
- return { categories, lastVisible: newLastVisible };
460
+ return { categories: filteredCategories, lastVisible: newLastVisible };
448
461
  }
449
462
  /**
450
463
  * Vraća sve aktivne kategorije za određenu familiju procedura sa paginacijom
@@ -469,8 +482,9 @@ var CategoryService = class extends BaseService {
469
482
  ...doc11.data()
470
483
  })
471
484
  );
485
+ const filteredCategories = this.filterExcludedCategories(categories);
472
486
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
473
- return { categories, lastVisible: newLastVisible };
487
+ return { categories: filteredCategories, lastVisible: newLastVisible };
474
488
  }
475
489
  /**
476
490
  * Ažurira postojeću kategoriju
@@ -507,6 +521,22 @@ var CategoryService = class extends BaseService {
507
521
  * @returns Kategorija ili null ako ne postoji
508
522
  */
509
523
  async getById(id) {
524
+ if (id === EXCLUDED_CATEGORY_ID) return null;
525
+ const docRef = (0, import_firestore2.doc)(this.categoriesRef, id);
526
+ const docSnap = await (0, import_firestore2.getDoc)(docRef);
527
+ if (!docSnap.exists()) return null;
528
+ return {
529
+ id: docSnap.id,
530
+ ...docSnap.data()
531
+ };
532
+ }
533
+ /**
534
+ * Internal method to get category by ID without filtering.
535
+ * Used internally for consultation procedures.
536
+ * @param id - ID of the category to get
537
+ * @returns Category or null if not found
538
+ */
539
+ async getByIdInternal(id) {
510
540
  const docRef = (0, import_firestore2.doc)(this.categoriesRef, id);
511
541
  const docSnap = await (0, import_firestore2.getDoc)(docRef);
512
542
  if (!docSnap.exists()) return null;
@@ -532,6 +562,7 @@ var CategoryService = class extends BaseService {
532
562
  const snapshot = await (0, import_firestore2.getDocs)(q);
533
563
  if (snapshot.empty) return null;
534
564
  const doc11 = snapshot.docs[0];
565
+ if (doc11.id === EXCLUDED_CATEGORY_ID) return null;
535
566
  return {
536
567
  id: doc11.id,
537
568
  ...doc11.data()
@@ -569,6 +600,7 @@ var CategoryService = class extends BaseService {
569
600
  const snapshot = await (0, import_firestore2.getDocs)(q);
570
601
  if (snapshot.empty) break;
571
602
  for (const d of snapshot.docs) {
603
+ if (d.id === EXCLUDED_CATEGORY_ID) continue;
572
604
  const category = { id: d.id, ...d.data() };
573
605
  rows.push(this.categoryToCsvRow(category));
574
606
  }
@@ -2249,7 +2281,16 @@ var import_firestore10 = require("firebase/firestore");
2249
2281
  var SUBCATEGORIES_COLLECTION = "subcategories";
2250
2282
 
2251
2283
  // src/backoffice/services/subcategory.service.ts
2284
+ var EXCLUDED_SUBCATEGORY_ID = "free-consultation";
2252
2285
  var SubcategoryService = class extends BaseService {
2286
+ /**
2287
+ * Filters out excluded subcategories from a list.
2288
+ * @param subcategories - List of subcategories to filter
2289
+ * @returns Filtered list without excluded subcategories
2290
+ */
2291
+ filterExcludedSubcategories(subcategories) {
2292
+ return subcategories.filter((sub) => sub.id !== EXCLUDED_SUBCATEGORY_ID);
2293
+ }
2253
2294
  /**
2254
2295
  * Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
2255
2296
  * @param categoryId - ID roditeljske kategorije
@@ -2296,8 +2337,9 @@ var SubcategoryService = class extends BaseService {
2296
2337
  const categoryId = categoryDoc.id;
2297
2338
  const subcategoriesRef = this.getSubcategoriesRef(categoryId);
2298
2339
  const q = (0, import_firestore10.query)(subcategoriesRef, (0, import_firestore10.where)("isActive", "==", active));
2299
- const snapshot = await (0, import_firestore10.getCountFromServer)(q);
2300
- counts[categoryId] = snapshot.data().count;
2340
+ const snapshot = await (0, import_firestore10.getDocs)(q);
2341
+ const filteredDocs = snapshot.docs.filter((doc11) => doc11.id !== EXCLUDED_SUBCATEGORY_ID);
2342
+ counts[categoryId] = filteredDocs.length;
2301
2343
  }
2302
2344
  return counts;
2303
2345
  }
@@ -2323,8 +2365,9 @@ var SubcategoryService = class extends BaseService {
2323
2365
  ...doc11.data()
2324
2366
  })
2325
2367
  );
2368
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
2326
2369
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
2327
- return { subcategories, lastVisible: newLastVisible };
2370
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
2328
2371
  }
2329
2372
  /**
2330
2373
  * Vraća sve podkategorije sa paginacijom koristeći collection group query.
@@ -2353,8 +2396,9 @@ var SubcategoryService = class extends BaseService {
2353
2396
  ...doc11.data()
2354
2397
  })
2355
2398
  );
2399
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
2356
2400
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
2357
- return { subcategories, lastVisible: newLastVisible };
2401
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
2358
2402
  }
2359
2403
  /**
2360
2404
  * Vraća sve subkategorije za određenu kategoriju za potrebe filtera (bez paginacije)
@@ -2367,12 +2411,13 @@ var SubcategoryService = class extends BaseService {
2367
2411
  (0, import_firestore10.where)("isActive", "==", true)
2368
2412
  );
2369
2413
  const querySnapshot = await (0, import_firestore10.getDocs)(q);
2370
- return querySnapshot.docs.map(
2414
+ const subcategories = querySnapshot.docs.map(
2371
2415
  (doc11) => ({
2372
2416
  id: doc11.id,
2373
2417
  ...doc11.data()
2374
2418
  })
2375
2419
  );
2420
+ return this.filterExcludedSubcategories(subcategories);
2376
2421
  }
2377
2422
  /**
2378
2423
  * Vraća sve subkategorije za potrebe filtera (bez paginacije)
@@ -2384,12 +2429,13 @@ var SubcategoryService = class extends BaseService {
2384
2429
  (0, import_firestore10.where)("isActive", "==", true)
2385
2430
  );
2386
2431
  const querySnapshot = await (0, import_firestore10.getDocs)(q);
2387
- return querySnapshot.docs.map(
2432
+ const subcategories = querySnapshot.docs.map(
2388
2433
  (doc11) => ({
2389
2434
  id: doc11.id,
2390
2435
  ...doc11.data()
2391
2436
  })
2392
2437
  );
2438
+ return this.filterExcludedSubcategories(subcategories);
2393
2439
  }
2394
2440
  /**
2395
2441
  * Ažurira postojeću podkategoriju
@@ -2459,6 +2505,23 @@ var SubcategoryService = class extends BaseService {
2459
2505
  * @returns Podkategorija ili null ako ne postoji
2460
2506
  */
2461
2507
  async getById(categoryId, subcategoryId) {
2508
+ if (subcategoryId === EXCLUDED_SUBCATEGORY_ID) return null;
2509
+ const docRef = (0, import_firestore10.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
2510
+ const docSnap = await (0, import_firestore10.getDoc)(docRef);
2511
+ if (!docSnap.exists()) return null;
2512
+ return {
2513
+ id: docSnap.id,
2514
+ ...docSnap.data()
2515
+ };
2516
+ }
2517
+ /**
2518
+ * Internal method to get subcategory by ID without filtering.
2519
+ * Used internally for consultation procedures.
2520
+ * @param categoryId - ID of the category
2521
+ * @param subcategoryId - ID of the subcategory to get
2522
+ * @returns Subcategory or null if not found
2523
+ */
2524
+ async getByIdInternal(categoryId, subcategoryId) {
2462
2525
  const docRef = (0, import_firestore10.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
2463
2526
  const docSnap = await (0, import_firestore10.getDoc)(docRef);
2464
2527
  if (!docSnap.exists()) return null;
@@ -2483,6 +2546,7 @@ var SubcategoryService = class extends BaseService {
2483
2546
  const querySnapshot = await (0, import_firestore10.getDocs)(q);
2484
2547
  if (querySnapshot.empty) return null;
2485
2548
  const doc11 = querySnapshot.docs[0];
2549
+ if (doc11.id === EXCLUDED_SUBCATEGORY_ID) return null;
2486
2550
  return {
2487
2551
  id: doc11.id,
2488
2552
  ...doc11.data()
@@ -2523,6 +2587,7 @@ var SubcategoryService = class extends BaseService {
2523
2587
  const snapshot = await (0, import_firestore10.getDocs)(q);
2524
2588
  if (snapshot.empty) break;
2525
2589
  for (const d of snapshot.docs) {
2590
+ if (d.id === EXCLUDED_SUBCATEGORY_ID) continue;
2526
2591
  const subcategory = { id: d.id, ...d.data() };
2527
2592
  rows.push(this.subcategoryToCsvRow(subcategory));
2528
2593
  }
@@ -2586,11 +2651,20 @@ var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
2586
2651
  })(CertificationSpecialty || {});
2587
2652
 
2588
2653
  // src/backoffice/services/technology.service.ts
2654
+ var EXCLUDED_TECHNOLOGY_ID = "free-consultation-tech";
2589
2655
  var DEFAULT_CERTIFICATION_REQUIREMENT = {
2590
2656
  minimumLevel: "aesthetician" /* AESTHETICIAN */,
2591
2657
  requiredSpecialties: []
2592
2658
  };
2593
2659
  var TechnologyService = class extends BaseService {
2660
+ /**
2661
+ * Filters out excluded technologies from a list.
2662
+ * @param technologies - List of technologies to filter
2663
+ * @returns Filtered list without excluded technologies
2664
+ */
2665
+ filterExcludedTechnologies(technologies) {
2666
+ return technologies.filter((tech) => tech.id !== EXCLUDED_TECHNOLOGY_ID);
2667
+ }
2594
2668
  /**
2595
2669
  * Reference to the Firestore collection of technologies.
2596
2670
  */
@@ -2639,6 +2713,7 @@ var TechnologyService = class extends BaseService {
2639
2713
  const snapshot = await (0, import_firestore11.getDocs)(q);
2640
2714
  const counts = {};
2641
2715
  snapshot.docs.forEach((doc11) => {
2716
+ if (doc11.id === EXCLUDED_TECHNOLOGY_ID) return;
2642
2717
  const tech = doc11.data();
2643
2718
  counts[tech.subcategoryId] = (counts[tech.subcategoryId] || 0) + 1;
2644
2719
  });
@@ -2654,6 +2729,7 @@ var TechnologyService = class extends BaseService {
2654
2729
  const snapshot = await (0, import_firestore11.getDocs)(q);
2655
2730
  const counts = {};
2656
2731
  snapshot.docs.forEach((doc11) => {
2732
+ if (doc11.id === EXCLUDED_TECHNOLOGY_ID) return;
2657
2733
  const tech = doc11.data();
2658
2734
  counts[tech.categoryId] = (counts[tech.categoryId] || 0) + 1;
2659
2735
  });
@@ -2680,8 +2756,9 @@ var TechnologyService = class extends BaseService {
2680
2756
  ...doc11.data()
2681
2757
  })
2682
2758
  );
2759
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
2683
2760
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
2684
- return { technologies, lastVisible: newLastVisible };
2761
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
2685
2762
  }
2686
2763
  /**
2687
2764
  * Returns all technologies for a specific category with pagination.
@@ -2706,8 +2783,9 @@ var TechnologyService = class extends BaseService {
2706
2783
  ...doc11.data()
2707
2784
  })
2708
2785
  );
2786
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
2709
2787
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
2710
- return { technologies, lastVisible: newLastVisible };
2788
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
2711
2789
  }
2712
2790
  /**
2713
2791
  * Returns all technologies for a specific subcategory with pagination.
@@ -2732,8 +2810,9 @@ var TechnologyService = class extends BaseService {
2732
2810
  ...doc11.data()
2733
2811
  })
2734
2812
  );
2813
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
2735
2814
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
2736
- return { technologies, lastVisible: newLastVisible };
2815
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
2737
2816
  }
2738
2817
  /**
2739
2818
  * Updates an existing technology.
@@ -2791,6 +2870,22 @@ var TechnologyService = class extends BaseService {
2791
2870
  * @returns The technology or null if it doesn't exist.
2792
2871
  */
2793
2872
  async getById(id) {
2873
+ if (id === EXCLUDED_TECHNOLOGY_ID) return null;
2874
+ const docRef = (0, import_firestore11.doc)(this.technologiesRef, id);
2875
+ const docSnap = await (0, import_firestore11.getDoc)(docRef);
2876
+ if (!docSnap.exists()) return null;
2877
+ return {
2878
+ id: docSnap.id,
2879
+ ...docSnap.data()
2880
+ };
2881
+ }
2882
+ /**
2883
+ * Internal method to get technology by ID without filtering.
2884
+ * Used internally for consultation procedures.
2885
+ * @param id - The ID of the requested technology
2886
+ * @returns The technology or null if it doesn't exist
2887
+ */
2888
+ async getByIdInternal(id) {
2794
2889
  const docRef = (0, import_firestore11.doc)(this.technologiesRef, id);
2795
2890
  const docSnap = await (0, import_firestore11.getDoc)(docRef);
2796
2891
  if (!docSnap.exists()) return null;
@@ -2814,6 +2909,7 @@ var TechnologyService = class extends BaseService {
2814
2909
  const snapshot = await (0, import_firestore11.getDocs)(q);
2815
2910
  if (snapshot.empty) return null;
2816
2911
  const doc11 = snapshot.docs[0];
2912
+ if (doc11.id === EXCLUDED_TECHNOLOGY_ID) return null;
2817
2913
  return {
2818
2914
  id: doc11.id,
2819
2915
  ...doc11.data()
@@ -3179,12 +3275,13 @@ var TechnologyService = class extends BaseService {
3179
3275
  (0, import_firestore11.orderBy)("name")
3180
3276
  );
3181
3277
  const snapshot = await (0, import_firestore11.getDocs)(q);
3182
- return snapshot.docs.map(
3278
+ const technologies = snapshot.docs.map(
3183
3279
  (doc11) => ({
3184
3280
  id: doc11.id,
3185
3281
  ...doc11.data()
3186
3282
  })
3187
3283
  );
3284
+ return this.filterExcludedTechnologies(technologies);
3188
3285
  }
3189
3286
  /**
3190
3287
  * Gets all active technologies for a subcategory for filter dropdowns.
@@ -3200,12 +3297,13 @@ var TechnologyService = class extends BaseService {
3200
3297
  (0, import_firestore11.orderBy)("name")
3201
3298
  );
3202
3299
  const snapshot = await (0, import_firestore11.getDocs)(q);
3203
- return snapshot.docs.map(
3300
+ const technologies = snapshot.docs.map(
3204
3301
  (doc11) => ({
3205
3302
  id: doc11.id,
3206
3303
  ...doc11.data()
3207
3304
  })
3208
3305
  );
3306
+ return this.filterExcludedTechnologies(technologies);
3209
3307
  }
3210
3308
  /**
3211
3309
  * Gets all active technologies for filter dropdowns.
@@ -3217,12 +3315,13 @@ var TechnologyService = class extends BaseService {
3217
3315
  (0, import_firestore11.orderBy)("name")
3218
3316
  );
3219
3317
  const snapshot = await (0, import_firestore11.getDocs)(q);
3220
- return snapshot.docs.map(
3318
+ const technologies = snapshot.docs.map(
3221
3319
  (doc11) => ({
3222
3320
  id: doc11.id,
3223
3321
  ...doc11.data()
3224
3322
  })
3225
3323
  );
3324
+ return this.filterExcludedTechnologies(technologies);
3226
3325
  }
3227
3326
  // ==========================================
3228
3327
  // NEW METHODS: Product assignment management
@@ -3388,6 +3487,7 @@ var TechnologyService = class extends BaseService {
3388
3487
  const snapshot = await (0, import_firestore11.getDocs)(q);
3389
3488
  if (snapshot.empty) break;
3390
3489
  for (const d of snapshot.docs) {
3490
+ if (d.id === EXCLUDED_TECHNOLOGY_ID) continue;
3391
3491
  const technology = { id: d.id, ...d.data() };
3392
3492
  const productNames = await this.getProductNamesForTechnology(technology.id);
3393
3493
  rows.push(this.technologyToCsvRow(technology, productNames));