@blackcode_sa/metaestetics-api 1.5.12 → 1.5.13

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.
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  addDoc,
3
3
  collection,
4
- collectionGroup,
5
4
  doc,
6
5
  getDoc,
7
6
  getDocs,
@@ -9,45 +8,40 @@ import {
9
8
  updateDoc,
10
9
  where,
11
10
  } from "firebase/firestore";
12
- import { Product, PRODUCTS_COLLECTION } from "../types/product.types";
11
+ import {
12
+ Product,
13
+ PRODUCTS_COLLECTION,
14
+ IProductService,
15
+ } from "../types/product.types";
13
16
  import { BaseService } from "../../services/base.service";
14
- import { CATEGORIES_COLLECTION } from "../types/category.types";
15
- import { BRANDS_COLLECTION } from "../types/brand.types";
16
- import { SUBCATEGORIES_COLLECTION } from "../types/subcategory.types";
17
17
  import { TECHNOLOGIES_COLLECTION } from "../types/technology.types";
18
18
 
19
- export class ProductService extends BaseService {
20
- private getProductsRefByTechnology(
21
- categoryId: string,
22
- subcategoryId: string,
23
- technologyId: string
24
- ) {
19
+ export class ProductService extends BaseService implements IProductService {
20
+ /**
21
+ * Gets reference to products collection under a technology
22
+ * @param technologyId - ID of the technology
23
+ * @returns Firestore collection reference
24
+ */
25
+ private getProductsRef(technologyId: string) {
25
26
  return collection(
26
27
  this.db,
27
- CATEGORIES_COLLECTION,
28
- categoryId,
29
- SUBCATEGORIES_COLLECTION,
30
- subcategoryId,
31
28
  TECHNOLOGIES_COLLECTION,
32
29
  technologyId,
33
30
  PRODUCTS_COLLECTION
34
31
  );
35
32
  }
36
33
 
37
- private getProductsRefByBrand(brandId: string) {
38
- return collection(this.db, BRANDS_COLLECTION, brandId, PRODUCTS_COLLECTION);
39
- }
40
-
34
+ /**
35
+ * Creates a new product under technology
36
+ */
41
37
  async create(
42
- categoryId: string,
43
- subcategoryId: string,
44
38
  technologyId: string,
45
39
  brandId: string,
46
40
  product: Omit<
47
41
  Product,
48
42
  "id" | "createdAt" | "updatedAt" | "brandId" | "technologyId"
49
43
  >
50
- ) {
44
+ ): Promise<Product> {
51
45
  const now = new Date();
52
46
  const newProduct: Omit<Product, "id"> = {
53
47
  ...product,
@@ -58,31 +52,20 @@ export class ProductService extends BaseService {
58
52
  isActive: true,
59
53
  };
60
54
 
61
- // Create in technology collection
62
- const techProductRef = await addDoc(
63
- this.getProductsRefByTechnology(categoryId, subcategoryId, technologyId),
55
+ const productRef = await addDoc(
56
+ this.getProductsRef(technologyId),
64
57
  newProduct
65
58
  );
66
59
 
67
- // Create in brand collection (for easy access to brand's products)
68
- await addDoc(this.getProductsRefByBrand(brandId), {
69
- ...newProduct,
70
- id: techProductRef.id, // Store the original ID for reference
71
- categoryId,
72
- subcategoryId,
73
- technologyId,
74
- });
75
-
76
- return { id: techProductRef.id, ...newProduct };
60
+ return { id: productRef.id, ...newProduct };
77
61
  }
78
62
 
79
- async getAllByTechnology(
80
- categoryId: string,
81
- subcategoryId: string,
82
- technologyId: string
83
- ) {
63
+ /**
64
+ * Gets all products for a technology
65
+ */
66
+ async getAllByTechnology(technologyId: string): Promise<Product[]> {
84
67
  const q = query(
85
- this.getProductsRefByTechnology(categoryId, subcategoryId, technologyId),
68
+ this.getProductsRef(technologyId),
86
69
  where("isActive", "==", true)
87
70
  );
88
71
  const snapshot = await getDocs(q);
@@ -95,76 +78,74 @@ export class ProductService extends BaseService {
95
78
  );
96
79
  }
97
80
 
98
- async getAllByBrand(brandId: string) {
99
- const q = query(
100
- this.getProductsRefByBrand(brandId),
101
- where("isActive", "==", true)
102
- );
103
- const snapshot = await getDocs(q);
104
- return snapshot.docs.map(
105
- (doc) =>
106
- ({
107
- id: doc.id,
108
- ...doc.data(),
109
- } as Product)
110
- );
81
+ /**
82
+ * Gets all products for a brand by filtering through all technologies
83
+ */
84
+ async getAllByBrand(brandId: string): Promise<Product[]> {
85
+ const allTechnologiesRef = collection(this.db, TECHNOLOGIES_COLLECTION);
86
+ const technologiesSnapshot = await getDocs(allTechnologiesRef);
87
+
88
+ const products: Product[] = [];
89
+
90
+ for (const techDoc of technologiesSnapshot.docs) {
91
+ const q = query(
92
+ this.getProductsRef(techDoc.id),
93
+ where("brandId", "==", brandId),
94
+ where("isActive", "==", true)
95
+ );
96
+ const snapshot = await getDocs(q);
97
+ products.push(
98
+ ...snapshot.docs.map(
99
+ (doc) =>
100
+ ({
101
+ id: doc.id,
102
+ ...doc.data(),
103
+ } as Product)
104
+ )
105
+ );
106
+ }
107
+
108
+ return products;
111
109
  }
112
110
 
111
+ /**
112
+ * Updates a product
113
+ */
113
114
  async update(
114
- categoryId: string,
115
- subcategoryId: string,
116
115
  technologyId: string,
117
116
  productId: string,
118
117
  product: Partial<
119
118
  Omit<Product, "id" | "createdAt" | "brandId" | "technologyId">
120
119
  >
121
- ) {
120
+ ): Promise<Product | null> {
122
121
  const updateData = {
123
122
  ...product,
124
123
  updatedAt: new Date(),
125
124
  };
126
125
 
127
- // Update in technology collection
128
- const techDocRef = doc(
129
- this.getProductsRefByTechnology(categoryId, subcategoryId, technologyId),
130
- productId
131
- );
132
- await updateDoc(techDocRef, updateData);
133
-
134
- // Update in brand collection
135
- const brandProductsQuery = query(
136
- collectionGroup(this.db, PRODUCTS_COLLECTION),
137
- where("id", "==", productId)
138
- );
139
- const brandProductsSnapshot = await getDocs(brandProductsQuery);
140
- for (const doc of brandProductsSnapshot.docs) {
141
- await updateDoc(doc.ref, updateData);
142
- }
126
+ const docRef = doc(this.getProductsRef(technologyId), productId);
127
+ await updateDoc(docRef, updateData);
143
128
 
144
- return this.getById(categoryId, subcategoryId, technologyId, productId);
129
+ return this.getById(technologyId, productId);
145
130
  }
146
131
 
147
- async delete(
148
- categoryId: string,
149
- subcategoryId: string,
150
- technologyId: string,
151
- productId: string
152
- ) {
153
- await this.update(categoryId, subcategoryId, technologyId, productId, {
132
+ /**
133
+ * Soft deletes a product
134
+ */
135
+ async delete(technologyId: string, productId: string): Promise<void> {
136
+ await this.update(technologyId, productId, {
154
137
  isActive: false,
155
138
  });
156
139
  }
157
140
 
141
+ /**
142
+ * Gets a product by ID
143
+ */
158
144
  async getById(
159
- categoryId: string,
160
- subcategoryId: string,
161
145
  technologyId: string,
162
146
  productId: string
163
- ) {
164
- const docRef = doc(
165
- this.getProductsRefByTechnology(categoryId, subcategoryId, technologyId),
166
- productId
167
- );
147
+ ): Promise<Product | null> {
148
+ const docRef = doc(this.getProductsRef(technologyId), productId);
168
149
  const docSnap = await getDoc(docRef);
169
150
  if (!docSnap.exists()) return null;
170
151
  return {
@@ -1,21 +1,21 @@
1
1
  /**
2
- * Proizvod koji se koristi u procedurama
3
- * Može biti potrošni materijal, oprema ili bilo koji drugi proizvod potreban za izvođenje procedure
2
+ * Product used in procedures
3
+ * Can be consumables, equipment, or any other product needed for performing procedures
4
4
  *
5
- * @property id - Jedinstveni identifikator proizvoda
6
- * @property name - Naziv proizvoda
7
- * @property description - Detaljan opis proizvoda i njegove namene
8
- * @property brandId - ID brenda koji proizvodi ovaj proizvod
9
- * @property technologyId - ID tehnologije sa kojom se proizvod koristi
10
- * @property technicalDetails - Tehnički detalji i specifikacije proizvoda
11
- * @property warnings - Lista upozorenja vezanih za korišćenje proizvoda
12
- * @property dosage - Informacije o doziranju (ako je primenljivo)
13
- * @property composition - Sastav proizvoda
14
- * @property indications - Lista indikacija za korišćenje
15
- * @property contraindications - Lista kontraindikacija
16
- * @property isActive - Da li je proizvod aktivan u sistemu
17
- * @property createdAt - Datum kreiranja
18
- * @property updatedAt - Datum poslednjeg ažuriranja
5
+ * @property id - Unique identifier of the product
6
+ * @property name - Name of the product
7
+ * @property description - Detailed description of the product and its purpose
8
+ * @property brandId - ID of the brand that manufactures this product
9
+ * @property technologyId - ID of the technology this product is used with
10
+ * @property technicalDetails - Technical details and specifications
11
+ * @property warnings - List of warnings related to product use
12
+ * @property dosage - Dosage information (if applicable)
13
+ * @property composition - Product composition
14
+ * @property indications - List of indications for use
15
+ * @property contraindications - List of contraindications
16
+ * @property isActive - Whether the product is active in the system
17
+ * @property createdAt - Creation date
18
+ * @property updatedAt - Last update date
19
19
  */
20
20
  export interface Product {
21
21
  id?: string;
@@ -35,6 +35,66 @@ export interface Product {
35
35
  }
36
36
 
37
37
  /**
38
- * Kolekcija u Firestore bazi gde se čuvaju proizvodi
38
+ * Collection in Firestore database where products are stored
39
39
  */
40
40
  export const PRODUCTS_COLLECTION = "products";
41
+
42
+ /**
43
+ * Interface for the ProductService class
44
+ */
45
+ export interface IProductService {
46
+ /**
47
+ * Creates a new product
48
+ * @param technologyId - ID of the technology this product is used with
49
+ * @param brandId - ID of the brand that manufactures this product
50
+ * @param product - Product data
51
+ */
52
+ create(
53
+ technologyId: string,
54
+ brandId: string,
55
+ product: Omit<
56
+ Product,
57
+ "id" | "createdAt" | "updatedAt" | "brandId" | "technologyId"
58
+ >
59
+ ): Promise<Product>;
60
+
61
+ /**
62
+ * Gets all products for a technology
63
+ * @param technologyId - ID of the technology
64
+ */
65
+ getAllByTechnology(technologyId: string): Promise<Product[]>;
66
+
67
+ /**
68
+ * Gets all products for a brand
69
+ * @param brandId - ID of the brand
70
+ */
71
+ getAllByBrand(brandId: string): Promise<Product[]>;
72
+
73
+ /**
74
+ * Updates a product
75
+ * @param technologyId - ID of the technology
76
+ * @param productId - ID of the product to update
77
+ * @param product - Updated product data
78
+ */
79
+ update(
80
+ technologyId: string,
81
+ productId: string,
82
+ product: Partial<
83
+ Omit<Product, "id" | "createdAt" | "brandId" | "technologyId">
84
+ >
85
+ ): Promise<Product | null>;
86
+
87
+ /**
88
+ * Deletes a product (soft delete)
89
+ * @param technologyId - ID of the technology
90
+ * @param productId - ID of the product to delete
91
+ */
92
+ delete(technologyId: string, productId: string): Promise<void>;
93
+
94
+ /**
95
+ * Gets a product by ID
96
+ * @param technologyId - ID of the technology
97
+ * @param productId - ID of the product
98
+ */
99
+ getById(technologyId: string, productId: string): Promise<Product | null>;
100
+ }
@@ -39,58 +39,28 @@ export interface TechnologyRequirements {
39
39
  * @property updatedAt - Last update date
40
40
  */
41
41
  export interface Technology {
42
- /** Jedinstveni identifikator tehnologije (automatski generisan od strane Firestore) */
43
42
  id?: string;
44
- /** Naziv tehnologije */
45
43
  name: string;
46
-
47
- /** Detaljan opis tehnologije */
48
44
  description: string;
49
-
50
- /** Familija procedura kojoj tehnologija pripada */
51
45
  family: ProcedureFamily;
52
-
53
- /** ID kategorije kojoj tehnologija pripada */
54
46
  categoryId: string;
55
-
56
- /** ID potkategorije kojoj tehnologija pripada */
57
47
  subcategoryId: string;
58
-
59
- /** Tehnički detalji i specifikacije */
60
48
  technicalDetails?: string;
61
-
62
- /** Zahtevi pre i posle tretmana */
63
49
  requirements: {
64
50
  pre: Requirement[];
65
51
  post: Requirement[];
66
52
  };
67
-
68
- /** Apsolutne kontraindikacije koje sprečavaju tretman */
69
53
  blockingConditions: BlockingCondition[];
70
-
71
- /** Relativne kontraindikacije koje zahtevaju posebnu pažnju */
72
54
  contraindications: Contraindication[];
73
-
74
- /** Očekivane dobrobiti tretmana */
75
55
  benefits: TreatmentBenefit[];
76
-
77
- /** Potrebna sertifikacija za korišćenje tehnologije */
78
56
  certificationRequirement: CertificationRequirement;
79
-
80
- /** Dokumentacioni šabloni potrebni za ovu tehnologiju */
81
57
  documentationTemplates?: DocumentTemplate[];
82
-
83
- /** Da li je tehnologija trenutno aktivna */
84
58
  isActive: boolean;
85
-
86
- /** Datum kreiranja */
87
59
  createdAt: Date;
88
-
89
- /** Datum poslednjeg ažuriranja */
90
60
  updatedAt: Date;
91
61
  }
92
62
 
93
63
  /**
94
- * Kolekcija u Firestore bazi gde se čuvaju tehnologije
64
+ * Collection in Firestore database where technologies are stored
95
65
  */
96
66
  export const TECHNOLOGIES_COLLECTION = "technologies";
@@ -94,8 +94,6 @@ export class ProcedureService extends BaseService {
94
94
  ),
95
95
  this.technologyService.getById(validatedData.technologyId),
96
96
  this.productService.getById(
97
- validatedData.categoryId,
98
- validatedData.subcategoryId,
99
97
  validatedData.technologyId,
100
98
  validatedData.productId
101
99
  ),