@blackcode_sa/metaestetics-api 1.12.67 → 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.mjs CHANGED
@@ -18059,9 +18059,9 @@ var ProcedureService = class extends BaseService {
18059
18059
  var _a, _b;
18060
18060
  const procedureId = this.generateId();
18061
18061
  const [category, subcategory, technology] = await Promise.all([
18062
- this.categoryService.getById(data.categoryId),
18063
- this.subcategoryService.getById(data.categoryId, data.subcategoryId),
18064
- this.technologyService.getById(data.technologyId)
18062
+ this.categoryService.getByIdInternal(data.categoryId),
18063
+ this.subcategoryService.getByIdInternal(data.categoryId, data.subcategoryId),
18064
+ this.technologyService.getByIdInternal(data.technologyId)
18065
18065
  ]);
18066
18066
  if (!category || !subcategory || !technology) {
18067
18067
  throw new Error("One or more required base entities not found");
@@ -19019,7 +19019,6 @@ import {
19019
19019
  addDoc as addDoc5,
19020
19020
  collection as collection34,
19021
19021
  doc as doc40,
19022
- getCountFromServer as getCountFromServer4,
19023
19022
  getDoc as getDoc41,
19024
19023
  getDocs as getDocs34,
19025
19024
  limit as limit18,
@@ -19034,7 +19033,16 @@ import {
19034
19033
  var CATEGORIES_COLLECTION = "backoffice_categories";
19035
19034
 
19036
19035
  // src/backoffice/services/category.service.ts
19036
+ var EXCLUDED_CATEGORY_ID = "consultation";
19037
19037
  var CategoryService = class extends BaseService {
19038
+ /**
19039
+ * Filters out excluded categories from a list.
19040
+ * @param categories - List of categories to filter
19041
+ * @returns Filtered list without excluded categories
19042
+ */
19043
+ filterExcludedCategories(categories) {
19044
+ return categories.filter((cat) => cat.id !== EXCLUDED_CATEGORY_ID);
19045
+ }
19038
19046
  /**
19039
19047
  * Referenca na Firestore kolekciju kategorija
19040
19048
  */
@@ -19071,8 +19079,9 @@ var CategoryService = class extends BaseService {
19071
19079
  where34("family", "==", family),
19072
19080
  where34("isActive", "==", active)
19073
19081
  );
19074
- const snapshot = await getCountFromServer4(q);
19075
- counts[family] = snapshot.data().count;
19082
+ const snapshot = await getDocs34(q);
19083
+ const filteredDocs = snapshot.docs.filter((doc45) => doc45.id !== EXCLUDED_CATEGORY_ID);
19084
+ counts[family] = filteredDocs.length;
19076
19085
  }
19077
19086
  return counts;
19078
19087
  }
@@ -19083,12 +19092,13 @@ var CategoryService = class extends BaseService {
19083
19092
  async getAllForFilter() {
19084
19093
  const q = query34(this.categoriesRef, where34("isActive", "==", true));
19085
19094
  const snapshot = await getDocs34(q);
19086
- return snapshot.docs.map(
19095
+ const categories = snapshot.docs.map(
19087
19096
  (doc45) => ({
19088
19097
  id: doc45.id,
19089
19098
  ...doc45.data()
19090
19099
  })
19091
19100
  );
19101
+ return this.filterExcludedCategories(categories);
19092
19102
  }
19093
19103
  /**
19094
19104
  * Vraća sve kategorije za određenu familiju za potrebe filtera (bez paginacije)
@@ -19103,12 +19113,13 @@ var CategoryService = class extends BaseService {
19103
19113
  orderBy20("name")
19104
19114
  );
19105
19115
  const snapshot = await getDocs34(q);
19106
- return snapshot.docs.map(
19116
+ const categories = snapshot.docs.map(
19107
19117
  (doc45) => ({
19108
19118
  id: doc45.id,
19109
19119
  ...doc45.data()
19110
19120
  })
19111
19121
  );
19122
+ return this.filterExcludedCategories(categories);
19112
19123
  }
19113
19124
  /**
19114
19125
  * Vraća sve kategorije sa paginacijom
@@ -19131,8 +19142,9 @@ var CategoryService = class extends BaseService {
19131
19142
  ...doc45.data()
19132
19143
  })
19133
19144
  );
19145
+ const filteredCategories = this.filterExcludedCategories(categories);
19134
19146
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19135
- return { categories, lastVisible: newLastVisible };
19147
+ return { categories: filteredCategories, lastVisible: newLastVisible };
19136
19148
  }
19137
19149
  /**
19138
19150
  * Vraća sve aktivne kategorije za određenu familiju procedura sa paginacijom
@@ -19157,8 +19169,9 @@ var CategoryService = class extends BaseService {
19157
19169
  ...doc45.data()
19158
19170
  })
19159
19171
  );
19172
+ const filteredCategories = this.filterExcludedCategories(categories);
19160
19173
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19161
- return { categories, lastVisible: newLastVisible };
19174
+ return { categories: filteredCategories, lastVisible: newLastVisible };
19162
19175
  }
19163
19176
  /**
19164
19177
  * Ažurira postojeću kategoriju
@@ -19195,6 +19208,22 @@ var CategoryService = class extends BaseService {
19195
19208
  * @returns Kategorija ili null ako ne postoji
19196
19209
  */
19197
19210
  async getById(id) {
19211
+ if (id === EXCLUDED_CATEGORY_ID) return null;
19212
+ const docRef = doc40(this.categoriesRef, id);
19213
+ const docSnap = await getDoc41(docRef);
19214
+ if (!docSnap.exists()) return null;
19215
+ return {
19216
+ id: docSnap.id,
19217
+ ...docSnap.data()
19218
+ };
19219
+ }
19220
+ /**
19221
+ * Internal method to get category by ID without filtering.
19222
+ * Used internally for consultation procedures.
19223
+ * @param id - ID of the category to get
19224
+ * @returns Category or null if not found
19225
+ */
19226
+ async getByIdInternal(id) {
19198
19227
  const docRef = doc40(this.categoriesRef, id);
19199
19228
  const docSnap = await getDoc41(docRef);
19200
19229
  if (!docSnap.exists()) return null;
@@ -19220,6 +19249,7 @@ var CategoryService = class extends BaseService {
19220
19249
  const snapshot = await getDocs34(q);
19221
19250
  if (snapshot.empty) return null;
19222
19251
  const doc45 = snapshot.docs[0];
19252
+ if (doc45.id === EXCLUDED_CATEGORY_ID) return null;
19223
19253
  return {
19224
19254
  id: doc45.id,
19225
19255
  ...doc45.data()
@@ -19257,6 +19287,7 @@ var CategoryService = class extends BaseService {
19257
19287
  const snapshot = await getDocs34(q);
19258
19288
  if (snapshot.empty) break;
19259
19289
  for (const d of snapshot.docs) {
19290
+ if (d.id === EXCLUDED_CATEGORY_ID) continue;
19260
19291
  const category = { id: d.id, ...d.data() };
19261
19292
  rows.push(this.categoryToCsvRow(category));
19262
19293
  }
@@ -19299,7 +19330,6 @@ import {
19299
19330
  collectionGroup as collectionGroup2,
19300
19331
  deleteDoc as deleteDoc21,
19301
19332
  doc as doc41,
19302
- getCountFromServer as getCountFromServer5,
19303
19333
  getDoc as getDoc42,
19304
19334
  getDocs as getDocs35,
19305
19335
  limit as limit19,
@@ -19315,7 +19345,16 @@ import {
19315
19345
  var SUBCATEGORIES_COLLECTION = "subcategories";
19316
19346
 
19317
19347
  // src/backoffice/services/subcategory.service.ts
19348
+ var EXCLUDED_SUBCATEGORY_ID = "free-consultation";
19318
19349
  var SubcategoryService = class extends BaseService {
19350
+ /**
19351
+ * Filters out excluded subcategories from a list.
19352
+ * @param subcategories - List of subcategories to filter
19353
+ * @returns Filtered list without excluded subcategories
19354
+ */
19355
+ filterExcludedSubcategories(subcategories) {
19356
+ return subcategories.filter((sub) => sub.id !== EXCLUDED_SUBCATEGORY_ID);
19357
+ }
19319
19358
  /**
19320
19359
  * Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
19321
19360
  * @param categoryId - ID roditeljske kategorije
@@ -19362,8 +19401,9 @@ var SubcategoryService = class extends BaseService {
19362
19401
  const categoryId = categoryDoc.id;
19363
19402
  const subcategoriesRef = this.getSubcategoriesRef(categoryId);
19364
19403
  const q = query35(subcategoriesRef, where35("isActive", "==", active));
19365
- const snapshot = await getCountFromServer5(q);
19366
- counts[categoryId] = snapshot.data().count;
19404
+ const snapshot = await getDocs35(q);
19405
+ const filteredDocs = snapshot.docs.filter((doc45) => doc45.id !== EXCLUDED_SUBCATEGORY_ID);
19406
+ counts[categoryId] = filteredDocs.length;
19367
19407
  }
19368
19408
  return counts;
19369
19409
  }
@@ -19389,8 +19429,9 @@ var SubcategoryService = class extends BaseService {
19389
19429
  ...doc45.data()
19390
19430
  })
19391
19431
  );
19432
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
19392
19433
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
19393
- return { subcategories, lastVisible: newLastVisible };
19434
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
19394
19435
  }
19395
19436
  /**
19396
19437
  * Vraća sve podkategorije sa paginacijom koristeći collection group query.
@@ -19419,8 +19460,9 @@ var SubcategoryService = class extends BaseService {
19419
19460
  ...doc45.data()
19420
19461
  })
19421
19462
  );
19463
+ const filteredSubcategories = this.filterExcludedSubcategories(subcategories);
19422
19464
  const newLastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
19423
- return { subcategories, lastVisible: newLastVisible };
19465
+ return { subcategories: filteredSubcategories, lastVisible: newLastVisible };
19424
19466
  }
19425
19467
  /**
19426
19468
  * Vraća sve subkategorije za određenu kategoriju za potrebe filtera (bez paginacije)
@@ -19433,12 +19475,13 @@ var SubcategoryService = class extends BaseService {
19433
19475
  where35("isActive", "==", true)
19434
19476
  );
19435
19477
  const querySnapshot = await getDocs35(q);
19436
- return querySnapshot.docs.map(
19478
+ const subcategories = querySnapshot.docs.map(
19437
19479
  (doc45) => ({
19438
19480
  id: doc45.id,
19439
19481
  ...doc45.data()
19440
19482
  })
19441
19483
  );
19484
+ return this.filterExcludedSubcategories(subcategories);
19442
19485
  }
19443
19486
  /**
19444
19487
  * Vraća sve subkategorije za potrebe filtera (bez paginacije)
@@ -19450,12 +19493,13 @@ var SubcategoryService = class extends BaseService {
19450
19493
  where35("isActive", "==", true)
19451
19494
  );
19452
19495
  const querySnapshot = await getDocs35(q);
19453
- return querySnapshot.docs.map(
19496
+ const subcategories = querySnapshot.docs.map(
19454
19497
  (doc45) => ({
19455
19498
  id: doc45.id,
19456
19499
  ...doc45.data()
19457
19500
  })
19458
19501
  );
19502
+ return this.filterExcludedSubcategories(subcategories);
19459
19503
  }
19460
19504
  /**
19461
19505
  * Ažurira postojeću podkategoriju
@@ -19525,6 +19569,23 @@ var SubcategoryService = class extends BaseService {
19525
19569
  * @returns Podkategorija ili null ako ne postoji
19526
19570
  */
19527
19571
  async getById(categoryId, subcategoryId) {
19572
+ if (subcategoryId === EXCLUDED_SUBCATEGORY_ID) return null;
19573
+ const docRef = doc41(this.getSubcategoriesRef(categoryId), subcategoryId);
19574
+ const docSnap = await getDoc42(docRef);
19575
+ if (!docSnap.exists()) return null;
19576
+ return {
19577
+ id: docSnap.id,
19578
+ ...docSnap.data()
19579
+ };
19580
+ }
19581
+ /**
19582
+ * Internal method to get subcategory by ID without filtering.
19583
+ * Used internally for consultation procedures.
19584
+ * @param categoryId - ID of the category
19585
+ * @param subcategoryId - ID of the subcategory to get
19586
+ * @returns Subcategory or null if not found
19587
+ */
19588
+ async getByIdInternal(categoryId, subcategoryId) {
19528
19589
  const docRef = doc41(this.getSubcategoriesRef(categoryId), subcategoryId);
19529
19590
  const docSnap = await getDoc42(docRef);
19530
19591
  if (!docSnap.exists()) return null;
@@ -19549,6 +19610,7 @@ var SubcategoryService = class extends BaseService {
19549
19610
  const querySnapshot = await getDocs35(q);
19550
19611
  if (querySnapshot.empty) return null;
19551
19612
  const doc45 = querySnapshot.docs[0];
19613
+ if (doc45.id === EXCLUDED_SUBCATEGORY_ID) return null;
19552
19614
  return {
19553
19615
  id: doc45.id,
19554
19616
  ...doc45.data()
@@ -19589,6 +19651,7 @@ var SubcategoryService = class extends BaseService {
19589
19651
  const snapshot = await getDocs35(q);
19590
19652
  if (snapshot.empty) break;
19591
19653
  for (const d of snapshot.docs) {
19654
+ if (d.id === EXCLUDED_SUBCATEGORY_ID) continue;
19592
19655
  const subcategory = { id: d.id, ...d.data() };
19593
19656
  rows.push(this.subcategoryToCsvRow(subcategory));
19594
19657
  }
@@ -19646,11 +19709,20 @@ import {
19646
19709
  var PRODUCTS_COLLECTION = "products";
19647
19710
 
19648
19711
  // src/backoffice/services/technology.service.ts
19712
+ var EXCLUDED_TECHNOLOGY_ID = "free-consultation-tech";
19649
19713
  var DEFAULT_CERTIFICATION_REQUIREMENT = {
19650
19714
  minimumLevel: "aesthetician" /* AESTHETICIAN */,
19651
19715
  requiredSpecialties: []
19652
19716
  };
19653
19717
  var TechnologyService = class extends BaseService {
19718
+ /**
19719
+ * Filters out excluded technologies from a list.
19720
+ * @param technologies - List of technologies to filter
19721
+ * @returns Filtered list without excluded technologies
19722
+ */
19723
+ filterExcludedTechnologies(technologies) {
19724
+ return technologies.filter((tech) => tech.id !== EXCLUDED_TECHNOLOGY_ID);
19725
+ }
19654
19726
  /**
19655
19727
  * Reference to the Firestore collection of technologies.
19656
19728
  */
@@ -19699,6 +19771,7 @@ var TechnologyService = class extends BaseService {
19699
19771
  const snapshot = await getDocs36(q);
19700
19772
  const counts = {};
19701
19773
  snapshot.docs.forEach((doc45) => {
19774
+ if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return;
19702
19775
  const tech = doc45.data();
19703
19776
  counts[tech.subcategoryId] = (counts[tech.subcategoryId] || 0) + 1;
19704
19777
  });
@@ -19714,6 +19787,7 @@ var TechnologyService = class extends BaseService {
19714
19787
  const snapshot = await getDocs36(q);
19715
19788
  const counts = {};
19716
19789
  snapshot.docs.forEach((doc45) => {
19790
+ if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return;
19717
19791
  const tech = doc45.data();
19718
19792
  counts[tech.categoryId] = (counts[tech.categoryId] || 0) + 1;
19719
19793
  });
@@ -19740,8 +19814,9 @@ var TechnologyService = class extends BaseService {
19740
19814
  ...doc45.data()
19741
19815
  })
19742
19816
  );
19817
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
19743
19818
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19744
- return { technologies, lastVisible: newLastVisible };
19819
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
19745
19820
  }
19746
19821
  /**
19747
19822
  * Returns all technologies for a specific category with pagination.
@@ -19766,8 +19841,9 @@ var TechnologyService = class extends BaseService {
19766
19841
  ...doc45.data()
19767
19842
  })
19768
19843
  );
19844
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
19769
19845
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19770
- return { technologies, lastVisible: newLastVisible };
19846
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
19771
19847
  }
19772
19848
  /**
19773
19849
  * Returns all technologies for a specific subcategory with pagination.
@@ -19792,8 +19868,9 @@ var TechnologyService = class extends BaseService {
19792
19868
  ...doc45.data()
19793
19869
  })
19794
19870
  );
19871
+ const filteredTechnologies = this.filterExcludedTechnologies(technologies);
19795
19872
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
19796
- return { technologies, lastVisible: newLastVisible };
19873
+ return { technologies: filteredTechnologies, lastVisible: newLastVisible };
19797
19874
  }
19798
19875
  /**
19799
19876
  * Updates an existing technology.
@@ -19851,6 +19928,22 @@ var TechnologyService = class extends BaseService {
19851
19928
  * @returns The technology or null if it doesn't exist.
19852
19929
  */
19853
19930
  async getById(id) {
19931
+ if (id === EXCLUDED_TECHNOLOGY_ID) return null;
19932
+ const docRef = doc42(this.technologiesRef, id);
19933
+ const docSnap = await getDoc43(docRef);
19934
+ if (!docSnap.exists()) return null;
19935
+ return {
19936
+ id: docSnap.id,
19937
+ ...docSnap.data()
19938
+ };
19939
+ }
19940
+ /**
19941
+ * Internal method to get technology by ID without filtering.
19942
+ * Used internally for consultation procedures.
19943
+ * @param id - The ID of the requested technology
19944
+ * @returns The technology or null if it doesn't exist
19945
+ */
19946
+ async getByIdInternal(id) {
19854
19947
  const docRef = doc42(this.technologiesRef, id);
19855
19948
  const docSnap = await getDoc43(docRef);
19856
19949
  if (!docSnap.exists()) return null;
@@ -19874,6 +19967,7 @@ var TechnologyService = class extends BaseService {
19874
19967
  const snapshot = await getDocs36(q);
19875
19968
  if (snapshot.empty) return null;
19876
19969
  const doc45 = snapshot.docs[0];
19970
+ if (doc45.id === EXCLUDED_TECHNOLOGY_ID) return null;
19877
19971
  return {
19878
19972
  id: doc45.id,
19879
19973
  ...doc45.data()
@@ -20239,12 +20333,13 @@ var TechnologyService = class extends BaseService {
20239
20333
  orderBy22("name")
20240
20334
  );
20241
20335
  const snapshot = await getDocs36(q);
20242
- return snapshot.docs.map(
20336
+ const technologies = snapshot.docs.map(
20243
20337
  (doc45) => ({
20244
20338
  id: doc45.id,
20245
20339
  ...doc45.data()
20246
20340
  })
20247
20341
  );
20342
+ return this.filterExcludedTechnologies(technologies);
20248
20343
  }
20249
20344
  /**
20250
20345
  * Gets all active technologies for a subcategory for filter dropdowns.
@@ -20260,12 +20355,13 @@ var TechnologyService = class extends BaseService {
20260
20355
  orderBy22("name")
20261
20356
  );
20262
20357
  const snapshot = await getDocs36(q);
20263
- return snapshot.docs.map(
20358
+ const technologies = snapshot.docs.map(
20264
20359
  (doc45) => ({
20265
20360
  id: doc45.id,
20266
20361
  ...doc45.data()
20267
20362
  })
20268
20363
  );
20364
+ return this.filterExcludedTechnologies(technologies);
20269
20365
  }
20270
20366
  /**
20271
20367
  * Gets all active technologies for filter dropdowns.
@@ -20277,12 +20373,13 @@ var TechnologyService = class extends BaseService {
20277
20373
  orderBy22("name")
20278
20374
  );
20279
20375
  const snapshot = await getDocs36(q);
20280
- return snapshot.docs.map(
20376
+ const technologies = snapshot.docs.map(
20281
20377
  (doc45) => ({
20282
20378
  id: doc45.id,
20283
20379
  ...doc45.data()
20284
20380
  })
20285
20381
  );
20382
+ return this.filterExcludedTechnologies(technologies);
20286
20383
  }
20287
20384
  // ==========================================
20288
20385
  // NEW METHODS: Product assignment management
@@ -20448,6 +20545,7 @@ var TechnologyService = class extends BaseService {
20448
20545
  const snapshot = await getDocs36(q);
20449
20546
  if (snapshot.empty) break;
20450
20547
  for (const d of snapshot.docs) {
20548
+ if (d.id === EXCLUDED_TECHNOLOGY_ID) continue;
20451
20549
  const technology = { id: d.id, ...d.data() };
20452
20550
  const productNames = await this.getProductNamesForTechnology(technology.id);
20453
20551
  rows.push(this.technologyToCsvRow(technology, productNames));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.12.67",
4
+ "version": "1.12.68",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -17,6 +17,12 @@ import { Category, CATEGORIES_COLLECTION, ICategoryService } from '../types/cate
17
17
  import { BaseService } from '../../services/base.service';
18
18
  import { ProcedureFamily } from '../types/static/procedure-family.types';
19
19
 
20
+ /**
21
+ * ID of the consultation category that should be hidden from admin backoffice.
22
+ * This category is used internally for free consultation procedures.
23
+ */
24
+ const EXCLUDED_CATEGORY_ID = 'consultation';
25
+
20
26
  /**
21
27
  * Servis za upravljanje kategorijama procedura.
22
28
  * Kategorije su prvi nivo organizacije nakon procedure family (aesthetics/surgery).
@@ -31,6 +37,14 @@ import { ProcedureFamily } from '../types/static/procedure-family.types';
31
37
  * });
32
38
  */
33
39
  export class CategoryService extends BaseService implements ICategoryService {
40
+ /**
41
+ * Filters out excluded categories from a list.
42
+ * @param categories - List of categories to filter
43
+ * @returns Filtered list without excluded categories
44
+ */
45
+ private filterExcludedCategories(categories: Category[]): Category[] {
46
+ return categories.filter(cat => cat.id !== EXCLUDED_CATEGORY_ID);
47
+ }
34
48
  /**
35
49
  * Referenca na Firestore kolekciju kategorija
36
50
  */
@@ -71,8 +85,10 @@ export class CategoryService extends BaseService implements ICategoryService {
71
85
  where('family', '==', family),
72
86
  where('isActive', '==', active),
73
87
  );
74
- const snapshot = await getCountFromServer(q);
75
- counts[family] = snapshot.data().count;
88
+ const snapshot = await getDocs(q);
89
+ // Filter out excluded category and count
90
+ const filteredDocs = snapshot.docs.filter(doc => doc.id !== EXCLUDED_CATEGORY_ID);
91
+ counts[family] = filteredDocs.length;
76
92
  }
77
93
  return counts;
78
94
  }
@@ -84,13 +100,14 @@ export class CategoryService extends BaseService implements ICategoryService {
84
100
  async getAllForFilter() {
85
101
  const q = query(this.categoriesRef, where('isActive', '==', true));
86
102
  const snapshot = await getDocs(q);
87
- return snapshot.docs.map(
103
+ const categories = snapshot.docs.map(
88
104
  doc =>
89
105
  ({
90
106
  id: doc.id,
91
107
  ...doc.data(),
92
108
  } as Category),
93
109
  );
110
+ return this.filterExcludedCategories(categories);
94
111
  }
95
112
 
96
113
  /**
@@ -106,13 +123,14 @@ export class CategoryService extends BaseService implements ICategoryService {
106
123
  orderBy('name'),
107
124
  );
108
125
  const snapshot = await getDocs(q);
109
- return snapshot.docs.map(
126
+ const categories = snapshot.docs.map(
110
127
  doc =>
111
128
  ({
112
129
  id: doc.id,
113
130
  ...doc.data(),
114
131
  } as Category),
115
132
  );
133
+ return this.filterExcludedCategories(categories);
116
134
  }
117
135
 
118
136
  /**
@@ -144,8 +162,9 @@ export class CategoryService extends BaseService implements ICategoryService {
144
162
  ...doc.data(),
145
163
  } as Category),
146
164
  );
165
+ const filteredCategories = this.filterExcludedCategories(categories);
147
166
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
148
- return { categories, lastVisible: newLastVisible };
167
+ return { categories: filteredCategories, lastVisible: newLastVisible };
149
168
  }
150
169
 
151
170
  /**
@@ -180,8 +199,9 @@ export class CategoryService extends BaseService implements ICategoryService {
180
199
  ...doc.data(),
181
200
  } as Category),
182
201
  );
202
+ const filteredCategories = this.filterExcludedCategories(categories);
183
203
  const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
184
- return { categories, lastVisible: newLastVisible };
204
+ return { categories: filteredCategories, lastVisible: newLastVisible };
185
205
  }
186
206
 
187
207
  /**
@@ -223,6 +243,25 @@ export class CategoryService extends BaseService implements ICategoryService {
223
243
  * @returns Kategorija ili null ako ne postoji
224
244
  */
225
245
  async getById(id: string) {
246
+ // Prevent access to excluded category
247
+ if (id === EXCLUDED_CATEGORY_ID) return null;
248
+
249
+ const docRef = doc(this.categoriesRef, id);
250
+ const docSnap = await getDoc(docRef);
251
+ if (!docSnap.exists()) return null;
252
+ return {
253
+ id: docSnap.id,
254
+ ...docSnap.data(),
255
+ } as Category;
256
+ }
257
+
258
+ /**
259
+ * Internal method to get category by ID without filtering.
260
+ * Used internally for consultation procedures.
261
+ * @param id - ID of the category to get
262
+ * @returns Category or null if not found
263
+ */
264
+ async getByIdInternal(id: string): Promise<Category | null> {
226
265
  const docRef = doc(this.categoriesRef, id);
227
266
  const docSnap = await getDoc(docRef);
228
267
  if (!docSnap.exists()) return null;
@@ -249,6 +288,8 @@ export class CategoryService extends BaseService implements ICategoryService {
249
288
  const snapshot = await getDocs(q);
250
289
  if (snapshot.empty) return null;
251
290
  const doc = snapshot.docs[0];
291
+ // Exclude consultation category
292
+ if (doc.id === EXCLUDED_CATEGORY_ID) return null;
252
293
  return {
253
294
  id: doc.id,
254
295
  ...doc.data(),
@@ -299,6 +340,8 @@ export class CategoryService extends BaseService implements ICategoryService {
299
340
  if (snapshot.empty) break;
300
341
 
301
342
  for (const d of snapshot.docs) {
343
+ // Exclude consultation category from CSV export
344
+ if (d.id === EXCLUDED_CATEGORY_ID) continue;
302
345
  const category = ({ id: d.id, ...d.data() } as unknown) as Category;
303
346
  rows.push(this.categoryToCsvRow(category));
304
347
  }