@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.
package/dist/index.d.ts 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
package/dist/index.js CHANGED
@@ -17811,9 +17811,9 @@ var ProcedureService = class extends BaseService {
17811
17811
  var _a, _b;
17812
17812
  const procedureId = this.generateId();
17813
17813
  const [category, subcategory, technology] = await Promise.all([
17814
- this.categoryService.getById(data.categoryId),
17815
- this.subcategoryService.getById(data.categoryId, data.subcategoryId),
17816
- this.technologyService.getById(data.technologyId)
17814
+ this.categoryService.getByIdInternal(data.categoryId),
17815
+ this.subcategoryService.getByIdInternal(data.categoryId, data.subcategoryId),
17816
+ this.technologyService.getByIdInternal(data.technologyId)
17817
17817
  ]);
17818
17818
  if (!category || !subcategory || !technology) {
17819
17819
  throw new Error("One or more required base entities not found");
@@ -18750,7 +18750,16 @@ var import_firestore59 = require("firebase/firestore");
18750
18750
  var CATEGORIES_COLLECTION = "backoffice_categories";
18751
18751
 
18752
18752
  // src/backoffice/services/category.service.ts
18753
+ var EXCLUDED_CATEGORY_ID = "consultation";
18753
18754
  var CategoryService = class extends BaseService {
18755
+ /**
18756
+ * Filters out excluded categories from a list.
18757
+ * @param categories - List of categories to filter
18758
+ * @returns Filtered list without excluded categories
18759
+ */
18760
+ filterExcludedCategories(categories) {
18761
+ return categories.filter((cat) => cat.id !== EXCLUDED_CATEGORY_ID);
18762
+ }
18754
18763
  /**
18755
18764
  * Referenca na Firestore kolekciju kategorija
18756
18765
  */
@@ -18787,8 +18796,9 @@ var CategoryService = class extends BaseService {
18787
18796
  (0, import_firestore59.where)("family", "==", family),
18788
18797
  (0, import_firestore59.where)("isActive", "==", active)
18789
18798
  );
18790
- const snapshot = await (0, import_firestore59.getCountFromServer)(q);
18791
- counts[family] = snapshot.data().count;
18799
+ const snapshot = await (0, import_firestore59.getDocs)(q);
18800
+ const filteredDocs = snapshot.docs.filter((doc45) => doc45.id !== EXCLUDED_CATEGORY_ID);
18801
+ counts[family] = filteredDocs.length;
18792
18802
  }
18793
18803
  return counts;
18794
18804
  }
@@ -18799,12 +18809,13 @@ var CategoryService = class extends BaseService {
18799
18809
  async getAllForFilter() {
18800
18810
  const q = (0, import_firestore59.query)(this.categoriesRef, (0, import_firestore59.where)("isActive", "==", true));
18801
18811
  const snapshot = await (0, import_firestore59.getDocs)(q);
18802
- return snapshot.docs.map(
18812
+ const categories = snapshot.docs.map(
18803
18813
  (doc45) => ({
18804
18814
  id: doc45.id,
18805
18815
  ...doc45.data()
18806
18816
  })
18807
18817
  );
18818
+ return this.filterExcludedCategories(categories);
18808
18819
  }
18809
18820
  /**
18810
18821
  * Vraća sve kategorije za određenu familiju za potrebe filtera (bez paginacije)
@@ -18819,12 +18830,13 @@ var CategoryService = class extends BaseService {
18819
18830
  (0, import_firestore59.orderBy)("name")
18820
18831
  );
18821
18832
  const snapshot = await (0, import_firestore59.getDocs)(q);
18822
- return snapshot.docs.map(
18833
+ const categories = snapshot.docs.map(
18823
18834
  (doc45) => ({
18824
18835
  id: doc45.id,
18825
18836
  ...doc45.data()
18826
18837
  })
18827
18838
  );
18839
+ return this.filterExcludedCategories(categories);
18828
18840
  }
18829
18841
  /**
18830
18842
  * Vraća sve kategorije sa paginacijom
@@ -18847,8 +18859,9 @@ var CategoryService = class extends BaseService {
18847
18859
  ...doc45.data()
18848
18860
  })
18849
18861
  );
18862
+ const filteredCategories = this.filterExcludedCategories(categories);
18850
18863
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
18851
- return { categories, lastVisible: newLastVisible };
18864
+ return { categories: filteredCategories, lastVisible: newLastVisible };
18852
18865
  }
18853
18866
  /**
18854
18867
  * Vraća sve aktivne kategorije za određenu familiju procedura sa paginacijom
@@ -18873,8 +18886,9 @@ var CategoryService = class extends BaseService {
18873
18886
  ...doc45.data()
18874
18887
  })
18875
18888
  );
18889
+ const filteredCategories = this.filterExcludedCategories(categories);
18876
18890
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
18877
- return { categories, lastVisible: newLastVisible };
18891
+ return { categories: filteredCategories, lastVisible: newLastVisible };
18878
18892
  }
18879
18893
  /**
18880
18894
  * Ažurira postojeću kategoriju
@@ -18911,6 +18925,22 @@ var CategoryService = class extends BaseService {
18911
18925
  * @returns Kategorija ili null ako ne postoji
18912
18926
  */
18913
18927
  async getById(id) {
18928
+ if (id === EXCLUDED_CATEGORY_ID) return null;
18929
+ const docRef = (0, import_firestore59.doc)(this.categoriesRef, id);
18930
+ const docSnap = await (0, import_firestore59.getDoc)(docRef);
18931
+ if (!docSnap.exists()) return null;
18932
+ return {
18933
+ id: docSnap.id,
18934
+ ...docSnap.data()
18935
+ };
18936
+ }
18937
+ /**
18938
+ * Internal method to get category by ID without filtering.
18939
+ * Used internally for consultation procedures.
18940
+ * @param id - ID of the category to get
18941
+ * @returns Category or null if not found
18942
+ */
18943
+ async getByIdInternal(id) {
18914
18944
  const docRef = (0, import_firestore59.doc)(this.categoriesRef, id);
18915
18945
  const docSnap = await (0, import_firestore59.getDoc)(docRef);
18916
18946
  if (!docSnap.exists()) return null;
@@ -18919,6 +18949,29 @@ var CategoryService = class extends BaseService {
18919
18949
  ...docSnap.data()
18920
18950
  };
18921
18951
  }
18952
+ /**
18953
+ * Finds a category by exact name match within a specific family.
18954
+ * Used for CSV import matching.
18955
+ * @param name - Exact name of the category to find
18956
+ * @param family - Procedure family to search within
18957
+ * @returns Category if found, null otherwise
18958
+ */
18959
+ async findByNameAndFamily(name, family) {
18960
+ const q = (0, import_firestore59.query)(
18961
+ this.categoriesRef,
18962
+ (0, import_firestore59.where)("name", "==", name),
18963
+ (0, import_firestore59.where)("family", "==", family),
18964
+ (0, import_firestore59.where)("isActive", "==", true)
18965
+ );
18966
+ const snapshot = await (0, import_firestore59.getDocs)(q);
18967
+ if (snapshot.empty) return null;
18968
+ const doc45 = snapshot.docs[0];
18969
+ if (doc45.id === EXCLUDED_CATEGORY_ID) return null;
18970
+ return {
18971
+ id: doc45.id,
18972
+ ...doc45.data()
18973
+ };
18974
+ }
18922
18975
  /**
18923
18976
  * Exports categories to CSV string, suitable for Excel/Sheets.
18924
18977
  * Includes headers and optional UTF-8 BOM.
@@ -18951,6 +19004,7 @@ var CategoryService = class extends BaseService {
18951
19004
  const snapshot = await (0, import_firestore59.getDocs)(q);
18952
19005
  if (snapshot.empty) break;
18953
19006
  for (const d of snapshot.docs) {
19007
+ if (d.id === EXCLUDED_CATEGORY_ID) continue;
18954
19008
  const category = { id: d.id, ...d.data() };
18955
19009
  rows.push(this.categoryToCsvRow(category));
18956
19010
  }
@@ -18993,7 +19047,16 @@ var import_firestore60 = require("firebase/firestore");
18993
19047
  var SUBCATEGORIES_COLLECTION = "subcategories";
18994
19048
 
18995
19049
  // src/backoffice/services/subcategory.service.ts
19050
+ var EXCLUDED_SUBCATEGORY_ID = "free-consultation";
18996
19051
  var SubcategoryService = class extends BaseService {
19052
+ /**
19053
+ * Filters out excluded subcategories from a list.
19054
+ * @param subcategories - List of subcategories to filter
19055
+ * @returns Filtered list without excluded subcategories
19056
+ */
19057
+ filterExcludedSubcategories(subcategories) {
19058
+ return subcategories.filter((sub) => sub.id !== EXCLUDED_SUBCATEGORY_ID);
19059
+ }
18997
19060
  /**
18998
19061
  * Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
18999
19062
  * @param categoryId - ID roditeljske kategorije
@@ -19040,8 +19103,9 @@ var SubcategoryService = class extends BaseService {
19040
19103
  const categoryId = categoryDoc.id;
19041
19104
  const subcategoriesRef = this.getSubcategoriesRef(categoryId);
19042
19105
  const q = (0, import_firestore60.query)(subcategoriesRef, (0, import_firestore60.where)("isActive", "==", active));
19043
- const snapshot = await (0, import_firestore60.getCountFromServer)(q);
19044
- counts[categoryId] = snapshot.data().count;
19106
+ const snapshot = await (0, import_firestore60.getDocs)(q);
19107
+ const filteredDocs = snapshot.docs.filter((doc45) => doc45.id !== EXCLUDED_SUBCATEGORY_ID);
19108
+ counts[categoryId] = filteredDocs.length;
19045
19109
  }
19046
19110
  return counts;
19047
19111
  }
@@ -19067,8 +19131,9 @@ var SubcategoryService = class extends BaseService {
19067
19131
  ...doc45.data()
19068
19132
  })
19069
19133
  );
19134
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
19070
19135
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
19071
- return { subcategories, lastVisible: newLastVisible };
19136
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
19072
19137
  }
19073
19138
  /**
19074
19139
  * Vraća sve podkategorije sa paginacijom koristeći collection group query.
@@ -19097,8 +19162,9 @@ var SubcategoryService = class extends BaseService {
19097
19162
  ...doc45.data()
19098
19163
  })
19099
19164
  );
19165
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
19100
19166
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
19101
- return { subcategories, lastVisible: newLastVisible };
19167
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
19102
19168
  }
19103
19169
  /**
19104
19170
  * Vraća sve subkategorije za određenu kategoriju za potrebe filtera (bez paginacije)
@@ -19111,12 +19177,13 @@ var SubcategoryService = class extends BaseService {
19111
19177
  (0, import_firestore60.where)("isActive", "==", true)
19112
19178
  );
19113
19179
  const querySnapshot = await (0, import_firestore60.getDocs)(q);
19114
- return querySnapshot.docs.map(
19180
+ const subcategories = querySnapshot.docs.map(
19115
19181
  (doc45) => ({
19116
19182
  id: doc45.id,
19117
19183
  ...doc45.data()
19118
19184
  })
19119
19185
  );
19186
+ return this.filterExcludedSubcategories(subcategories);
19120
19187
  }
19121
19188
  /**
19122
19189
  * Vraća sve subkategorije za potrebe filtera (bez paginacije)
@@ -19128,12 +19195,13 @@ var SubcategoryService = class extends BaseService {
19128
19195
  (0, import_firestore60.where)("isActive", "==", true)
19129
19196
  );
19130
19197
  const querySnapshot = await (0, import_firestore60.getDocs)(q);
19131
- return querySnapshot.docs.map(
19198
+ const subcategories = querySnapshot.docs.map(
19132
19199
  (doc45) => ({
19133
19200
  id: doc45.id,
19134
19201
  ...doc45.data()
19135
19202
  })
19136
19203
  );
19204
+ return this.filterExcludedSubcategories(subcategories);
19137
19205
  }
19138
19206
  /**
19139
19207
  * Ažurira postojeću podkategoriju
@@ -19203,6 +19271,23 @@ var SubcategoryService = class extends BaseService {
19203
19271
  * @returns Podkategorija ili null ako ne postoji
19204
19272
  */
19205
19273
  async getById(categoryId, subcategoryId) {
19274
+ if (subcategoryId === EXCLUDED_SUBCATEGORY_ID) return null;
19275
+ const docRef = (0, import_firestore60.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
19276
+ const docSnap = await (0, import_firestore60.getDoc)(docRef);
19277
+ if (!docSnap.exists()) return null;
19278
+ return {
19279
+ id: docSnap.id,
19280
+ ...docSnap.data()
19281
+ };
19282
+ }
19283
+ /**
19284
+ * Internal method to get subcategory by ID without filtering.
19285
+ * Used internally for consultation procedures.
19286
+ * @param categoryId - ID of the category
19287
+ * @param subcategoryId - ID of the subcategory to get
19288
+ * @returns Subcategory or null if not found
19289
+ */
19290
+ async getByIdInternal(categoryId, subcategoryId) {
19206
19291
  const docRef = (0, import_firestore60.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
19207
19292
  const docSnap = await (0, import_firestore60.getDoc)(docRef);
19208
19293
  if (!docSnap.exists()) return null;
@@ -19211,6 +19296,28 @@ var SubcategoryService = class extends BaseService {
19211
19296
  ...docSnap.data()
19212
19297
  };
19213
19298
  }
19299
+ /**
19300
+ * Finds a subcategory by exact name match within a specific category.
19301
+ * Used for CSV import matching.
19302
+ * @param name - Exact name of the subcategory to find
19303
+ * @param categoryId - ID of the category to search within
19304
+ * @returns Subcategory if found, null otherwise
19305
+ */
19306
+ async findByNameAndCategory(name, categoryId) {
19307
+ const q = (0, import_firestore60.query)(
19308
+ this.getSubcategoriesRef(categoryId),
19309
+ (0, import_firestore60.where)("name", "==", name),
19310
+ (0, import_firestore60.where)("isActive", "==", true)
19311
+ );
19312
+ const querySnapshot = await (0, import_firestore60.getDocs)(q);
19313
+ if (querySnapshot.empty) return null;
19314
+ const doc45 = querySnapshot.docs[0];
19315
+ if (doc45.id === EXCLUDED_SUBCATEGORY_ID) return null;
19316
+ return {
19317
+ id: doc45.id,
19318
+ ...doc45.data()
19319
+ };
19320
+ }
19214
19321
  /**
19215
19322
  * Exports subcategories to CSV string, suitable for Excel/Sheets.
19216
19323
  * Includes headers and optional UTF-8 BOM.
@@ -19246,6 +19353,7 @@ var SubcategoryService = class extends BaseService {
19246
19353
  const snapshot = await (0, import_firestore60.getDocs)(q);
19247
19354
  if (snapshot.empty) break;
19248
19355
  for (const d of snapshot.docs) {
19356
+ if (d.id === EXCLUDED_SUBCATEGORY_ID) continue;
19249
19357
  const subcategory = { id: d.id, ...d.data() };
19250
19358
  rows.push(this.subcategoryToCsvRow(subcategory));
19251
19359
  }
@@ -19288,11 +19396,20 @@ var import_firestore61 = require("firebase/firestore");
19288
19396
  var PRODUCTS_COLLECTION = "products";
19289
19397
 
19290
19398
  // src/backoffice/services/technology.service.ts
19399
+ var EXCLUDED_TECHNOLOGY_ID = "free-consultation-tech";
19291
19400
  var DEFAULT_CERTIFICATION_REQUIREMENT = {
19292
19401
  minimumLevel: "aesthetician" /* AESTHETICIAN */,
19293
19402
  requiredSpecialties: []
19294
19403
  };
19295
19404
  var TechnologyService = class extends BaseService {
19405
+ /**
19406
+ * Filters out excluded technologies from a list.
19407
+ * @param technologies - List of technologies to filter
19408
+ * @returns Filtered list without excluded technologies
19409
+ */
19410
+ filterExcludedTechnologies(technologies) {
19411
+ return technologies.filter((tech) => tech.id !== EXCLUDED_TECHNOLOGY_ID);
19412
+ }
19296
19413
  /**
19297
19414
  * Reference to the Firestore collection of technologies.
19298
19415
  */
@@ -19341,6 +19458,7 @@ var TechnologyService = class extends BaseService {
19341
19458
  const snapshot = await (0, import_firestore61.getDocs)(q);
19342
19459
  const counts = {};
19343
19460
  snapshot.docs.forEach((doc45) => {
19461
+ if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return;
19344
19462
  const tech = doc45.data();
19345
19463
  counts[tech.subcategoryId] = (counts[tech.subcategoryId] || 0) + 1;
19346
19464
  });
@@ -19356,6 +19474,7 @@ var TechnologyService = class extends BaseService {
19356
19474
  const snapshot = await (0, import_firestore61.getDocs)(q);
19357
19475
  const counts = {};
19358
19476
  snapshot.docs.forEach((doc45) => {
19477
+ if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return;
19359
19478
  const tech = doc45.data();
19360
19479
  counts[tech.categoryId] = (counts[tech.categoryId] || 0) + 1;
19361
19480
  });
@@ -19382,8 +19501,9 @@ var TechnologyService = class extends BaseService {
19382
19501
  ...doc45.data()
19383
19502
  })
19384
19503
  );
19504
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
19385
19505
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19386
- return { technologies, lastVisible: newLastVisible };
19506
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
19387
19507
  }
19388
19508
  /**
19389
19509
  * Returns all technologies for a specific category with pagination.
@@ -19408,8 +19528,9 @@ var TechnologyService = class extends BaseService {
19408
19528
  ...doc45.data()
19409
19529
  })
19410
19530
  );
19531
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
19411
19532
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19412
- return { technologies, lastVisible: newLastVisible };
19533
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
19413
19534
  }
19414
19535
  /**
19415
19536
  * Returns all technologies for a specific subcategory with pagination.
@@ -19434,8 +19555,9 @@ var TechnologyService = class extends BaseService {
19434
19555
  ...doc45.data()
19435
19556
  })
19436
19557
  );
19558
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
19437
19559
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19438
- return { technologies, lastVisible: newLastVisible };
19560
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
19439
19561
  }
19440
19562
  /**
19441
19563
  * Updates an existing technology.
@@ -19493,6 +19615,22 @@ var TechnologyService = class extends BaseService {
19493
19615
  * @returns The technology or null if it doesn't exist.
19494
19616
  */
19495
19617
  async getById(id) {
19618
+ if (id === EXCLUDED_TECHNOLOGY_ID) return null;
19619
+ const docRef = (0, import_firestore61.doc)(this.technologiesRef, id);
19620
+ const docSnap = await (0, import_firestore61.getDoc)(docRef);
19621
+ if (!docSnap.exists()) return null;
19622
+ return {
19623
+ id: docSnap.id,
19624
+ ...docSnap.data()
19625
+ };
19626
+ }
19627
+ /**
19628
+ * Internal method to get technology by ID without filtering.
19629
+ * Used internally for consultation procedures.
19630
+ * @param id - The ID of the requested technology
19631
+ * @returns The technology or null if it doesn't exist
19632
+ */
19633
+ async getByIdInternal(id) {
19496
19634
  const docRef = (0, import_firestore61.doc)(this.technologiesRef, id);
19497
19635
  const docSnap = await (0, import_firestore61.getDoc)(docRef);
19498
19636
  if (!docSnap.exists()) return null;
@@ -19501,6 +19639,27 @@ var TechnologyService = class extends BaseService {
19501
19639
  ...docSnap.data()
19502
19640
  };
19503
19641
  }
19642
+ /**
19643
+ * Finds a technology by exact name match.
19644
+ * Used for CSV import duplicate detection.
19645
+ * @param name - Exact name of the technology to find
19646
+ * @returns Technology if found, null otherwise
19647
+ */
19648
+ async findByName(name) {
19649
+ const q = (0, import_firestore61.query)(
19650
+ this.technologiesRef,
19651
+ (0, import_firestore61.where)("name", "==", name),
19652
+ (0, import_firestore61.where)("isActive", "==", true)
19653
+ );
19654
+ const snapshot = await (0, import_firestore61.getDocs)(q);
19655
+ if (snapshot.empty) return null;
19656
+ const doc45 = snapshot.docs[0];
19657
+ if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return null;
19658
+ return {
19659
+ id: doc45.id,
19660
+ ...doc45.data()
19661
+ };
19662
+ }
19504
19663
  /**
19505
19664
  * Dodaje novi zahtev tehnologiji
19506
19665
  * @param technologyId - ID tehnologije
@@ -19861,12 +20020,13 @@ var TechnologyService = class extends BaseService {
19861
20020
  (0, import_firestore61.orderBy)("name")
19862
20021
  );
19863
20022
  const snapshot = await (0, import_firestore61.getDocs)(q);
19864
- return snapshot.docs.map(
20023
+ const technologies = snapshot.docs.map(
19865
20024
  (doc45) => ({
19866
20025
  id: doc45.id,
19867
20026
  ...doc45.data()
19868
20027
  })
19869
20028
  );
20029
+ return this.filterExcludedTechnologies(technologies);
19870
20030
  }
19871
20031
  /**
19872
20032
  * Gets all active technologies for a subcategory for filter dropdowns.
@@ -19882,12 +20042,13 @@ var TechnologyService = class extends BaseService {
19882
20042
  (0, import_firestore61.orderBy)("name")
19883
20043
  );
19884
20044
  const snapshot = await (0, import_firestore61.getDocs)(q);
19885
- return snapshot.docs.map(
20045
+ const technologies = snapshot.docs.map(
19886
20046
  (doc45) => ({
19887
20047
  id: doc45.id,
19888
20048
  ...doc45.data()
19889
20049
  })
19890
20050
  );
20051
+ return this.filterExcludedTechnologies(technologies);
19891
20052
  }
19892
20053
  /**
19893
20054
  * Gets all active technologies for filter dropdowns.
@@ -19899,12 +20060,13 @@ var TechnologyService = class extends BaseService {
19899
20060
  (0, import_firestore61.orderBy)("name")
19900
20061
  );
19901
20062
  const snapshot = await (0, import_firestore61.getDocs)(q);
19902
- return snapshot.docs.map(
20063
+ const technologies = snapshot.docs.map(
19903
20064
  (doc45) => ({
19904
20065
  id: doc45.id,
19905
20066
  ...doc45.data()
19906
20067
  })
19907
20068
  );
20069
+ return this.filterExcludedTechnologies(technologies);
19908
20070
  }
19909
20071
  // ==========================================
19910
20072
  // NEW METHODS: Product assignment management
@@ -20070,6 +20232,7 @@ var TechnologyService = class extends BaseService {
20070
20232
  const snapshot = await (0, import_firestore61.getDocs)(q);
20071
20233
  if (snapshot.empty) break;
20072
20234
  for (const d of snapshot.docs) {
20235
+ if (d.id === EXCLUDED_TECHNOLOGY_ID) continue;
20073
20236
  const technology = { id: d.id, ...d.data() };
20074
20237
  const productNames = await this.getProductNamesForTechnology(technology.id);
20075
20238
  rows.push(this.technologyToCsvRow(technology, productNames));