@blackcode_sa/metaestetics-api 1.5.12 → 1.5.14
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/backoffice/index.d.mts +268 -218
- package/dist/backoffice/index.d.ts +268 -218
- package/dist/backoffice/index.js +88 -65
- package/dist/backoffice/index.mjs +88 -66
- package/dist/index.d.mts +117 -63
- package/dist/index.d.ts +117 -63
- package/dist/index.js +102 -69
- package/dist/index.mjs +102 -70
- package/package.json +1 -1
- package/src/backoffice/services/brand.service.ts +33 -10
- package/src/backoffice/services/product.service.ts +69 -88
- package/src/backoffice/types/product.types.ts +77 -17
- package/src/backoffice/types/technology.types.ts +1 -31
- package/src/services/practitioner/practitioner.service.ts +16 -2
- package/src/services/procedure/procedure.service.ts +0 -2
|
@@ -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 {
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
38
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
this.getProductsRefByTechnology(categoryId, subcategoryId, technologyId),
|
|
55
|
+
const productRef = await addDoc(
|
|
56
|
+
this.getProductsRef(technologyId),
|
|
64
57
|
newProduct
|
|
65
58
|
);
|
|
66
59
|
|
|
67
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
) {
|
|
63
|
+
/**
|
|
64
|
+
* Gets all products for a technology
|
|
65
|
+
*/
|
|
66
|
+
async getAllByTechnology(technologyId: string): Promise<Product[]> {
|
|
84
67
|
const q = query(
|
|
85
|
-
this.
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
);
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
128
|
-
|
|
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(
|
|
129
|
+
return this.getById(technologyId, productId);
|
|
145
130
|
}
|
|
146
131
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
productId
|
|
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
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Product used in procedures
|
|
3
|
+
* Can be consumables, equipment, or any other product needed for performing procedures
|
|
4
4
|
*
|
|
5
|
-
* @property id -
|
|
6
|
-
* @property name -
|
|
7
|
-
* @property description -
|
|
8
|
-
* @property brandId - ID
|
|
9
|
-
* @property technologyId - ID
|
|
10
|
-
* @property technicalDetails -
|
|
11
|
-
* @property warnings -
|
|
12
|
-
* @property dosage -
|
|
13
|
-
* @property composition -
|
|
14
|
-
* @property indications -
|
|
15
|
-
* @property contraindications -
|
|
16
|
-
* @property isActive -
|
|
17
|
-
* @property createdAt -
|
|
18
|
-
* @property updatedAt -
|
|
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
|
-
*
|
|
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
|
-
*
|
|
64
|
+
* Collection in Firestore database where technologies are stored
|
|
95
65
|
*/
|
|
96
66
|
export const TECHNOLOGIES_COLLECTION = "technologies";
|
|
@@ -443,7 +443,7 @@ export class PractitionerService extends BaseService {
|
|
|
443
443
|
}
|
|
444
444
|
|
|
445
445
|
/**
|
|
446
|
-
* Dohvata sve zdravstvene radnike za određenu kliniku
|
|
446
|
+
* Dohvata sve zdravstvene radnike za određenu kliniku sa statusom ACTIVE
|
|
447
447
|
*/
|
|
448
448
|
async getPractitionersByClinic(clinicId: string): Promise<Practitioner[]> {
|
|
449
449
|
const q = query(
|
|
@@ -458,7 +458,21 @@ export class PractitionerService extends BaseService {
|
|
|
458
458
|
}
|
|
459
459
|
|
|
460
460
|
/**
|
|
461
|
-
* Dohvata sve
|
|
461
|
+
* Dohvata sve zdravstvene radnike za određenu kliniku
|
|
462
|
+
*/
|
|
463
|
+
async getAllPractitionersByClinic(clinicId: string): Promise<Practitioner[]> {
|
|
464
|
+
const q = query(
|
|
465
|
+
collection(this.db, PRACTITIONERS_COLLECTION),
|
|
466
|
+
where("clinics", "array-contains", clinicId),
|
|
467
|
+
where("isActive", "==", true)
|
|
468
|
+
);
|
|
469
|
+
|
|
470
|
+
const querySnapshot = await getDocs(q);
|
|
471
|
+
return querySnapshot.docs.map((doc) => doc.data() as Practitioner);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Dohvata sve draft zdravstvene radnike za određenu kliniku sa statusom DRAFT
|
|
462
476
|
*/
|
|
463
477
|
async getDraftPractitionersByClinic(
|
|
464
478
|
clinicId: string
|
|
@@ -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
|
),
|