@blackcode_sa/metaestetics-api 1.7.47 → 1.8.1
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/admin/index.d.mts +1815 -1667
- package/dist/admin/index.d.ts +1815 -1667
- package/dist/admin/index.js +6993 -6535
- package/dist/admin/index.mjs +6991 -6532
- package/dist/backoffice/index.d.mts +1418 -1418
- package/dist/backoffice/index.d.ts +1418 -1418
- package/dist/backoffice/index.js +1464 -1454
- package/dist/backoffice/index.mjs +1509 -1499
- package/dist/index.d.mts +16217 -14582
- package/dist/index.d.ts +16217 -14582
- package/dist/index.js +11419 -13806
- package/dist/index.mjs +12081 -14593
- package/package.json +5 -5
- package/src/admin/aggregation/appointment/index.ts +1 -0
- package/src/admin/aggregation/clinic/index.ts +1 -0
- package/src/admin/aggregation/forms/index.ts +1 -0
- package/src/admin/aggregation/index.ts +8 -0
- package/src/admin/aggregation/patient/index.ts +1 -0
- package/src/admin/aggregation/practitioner/index.ts +1 -0
- package/src/admin/aggregation/practitioner-invite/index.ts +1 -0
- package/src/admin/aggregation/procedure/index.ts +1 -0
- package/src/admin/aggregation/reviews/index.ts +1 -0
- package/src/admin/booking/index.ts +1 -1
- package/src/admin/calendar/index.ts +1 -0
- package/src/admin/documentation-templates/index.ts +1 -0
- package/src/admin/free-consultation/index.ts +1 -0
- package/src/admin/index.ts +23 -118
- package/src/admin/mailing/appointment/index.ts +1 -0
- package/src/admin/mailing/index.ts +1 -2
- package/src/admin/mailing/practitionerInvite/index.ts +1 -0
- package/src/admin/notifications/index.ts +1 -0
- package/src/admin/requirements/index.ts +1 -0
- package/src/admin/users/index.ts +1 -0
- package/src/admin/users/user-profile.admin.ts +1 -0
- package/src/backoffice/constants/index.ts +1 -0
- package/src/backoffice/errors/index.ts +1 -0
- package/src/backoffice/index.ts +5 -14
- package/src/backoffice/services/index.ts +7 -0
- package/src/backoffice/validations/index.ts +1 -0
- package/src/index.backup.ts +407 -0
- package/src/index.ts +5 -406
- package/src/services/PATIENTAUTH.MD +197 -0
- package/src/services/__tests__/auth/auth.setup.ts +2 -2
- package/src/services/__tests__/auth.service.test.ts +1 -1
- package/src/services/__tests__/user.service.test.ts +1 -1
- package/src/services/appointment/index.ts +1 -2
- package/src/services/{auth.service.ts → auth/auth.service.ts} +36 -22
- package/src/services/{auth.v2.service.ts → auth/auth.v2.service.ts} +17 -17
- package/src/services/auth/index.ts +2 -16
- package/src/services/calendar/calendar-refactored.service.ts +1 -1
- package/src/services/calendar/index.ts +5 -0
- package/src/services/clinic/index.ts +4 -0
- package/src/services/index.ts +12 -0
- package/src/services/media/index.ts +1 -0
- package/src/services/notifications/index.ts +1 -0
- package/src/services/patient/README.md +48 -0
- package/src/services/patient/To-Do.md +43 -0
- package/src/services/patient/index.ts +2 -0
- package/src/services/patient/patient.service.ts +289 -34
- package/src/services/patient/utils/index.ts +9 -0
- package/src/services/patient/utils/medical.utils.ts +114 -157
- package/src/services/patient/utils/profile.utils.ts +9 -0
- package/src/services/patient/utils/sensitive.utils.ts +79 -14
- package/src/services/patient/utils/token.utils.ts +211 -0
- package/src/services/practitioner/index.ts +1 -0
- package/src/services/procedure/index.ts +1 -0
- package/src/services/reviews/index.ts +1 -0
- package/src/services/user/index.ts +1 -0
- package/src/services/{user.service.ts → user/user.service.ts} +61 -12
- package/src/services/{user.v2.service.ts → user/user.v2.service.ts} +12 -12
- package/src/types/index.ts +42 -42
- package/src/types/patient/index.ts +33 -6
- package/src/types/patient/token.types.ts +61 -0
- package/src/types/user/index.ts +38 -0
- package/src/utils/index.ts +1 -0
- package/src/validations/calendar.schema.ts +6 -45
- package/src/validations/documentation-templates/index.ts +1 -0
- package/src/validations/documentation-templates.schema.ts +1 -1
- package/src/validations/index.ts +20 -0
- package/src/validations/patient/token.schema.ts +29 -0
- package/src/validations/patient.schema.ts +23 -6
- package/src/validations/profile-info.schema.ts +1 -1
- package/src/validations/schemas.ts +24 -24
package/dist/backoffice/index.js
CHANGED
|
@@ -32,7 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
CircularReferenceError: () => CircularReferenceError,
|
|
33
33
|
Contraindication: () => Contraindication,
|
|
34
34
|
ContraindicationError: () => ContraindicationError,
|
|
35
|
-
DEFAULT_CERTIFICATION_REQUIREMENT: () =>
|
|
35
|
+
DEFAULT_CERTIFICATION_REQUIREMENT: () => DEFAULT_CERTIFICATION_REQUIREMENT2,
|
|
36
36
|
DocumentElementType: () => DocumentElementType,
|
|
37
37
|
DocumentationTemplateService: () => DocumentationTemplateService2,
|
|
38
38
|
DynamicVariable: () => DynamicVariable,
|
|
@@ -90,371 +90,310 @@ __export(index_exports, {
|
|
|
90
90
|
});
|
|
91
91
|
module.exports = __toCommonJS(index_exports);
|
|
92
92
|
|
|
93
|
+
// src/backoffice/services/brand.service.ts
|
|
94
|
+
var import_firestore = require("firebase/firestore");
|
|
95
|
+
|
|
93
96
|
// src/backoffice/types/brand.types.ts
|
|
94
97
|
var BRANDS_COLLECTION = "brands";
|
|
95
98
|
|
|
96
|
-
// src/
|
|
97
|
-
var
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
TimeUnit2["HOURS"] = "hours";
|
|
105
|
-
TimeUnit2["DAYS"] = "days";
|
|
106
|
-
return TimeUnit2;
|
|
107
|
-
})(TimeUnit || {});
|
|
108
|
-
var RequirementType = /* @__PURE__ */ ((RequirementType3) => {
|
|
109
|
-
RequirementType3["PRE"] = "pre";
|
|
110
|
-
RequirementType3["POST"] = "post";
|
|
111
|
-
return RequirementType3;
|
|
112
|
-
})(RequirementType || {});
|
|
113
|
-
var REQUIREMENTS_COLLECTION = "backoffice_requirements";
|
|
114
|
-
|
|
115
|
-
// src/backoffice/types/subcategory.types.ts
|
|
116
|
-
var SUBCATEGORIES_COLLECTION = "subcategories";
|
|
117
|
-
|
|
118
|
-
// src/backoffice/types/technology.types.ts
|
|
119
|
-
var TECHNOLOGIES_COLLECTION = "technologies";
|
|
120
|
-
|
|
121
|
-
// src/backoffice/types/static/blocking-condition.types.ts
|
|
122
|
-
var BlockingCondition = /* @__PURE__ */ ((BlockingCondition2) => {
|
|
123
|
-
BlockingCondition2["PREGNANCY"] = "pregnancy";
|
|
124
|
-
BlockingCondition2["BREASTFEEDING"] = "breastfeeding";
|
|
125
|
-
BlockingCondition2["ACTIVE_INFECTION"] = "active_infection";
|
|
126
|
-
BlockingCondition2["SKIN_CONDITION"] = "skin_condition";
|
|
127
|
-
BlockingCondition2["AUTOIMMUNE_DISEASE"] = "autoimmune_disease";
|
|
128
|
-
BlockingCondition2["BLOOD_THINNERS"] = "blood_thinners";
|
|
129
|
-
BlockingCondition2["RECENT_SURGERY"] = "recent_surgery";
|
|
130
|
-
BlockingCondition2["DIABETES"] = "diabetes";
|
|
131
|
-
BlockingCondition2["HEART_CONDITION"] = "heart_condition";
|
|
132
|
-
BlockingCondition2["HIGH_BLOOD_PRESSURE"] = "high_blood_pressure";
|
|
133
|
-
BlockingCondition2["KELOID_SCARRING"] = "keloid_scarring";
|
|
134
|
-
BlockingCondition2["METAL_IMPLANTS"] = "metal_implants";
|
|
135
|
-
BlockingCondition2["PACEMAKER"] = "pacemaker";
|
|
136
|
-
BlockingCondition2["CANCER"] = "cancer";
|
|
137
|
-
BlockingCondition2["EPILEPSY"] = "epilepsy";
|
|
138
|
-
return BlockingCondition2;
|
|
139
|
-
})(BlockingCondition || {});
|
|
140
|
-
|
|
141
|
-
// src/backoffice/types/static/certification.types.ts
|
|
142
|
-
var CertificationLevel = /* @__PURE__ */ ((CertificationLevel2) => {
|
|
143
|
-
CertificationLevel2["AESTHETICIAN"] = "aesthetician";
|
|
144
|
-
CertificationLevel2["NURSE_ASSISTANT"] = "nurse_assistant";
|
|
145
|
-
CertificationLevel2["NURSE"] = "nurse";
|
|
146
|
-
CertificationLevel2["NURSE_PRACTITIONER"] = "nurse_practitioner";
|
|
147
|
-
CertificationLevel2["PHYSICIAN_ASSISTANT"] = "physician_assistant";
|
|
148
|
-
CertificationLevel2["DOCTOR"] = "doctor";
|
|
149
|
-
CertificationLevel2["SPECIALIST"] = "specialist";
|
|
150
|
-
CertificationLevel2["PLASTIC_SURGEON"] = "plastic_surgeon";
|
|
151
|
-
return CertificationLevel2;
|
|
152
|
-
})(CertificationLevel || {});
|
|
153
|
-
var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
|
|
154
|
-
CertificationSpecialty3["LASER"] = "laser";
|
|
155
|
-
CertificationSpecialty3["INJECTABLES"] = "injectables";
|
|
156
|
-
CertificationSpecialty3["CHEMICAL_PEELS"] = "chemical_peels";
|
|
157
|
-
CertificationSpecialty3["MICRODERMABRASION"] = "microdermabrasion";
|
|
158
|
-
CertificationSpecialty3["BODY_CONTOURING"] = "body_contouring";
|
|
159
|
-
CertificationSpecialty3["SKIN_CARE"] = "skin_care";
|
|
160
|
-
CertificationSpecialty3["WOUND_CARE"] = "wound_care";
|
|
161
|
-
CertificationSpecialty3["ANESTHESIA"] = "anesthesia";
|
|
162
|
-
return CertificationSpecialty3;
|
|
163
|
-
})(CertificationSpecialty || {});
|
|
164
|
-
|
|
165
|
-
// src/backoffice/types/static/contraindication.types.ts
|
|
166
|
-
var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
167
|
-
Contraindication2["SENSITIVE_SKIN"] = "sensitive_skin";
|
|
168
|
-
Contraindication2["RECENT_TANNING"] = "recent_tanning";
|
|
169
|
-
Contraindication2["RECENT_BOTOX"] = "recent_botox";
|
|
170
|
-
Contraindication2["RECENT_FILLERS"] = "recent_fillers";
|
|
171
|
-
Contraindication2["SKIN_ALLERGIES"] = "skin_allergies";
|
|
172
|
-
Contraindication2["MEDICATIONS"] = "medications";
|
|
173
|
-
Contraindication2["RECENT_CHEMICAL_PEEL"] = "recent_chemical_peel";
|
|
174
|
-
Contraindication2["RECENT_LASER"] = "recent_laser";
|
|
175
|
-
Contraindication2["SKIN_INFLAMMATION"] = "skin_inflammation";
|
|
176
|
-
Contraindication2["OPEN_WOUNDS"] = "open_wounds";
|
|
177
|
-
Contraindication2["HERPES_SIMPLEX"] = "herpes_simplex";
|
|
178
|
-
Contraindication2["COLD_SORES"] = "cold_sores";
|
|
179
|
-
return Contraindication2;
|
|
180
|
-
})(Contraindication || {});
|
|
181
|
-
|
|
182
|
-
// src/backoffice/types/static/procedure-family.types.ts
|
|
183
|
-
var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
|
|
184
|
-
ProcedureFamily2["AESTHETICS"] = "aesthetics";
|
|
185
|
-
ProcedureFamily2["SURGERY"] = "surgery";
|
|
186
|
-
return ProcedureFamily2;
|
|
187
|
-
})(ProcedureFamily || {});
|
|
188
|
-
|
|
189
|
-
// src/backoffice/types/static/treatment-benefit.types.ts
|
|
190
|
-
var TreatmentBenefit = /* @__PURE__ */ ((TreatmentBenefit2) => {
|
|
191
|
-
TreatmentBenefit2["WRINKLE_REDUCTION"] = "wrinkle_reduction";
|
|
192
|
-
TreatmentBenefit2["SKIN_TIGHTENING"] = "skin_tightening";
|
|
193
|
-
TreatmentBenefit2["COLLAGEN_PRODUCTION"] = "collagen_production";
|
|
194
|
-
TreatmentBenefit2["ACNE_REDUCTION"] = "acne_reduction";
|
|
195
|
-
TreatmentBenefit2["SCAR_REDUCTION"] = "scar_reduction";
|
|
196
|
-
TreatmentBenefit2["PIGMENTATION_IMPROVEMENT"] = "pigmentation_improvement";
|
|
197
|
-
TreatmentBenefit2["HAIR_REMOVAL"] = "hair_removal";
|
|
198
|
-
TreatmentBenefit2["MUSCLE_TONING"] = "muscle_toning";
|
|
199
|
-
TreatmentBenefit2["FAT_REDUCTION"] = "fat_reduction";
|
|
200
|
-
TreatmentBenefit2["CELLULITE_REDUCTION"] = "cellulite_reduction";
|
|
201
|
-
TreatmentBenefit2["SKIN_REJUVENATION"] = "skin_rejuvenation";
|
|
202
|
-
TreatmentBenefit2["PORE_REDUCTION"] = "pore_reduction";
|
|
203
|
-
TreatmentBenefit2["TEXTURE_IMPROVEMENT"] = "texture_improvement";
|
|
204
|
-
TreatmentBenefit2["HYDRATION_BOOST"] = "hydration_boost";
|
|
205
|
-
TreatmentBenefit2["CIRCULATION_IMPROVEMENT"] = "circulation_improvement";
|
|
206
|
-
return TreatmentBenefit2;
|
|
207
|
-
})(TreatmentBenefit || {});
|
|
208
|
-
|
|
209
|
-
// src/types/documentation-templates/index.ts
|
|
210
|
-
var DOCUMENTATION_TEMPLATES_COLLECTION = "documentation-templates";
|
|
211
|
-
var DocumentElementType = /* @__PURE__ */ ((DocumentElementType2) => {
|
|
212
|
-
DocumentElementType2["HEADING"] = "heading";
|
|
213
|
-
DocumentElementType2["PARAGRAPH"] = "paragraph";
|
|
214
|
-
DocumentElementType2["LIST"] = "list";
|
|
215
|
-
DocumentElementType2["DYNAMIC_TEXT"] = "dynamic_text";
|
|
216
|
-
DocumentElementType2["BINARY_CHOICE"] = "binary_choice";
|
|
217
|
-
DocumentElementType2["MULTIPLE_CHOICE"] = "multiple_choice";
|
|
218
|
-
DocumentElementType2["SINGLE_CHOICE"] = "single_choice";
|
|
219
|
-
DocumentElementType2["RATING_SCALE"] = "rating_scale";
|
|
220
|
-
DocumentElementType2["TEXT_INPUT"] = "text_input";
|
|
221
|
-
DocumentElementType2["DATE_PICKER"] = "date_picker";
|
|
222
|
-
DocumentElementType2["SIGNATURE"] = "signature";
|
|
223
|
-
DocumentElementType2["DITIGAL_SIGNATURE"] = "digital_signature";
|
|
224
|
-
DocumentElementType2["FILE_UPLOAD"] = "file_upload";
|
|
225
|
-
return DocumentElementType2;
|
|
226
|
-
})(DocumentElementType || {});
|
|
227
|
-
var ListType = /* @__PURE__ */ ((ListType2) => {
|
|
228
|
-
ListType2["ORDERED"] = "ordered";
|
|
229
|
-
ListType2["UNORDERED"] = "unordered";
|
|
230
|
-
return ListType2;
|
|
231
|
-
})(ListType || {});
|
|
232
|
-
var HeadingLevel = /* @__PURE__ */ ((HeadingLevel2) => {
|
|
233
|
-
HeadingLevel2["H1"] = "h1";
|
|
234
|
-
HeadingLevel2["H2"] = "h2";
|
|
235
|
-
HeadingLevel2["H3"] = "h3";
|
|
236
|
-
HeadingLevel2["H4"] = "h4";
|
|
237
|
-
HeadingLevel2["H5"] = "h5";
|
|
238
|
-
HeadingLevel2["H6"] = "h6";
|
|
239
|
-
return HeadingLevel2;
|
|
240
|
-
})(HeadingLevel || {});
|
|
241
|
-
var DynamicVariable = /* @__PURE__ */ ((DynamicVariable2) => {
|
|
242
|
-
DynamicVariable2["PATIENT_NAME"] = "$[PATIENT_NAME]";
|
|
243
|
-
DynamicVariable2["DOCTOR_NAME"] = "$[DOCTOR_NAME]";
|
|
244
|
-
DynamicVariable2["CLINIC_NAME"] = "$[CLINIC_NAME]";
|
|
245
|
-
DynamicVariable2["PATIENT_BIRTHDAY"] = "$[PATIENT_BIRTHDAY]";
|
|
246
|
-
DynamicVariable2["APPOINTMENT_DATE"] = "$[APPOINTMENT_DATE]";
|
|
247
|
-
DynamicVariable2["CURRENT_DATE"] = "$[CURRENT_DATE]";
|
|
248
|
-
DynamicVariable2["PROCEDURE_NAME"] = "$[PROCEDURE_NAME]";
|
|
249
|
-
DynamicVariable2["PROCEDURE_DESCRIPTION"] = "$[PROCEDURE_DESCRIPTION]";
|
|
250
|
-
DynamicVariable2["PROCEDURE_COST"] = "$[PROCEDURE_COST]";
|
|
251
|
-
DynamicVariable2["PROCEDURE_DURATION"] = "$[PROCEDURE_DURATION]";
|
|
252
|
-
DynamicVariable2["PROCEDURE_RISK"] = "$[PROCEDURE_RISK]";
|
|
253
|
-
return DynamicVariable2;
|
|
254
|
-
})(DynamicVariable || {});
|
|
255
|
-
var FilledDocumentStatus = /* @__PURE__ */ ((FilledDocumentStatus2) => {
|
|
256
|
-
FilledDocumentStatus2["DRAFT"] = "draft";
|
|
257
|
-
FilledDocumentStatus2["SKIPPED"] = "skipped";
|
|
258
|
-
FilledDocumentStatus2["PENDING"] = "pending";
|
|
259
|
-
FilledDocumentStatus2["COMPLETED"] = "completed";
|
|
260
|
-
FilledDocumentStatus2["SIGNED"] = "signed";
|
|
261
|
-
FilledDocumentStatus2["REJECTED"] = "rejected";
|
|
262
|
-
return FilledDocumentStatus2;
|
|
263
|
-
})(FilledDocumentStatus || {});
|
|
264
|
-
|
|
265
|
-
// src/backoffice/constants/certification.constants.ts
|
|
266
|
-
var DEFAULT_CERTIFICATION_REQUIREMENT = {
|
|
267
|
-
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
268
|
-
requiredSpecialties: []
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
// src/backoffice/errors/backoffice.errors.ts
|
|
272
|
-
var BackofficeError = class extends Error {
|
|
273
|
-
constructor(message) {
|
|
274
|
-
super(message);
|
|
275
|
-
this.name = "BackofficeError";
|
|
99
|
+
// src/services/base.service.ts
|
|
100
|
+
var import_storage = require("firebase/storage");
|
|
101
|
+
var BaseService = class {
|
|
102
|
+
constructor(db, auth, app) {
|
|
103
|
+
this.db = db;
|
|
104
|
+
this.auth = auth;
|
|
105
|
+
this.app = app;
|
|
106
|
+
this.storage = (0, import_storage.getStorage)(app);
|
|
276
107
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Generiše jedinstveni ID za dokumente
|
|
110
|
+
* Format: xxxxxxxxxxxx-timestamp
|
|
111
|
+
* Gde je x random karakter (broj ili slovo)
|
|
112
|
+
*/
|
|
113
|
+
generateId() {
|
|
114
|
+
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
115
|
+
const timestamp = Date.now().toString(36);
|
|
116
|
+
const randomPart = Array.from(
|
|
117
|
+
{ length: 12 },
|
|
118
|
+
() => chars.charAt(Math.floor(Math.random() * chars.length))
|
|
119
|
+
).join("");
|
|
120
|
+
return `${randomPart}-${timestamp}`;
|
|
282
121
|
}
|
|
283
122
|
};
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
123
|
+
|
|
124
|
+
// src/backoffice/services/brand.service.ts
|
|
125
|
+
var BrandService = class extends BaseService {
|
|
126
|
+
/**
|
|
127
|
+
* Gets reference to brands collection
|
|
128
|
+
*/
|
|
129
|
+
getBrandsRef() {
|
|
130
|
+
return (0, import_firestore.collection)(this.db, BRANDS_COLLECTION);
|
|
288
131
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Creates a new brand
|
|
134
|
+
*/
|
|
135
|
+
async create(brand) {
|
|
136
|
+
const now = /* @__PURE__ */ new Date();
|
|
137
|
+
const newBrand = {
|
|
138
|
+
...brand,
|
|
139
|
+
createdAt: now,
|
|
140
|
+
updatedAt: now,
|
|
141
|
+
isActive: true
|
|
142
|
+
};
|
|
143
|
+
const docRef = await (0, import_firestore.addDoc)(this.getBrandsRef(), newBrand);
|
|
144
|
+
return { id: docRef.id, ...newBrand };
|
|
294
145
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
this.
|
|
146
|
+
/**
|
|
147
|
+
* Gets all active brands
|
|
148
|
+
*/
|
|
149
|
+
async getAll() {
|
|
150
|
+
const q = (0, import_firestore.query)(this.getBrandsRef(), (0, import_firestore.where)("isActive", "==", true));
|
|
151
|
+
const snapshot = await (0, import_firestore.getDocs)(q);
|
|
152
|
+
return snapshot.docs.map(
|
|
153
|
+
(doc10) => ({
|
|
154
|
+
id: doc10.id,
|
|
155
|
+
...doc10.data()
|
|
156
|
+
})
|
|
157
|
+
);
|
|
300
158
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
this.
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
var TechnologyError = class extends BackofficeError {
|
|
315
|
-
constructor(message) {
|
|
316
|
-
super(message);
|
|
317
|
-
this.name = "TechnologyError";
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
var TechnologyNotFoundError = class extends TechnologyError {
|
|
321
|
-
constructor(id) {
|
|
322
|
-
super(`Tehnologija sa ID-em ${id} nije prona\u0111ena`);
|
|
323
|
-
this.name = "TechnologyNotFoundError";
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
var InvalidTechnologyDataError = class extends TechnologyError {
|
|
327
|
-
constructor(message) {
|
|
328
|
-
super(`Neva\u017Ee\u0107i podaci za tehnologiju: ${message}`);
|
|
329
|
-
this.name = "InvalidTechnologyDataError";
|
|
330
|
-
}
|
|
331
|
-
};
|
|
332
|
-
var RequirementError = class extends BackofficeError {
|
|
333
|
-
constructor(message) {
|
|
334
|
-
super(message);
|
|
335
|
-
this.name = "RequirementError";
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
var RequirementNotFoundError = class extends RequirementError {
|
|
339
|
-
constructor(id) {
|
|
340
|
-
super(`Zahtev sa ID-em ${id} nije prona\u0111en`);
|
|
341
|
-
this.name = "RequirementNotFoundError";
|
|
342
|
-
}
|
|
343
|
-
};
|
|
344
|
-
var InvalidRequirementDataError = class extends RequirementError {
|
|
345
|
-
constructor(message) {
|
|
346
|
-
super(`Neva\u017Ee\u0107i podaci za zahtev: ${message}`);
|
|
347
|
-
this.name = "InvalidRequirementDataError";
|
|
348
|
-
}
|
|
349
|
-
};
|
|
350
|
-
var InvalidTimeframeError = class extends RequirementError {
|
|
351
|
-
constructor(message) {
|
|
352
|
-
super(`Invalid timeframe: ${message}`);
|
|
353
|
-
this.name = "InvalidTimeframeError";
|
|
159
|
+
/**
|
|
160
|
+
* Updates a brand
|
|
161
|
+
*/
|
|
162
|
+
async update(brandId, brand) {
|
|
163
|
+
const updateData = {
|
|
164
|
+
...brand,
|
|
165
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
166
|
+
};
|
|
167
|
+
const docRef = (0, import_firestore.doc)(this.getBrandsRef(), brandId);
|
|
168
|
+
await (0, import_firestore.updateDoc)(docRef, updateData);
|
|
169
|
+
return this.getById(brandId);
|
|
354
170
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
this.
|
|
171
|
+
/**
|
|
172
|
+
* Soft deletes a brand
|
|
173
|
+
*/
|
|
174
|
+
async delete(brandId) {
|
|
175
|
+
await this.update(brandId, {
|
|
176
|
+
isActive: false
|
|
177
|
+
});
|
|
360
178
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
this.
|
|
179
|
+
/**
|
|
180
|
+
* Gets a brand by ID
|
|
181
|
+
*/
|
|
182
|
+
async getById(brandId) {
|
|
183
|
+
const docRef = (0, import_firestore.doc)(this.getBrandsRef(), brandId);
|
|
184
|
+
const docSnap = await (0, import_firestore.getDoc)(docRef);
|
|
185
|
+
if (!docSnap.exists()) return null;
|
|
186
|
+
return {
|
|
187
|
+
id: docSnap.id,
|
|
188
|
+
...docSnap.data()
|
|
189
|
+
};
|
|
366
190
|
}
|
|
367
191
|
};
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
192
|
+
|
|
193
|
+
// src/backoffice/services/category.service.ts
|
|
194
|
+
var import_firestore2 = require("firebase/firestore");
|
|
195
|
+
|
|
196
|
+
// src/backoffice/types/category.types.ts
|
|
197
|
+
var CATEGORIES_COLLECTION = "backoffice_categories";
|
|
198
|
+
|
|
199
|
+
// src/backoffice/services/category.service.ts
|
|
200
|
+
var CategoryService = class extends BaseService {
|
|
201
|
+
/**
|
|
202
|
+
* Referenca na Firestore kolekciju kategorija
|
|
203
|
+
*/
|
|
204
|
+
get categoriesRef() {
|
|
205
|
+
return (0, import_firestore2.collection)(this.db, CATEGORIES_COLLECTION);
|
|
372
206
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
207
|
+
/**
|
|
208
|
+
* Kreira novu kategoriju u sistemu
|
|
209
|
+
* @param category - Podaci za novu kategoriju
|
|
210
|
+
* @returns Kreirana kategorija sa generisanim ID-em
|
|
211
|
+
*/
|
|
212
|
+
async create(category) {
|
|
213
|
+
const now = /* @__PURE__ */ new Date();
|
|
214
|
+
const newCategory = {
|
|
215
|
+
...category,
|
|
216
|
+
createdAt: now,
|
|
217
|
+
updatedAt: now,
|
|
218
|
+
isActive: true
|
|
219
|
+
};
|
|
220
|
+
const docRef = await (0, import_firestore2.addDoc)(this.categoriesRef, newCategory);
|
|
221
|
+
return { id: docRef.id, ...newCategory };
|
|
378
222
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
223
|
+
/**
|
|
224
|
+
* Vraća sve aktivne kategorije
|
|
225
|
+
* @returns Lista aktivnih kategorija
|
|
226
|
+
*/
|
|
227
|
+
async getAll() {
|
|
228
|
+
const q = (0, import_firestore2.query)(this.categoriesRef, (0, import_firestore2.where)("isActive", "==", true));
|
|
229
|
+
const snapshot = await (0, import_firestore2.getDocs)(q);
|
|
230
|
+
return snapshot.docs.map(
|
|
231
|
+
(doc10) => ({
|
|
232
|
+
id: doc10.id,
|
|
233
|
+
...doc10.data()
|
|
234
|
+
})
|
|
235
|
+
);
|
|
384
236
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
237
|
+
/**
|
|
238
|
+
* Vraća sve aktivne kategorije za određenu familiju procedura
|
|
239
|
+
* @param family - Familija procedura (aesthetics/surgery)
|
|
240
|
+
* @returns Lista kategorija koje pripadaju traženoj familiji
|
|
241
|
+
*/
|
|
242
|
+
async getAllByFamily(family) {
|
|
243
|
+
const q = (0, import_firestore2.query)(
|
|
244
|
+
this.categoriesRef,
|
|
245
|
+
(0, import_firestore2.where)("family", "==", family),
|
|
246
|
+
(0, import_firestore2.where)("isActive", "==", true)
|
|
247
|
+
);
|
|
248
|
+
const snapshot = await (0, import_firestore2.getDocs)(q);
|
|
249
|
+
return snapshot.docs.map(
|
|
250
|
+
(doc10) => ({
|
|
251
|
+
id: doc10.id,
|
|
252
|
+
...doc10.data()
|
|
253
|
+
})
|
|
254
|
+
);
|
|
390
255
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
256
|
+
/**
|
|
257
|
+
* Ažurira postojeću kategoriju
|
|
258
|
+
* @param id - ID kategorije koja se ažurira
|
|
259
|
+
* @param category - Novi podaci za kategoriju
|
|
260
|
+
* @returns Ažurirana kategorija
|
|
261
|
+
*/
|
|
262
|
+
async update(id, category) {
|
|
263
|
+
const updateData = {
|
|
264
|
+
...category,
|
|
265
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
266
|
+
};
|
|
267
|
+
const docRef = (0, import_firestore2.doc)(this.categoriesRef, id);
|
|
268
|
+
await (0, import_firestore2.updateDoc)(docRef, updateData);
|
|
269
|
+
return this.getById(id);
|
|
396
270
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
271
|
+
/**
|
|
272
|
+
* Soft delete kategorije (postavlja isActive na false)
|
|
273
|
+
* @param id - ID kategorije koja se briše
|
|
274
|
+
*/
|
|
275
|
+
async delete(id) {
|
|
276
|
+
await this.update(id, { isActive: false });
|
|
402
277
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
278
|
+
/**
|
|
279
|
+
* Vraća kategoriju po ID-u
|
|
280
|
+
* @param id - ID tražene kategorije
|
|
281
|
+
* @returns Kategorija ili null ako ne postoji
|
|
282
|
+
*/
|
|
283
|
+
async getById(id) {
|
|
284
|
+
const docRef = (0, import_firestore2.doc)(this.categoriesRef, id);
|
|
285
|
+
const docSnap = await (0, import_firestore2.getDoc)(docRef);
|
|
286
|
+
if (!docSnap.exists()) return null;
|
|
287
|
+
return {
|
|
288
|
+
id: docSnap.id,
|
|
289
|
+
...docSnap.data()
|
|
290
|
+
};
|
|
408
291
|
}
|
|
409
292
|
};
|
|
410
293
|
|
|
411
|
-
// src/
|
|
412
|
-
var
|
|
294
|
+
// src/services/documentation-templates/documentation-template.service.ts
|
|
295
|
+
var import_firestore3 = require("firebase/firestore");
|
|
413
296
|
|
|
414
|
-
// src/
|
|
415
|
-
var
|
|
416
|
-
var
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
297
|
+
// src/types/documentation-templates/index.ts
|
|
298
|
+
var DOCUMENTATION_TEMPLATES_COLLECTION = "documentation-templates";
|
|
299
|
+
var DocumentElementType = /* @__PURE__ */ ((DocumentElementType2) => {
|
|
300
|
+
DocumentElementType2["HEADING"] = "heading";
|
|
301
|
+
DocumentElementType2["PARAGRAPH"] = "paragraph";
|
|
302
|
+
DocumentElementType2["LIST"] = "list";
|
|
303
|
+
DocumentElementType2["DYNAMIC_TEXT"] = "dynamic_text";
|
|
304
|
+
DocumentElementType2["BINARY_CHOICE"] = "binary_choice";
|
|
305
|
+
DocumentElementType2["MULTIPLE_CHOICE"] = "multiple_choice";
|
|
306
|
+
DocumentElementType2["SINGLE_CHOICE"] = "single_choice";
|
|
307
|
+
DocumentElementType2["RATING_SCALE"] = "rating_scale";
|
|
308
|
+
DocumentElementType2["TEXT_INPUT"] = "text_input";
|
|
309
|
+
DocumentElementType2["DATE_PICKER"] = "date_picker";
|
|
310
|
+
DocumentElementType2["SIGNATURE"] = "signature";
|
|
311
|
+
DocumentElementType2["DITIGAL_SIGNATURE"] = "digital_signature";
|
|
312
|
+
DocumentElementType2["FILE_UPLOAD"] = "file_upload";
|
|
313
|
+
return DocumentElementType2;
|
|
314
|
+
})(DocumentElementType || {});
|
|
315
|
+
var ListType = /* @__PURE__ */ ((ListType2) => {
|
|
316
|
+
ListType2["ORDERED"] = "ordered";
|
|
317
|
+
ListType2["UNORDERED"] = "unordered";
|
|
318
|
+
return ListType2;
|
|
319
|
+
})(ListType || {});
|
|
320
|
+
var HeadingLevel = /* @__PURE__ */ ((HeadingLevel2) => {
|
|
321
|
+
HeadingLevel2["H1"] = "h1";
|
|
322
|
+
HeadingLevel2["H2"] = "h2";
|
|
323
|
+
HeadingLevel2["H3"] = "h3";
|
|
324
|
+
HeadingLevel2["H4"] = "h4";
|
|
325
|
+
HeadingLevel2["H5"] = "h5";
|
|
326
|
+
HeadingLevel2["H6"] = "h6";
|
|
327
|
+
return HeadingLevel2;
|
|
328
|
+
})(HeadingLevel || {});
|
|
329
|
+
var DynamicVariable = /* @__PURE__ */ ((DynamicVariable2) => {
|
|
330
|
+
DynamicVariable2["PATIENT_NAME"] = "$[PATIENT_NAME]";
|
|
331
|
+
DynamicVariable2["DOCTOR_NAME"] = "$[DOCTOR_NAME]";
|
|
332
|
+
DynamicVariable2["CLINIC_NAME"] = "$[CLINIC_NAME]";
|
|
333
|
+
DynamicVariable2["PATIENT_BIRTHDAY"] = "$[PATIENT_BIRTHDAY]";
|
|
334
|
+
DynamicVariable2["APPOINTMENT_DATE"] = "$[APPOINTMENT_DATE]";
|
|
335
|
+
DynamicVariable2["CURRENT_DATE"] = "$[CURRENT_DATE]";
|
|
336
|
+
DynamicVariable2["PROCEDURE_NAME"] = "$[PROCEDURE_NAME]";
|
|
337
|
+
DynamicVariable2["PROCEDURE_DESCRIPTION"] = "$[PROCEDURE_DESCRIPTION]";
|
|
338
|
+
DynamicVariable2["PROCEDURE_COST"] = "$[PROCEDURE_COST]";
|
|
339
|
+
DynamicVariable2["PROCEDURE_DURATION"] = "$[PROCEDURE_DURATION]";
|
|
340
|
+
DynamicVariable2["PROCEDURE_RISK"] = "$[PROCEDURE_RISK]";
|
|
341
|
+
return DynamicVariable2;
|
|
342
|
+
})(DynamicVariable || {});
|
|
343
|
+
var FilledDocumentStatus = /* @__PURE__ */ ((FilledDocumentStatus2) => {
|
|
344
|
+
FilledDocumentStatus2["DRAFT"] = "draft";
|
|
345
|
+
FilledDocumentStatus2["SKIPPED"] = "skipped";
|
|
346
|
+
FilledDocumentStatus2["PENDING"] = "pending";
|
|
347
|
+
FilledDocumentStatus2["COMPLETED"] = "completed";
|
|
348
|
+
FilledDocumentStatus2["SIGNED"] = "signed";
|
|
349
|
+
FilledDocumentStatus2["REJECTED"] = "rejected";
|
|
350
|
+
return FilledDocumentStatus2;
|
|
351
|
+
})(FilledDocumentStatus || {});
|
|
352
|
+
|
|
353
|
+
// src/validations/documentation-templates/template.schema.ts
|
|
354
|
+
var import_zod = require("zod");
|
|
355
|
+
var baseElementSchema = import_zod.z.object({
|
|
356
|
+
id: import_zod.z.string().optional(),
|
|
357
|
+
// Make id optional so we can omit it later
|
|
358
|
+
type: import_zod.z.nativeEnum(DocumentElementType),
|
|
359
|
+
required: import_zod.z.boolean().optional()
|
|
360
|
+
});
|
|
361
|
+
var headingElementSchema = baseElementSchema.extend({
|
|
362
|
+
type: import_zod.z.literal("heading" /* HEADING */),
|
|
363
|
+
text: import_zod.z.string().min(1).max(200),
|
|
364
|
+
level: import_zod.z.nativeEnum(HeadingLevel)
|
|
365
|
+
});
|
|
366
|
+
var paragraphElementSchema = baseElementSchema.extend({
|
|
367
|
+
type: import_zod.z.literal("paragraph" /* PARAGRAPH */),
|
|
368
|
+
text: import_zod.z.string().min(1).max(5e3)
|
|
369
|
+
});
|
|
370
|
+
var listElementSchema = baseElementSchema.extend({
|
|
371
|
+
type: import_zod.z.literal("list" /* LIST */),
|
|
372
|
+
items: import_zod.z.array(import_zod.z.string().min(1).max(500)).min(1).max(100),
|
|
373
|
+
listType: import_zod.z.nativeEnum(ListType)
|
|
374
|
+
});
|
|
375
|
+
var dynamicTextElementSchema = baseElementSchema.extend({
|
|
376
|
+
type: import_zod.z.literal("dynamic_text" /* DYNAMIC_TEXT */),
|
|
377
|
+
text: import_zod.z.string().min(1).max(5e3)
|
|
378
|
+
});
|
|
379
|
+
var binaryChoiceElementSchema = baseElementSchema.extend({
|
|
380
|
+
type: import_zod.z.literal("binary_choice" /* BINARY_CHOICE */),
|
|
381
|
+
question: import_zod.z.string().min(1).max(500),
|
|
382
|
+
defaultValue: import_zod.z.boolean().optional()
|
|
383
|
+
});
|
|
384
|
+
var multipleChoiceElementSchema = baseElementSchema.extend({
|
|
385
|
+
type: import_zod.z.literal("multiple_choice" /* MULTIPLE_CHOICE */),
|
|
386
|
+
question: import_zod.z.string().min(1).max(500),
|
|
387
|
+
options: import_zod.z.array(import_zod.z.string().min(1).max(200)).min(2).max(50),
|
|
388
|
+
defaultValues: import_zod.z.array(import_zod.z.string()).optional()
|
|
389
|
+
});
|
|
390
|
+
var singleChoiceElementSchema = baseElementSchema.extend({
|
|
391
|
+
type: import_zod.z.literal("single_choice" /* SINGLE_CHOICE */),
|
|
392
|
+
question: import_zod.z.string().min(1).max(500),
|
|
393
|
+
options: import_zod.z.array(import_zod.z.string().min(1).max(200)).min(2).max(50),
|
|
394
|
+
defaultValue: import_zod.z.string().optional()
|
|
395
|
+
});
|
|
396
|
+
var ratingScaleElementSchema = baseElementSchema.extend({
|
|
458
397
|
type: import_zod.z.literal("rating_scale" /* RATING_SCALE */),
|
|
459
398
|
question: import_zod.z.string().min(1).max(500),
|
|
460
399
|
min: import_zod.z.number().int().min(0).max(10),
|
|
@@ -585,392 +524,440 @@ var updateFilledDocumentDataSchema = import_zod.z.object({
|
|
|
585
524
|
status: filledDocumentStatusSchema.optional()
|
|
586
525
|
});
|
|
587
526
|
|
|
588
|
-
// src/
|
|
589
|
-
var
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
var certificationSpecialtySchema = import_zod2.z.nativeEnum(
|
|
597
|
-
CertificationSpecialty
|
|
598
|
-
);
|
|
599
|
-
var certificationRequirementSchema = import_zod2.z.object({
|
|
600
|
-
minimumLevel: certificationLevelSchema,
|
|
601
|
-
requiredSpecialties: import_zod2.z.array(certificationSpecialtySchema).max(5, "Maximum 5 specialties allowed").optional()
|
|
602
|
-
});
|
|
603
|
-
var timeframeSchema = import_zod2.z.object({
|
|
604
|
-
duration: import_zod2.z.number().min(1, "Duration must be positive"),
|
|
605
|
-
unit: timeUnitSchema,
|
|
606
|
-
notifyAt: import_zod2.z.array(import_zod2.z.number()).min(1, "At least one notification point is required")
|
|
607
|
-
});
|
|
608
|
-
var requirementSchema = import_zod2.z.object({
|
|
609
|
-
name: import_zod2.z.string().min(1, "Name is required").max(100, "Name is too long"),
|
|
610
|
-
description: import_zod2.z.string().min(1, "Description is required"),
|
|
611
|
-
type: requirementTypeSchema,
|
|
612
|
-
timeframe: timeframeSchema,
|
|
613
|
-
importance: import_zod2.z.enum(["low", "medium", "high"]),
|
|
614
|
-
isActive: import_zod2.z.boolean().default(true)
|
|
615
|
-
});
|
|
616
|
-
var technologyRequirementsSchema = import_zod2.z.object({
|
|
617
|
-
pre: import_zod2.z.array(requirementSchema),
|
|
618
|
-
post: import_zod2.z.array(requirementSchema)
|
|
619
|
-
});
|
|
620
|
-
var technologySchema = import_zod2.z.object({
|
|
621
|
-
name: import_zod2.z.string().min(1, "Name is required").max(100, "Name is too long"),
|
|
622
|
-
description: import_zod2.z.string().max(1e3, "Description is too long").optional(),
|
|
623
|
-
technicalDetails: import_zod2.z.string().max(2e3, "Technical details are too long").optional(),
|
|
624
|
-
family: procedureFamilySchema,
|
|
625
|
-
categoryId: import_zod2.z.string().min(1, "Category ID is required"),
|
|
626
|
-
subcategoryId: import_zod2.z.string().min(1, "Subcategory ID is required"),
|
|
627
|
-
requirements: technologyRequirementsSchema.default({
|
|
628
|
-
pre: [],
|
|
629
|
-
post: []
|
|
630
|
-
}),
|
|
631
|
-
blockingConditions: import_zod2.z.array(blockingConditionSchema),
|
|
632
|
-
contraindications: import_zod2.z.array(contraindicationSchema),
|
|
633
|
-
documentationTemplates: import_zod2.z.array(documentTemplateSchema),
|
|
634
|
-
benefits: import_zod2.z.array(treatmentBenefitSchema),
|
|
635
|
-
certificationRequirement: certificationRequirementSchema,
|
|
636
|
-
isActive: import_zod2.z.boolean().default(true)
|
|
637
|
-
});
|
|
638
|
-
var categorySchema = import_zod2.z.object({
|
|
639
|
-
name: import_zod2.z.string().min(1, "Name is required").max(100, "Name is too long"),
|
|
640
|
-
description: import_zod2.z.string().optional(),
|
|
641
|
-
family: procedureFamilySchema,
|
|
642
|
-
isActive: import_zod2.z.boolean().default(true)
|
|
643
|
-
});
|
|
644
|
-
var subcategorySchema = import_zod2.z.object({
|
|
645
|
-
name: import_zod2.z.string().min(1, "Name is required").max(100, "Name is too long"),
|
|
646
|
-
description: import_zod2.z.string().optional(),
|
|
647
|
-
categoryId: import_zod2.z.string().min(1, "Category ID is required"),
|
|
648
|
-
isActive: import_zod2.z.boolean().default(true)
|
|
649
|
-
});
|
|
650
|
-
var categoryUpdateSchema = categorySchema.partial();
|
|
651
|
-
var subcategoryUpdateSchema = subcategorySchema.partial();
|
|
652
|
-
var technologyUpdateSchema = technologySchema.partial();
|
|
653
|
-
var requirementUpdateSchema = requirementSchema.partial();
|
|
654
|
-
|
|
655
|
-
// src/backoffice/services/category.service.ts
|
|
656
|
-
var import_firestore = require("firebase/firestore");
|
|
657
|
-
|
|
658
|
-
// src/services/base.service.ts
|
|
659
|
-
var import_storage = require("firebase/storage");
|
|
660
|
-
var BaseService = class {
|
|
661
|
-
constructor(db, auth, app) {
|
|
662
|
-
this.db = db;
|
|
663
|
-
this.auth = auth;
|
|
664
|
-
this.app = app;
|
|
665
|
-
this.storage = (0, import_storage.getStorage)(app);
|
|
666
|
-
}
|
|
667
|
-
/**
|
|
668
|
-
* Generiše jedinstveni ID za dokumente
|
|
669
|
-
* Format: xxxxxxxxxxxx-timestamp
|
|
670
|
-
* Gde je x random karakter (broj ili slovo)
|
|
671
|
-
*/
|
|
672
|
-
generateId() {
|
|
673
|
-
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
674
|
-
const timestamp = Date.now().toString(36);
|
|
675
|
-
const randomPart = Array.from(
|
|
676
|
-
{ length: 12 },
|
|
677
|
-
() => chars.charAt(Math.floor(Math.random() * chars.length))
|
|
678
|
-
).join("");
|
|
679
|
-
return `${randomPart}-${timestamp}`;
|
|
680
|
-
}
|
|
681
|
-
};
|
|
682
|
-
|
|
683
|
-
// src/backoffice/services/category.service.ts
|
|
684
|
-
var CategoryService = class extends BaseService {
|
|
685
|
-
/**
|
|
686
|
-
* Referenca na Firestore kolekciju kategorija
|
|
687
|
-
*/
|
|
688
|
-
get categoriesRef() {
|
|
689
|
-
return (0, import_firestore.collection)(this.db, CATEGORIES_COLLECTION);
|
|
527
|
+
// src/services/documentation-templates/documentation-template.service.ts
|
|
528
|
+
var DocumentationTemplateService = class extends BaseService {
|
|
529
|
+
constructor() {
|
|
530
|
+
super(...arguments);
|
|
531
|
+
this.collectionRef = (0, import_firestore3.collection)(
|
|
532
|
+
this.db,
|
|
533
|
+
DOCUMENTATION_TEMPLATES_COLLECTION
|
|
534
|
+
);
|
|
690
535
|
}
|
|
691
536
|
/**
|
|
692
|
-
*
|
|
693
|
-
* @param
|
|
694
|
-
* @
|
|
537
|
+
* Create a new document template
|
|
538
|
+
* @param data - Template data
|
|
539
|
+
* @param userId - ID of the user creating the template
|
|
540
|
+
* @returns The created template
|
|
695
541
|
*/
|
|
696
|
-
async
|
|
697
|
-
const
|
|
698
|
-
const
|
|
699
|
-
|
|
542
|
+
async createTemplate(data, userId) {
|
|
543
|
+
const validatedData = createDocumentTemplateSchema.parse(data);
|
|
544
|
+
const templateId = this.generateId();
|
|
545
|
+
const elementsWithIds = validatedData.elements.map((element) => ({
|
|
546
|
+
...element,
|
|
547
|
+
id: this.generateId()
|
|
548
|
+
}));
|
|
549
|
+
const now = Date.now();
|
|
550
|
+
const template = {
|
|
551
|
+
id: templateId,
|
|
552
|
+
title: validatedData.title,
|
|
553
|
+
description: validatedData.description,
|
|
554
|
+
elements: elementsWithIds,
|
|
700
555
|
createdAt: now,
|
|
701
556
|
updatedAt: now,
|
|
702
|
-
|
|
557
|
+
createdBy: userId,
|
|
558
|
+
version: 1,
|
|
559
|
+
isActive: true,
|
|
560
|
+
tags: validatedData.tags || [],
|
|
561
|
+
isUserForm: validatedData.isUserForm || false,
|
|
562
|
+
isRequired: validatedData.isRequired || false,
|
|
563
|
+
sortingOrder: validatedData.sortingOrder || 0
|
|
703
564
|
};
|
|
704
|
-
const docRef =
|
|
705
|
-
|
|
565
|
+
const docRef = (0, import_firestore3.doc)(this.collectionRef, templateId);
|
|
566
|
+
await (0, import_firestore3.setDoc)(docRef, template);
|
|
567
|
+
return template;
|
|
706
568
|
}
|
|
707
569
|
/**
|
|
708
|
-
*
|
|
709
|
-
* @
|
|
570
|
+
* Get a document template by ID
|
|
571
|
+
* @param templateId - ID of the template to retrieve
|
|
572
|
+
* @param version - Optional version number to retrieve (defaults to latest version)
|
|
573
|
+
* @returns The template or null if not found
|
|
710
574
|
*/
|
|
711
|
-
async
|
|
712
|
-
const
|
|
713
|
-
const
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
575
|
+
async getTemplateById(templateId, version) {
|
|
576
|
+
const docRef = (0, import_firestore3.doc)(this.collectionRef, templateId);
|
|
577
|
+
const docSnap = await (0, import_firestore3.getDoc)(docRef);
|
|
578
|
+
if (!docSnap.exists()) {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
const currentTemplate = docSnap.data();
|
|
582
|
+
if (version === void 0) {
|
|
583
|
+
return currentTemplate;
|
|
584
|
+
}
|
|
585
|
+
if (currentTemplate.version === version) {
|
|
586
|
+
return currentTemplate;
|
|
587
|
+
}
|
|
588
|
+
try {
|
|
589
|
+
const versionTemplate = await this.getTemplateVersion(
|
|
590
|
+
templateId,
|
|
591
|
+
version
|
|
592
|
+
);
|
|
593
|
+
if (versionTemplate) {
|
|
594
|
+
return versionTemplate;
|
|
595
|
+
}
|
|
596
|
+
} catch (error) {
|
|
597
|
+
console.error(`Error getting template version ${version}:`, error);
|
|
598
|
+
}
|
|
599
|
+
return null;
|
|
720
600
|
}
|
|
721
601
|
/**
|
|
722
|
-
*
|
|
723
|
-
* @param
|
|
724
|
-
* @
|
|
602
|
+
* Update an existing document template
|
|
603
|
+
* @param templateId - ID of the template to update
|
|
604
|
+
* @param data - Updated template data
|
|
605
|
+
* @returns The updated template
|
|
725
606
|
*/
|
|
726
|
-
async
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
607
|
+
async updateTemplate(templateId, data) {
|
|
608
|
+
var _a, _b, _c;
|
|
609
|
+
const validatedData = updateDocumentTemplateSchema.parse(data);
|
|
610
|
+
console.log("Validated data", validatedData);
|
|
611
|
+
const template = await this.getTemplateById(templateId);
|
|
612
|
+
if (!template) {
|
|
613
|
+
throw new Error(`Template with ID ${templateId} not found`);
|
|
614
|
+
}
|
|
615
|
+
const versionsCollectionRef = (0, import_firestore3.collection)(
|
|
616
|
+
this.db,
|
|
617
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
731
618
|
);
|
|
732
|
-
const
|
|
733
|
-
|
|
734
|
-
(
|
|
735
|
-
id: doc10.id,
|
|
736
|
-
...doc10.data()
|
|
737
|
-
})
|
|
619
|
+
const versionDocRef = (0, import_firestore3.doc)(
|
|
620
|
+
versionsCollectionRef,
|
|
621
|
+
template.version.toString()
|
|
738
622
|
);
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
updatedAt:
|
|
623
|
+
await (0, import_firestore3.setDoc)(versionDocRef, template);
|
|
624
|
+
let updatedElements = template.elements;
|
|
625
|
+
if (validatedData.elements) {
|
|
626
|
+
updatedElements = validatedData.elements.map((element) => ({
|
|
627
|
+
...element,
|
|
628
|
+
id: element.id || this.generateId()
|
|
629
|
+
}));
|
|
630
|
+
}
|
|
631
|
+
const updatePayload = {
|
|
632
|
+
elements: updatedElements,
|
|
633
|
+
updatedAt: Date.now(),
|
|
634
|
+
version: template.version + 1
|
|
750
635
|
};
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
636
|
+
if (validatedData.title !== void 0)
|
|
637
|
+
updatePayload.title = validatedData.title;
|
|
638
|
+
if (validatedData.description !== void 0)
|
|
639
|
+
updatePayload.description = validatedData.description;
|
|
640
|
+
if (validatedData.isActive !== void 0)
|
|
641
|
+
updatePayload.isActive = validatedData.isActive;
|
|
642
|
+
if (validatedData.tags !== void 0)
|
|
643
|
+
updatePayload.tags = validatedData.tags;
|
|
644
|
+
updatePayload.isUserForm = (_a = validatedData.isUserForm) != null ? _a : false;
|
|
645
|
+
updatePayload.isRequired = (_b = validatedData.isRequired) != null ? _b : false;
|
|
646
|
+
updatePayload.sortingOrder = (_c = validatedData.sortingOrder) != null ? _c : 0;
|
|
647
|
+
const docRef = (0, import_firestore3.doc)(this.collectionRef, templateId);
|
|
648
|
+
console.log("Update payload", updatePayload);
|
|
649
|
+
await (0, import_firestore3.updateDoc)(docRef, updatePayload);
|
|
650
|
+
return { ...template, ...updatePayload };
|
|
761
651
|
}
|
|
762
652
|
/**
|
|
763
|
-
*
|
|
764
|
-
* @param
|
|
765
|
-
* @
|
|
653
|
+
* Get a specific version of a template
|
|
654
|
+
* @param templateId - ID of the template
|
|
655
|
+
* @param versionNumber - Version number to retrieve
|
|
656
|
+
* @returns The template version or null if not found
|
|
766
657
|
*/
|
|
767
|
-
async
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
658
|
+
async getTemplateVersion(templateId, versionNumber) {
|
|
659
|
+
const versionDocRef = (0, import_firestore3.doc)(
|
|
660
|
+
this.db,
|
|
661
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions/${versionNumber}`
|
|
662
|
+
);
|
|
663
|
+
const versionDocSnap = await (0, import_firestore3.getDoc)(versionDocRef);
|
|
664
|
+
if (!versionDocSnap.exists()) {
|
|
665
|
+
return null;
|
|
666
|
+
}
|
|
667
|
+
return versionDocSnap.data();
|
|
775
668
|
}
|
|
776
|
-
};
|
|
777
|
-
|
|
778
|
-
// src/backoffice/services/subcategory.service.ts
|
|
779
|
-
var import_firestore2 = require("firebase/firestore");
|
|
780
|
-
var SubcategoryService = class extends BaseService {
|
|
781
669
|
/**
|
|
782
|
-
*
|
|
783
|
-
* @param
|
|
670
|
+
* Get all versions of a template
|
|
671
|
+
* @param templateId - ID of the template
|
|
672
|
+
* @returns Array of template versions
|
|
784
673
|
*/
|
|
785
|
-
|
|
786
|
-
|
|
674
|
+
async getTemplateOldVersions(templateId) {
|
|
675
|
+
const versionsCollectionRef = (0, import_firestore3.collection)(
|
|
787
676
|
this.db,
|
|
788
|
-
|
|
789
|
-
categoryId,
|
|
790
|
-
SUBCATEGORIES_COLLECTION
|
|
677
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
791
678
|
);
|
|
679
|
+
const q = (0, import_firestore3.query)(versionsCollectionRef, (0, import_firestore3.orderBy)("version", "desc"));
|
|
680
|
+
const querySnapshot = await (0, import_firestore3.getDocs)(q);
|
|
681
|
+
const versions = [];
|
|
682
|
+
querySnapshot.forEach((doc10) => {
|
|
683
|
+
versions.push(doc10.data());
|
|
684
|
+
});
|
|
685
|
+
return versions;
|
|
792
686
|
}
|
|
793
687
|
/**
|
|
794
|
-
*
|
|
795
|
-
* @param
|
|
796
|
-
* @param subcategory - Podaci za novu podkategoriju
|
|
797
|
-
* @returns Kreirana podkategorija sa generisanim ID-em
|
|
688
|
+
* Delete a document template
|
|
689
|
+
* @param templateId - ID of the template to delete
|
|
798
690
|
*/
|
|
799
|
-
async
|
|
800
|
-
const
|
|
801
|
-
|
|
802
|
-
...subcategory,
|
|
803
|
-
categoryId,
|
|
804
|
-
createdAt: now,
|
|
805
|
-
updatedAt: now,
|
|
806
|
-
isActive: true
|
|
807
|
-
};
|
|
808
|
-
const docRef = await (0, import_firestore2.addDoc)(
|
|
809
|
-
this.getSubcategoriesRef(categoryId),
|
|
810
|
-
newSubcategory
|
|
811
|
-
);
|
|
812
|
-
return { id: docRef.id, ...newSubcategory };
|
|
691
|
+
async deleteTemplate(templateId) {
|
|
692
|
+
const docRef = (0, import_firestore3.doc)(this.collectionRef, templateId);
|
|
693
|
+
await (0, import_firestore3.deleteDoc)(docRef);
|
|
813
694
|
}
|
|
814
695
|
/**
|
|
815
|
-
*
|
|
816
|
-
* @param
|
|
817
|
-
* @
|
|
696
|
+
* Get all active templates
|
|
697
|
+
* @param pageSize - Number of templates to retrieve
|
|
698
|
+
* @param lastDoc - Last document from previous page for pagination
|
|
699
|
+
* @returns Array of templates and the last document for pagination
|
|
818
700
|
*/
|
|
819
|
-
async
|
|
820
|
-
|
|
821
|
-
this.
|
|
822
|
-
(0,
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
return snapshot.docs.map(
|
|
826
|
-
(doc10) => ({
|
|
827
|
-
id: doc10.id,
|
|
828
|
-
...doc10.data()
|
|
829
|
-
})
|
|
701
|
+
async getActiveTemplates(pageSize = 20, lastDoc) {
|
|
702
|
+
let q = (0, import_firestore3.query)(
|
|
703
|
+
this.collectionRef,
|
|
704
|
+
(0, import_firestore3.where)("isActive", "==", true),
|
|
705
|
+
(0, import_firestore3.orderBy)("updatedAt", "desc"),
|
|
706
|
+
(0, import_firestore3.limit)(pageSize)
|
|
830
707
|
);
|
|
708
|
+
if (lastDoc) {
|
|
709
|
+
q = (0, import_firestore3.query)(q, (0, import_firestore3.startAfter)(lastDoc));
|
|
710
|
+
}
|
|
711
|
+
const querySnapshot = await (0, import_firestore3.getDocs)(q);
|
|
712
|
+
const templates = [];
|
|
713
|
+
let lastVisible = null;
|
|
714
|
+
querySnapshot.forEach((doc10) => {
|
|
715
|
+
templates.push(doc10.data());
|
|
716
|
+
lastVisible = doc10;
|
|
717
|
+
});
|
|
718
|
+
return {
|
|
719
|
+
templates,
|
|
720
|
+
lastDoc: lastVisible
|
|
721
|
+
};
|
|
831
722
|
}
|
|
832
723
|
/**
|
|
833
|
-
*
|
|
834
|
-
* @param
|
|
835
|
-
* @param
|
|
836
|
-
* @param
|
|
837
|
-
* @returns
|
|
724
|
+
* Get templates by tags
|
|
725
|
+
* @param tags - Tags to filter by
|
|
726
|
+
* @param pageSize - Number of templates to retrieve
|
|
727
|
+
* @param lastDoc - Last document from previous page for pagination
|
|
728
|
+
* @returns Array of templates and the last document for pagination
|
|
838
729
|
*/
|
|
839
|
-
async
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
730
|
+
async getTemplatesByTags(tags, pageSize = 20, lastDoc) {
|
|
731
|
+
let q = (0, import_firestore3.query)(
|
|
732
|
+
this.collectionRef,
|
|
733
|
+
(0, import_firestore3.where)("isActive", "==", true),
|
|
734
|
+
(0, import_firestore3.where)("tags", "array-contains-any", tags),
|
|
735
|
+
(0, import_firestore3.orderBy)("updatedAt", "desc"),
|
|
736
|
+
(0, import_firestore3.limit)(pageSize)
|
|
737
|
+
);
|
|
738
|
+
if (lastDoc) {
|
|
739
|
+
q = (0, import_firestore3.query)(q, (0, import_firestore3.startAfter)(lastDoc));
|
|
740
|
+
}
|
|
741
|
+
const querySnapshot = await (0, import_firestore3.getDocs)(q);
|
|
742
|
+
const templates = [];
|
|
743
|
+
let lastVisible = null;
|
|
744
|
+
querySnapshot.forEach((doc10) => {
|
|
745
|
+
templates.push(doc10.data());
|
|
746
|
+
lastVisible = doc10;
|
|
747
|
+
});
|
|
748
|
+
return {
|
|
749
|
+
templates,
|
|
750
|
+
lastDoc: lastVisible
|
|
843
751
|
};
|
|
844
|
-
const docRef = (0, import_firestore2.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
845
|
-
await (0, import_firestore2.updateDoc)(docRef, updateData);
|
|
846
|
-
return this.getById(categoryId, subcategoryId);
|
|
847
752
|
}
|
|
848
753
|
/**
|
|
849
|
-
*
|
|
850
|
-
* @param
|
|
851
|
-
* @param
|
|
754
|
+
* Get templates created by a specific user
|
|
755
|
+
* @param userId - ID of the user who created the templates
|
|
756
|
+
* @param pageSize - Number of templates to retrieve
|
|
757
|
+
* @param lastDoc - Last document from previous page for pagination
|
|
758
|
+
* @returns Array of templates and the last document for pagination
|
|
852
759
|
*/
|
|
853
|
-
async
|
|
854
|
-
|
|
760
|
+
async getTemplatesByCreator(userId, pageSize = 20, lastDoc) {
|
|
761
|
+
let q = (0, import_firestore3.query)(
|
|
762
|
+
this.collectionRef,
|
|
763
|
+
(0, import_firestore3.where)("createdBy", "==", userId),
|
|
764
|
+
(0, import_firestore3.orderBy)("updatedAt", "desc"),
|
|
765
|
+
(0, import_firestore3.limit)(pageSize)
|
|
766
|
+
);
|
|
767
|
+
if (lastDoc) {
|
|
768
|
+
q = (0, import_firestore3.query)(q, (0, import_firestore3.startAfter)(lastDoc));
|
|
769
|
+
}
|
|
770
|
+
const querySnapshot = await (0, import_firestore3.getDocs)(q);
|
|
771
|
+
const templates = [];
|
|
772
|
+
let lastVisible = null;
|
|
773
|
+
querySnapshot.forEach((doc10) => {
|
|
774
|
+
templates.push(doc10.data());
|
|
775
|
+
lastVisible = doc10;
|
|
776
|
+
});
|
|
777
|
+
return {
|
|
778
|
+
templates,
|
|
779
|
+
lastDoc: lastVisible
|
|
780
|
+
};
|
|
855
781
|
}
|
|
856
782
|
/**
|
|
857
|
-
*
|
|
858
|
-
* @param
|
|
859
|
-
* @
|
|
860
|
-
* @returns Podkategorija ili null ako ne postoji
|
|
783
|
+
* Get all templates for selection with optional filtering
|
|
784
|
+
* @param options - Filtering options
|
|
785
|
+
* @returns Array of templates
|
|
861
786
|
*/
|
|
862
|
-
async
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
787
|
+
async getAllTemplatesForSelection(options) {
|
|
788
|
+
let q = (0, import_firestore3.query)(
|
|
789
|
+
this.collectionRef,
|
|
790
|
+
(0, import_firestore3.where)("isActive", "==", true),
|
|
791
|
+
(0, import_firestore3.orderBy)("updatedAt", "desc")
|
|
792
|
+
);
|
|
793
|
+
if ((options == null ? void 0 : options.isUserForm) !== void 0) {
|
|
794
|
+
q = (0, import_firestore3.query)(q, (0, import_firestore3.where)("isUserForm", "==", options.isUserForm));
|
|
795
|
+
}
|
|
796
|
+
if ((options == null ? void 0 : options.isRequired) !== void 0) {
|
|
797
|
+
q = (0, import_firestore3.query)(q, (0, import_firestore3.where)("isRequired", "==", options.isRequired));
|
|
798
|
+
}
|
|
799
|
+
const querySnapshot = await (0, import_firestore3.getDocs)(q);
|
|
800
|
+
const templates = [];
|
|
801
|
+
querySnapshot.forEach((doc10) => {
|
|
802
|
+
templates.push(doc10.data());
|
|
803
|
+
});
|
|
804
|
+
return templates;
|
|
870
805
|
}
|
|
871
806
|
};
|
|
872
807
|
|
|
873
|
-
// src/
|
|
874
|
-
var
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
var
|
|
808
|
+
// src/services/documentation-templates/filled-document.service.ts
|
|
809
|
+
var import_firestore6 = require("firebase/firestore");
|
|
810
|
+
|
|
811
|
+
// src/services/media/media.service.ts
|
|
812
|
+
var import_firestore4 = require("firebase/firestore");
|
|
813
|
+
var import_storage2 = require("firebase/storage");
|
|
814
|
+
var import_firestore5 = require("firebase/firestore");
|
|
815
|
+
|
|
816
|
+
// src/backoffice/services/documentation-template.service.ts
|
|
817
|
+
var DocumentationTemplateService2 = class {
|
|
880
818
|
/**
|
|
881
|
-
*
|
|
819
|
+
* Constructor for DocumentationTemplateService
|
|
820
|
+
* @param db - Firestore instance
|
|
821
|
+
* @param auth - Firebase Auth instance
|
|
822
|
+
* @param app - Firebase App instance
|
|
882
823
|
*/
|
|
883
|
-
|
|
884
|
-
|
|
824
|
+
constructor(db, auth, app) {
|
|
825
|
+
this.apiService = new DocumentationTemplateService(db, auth, app);
|
|
885
826
|
}
|
|
886
827
|
/**
|
|
887
|
-
*
|
|
888
|
-
* @param
|
|
889
|
-
* @
|
|
828
|
+
* Create a new document template
|
|
829
|
+
* @param data - Template data
|
|
830
|
+
* @param userId - ID of the user creating the template
|
|
831
|
+
* @returns The created template
|
|
890
832
|
*/
|
|
891
|
-
async
|
|
892
|
-
|
|
893
|
-
const newTechnology = {
|
|
894
|
-
...technology,
|
|
895
|
-
createdAt: now,
|
|
896
|
-
updatedAt: now,
|
|
897
|
-
isActive: true,
|
|
898
|
-
requirements: technology.requirements || {
|
|
899
|
-
pre: [],
|
|
900
|
-
post: []
|
|
901
|
-
},
|
|
902
|
-
blockingConditions: technology.blockingConditions || [],
|
|
903
|
-
contraindications: technology.contraindications || [],
|
|
904
|
-
benefits: technology.benefits || [],
|
|
905
|
-
certificationRequirement: technology.certificationRequirement || DEFAULT_CERTIFICATION_REQUIREMENT2
|
|
906
|
-
};
|
|
907
|
-
const docRef = await (0, import_firestore3.addDoc)(this.getTechnologiesRef(), newTechnology);
|
|
908
|
-
return { id: docRef.id, ...newTechnology };
|
|
833
|
+
async createTemplate(data, userId) {
|
|
834
|
+
return this.apiService.createTemplate(data, userId);
|
|
909
835
|
}
|
|
910
836
|
/**
|
|
911
|
-
*
|
|
912
|
-
* @
|
|
837
|
+
* Get a document template by ID
|
|
838
|
+
* @param templateId - ID of the template to retrieve
|
|
839
|
+
* @param version - Optional version number to retrieve (defaults to latest version)
|
|
840
|
+
* @returns The template or null if not found
|
|
913
841
|
*/
|
|
914
|
-
async
|
|
915
|
-
|
|
916
|
-
const snapshot = await (0, import_firestore3.getDocs)(q);
|
|
917
|
-
return snapshot.docs.map(
|
|
918
|
-
(doc10) => ({
|
|
919
|
-
id: doc10.id,
|
|
920
|
-
...doc10.data()
|
|
921
|
-
})
|
|
922
|
-
);
|
|
842
|
+
async getTemplateById(templateId, version) {
|
|
843
|
+
return this.apiService.getTemplateById(templateId, version);
|
|
923
844
|
}
|
|
924
845
|
/**
|
|
925
|
-
*
|
|
926
|
-
* @param
|
|
927
|
-
* @
|
|
846
|
+
* Update an existing document template
|
|
847
|
+
* @param templateId - ID of the template to update
|
|
848
|
+
* @param data - Updated template data
|
|
849
|
+
* @returns The updated template
|
|
928
850
|
*/
|
|
929
|
-
async
|
|
930
|
-
|
|
931
|
-
this.getTechnologiesRef(),
|
|
932
|
-
(0, import_firestore3.where)("isActive", "==", true),
|
|
933
|
-
(0, import_firestore3.where)("family", "==", family)
|
|
934
|
-
);
|
|
935
|
-
const snapshot = await (0, import_firestore3.getDocs)(q);
|
|
936
|
-
return snapshot.docs.map(
|
|
937
|
-
(doc10) => ({
|
|
938
|
-
id: doc10.id,
|
|
939
|
-
...doc10.data()
|
|
940
|
-
})
|
|
941
|
-
);
|
|
851
|
+
async updateTemplate(templateId, data) {
|
|
852
|
+
return this.apiService.updateTemplate(templateId, data);
|
|
942
853
|
}
|
|
943
854
|
/**
|
|
944
|
-
*
|
|
945
|
-
* @param
|
|
946
|
-
* @returns Lista aktivnih tehnologija
|
|
855
|
+
* Delete a document template
|
|
856
|
+
* @param templateId - ID of the template to delete
|
|
947
857
|
*/
|
|
948
|
-
async
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
858
|
+
async deleteTemplate(templateId) {
|
|
859
|
+
return this.apiService.deleteTemplate(templateId);
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Get all active templates
|
|
863
|
+
* @param pageSize - Number of templates to retrieve
|
|
864
|
+
* @param lastDoc - Last document from previous page for pagination
|
|
865
|
+
* @returns Array of templates and the last document for pagination
|
|
866
|
+
*/
|
|
867
|
+
async getActiveTemplates(pageSize = 20, lastDoc) {
|
|
868
|
+
return this.apiService.getActiveTemplates(pageSize, lastDoc);
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Get templates by tags
|
|
872
|
+
* @param tags - Tags to filter by
|
|
873
|
+
* @param pageSize - Number of templates to retrieve
|
|
874
|
+
* @param lastDoc - Last document from previous page for pagination
|
|
875
|
+
* @returns Array of templates and the last document for pagination
|
|
876
|
+
*/
|
|
877
|
+
async getTemplatesByTags(tags, pageSize = 20, lastDoc) {
|
|
878
|
+
return this.apiService.getTemplatesByTags(tags, pageSize, lastDoc);
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Get templates created by a specific user
|
|
882
|
+
* @param userId - ID of the user who created the templates
|
|
883
|
+
* @param pageSize - Number of templates to retrieve
|
|
884
|
+
* @param lastDoc - Last document from previous page for pagination
|
|
885
|
+
* @returns Array of templates and the last document for pagination
|
|
886
|
+
*/
|
|
887
|
+
async getTemplatesByCreator(userId, pageSize = 20, lastDoc) {
|
|
888
|
+
return this.apiService.getTemplatesByCreator(userId, pageSize, lastDoc);
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Get a specific version of a template
|
|
892
|
+
* @param templateId - ID of the template
|
|
893
|
+
* @param versionNumber - Version number to retrieve
|
|
894
|
+
* @returns The template version or null if not found
|
|
895
|
+
*/
|
|
896
|
+
async getTemplateVersion(templateId, versionNumber) {
|
|
897
|
+
return this.apiService.getTemplateVersion(templateId, versionNumber);
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Get all versions of a template
|
|
901
|
+
* @param templateId - ID of the template
|
|
902
|
+
* @returns Array of template versions
|
|
903
|
+
*/
|
|
904
|
+
async getTemplateVersions(templateId) {
|
|
905
|
+
return this.apiService.getTemplateOldVersions(templateId);
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
|
|
909
|
+
// src/backoffice/services/product.service.ts
|
|
910
|
+
var import_firestore7 = require("firebase/firestore");
|
|
911
|
+
|
|
912
|
+
// src/backoffice/types/product.types.ts
|
|
913
|
+
var PRODUCTS_COLLECTION = "products";
|
|
914
|
+
|
|
915
|
+
// src/backoffice/types/technology.types.ts
|
|
916
|
+
var TECHNOLOGIES_COLLECTION = "technologies";
|
|
917
|
+
|
|
918
|
+
// src/backoffice/services/product.service.ts
|
|
919
|
+
var ProductService = class extends BaseService {
|
|
920
|
+
/**
|
|
921
|
+
* Gets reference to products collection under a technology
|
|
922
|
+
* @param technologyId - ID of the technology
|
|
923
|
+
* @returns Firestore collection reference
|
|
924
|
+
*/
|
|
925
|
+
getProductsRef(technologyId) {
|
|
926
|
+
return (0, import_firestore7.collection)(
|
|
927
|
+
this.db,
|
|
928
|
+
TECHNOLOGIES_COLLECTION,
|
|
929
|
+
technologyId,
|
|
930
|
+
PRODUCTS_COLLECTION
|
|
953
931
|
);
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Creates a new product under technology
|
|
935
|
+
*/
|
|
936
|
+
async create(technologyId, brandId, product) {
|
|
937
|
+
const now = /* @__PURE__ */ new Date();
|
|
938
|
+
const newProduct = {
|
|
939
|
+
...product,
|
|
940
|
+
brandId,
|
|
941
|
+
technologyId,
|
|
942
|
+
createdAt: now,
|
|
943
|
+
updatedAt: now,
|
|
944
|
+
isActive: true
|
|
945
|
+
};
|
|
946
|
+
const productRef = await (0, import_firestore7.addDoc)(
|
|
947
|
+
this.getProductsRef(technologyId),
|
|
948
|
+
newProduct
|
|
960
949
|
);
|
|
950
|
+
return { id: productRef.id, ...newProduct };
|
|
961
951
|
}
|
|
962
952
|
/**
|
|
963
|
-
*
|
|
964
|
-
* @param subcategoryId - ID podkategorije
|
|
965
|
-
* @returns Lista aktivnih tehnologija
|
|
953
|
+
* Gets all products for a technology
|
|
966
954
|
*/
|
|
967
|
-
async
|
|
968
|
-
const q = (0,
|
|
969
|
-
this.
|
|
970
|
-
(0,
|
|
971
|
-
(0, import_firestore3.where)("subcategoryId", "==", subcategoryId)
|
|
955
|
+
async getAllByTechnology(technologyId) {
|
|
956
|
+
const q = (0, import_firestore7.query)(
|
|
957
|
+
this.getProductsRef(technologyId),
|
|
958
|
+
(0, import_firestore7.where)("isActive", "==", true)
|
|
972
959
|
);
|
|
973
|
-
const snapshot = await (0,
|
|
960
|
+
const snapshot = await (0, import_firestore7.getDocs)(q);
|
|
974
961
|
return snapshot.docs.map(
|
|
975
962
|
(doc10) => ({
|
|
976
963
|
id: doc10.id,
|
|
@@ -979,348 +966,345 @@ var TechnologyService = class extends BaseService {
|
|
|
979
966
|
);
|
|
980
967
|
}
|
|
981
968
|
/**
|
|
982
|
-
*
|
|
983
|
-
* @param technologyId - ID tehnologije
|
|
984
|
-
* @param technology - Novi podaci za tehnologiju
|
|
985
|
-
* @returns Ažurirana tehnologija
|
|
969
|
+
* Gets all products for a brand by filtering through all technologies
|
|
986
970
|
*/
|
|
987
|
-
async
|
|
971
|
+
async getAllByBrand(brandId) {
|
|
972
|
+
const allTechnologiesRef = (0, import_firestore7.collection)(this.db, TECHNOLOGIES_COLLECTION);
|
|
973
|
+
const technologiesSnapshot = await (0, import_firestore7.getDocs)(allTechnologiesRef);
|
|
974
|
+
const products = [];
|
|
975
|
+
for (const techDoc of technologiesSnapshot.docs) {
|
|
976
|
+
const q = (0, import_firestore7.query)(
|
|
977
|
+
this.getProductsRef(techDoc.id),
|
|
978
|
+
(0, import_firestore7.where)("brandId", "==", brandId),
|
|
979
|
+
(0, import_firestore7.where)("isActive", "==", true)
|
|
980
|
+
);
|
|
981
|
+
const snapshot = await (0, import_firestore7.getDocs)(q);
|
|
982
|
+
products.push(
|
|
983
|
+
...snapshot.docs.map(
|
|
984
|
+
(doc10) => ({
|
|
985
|
+
id: doc10.id,
|
|
986
|
+
...doc10.data()
|
|
987
|
+
})
|
|
988
|
+
)
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
return products;
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Updates a product
|
|
995
|
+
*/
|
|
996
|
+
async update(technologyId, productId, product) {
|
|
988
997
|
const updateData = {
|
|
989
|
-
...
|
|
998
|
+
...product,
|
|
990
999
|
updatedAt: /* @__PURE__ */ new Date()
|
|
991
1000
|
};
|
|
992
|
-
const docRef = (0,
|
|
993
|
-
await (0,
|
|
994
|
-
return this.getById(technologyId);
|
|
1001
|
+
const docRef = (0, import_firestore7.doc)(this.getProductsRef(technologyId), productId);
|
|
1002
|
+
await (0, import_firestore7.updateDoc)(docRef, updateData);
|
|
1003
|
+
return this.getById(technologyId, productId);
|
|
995
1004
|
}
|
|
996
1005
|
/**
|
|
997
|
-
* Soft
|
|
998
|
-
* @param technologyId - ID tehnologije koja se briše
|
|
1006
|
+
* Soft deletes a product
|
|
999
1007
|
*/
|
|
1000
|
-
async delete(technologyId) {
|
|
1001
|
-
await this.update(technologyId, {
|
|
1008
|
+
async delete(technologyId, productId) {
|
|
1009
|
+
await this.update(technologyId, productId, {
|
|
1002
1010
|
isActive: false
|
|
1003
1011
|
});
|
|
1004
1012
|
}
|
|
1005
1013
|
/**
|
|
1006
|
-
*
|
|
1007
|
-
* @param technologyId - ID tražene tehnologije
|
|
1008
|
-
* @returns Tehnologija ili null ako ne postoji
|
|
1014
|
+
* Gets a product by ID
|
|
1009
1015
|
*/
|
|
1010
|
-
async getById(technologyId) {
|
|
1011
|
-
const docRef = (0,
|
|
1012
|
-
const docSnap = await (0,
|
|
1016
|
+
async getById(technologyId, productId) {
|
|
1017
|
+
const docRef = (0, import_firestore7.doc)(this.getProductsRef(technologyId), productId);
|
|
1018
|
+
const docSnap = await (0, import_firestore7.getDoc)(docRef);
|
|
1013
1019
|
if (!docSnap.exists()) return null;
|
|
1014
1020
|
return {
|
|
1015
1021
|
id: docSnap.id,
|
|
1016
1022
|
...docSnap.data()
|
|
1017
1023
|
};
|
|
1018
1024
|
}
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
// src/backoffice/services/requirement.service.ts
|
|
1028
|
+
var import_firestore8 = require("firebase/firestore");
|
|
1029
|
+
|
|
1030
|
+
// src/backoffice/types/requirement.types.ts
|
|
1031
|
+
var TimeUnit = /* @__PURE__ */ ((TimeUnit2) => {
|
|
1032
|
+
TimeUnit2["HOURS"] = "hours";
|
|
1033
|
+
TimeUnit2["DAYS"] = "days";
|
|
1034
|
+
return TimeUnit2;
|
|
1035
|
+
})(TimeUnit || {});
|
|
1036
|
+
var RequirementType = /* @__PURE__ */ ((RequirementType3) => {
|
|
1037
|
+
RequirementType3["PRE"] = "pre";
|
|
1038
|
+
RequirementType3["POST"] = "post";
|
|
1039
|
+
return RequirementType3;
|
|
1040
|
+
})(RequirementType || {});
|
|
1041
|
+
var REQUIREMENTS_COLLECTION = "backoffice_requirements";
|
|
1042
|
+
|
|
1043
|
+
// src/backoffice/services/requirement.service.ts
|
|
1044
|
+
var RequirementService = class extends BaseService {
|
|
1019
1045
|
/**
|
|
1020
|
-
*
|
|
1021
|
-
* @param technologyId - ID tehnologije
|
|
1022
|
-
* @param requirement - Zahtev koji se dodaje
|
|
1023
|
-
* @returns Ažurirana tehnologija sa novim zahtevom
|
|
1046
|
+
* Referenca na Firestore kolekciju zahteva
|
|
1024
1047
|
*/
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
1028
|
-
await (0, import_firestore3.updateDoc)(docRef, {
|
|
1029
|
-
[requirementType]: (0, import_firestore3.arrayUnion)(requirement),
|
|
1030
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
1031
|
-
});
|
|
1032
|
-
return this.getById(technologyId);
|
|
1048
|
+
get requirementsRef() {
|
|
1049
|
+
return (0, import_firestore8.collection)(this.db, REQUIREMENTS_COLLECTION);
|
|
1033
1050
|
}
|
|
1034
1051
|
/**
|
|
1035
|
-
*
|
|
1036
|
-
* @param
|
|
1037
|
-
* @
|
|
1038
|
-
* @returns Ažurirana tehnologija bez uklonjenog zahteva
|
|
1052
|
+
* Kreira novi globalni zahtev
|
|
1053
|
+
* @param requirement - Podaci za novi zahtev
|
|
1054
|
+
* @returns Kreirani zahtev sa generisanim ID-em
|
|
1039
1055
|
*/
|
|
1040
|
-
async
|
|
1041
|
-
const
|
|
1042
|
-
const
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
updatedAt:
|
|
1046
|
-
|
|
1047
|
-
|
|
1056
|
+
async create(requirement) {
|
|
1057
|
+
const now = /* @__PURE__ */ new Date();
|
|
1058
|
+
const newRequirement = {
|
|
1059
|
+
...requirement,
|
|
1060
|
+
createdAt: now,
|
|
1061
|
+
updatedAt: now,
|
|
1062
|
+
isActive: true
|
|
1063
|
+
};
|
|
1064
|
+
const docRef = await (0, import_firestore8.addDoc)(this.requirementsRef, newRequirement);
|
|
1065
|
+
return { id: docRef.id, ...newRequirement };
|
|
1048
1066
|
}
|
|
1049
1067
|
/**
|
|
1050
|
-
* Vraća sve zahteve
|
|
1051
|
-
* @
|
|
1052
|
-
* @param type - Opcioni filter za tip zahteva (pre/post)
|
|
1053
|
-
* @returns Lista zahteva
|
|
1068
|
+
* Vraća sve aktivne zahteve
|
|
1069
|
+
* @returns Lista aktivnih zahteva
|
|
1054
1070
|
*/
|
|
1055
|
-
async
|
|
1056
|
-
const
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1071
|
+
async getAll() {
|
|
1072
|
+
const q = (0, import_firestore8.query)(this.requirementsRef, (0, import_firestore8.where)("isActive", "==", true));
|
|
1073
|
+
const snapshot = await (0, import_firestore8.getDocs)(q);
|
|
1074
|
+
return snapshot.docs.map(
|
|
1075
|
+
(doc10) => ({
|
|
1076
|
+
id: doc10.id,
|
|
1077
|
+
...doc10.data()
|
|
1078
|
+
})
|
|
1079
|
+
);
|
|
1062
1080
|
}
|
|
1063
1081
|
/**
|
|
1064
|
-
*
|
|
1065
|
-
* @param
|
|
1066
|
-
* @
|
|
1067
|
-
* @param newRequirement - Novi zahtev koji zamenjuje stari
|
|
1068
|
-
* @returns Ažurirana tehnologija
|
|
1082
|
+
* Vraća sve aktivne zahteve određenog tipa
|
|
1083
|
+
* @param type - Tip zahteva (pre/post)
|
|
1084
|
+
* @returns Lista zahteva određenog tipa
|
|
1069
1085
|
*/
|
|
1070
|
-
async
|
|
1071
|
-
|
|
1072
|
-
|
|
1086
|
+
async getAllByType(type) {
|
|
1087
|
+
const q = (0, import_firestore8.query)(
|
|
1088
|
+
this.requirementsRef,
|
|
1089
|
+
(0, import_firestore8.where)("type", "==", type),
|
|
1090
|
+
(0, import_firestore8.where)("isActive", "==", true)
|
|
1091
|
+
);
|
|
1092
|
+
const snapshot = await (0, import_firestore8.getDocs)(q);
|
|
1093
|
+
return snapshot.docs.map(
|
|
1094
|
+
(doc10) => ({
|
|
1095
|
+
id: doc10.id,
|
|
1096
|
+
...doc10.data()
|
|
1097
|
+
})
|
|
1098
|
+
);
|
|
1073
1099
|
}
|
|
1074
1100
|
/**
|
|
1075
|
-
*
|
|
1076
|
-
* @param
|
|
1077
|
-
* @param
|
|
1078
|
-
* @returns
|
|
1101
|
+
* Ažurira postojeći zahtev
|
|
1102
|
+
* @param id - ID zahteva koji se ažurira
|
|
1103
|
+
* @param requirement - Novi podaci za zahtev
|
|
1104
|
+
* @returns Ažurirani zahtev
|
|
1079
1105
|
*/
|
|
1080
|
-
async
|
|
1081
|
-
const
|
|
1082
|
-
|
|
1083
|
-
blockingConditions: (0, import_firestore3.arrayUnion)(condition),
|
|
1106
|
+
async update(id, requirement) {
|
|
1107
|
+
const updateData = {
|
|
1108
|
+
...requirement,
|
|
1084
1109
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1110
|
+
};
|
|
1111
|
+
const docRef = (0, import_firestore8.doc)(this.requirementsRef, id);
|
|
1112
|
+
await (0, import_firestore8.updateDoc)(docRef, updateData);
|
|
1113
|
+
return this.getById(id);
|
|
1087
1114
|
}
|
|
1088
1115
|
/**
|
|
1089
|
-
*
|
|
1090
|
-
* @param
|
|
1091
|
-
* @param condition - Blokirajući uslov koji se uklanja
|
|
1092
|
-
* @returns Ažurirana tehnologija
|
|
1116
|
+
* Soft delete zahteva (postavlja isActive na false)
|
|
1117
|
+
* @param id - ID zahteva koji se briše
|
|
1093
1118
|
*/
|
|
1094
|
-
async
|
|
1095
|
-
|
|
1096
|
-
await (0, import_firestore3.updateDoc)(docRef, {
|
|
1097
|
-
blockingConditions: (0, import_firestore3.arrayRemove)(condition),
|
|
1098
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
1099
|
-
});
|
|
1100
|
-
return this.getById(technologyId);
|
|
1119
|
+
async delete(id) {
|
|
1120
|
+
await this.update(id, { isActive: false });
|
|
1101
1121
|
}
|
|
1102
1122
|
/**
|
|
1103
|
-
*
|
|
1104
|
-
* @param
|
|
1105
|
-
* @
|
|
1106
|
-
* @returns Ažurirana tehnologija
|
|
1123
|
+
* Vraća zahtev po ID-u
|
|
1124
|
+
* @param id - ID traženog zahteva
|
|
1125
|
+
* @returns Zahtev ili null ako ne postoji
|
|
1107
1126
|
*/
|
|
1108
|
-
async
|
|
1109
|
-
const docRef = (0,
|
|
1110
|
-
await (0,
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1127
|
+
async getById(id) {
|
|
1128
|
+
const docRef = (0, import_firestore8.doc)(this.requirementsRef, id);
|
|
1129
|
+
const docSnap = await (0, import_firestore8.getDoc)(docRef);
|
|
1130
|
+
if (!docSnap.exists()) return null;
|
|
1131
|
+
return {
|
|
1132
|
+
id: docSnap.id,
|
|
1133
|
+
...docSnap.data()
|
|
1134
|
+
};
|
|
1115
1135
|
}
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
// src/backoffice/services/subcategory.service.ts
|
|
1139
|
+
var import_firestore9 = require("firebase/firestore");
|
|
1140
|
+
|
|
1141
|
+
// src/backoffice/types/subcategory.types.ts
|
|
1142
|
+
var SUBCATEGORIES_COLLECTION = "subcategories";
|
|
1143
|
+
|
|
1144
|
+
// src/backoffice/services/subcategory.service.ts
|
|
1145
|
+
var SubcategoryService = class extends BaseService {
|
|
1116
1146
|
/**
|
|
1117
|
-
*
|
|
1118
|
-
* @param
|
|
1119
|
-
* @param contraindication - Kontraindikacija koja se uklanja
|
|
1120
|
-
* @returns Ažurirana tehnologija
|
|
1147
|
+
* Vraća referencu na Firestore kolekciju podkategorija za određenu kategoriju
|
|
1148
|
+
* @param categoryId - ID roditeljske kategorije
|
|
1121
1149
|
*/
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1150
|
+
getSubcategoriesRef(categoryId) {
|
|
1151
|
+
return (0, import_firestore9.collection)(
|
|
1152
|
+
this.db,
|
|
1153
|
+
CATEGORIES_COLLECTION,
|
|
1154
|
+
categoryId,
|
|
1155
|
+
SUBCATEGORIES_COLLECTION
|
|
1156
|
+
);
|
|
1129
1157
|
}
|
|
1130
1158
|
/**
|
|
1131
|
-
*
|
|
1132
|
-
* @param
|
|
1133
|
-
* @param
|
|
1134
|
-
* @returns
|
|
1159
|
+
* Kreira novu podkategoriju u okviru kategorije
|
|
1160
|
+
* @param categoryId - ID kategorije kojoj će pripadati nova podkategorija
|
|
1161
|
+
* @param subcategory - Podaci za novu podkategoriju
|
|
1162
|
+
* @returns Kreirana podkategorija sa generisanim ID-em
|
|
1135
1163
|
*/
|
|
1136
|
-
async
|
|
1137
|
-
const
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1164
|
+
async create(categoryId, subcategory) {
|
|
1165
|
+
const now = /* @__PURE__ */ new Date();
|
|
1166
|
+
const newSubcategory = {
|
|
1167
|
+
...subcategory,
|
|
1168
|
+
categoryId,
|
|
1169
|
+
createdAt: now,
|
|
1170
|
+
updatedAt: now,
|
|
1171
|
+
isActive: true
|
|
1172
|
+
};
|
|
1173
|
+
const docRef = await (0, import_firestore9.addDoc)(
|
|
1174
|
+
this.getSubcategoriesRef(categoryId),
|
|
1175
|
+
newSubcategory
|
|
1176
|
+
);
|
|
1177
|
+
return { id: docRef.id, ...newSubcategory };
|
|
1143
1178
|
}
|
|
1144
1179
|
/**
|
|
1145
|
-
*
|
|
1146
|
-
* @param
|
|
1147
|
-
* @
|
|
1148
|
-
* @returns Ažurirana tehnologija
|
|
1180
|
+
* Vraća sve aktivne podkategorije za određenu kategoriju
|
|
1181
|
+
* @param categoryId - ID kategorije čije podkategorije tražimo
|
|
1182
|
+
* @returns Lista aktivnih podkategorija
|
|
1149
1183
|
*/
|
|
1150
|
-
async
|
|
1151
|
-
const
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
return
|
|
1184
|
+
async getAllByCategoryId(categoryId) {
|
|
1185
|
+
const q = (0, import_firestore9.query)(
|
|
1186
|
+
this.getSubcategoriesRef(categoryId),
|
|
1187
|
+
(0, import_firestore9.where)("isActive", "==", true)
|
|
1188
|
+
);
|
|
1189
|
+
const snapshot = await (0, import_firestore9.getDocs)(q);
|
|
1190
|
+
return snapshot.docs.map(
|
|
1191
|
+
(doc10) => ({
|
|
1192
|
+
id: doc10.id,
|
|
1193
|
+
...doc10.data()
|
|
1194
|
+
})
|
|
1195
|
+
);
|
|
1157
1196
|
}
|
|
1158
1197
|
/**
|
|
1159
|
-
*
|
|
1160
|
-
* @param
|
|
1161
|
-
* @
|
|
1198
|
+
* Ažurira postojeću podkategoriju
|
|
1199
|
+
* @param categoryId - ID kategorije kojoj pripada podkategorija
|
|
1200
|
+
* @param subcategoryId - ID podkategorije koja se ažurira
|
|
1201
|
+
* @param subcategory - Novi podaci za podkategoriju
|
|
1202
|
+
* @returns Ažurirana podkategorija
|
|
1162
1203
|
*/
|
|
1163
|
-
async
|
|
1164
|
-
const
|
|
1165
|
-
|
|
1204
|
+
async update(categoryId, subcategoryId, subcategory) {
|
|
1205
|
+
const updateData = {
|
|
1206
|
+
...subcategory,
|
|
1207
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1208
|
+
};
|
|
1209
|
+
const docRef = (0, import_firestore9.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
1210
|
+
await (0, import_firestore9.updateDoc)(docRef, updateData);
|
|
1211
|
+
return this.getById(categoryId, subcategoryId);
|
|
1166
1212
|
}
|
|
1167
1213
|
/**
|
|
1168
|
-
*
|
|
1169
|
-
* @param
|
|
1170
|
-
* @
|
|
1214
|
+
* Soft delete podkategorije (postavlja isActive na false)
|
|
1215
|
+
* @param categoryId - ID kategorije kojoj pripada podkategorija
|
|
1216
|
+
* @param subcategoryId - ID podkategorije koja se briše
|
|
1171
1217
|
*/
|
|
1172
|
-
async
|
|
1173
|
-
|
|
1174
|
-
return (technology == null ? void 0 : technology.contraindications) || [];
|
|
1218
|
+
async delete(categoryId, subcategoryId) {
|
|
1219
|
+
await this.update(categoryId, subcategoryId, { isActive: false });
|
|
1175
1220
|
}
|
|
1176
1221
|
/**
|
|
1177
|
-
* Vraća
|
|
1178
|
-
* @param
|
|
1179
|
-
* @
|
|
1222
|
+
* Vraća podkategoriju po ID-u
|
|
1223
|
+
* @param categoryId - ID kategorije kojoj pripada podkategorija
|
|
1224
|
+
* @param subcategoryId - ID tražene podkategorije
|
|
1225
|
+
* @returns Podkategorija ili null ako ne postoji
|
|
1180
1226
|
*/
|
|
1181
|
-
async
|
|
1182
|
-
const
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
* @returns Ažurirana tehnologija
|
|
1190
|
-
*/
|
|
1191
|
-
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
1192
|
-
const docRef = (0, import_firestore3.doc)(this.getTechnologiesRef(), technologyId);
|
|
1193
|
-
await (0, import_firestore3.updateDoc)(docRef, {
|
|
1194
|
-
certificationRequirement,
|
|
1195
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
1196
|
-
});
|
|
1197
|
-
return this.getById(technologyId);
|
|
1198
|
-
}
|
|
1199
|
-
/**
|
|
1200
|
-
* Vraća zahteve sertifikacije za tehnologiju
|
|
1201
|
-
* @param technologyId - ID tehnologije
|
|
1202
|
-
* @returns Zahtevi sertifikacije ili null ako tehnologija ne postoji
|
|
1203
|
-
*/
|
|
1204
|
-
async getCertificationRequirement(technologyId) {
|
|
1205
|
-
const technology = await this.getById(technologyId);
|
|
1206
|
-
return (technology == null ? void 0 : technology.certificationRequirement) || null;
|
|
1207
|
-
}
|
|
1208
|
-
/**
|
|
1209
|
-
* Proverava da li doktor ima odgovarajuću sertifikaciju za izvođenje tehnologije
|
|
1210
|
-
*
|
|
1211
|
-
* @param requiredCertification - Zahtevana sertifikacija za tehnologiju
|
|
1212
|
-
* @param practitionerCertification - Sertifikacija zdravstvenog radnika
|
|
1213
|
-
* @returns true ako zdravstveni radnik ima odgovarajuću sertifikaciju, false ako nema
|
|
1214
|
-
*
|
|
1215
|
-
* @example
|
|
1216
|
-
* const isValid = technologyService.validateCertification(
|
|
1217
|
-
* {
|
|
1218
|
-
* minimumLevel: CertificationLevel.DOCTOR,
|
|
1219
|
-
* requiredSpecialties: [CertificationSpecialty.INJECTABLES]
|
|
1220
|
-
* },
|
|
1221
|
-
* {
|
|
1222
|
-
* level: CertificationLevel.SPECIALIST,
|
|
1223
|
-
* specialties: [CertificationSpecialty.INJECTABLES, CertificationSpecialty.LASER]
|
|
1224
|
-
* }
|
|
1225
|
-
* );
|
|
1226
|
-
*/
|
|
1227
|
-
validateCertification(requiredCertification, practitionerCertification) {
|
|
1228
|
-
const doctorLevel = Object.values(CertificationLevel).indexOf(
|
|
1229
|
-
practitionerCertification.level
|
|
1230
|
-
);
|
|
1231
|
-
const requiredLevel = Object.values(CertificationLevel).indexOf(
|
|
1232
|
-
requiredCertification.minimumLevel
|
|
1233
|
-
);
|
|
1234
|
-
if (doctorLevel < requiredLevel) return false;
|
|
1235
|
-
const requiredSpecialties = requiredCertification.requiredSpecialties || [];
|
|
1236
|
-
if (requiredSpecialties.length > 0) {
|
|
1237
|
-
const doctorSpecialties = practitionerCertification.specialties;
|
|
1238
|
-
const hasAllRequiredSpecialties = requiredSpecialties.every(
|
|
1239
|
-
(requiredSpecialty) => doctorSpecialties.includes(requiredSpecialty)
|
|
1240
|
-
);
|
|
1241
|
-
if (!hasAllRequiredSpecialties) return false;
|
|
1242
|
-
}
|
|
1243
|
-
return true;
|
|
1244
|
-
}
|
|
1245
|
-
/**
|
|
1246
|
-
* Vraća sve tehnologije koje je zdravstveni radnik sertifikovan da izvodi
|
|
1247
|
-
* zajedno sa listama dozvoljenih familija, kategorija i podkategorija
|
|
1248
|
-
*
|
|
1249
|
-
* @param practitioner - Profil zdravstvenog radnika
|
|
1250
|
-
* @returns Objekat koji sadrži:
|
|
1251
|
-
* - technologies: Lista tehnologija koje zdravstveni radnik može da izvodi
|
|
1252
|
-
* - families: Lista familija procedura koje zdravstveni radnik može da izvodi
|
|
1253
|
-
* - categories: Lista ID-eva kategorija koje zdravstveni radnik može da izvodi
|
|
1254
|
-
* - subcategories: Lista ID-eva podkategorija koje zdravstveni radnik može da izvodi
|
|
1255
|
-
*
|
|
1256
|
-
* @example
|
|
1257
|
-
* const practitioner = {
|
|
1258
|
-
* certification: {
|
|
1259
|
-
* level: CertificationLevel.DOCTOR,
|
|
1260
|
-
* specialties: [CertificationSpecialty.INJECTABLES]
|
|
1261
|
-
* }
|
|
1262
|
-
* };
|
|
1263
|
-
* const allowedTechnologies = await technologyService.getAllowedTechnologies(practitioner);
|
|
1264
|
-
* console.log(allowedTechnologies.families); // [ProcedureFamily.AESTHETICS]
|
|
1265
|
-
* console.log(allowedTechnologies.categories); // ["category1", "category2"]
|
|
1266
|
-
* console.log(allowedTechnologies.subcategories); // ["subcategory1", "subcategory2"]
|
|
1267
|
-
*/
|
|
1268
|
-
async getAllowedTechnologies(practitioner) {
|
|
1269
|
-
const allTechnologies = await this.getAll();
|
|
1270
|
-
const allowedTechnologies = allTechnologies.filter(
|
|
1271
|
-
(technology) => this.validateCertification(
|
|
1272
|
-
technology.certificationRequirement,
|
|
1273
|
-
practitioner.certification
|
|
1274
|
-
)
|
|
1275
|
-
);
|
|
1276
|
-
const families = [...new Set(allowedTechnologies.map((t) => t.family))];
|
|
1277
|
-
const categories = [
|
|
1278
|
-
...new Set(allowedTechnologies.map((t) => t.categoryId))
|
|
1279
|
-
];
|
|
1280
|
-
const subcategories = [
|
|
1281
|
-
...new Set(allowedTechnologies.map((t) => t.subcategoryId))
|
|
1282
|
-
];
|
|
1283
|
-
return {
|
|
1284
|
-
technologies: allowedTechnologies,
|
|
1285
|
-
families,
|
|
1286
|
-
categories,
|
|
1287
|
-
subcategories
|
|
1288
|
-
};
|
|
1227
|
+
async getById(categoryId, subcategoryId) {
|
|
1228
|
+
const docRef = (0, import_firestore9.doc)(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
1229
|
+
const docSnap = await (0, import_firestore9.getDoc)(docRef);
|
|
1230
|
+
if (!docSnap.exists()) return null;
|
|
1231
|
+
return {
|
|
1232
|
+
id: docSnap.id,
|
|
1233
|
+
...docSnap.data()
|
|
1234
|
+
};
|
|
1289
1235
|
}
|
|
1290
1236
|
};
|
|
1291
1237
|
|
|
1292
|
-
// src/backoffice/services/
|
|
1293
|
-
var
|
|
1294
|
-
|
|
1238
|
+
// src/backoffice/services/technology.service.ts
|
|
1239
|
+
var import_firestore10 = require("firebase/firestore");
|
|
1240
|
+
|
|
1241
|
+
// src/backoffice/types/static/certification.types.ts
|
|
1242
|
+
var CertificationLevel = /* @__PURE__ */ ((CertificationLevel2) => {
|
|
1243
|
+
CertificationLevel2["AESTHETICIAN"] = "aesthetician";
|
|
1244
|
+
CertificationLevel2["NURSE_ASSISTANT"] = "nurse_assistant";
|
|
1245
|
+
CertificationLevel2["NURSE"] = "nurse";
|
|
1246
|
+
CertificationLevel2["NURSE_PRACTITIONER"] = "nurse_practitioner";
|
|
1247
|
+
CertificationLevel2["PHYSICIAN_ASSISTANT"] = "physician_assistant";
|
|
1248
|
+
CertificationLevel2["DOCTOR"] = "doctor";
|
|
1249
|
+
CertificationLevel2["SPECIALIST"] = "specialist";
|
|
1250
|
+
CertificationLevel2["PLASTIC_SURGEON"] = "plastic_surgeon";
|
|
1251
|
+
return CertificationLevel2;
|
|
1252
|
+
})(CertificationLevel || {});
|
|
1253
|
+
var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
|
|
1254
|
+
CertificationSpecialty3["LASER"] = "laser";
|
|
1255
|
+
CertificationSpecialty3["INJECTABLES"] = "injectables";
|
|
1256
|
+
CertificationSpecialty3["CHEMICAL_PEELS"] = "chemical_peels";
|
|
1257
|
+
CertificationSpecialty3["MICRODERMABRASION"] = "microdermabrasion";
|
|
1258
|
+
CertificationSpecialty3["BODY_CONTOURING"] = "body_contouring";
|
|
1259
|
+
CertificationSpecialty3["SKIN_CARE"] = "skin_care";
|
|
1260
|
+
CertificationSpecialty3["WOUND_CARE"] = "wound_care";
|
|
1261
|
+
CertificationSpecialty3["ANESTHESIA"] = "anesthesia";
|
|
1262
|
+
return CertificationSpecialty3;
|
|
1263
|
+
})(CertificationSpecialty || {});
|
|
1264
|
+
|
|
1265
|
+
// src/backoffice/services/technology.service.ts
|
|
1266
|
+
var DEFAULT_CERTIFICATION_REQUIREMENT = {
|
|
1267
|
+
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
1268
|
+
requiredSpecialties: []
|
|
1269
|
+
};
|
|
1270
|
+
var TechnologyService = class extends BaseService {
|
|
1295
1271
|
/**
|
|
1296
|
-
*
|
|
1272
|
+
* Vraća referencu na Firestore kolekciju tehnologija
|
|
1297
1273
|
*/
|
|
1298
|
-
|
|
1299
|
-
return (0,
|
|
1274
|
+
getTechnologiesRef() {
|
|
1275
|
+
return (0, import_firestore10.collection)(this.db, TECHNOLOGIES_COLLECTION);
|
|
1300
1276
|
}
|
|
1301
1277
|
/**
|
|
1302
|
-
* Kreira
|
|
1303
|
-
* @param
|
|
1304
|
-
* @returns
|
|
1278
|
+
* Kreira novu tehnologiju
|
|
1279
|
+
* @param technology - Podaci za novu tehnologiju
|
|
1280
|
+
* @returns Kreirana tehnologija sa generisanim ID-em
|
|
1305
1281
|
*/
|
|
1306
|
-
async create(
|
|
1282
|
+
async create(technology) {
|
|
1307
1283
|
const now = /* @__PURE__ */ new Date();
|
|
1308
|
-
const
|
|
1309
|
-
...
|
|
1284
|
+
const newTechnology = {
|
|
1285
|
+
...technology,
|
|
1310
1286
|
createdAt: now,
|
|
1311
1287
|
updatedAt: now,
|
|
1312
|
-
isActive: true
|
|
1288
|
+
isActive: true,
|
|
1289
|
+
requirements: technology.requirements || {
|
|
1290
|
+
pre: [],
|
|
1291
|
+
post: []
|
|
1292
|
+
},
|
|
1293
|
+
blockingConditions: technology.blockingConditions || [],
|
|
1294
|
+
contraindications: technology.contraindications || [],
|
|
1295
|
+
benefits: technology.benefits || [],
|
|
1296
|
+
certificationRequirement: technology.certificationRequirement || DEFAULT_CERTIFICATION_REQUIREMENT
|
|
1313
1297
|
};
|
|
1314
|
-
const docRef = await (0,
|
|
1315
|
-
return { id: docRef.id, ...
|
|
1298
|
+
const docRef = await (0, import_firestore10.addDoc)(this.getTechnologiesRef(), newTechnology);
|
|
1299
|
+
return { id: docRef.id, ...newTechnology };
|
|
1316
1300
|
}
|
|
1317
1301
|
/**
|
|
1318
|
-
* Vraća sve aktivne
|
|
1319
|
-
* @returns Lista aktivnih
|
|
1302
|
+
* Vraća sve aktivne tehnologije
|
|
1303
|
+
* @returns Lista aktivnih tehnologija
|
|
1320
1304
|
*/
|
|
1321
1305
|
async getAll() {
|
|
1322
|
-
const q = (0,
|
|
1323
|
-
const snapshot = await (0,
|
|
1306
|
+
const q = (0, import_firestore10.query)(this.getTechnologiesRef(), (0, import_firestore10.where)("isActive", "==", true));
|
|
1307
|
+
const snapshot = await (0, import_firestore10.getDocs)(q);
|
|
1324
1308
|
return snapshot.docs.map(
|
|
1325
1309
|
(doc10) => ({
|
|
1326
1310
|
id: doc10.id,
|
|
@@ -1329,17 +1313,17 @@ var RequirementService = class extends BaseService {
|
|
|
1329
1313
|
);
|
|
1330
1314
|
}
|
|
1331
1315
|
/**
|
|
1332
|
-
* Vraća sve aktivne
|
|
1333
|
-
* @param
|
|
1334
|
-
* @returns Lista
|
|
1316
|
+
* Vraća sve aktivne tehnologije za određenu familiju
|
|
1317
|
+
* @param family - Familija procedura
|
|
1318
|
+
* @returns Lista aktivnih tehnologija
|
|
1335
1319
|
*/
|
|
1336
|
-
async
|
|
1337
|
-
const q = (0,
|
|
1338
|
-
this.
|
|
1339
|
-
(0,
|
|
1340
|
-
(0,
|
|
1320
|
+
async getAllByFamily(family) {
|
|
1321
|
+
const q = (0, import_firestore10.query)(
|
|
1322
|
+
this.getTechnologiesRef(),
|
|
1323
|
+
(0, import_firestore10.where)("isActive", "==", true),
|
|
1324
|
+
(0, import_firestore10.where)("family", "==", family)
|
|
1341
1325
|
);
|
|
1342
|
-
const snapshot = await (0,
|
|
1326
|
+
const snapshot = await (0, import_firestore10.getDocs)(q);
|
|
1343
1327
|
return snapshot.docs.map(
|
|
1344
1328
|
(doc10) => ({
|
|
1345
1329
|
id: doc10.id,
|
|
@@ -1348,603 +1332,629 @@ var RequirementService = class extends BaseService {
|
|
|
1348
1332
|
);
|
|
1349
1333
|
}
|
|
1350
1334
|
/**
|
|
1351
|
-
*
|
|
1352
|
-
* @param
|
|
1353
|
-
* @
|
|
1354
|
-
* @returns Ažurirani zahtev
|
|
1335
|
+
* Vraća sve aktivne tehnologije za određenu kategoriju
|
|
1336
|
+
* @param categoryId - ID kategorije
|
|
1337
|
+
* @returns Lista aktivnih tehnologija
|
|
1355
1338
|
*/
|
|
1356
|
-
async
|
|
1339
|
+
async getAllByCategoryId(categoryId) {
|
|
1340
|
+
const q = (0, import_firestore10.query)(
|
|
1341
|
+
this.getTechnologiesRef(),
|
|
1342
|
+
(0, import_firestore10.where)("isActive", "==", true),
|
|
1343
|
+
(0, import_firestore10.where)("categoryId", "==", categoryId)
|
|
1344
|
+
);
|
|
1345
|
+
const snapshot = await (0, import_firestore10.getDocs)(q);
|
|
1346
|
+
return snapshot.docs.map(
|
|
1347
|
+
(doc10) => ({
|
|
1348
|
+
id: doc10.id,
|
|
1349
|
+
...doc10.data()
|
|
1350
|
+
})
|
|
1351
|
+
);
|
|
1352
|
+
}
|
|
1353
|
+
/**
|
|
1354
|
+
* Vraća sve aktivne tehnologije za određenu podkategoriju
|
|
1355
|
+
* @param subcategoryId - ID podkategorije
|
|
1356
|
+
* @returns Lista aktivnih tehnologija
|
|
1357
|
+
*/
|
|
1358
|
+
async getAllBySubcategoryId(subcategoryId) {
|
|
1359
|
+
const q = (0, import_firestore10.query)(
|
|
1360
|
+
this.getTechnologiesRef(),
|
|
1361
|
+
(0, import_firestore10.where)("isActive", "==", true),
|
|
1362
|
+
(0, import_firestore10.where)("subcategoryId", "==", subcategoryId)
|
|
1363
|
+
);
|
|
1364
|
+
const snapshot = await (0, import_firestore10.getDocs)(q);
|
|
1365
|
+
return snapshot.docs.map(
|
|
1366
|
+
(doc10) => ({
|
|
1367
|
+
id: doc10.id,
|
|
1368
|
+
...doc10.data()
|
|
1369
|
+
})
|
|
1370
|
+
);
|
|
1371
|
+
}
|
|
1372
|
+
/**
|
|
1373
|
+
* Ažurira postojeću tehnologiju
|
|
1374
|
+
* @param technologyId - ID tehnologije
|
|
1375
|
+
* @param technology - Novi podaci za tehnologiju
|
|
1376
|
+
* @returns Ažurirana tehnologija
|
|
1377
|
+
*/
|
|
1378
|
+
async update(technologyId, technology) {
|
|
1357
1379
|
const updateData = {
|
|
1358
|
-
...
|
|
1380
|
+
...technology,
|
|
1359
1381
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1360
1382
|
};
|
|
1361
|
-
const docRef = (0,
|
|
1362
|
-
await (0,
|
|
1363
|
-
return this.getById(
|
|
1383
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1384
|
+
await (0, import_firestore10.updateDoc)(docRef, updateData);
|
|
1385
|
+
return this.getById(technologyId);
|
|
1364
1386
|
}
|
|
1365
1387
|
/**
|
|
1366
|
-
* Soft delete
|
|
1367
|
-
* @param
|
|
1388
|
+
* Soft delete tehnologije (postavlja isActive na false)
|
|
1389
|
+
* @param technologyId - ID tehnologije koja se briše
|
|
1368
1390
|
*/
|
|
1369
|
-
async delete(
|
|
1370
|
-
await this.update(
|
|
1391
|
+
async delete(technologyId) {
|
|
1392
|
+
await this.update(technologyId, {
|
|
1393
|
+
isActive: false
|
|
1394
|
+
});
|
|
1371
1395
|
}
|
|
1372
1396
|
/**
|
|
1373
|
-
* Vraća
|
|
1374
|
-
* @param
|
|
1375
|
-
* @returns
|
|
1397
|
+
* Vraća tehnologiju po ID-u
|
|
1398
|
+
* @param technologyId - ID tražene tehnologije
|
|
1399
|
+
* @returns Tehnologija ili null ako ne postoji
|
|
1376
1400
|
*/
|
|
1377
|
-
async getById(
|
|
1378
|
-
const docRef = (0,
|
|
1379
|
-
const docSnap = await (0,
|
|
1401
|
+
async getById(technologyId) {
|
|
1402
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1403
|
+
const docSnap = await (0, import_firestore10.getDoc)(docRef);
|
|
1380
1404
|
if (!docSnap.exists()) return null;
|
|
1381
1405
|
return {
|
|
1382
1406
|
id: docSnap.id,
|
|
1383
1407
|
...docSnap.data()
|
|
1384
1408
|
};
|
|
1385
1409
|
}
|
|
1386
|
-
};
|
|
1387
|
-
|
|
1388
|
-
// src/backoffice/services/brand.service.ts
|
|
1389
|
-
var import_firestore5 = require("firebase/firestore");
|
|
1390
|
-
var BrandService = class extends BaseService {
|
|
1391
1410
|
/**
|
|
1392
|
-
*
|
|
1411
|
+
* Dodaje novi zahtev tehnologiji
|
|
1412
|
+
* @param technologyId - ID tehnologije
|
|
1413
|
+
* @param requirement - Zahtev koji se dodaje
|
|
1414
|
+
* @returns Ažurirana tehnologija sa novim zahtevom
|
|
1393
1415
|
*/
|
|
1394
|
-
|
|
1395
|
-
|
|
1416
|
+
async addRequirement(technologyId, requirement) {
|
|
1417
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1418
|
+
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
1419
|
+
await (0, import_firestore10.updateDoc)(docRef, {
|
|
1420
|
+
[requirementType]: (0, import_firestore10.arrayUnion)(requirement),
|
|
1421
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1422
|
+
});
|
|
1423
|
+
return this.getById(technologyId);
|
|
1396
1424
|
}
|
|
1397
1425
|
/**
|
|
1398
|
-
*
|
|
1426
|
+
* Uklanja zahtev iz tehnologije
|
|
1427
|
+
* @param technologyId - ID tehnologije
|
|
1428
|
+
* @param requirement - Zahtev koji se uklanja
|
|
1429
|
+
* @returns Ažurirana tehnologija bez uklonjenog zahteva
|
|
1399
1430
|
*/
|
|
1400
|
-
async
|
|
1401
|
-
const
|
|
1402
|
-
const
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
updatedAt:
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
const docRef = await (0, import_firestore5.addDoc)(this.getBrandsRef(), newBrand);
|
|
1409
|
-
return { id: docRef.id, ...newBrand };
|
|
1431
|
+
async removeRequirement(technologyId, requirement) {
|
|
1432
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1433
|
+
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
1434
|
+
await (0, import_firestore10.updateDoc)(docRef, {
|
|
1435
|
+
[requirementType]: (0, import_firestore10.arrayRemove)(requirement),
|
|
1436
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1437
|
+
});
|
|
1438
|
+
return this.getById(technologyId);
|
|
1410
1439
|
}
|
|
1411
1440
|
/**
|
|
1412
|
-
*
|
|
1441
|
+
* Vraća sve zahteve za tehnologiju
|
|
1442
|
+
* @param technologyId - ID tehnologije
|
|
1443
|
+
* @param type - Opcioni filter za tip zahteva (pre/post)
|
|
1444
|
+
* @returns Lista zahteva
|
|
1413
1445
|
*/
|
|
1414
|
-
async
|
|
1415
|
-
const
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
})
|
|
1422
|
-
);
|
|
1446
|
+
async getRequirements(technologyId, type) {
|
|
1447
|
+
const technology = await this.getById(technologyId);
|
|
1448
|
+
if (!technology || !technology.requirements) return [];
|
|
1449
|
+
if (type) {
|
|
1450
|
+
return technology.requirements[type];
|
|
1451
|
+
}
|
|
1452
|
+
return [...technology.requirements.pre, ...technology.requirements.post];
|
|
1423
1453
|
}
|
|
1424
1454
|
/**
|
|
1425
|
-
*
|
|
1455
|
+
* Ažurira postojeći zahtev
|
|
1456
|
+
* @param technologyId - ID tehnologije
|
|
1457
|
+
* @param oldRequirement - Stari zahtev koji se menja
|
|
1458
|
+
* @param newRequirement - Novi zahtev koji zamenjuje stari
|
|
1459
|
+
* @returns Ažurirana tehnologija
|
|
1426
1460
|
*/
|
|
1427
|
-
async
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
1431
|
-
};
|
|
1432
|
-
const docRef = (0, import_firestore5.doc)(this.getBrandsRef(), brandId);
|
|
1433
|
-
await (0, import_firestore5.updateDoc)(docRef, updateData);
|
|
1434
|
-
return this.getById(brandId);
|
|
1461
|
+
async updateRequirement(technologyId, oldRequirement, newRequirement) {
|
|
1462
|
+
await this.removeRequirement(technologyId, oldRequirement);
|
|
1463
|
+
return this.addRequirement(technologyId, newRequirement);
|
|
1435
1464
|
}
|
|
1436
1465
|
/**
|
|
1437
|
-
*
|
|
1466
|
+
* Dodaje blokirajući uslov tehnologiji
|
|
1467
|
+
* @param technologyId - ID tehnologije
|
|
1468
|
+
* @param condition - Blokirajući uslov koji se dodaje
|
|
1469
|
+
* @returns Ažurirana tehnologija
|
|
1438
1470
|
*/
|
|
1439
|
-
async
|
|
1440
|
-
|
|
1441
|
-
|
|
1471
|
+
async addBlockingCondition(technologyId, condition) {
|
|
1472
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1473
|
+
await (0, import_firestore10.updateDoc)(docRef, {
|
|
1474
|
+
blockingConditions: (0, import_firestore10.arrayUnion)(condition),
|
|
1475
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1442
1476
|
});
|
|
1477
|
+
return this.getById(technologyId);
|
|
1443
1478
|
}
|
|
1444
1479
|
/**
|
|
1445
|
-
*
|
|
1480
|
+
* Uklanja blokirajući uslov iz tehnologije
|
|
1481
|
+
* @param technologyId - ID tehnologije
|
|
1482
|
+
* @param condition - Blokirajući uslov koji se uklanja
|
|
1483
|
+
* @returns Ažurirana tehnologija
|
|
1446
1484
|
*/
|
|
1447
|
-
async
|
|
1448
|
-
const docRef = (0,
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
};
|
|
1485
|
+
async removeBlockingCondition(technologyId, condition) {
|
|
1486
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1487
|
+
await (0, import_firestore10.updateDoc)(docRef, {
|
|
1488
|
+
blockingConditions: (0, import_firestore10.arrayRemove)(condition),
|
|
1489
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1490
|
+
});
|
|
1491
|
+
return this.getById(technologyId);
|
|
1455
1492
|
}
|
|
1456
|
-
};
|
|
1457
|
-
|
|
1458
|
-
// src/backoffice/services/product.service.ts
|
|
1459
|
-
var import_firestore6 = require("firebase/firestore");
|
|
1460
|
-
var ProductService = class extends BaseService {
|
|
1461
1493
|
/**
|
|
1462
|
-
*
|
|
1463
|
-
* @param technologyId - ID
|
|
1464
|
-
* @
|
|
1494
|
+
* Dodaje kontraindikaciju tehnologiji
|
|
1495
|
+
* @param technologyId - ID tehnologije
|
|
1496
|
+
* @param contraindication - Kontraindikacija koja se dodaje
|
|
1497
|
+
* @returns Ažurirana tehnologija
|
|
1465
1498
|
*/
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
);
|
|
1499
|
+
async addContraindication(technologyId, contraindication) {
|
|
1500
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1501
|
+
await (0, import_firestore10.updateDoc)(docRef, {
|
|
1502
|
+
contraindications: (0, import_firestore10.arrayUnion)(contraindication),
|
|
1503
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1504
|
+
});
|
|
1505
|
+
return this.getById(technologyId);
|
|
1473
1506
|
}
|
|
1474
1507
|
/**
|
|
1475
|
-
*
|
|
1508
|
+
* Uklanja kontraindikaciju iz tehnologije
|
|
1509
|
+
* @param technologyId - ID tehnologije
|
|
1510
|
+
* @param contraindication - Kontraindikacija koja se uklanja
|
|
1511
|
+
* @returns Ažurirana tehnologija
|
|
1476
1512
|
*/
|
|
1477
|
-
async
|
|
1478
|
-
const
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
updatedAt: now,
|
|
1485
|
-
isActive: true
|
|
1486
|
-
};
|
|
1487
|
-
const productRef = await (0, import_firestore6.addDoc)(
|
|
1488
|
-
this.getProductsRef(technologyId),
|
|
1489
|
-
newProduct
|
|
1490
|
-
);
|
|
1491
|
-
return { id: productRef.id, ...newProduct };
|
|
1513
|
+
async removeContraindication(technologyId, contraindication) {
|
|
1514
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1515
|
+
await (0, import_firestore10.updateDoc)(docRef, {
|
|
1516
|
+
contraindications: (0, import_firestore10.arrayRemove)(contraindication),
|
|
1517
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1518
|
+
});
|
|
1519
|
+
return this.getById(technologyId);
|
|
1492
1520
|
}
|
|
1493
1521
|
/**
|
|
1494
|
-
*
|
|
1522
|
+
* Dodaje benefit tehnologiji
|
|
1523
|
+
* @param technologyId - ID tehnologije
|
|
1524
|
+
* @param benefit - Benefit koji se dodaje
|
|
1525
|
+
* @returns Ažurirana tehnologija
|
|
1495
1526
|
*/
|
|
1496
|
-
async
|
|
1497
|
-
const
|
|
1498
|
-
|
|
1499
|
-
(0,
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
return
|
|
1503
|
-
(doc10) => ({
|
|
1504
|
-
id: doc10.id,
|
|
1505
|
-
...doc10.data()
|
|
1506
|
-
})
|
|
1507
|
-
);
|
|
1527
|
+
async addBenefit(technologyId, benefit) {
|
|
1528
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1529
|
+
await (0, import_firestore10.updateDoc)(docRef, {
|
|
1530
|
+
benefits: (0, import_firestore10.arrayUnion)(benefit),
|
|
1531
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1532
|
+
});
|
|
1533
|
+
return this.getById(technologyId);
|
|
1508
1534
|
}
|
|
1509
1535
|
/**
|
|
1510
|
-
*
|
|
1536
|
+
* Uklanja benefit iz tehnologije
|
|
1537
|
+
* @param technologyId - ID tehnologije
|
|
1538
|
+
* @param benefit - Benefit koji se uklanja
|
|
1539
|
+
* @returns Ažurirana tehnologija
|
|
1511
1540
|
*/
|
|
1512
|
-
async
|
|
1513
|
-
const
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
(0, import_firestore6.where)("brandId", "==", brandId),
|
|
1520
|
-
(0, import_firestore6.where)("isActive", "==", true)
|
|
1521
|
-
);
|
|
1522
|
-
const snapshot = await (0, import_firestore6.getDocs)(q);
|
|
1523
|
-
products.push(
|
|
1524
|
-
...snapshot.docs.map(
|
|
1525
|
-
(doc10) => ({
|
|
1526
|
-
id: doc10.id,
|
|
1527
|
-
...doc10.data()
|
|
1528
|
-
})
|
|
1529
|
-
)
|
|
1530
|
-
);
|
|
1531
|
-
}
|
|
1532
|
-
return products;
|
|
1541
|
+
async removeBenefit(technologyId, benefit) {
|
|
1542
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1543
|
+
await (0, import_firestore10.updateDoc)(docRef, {
|
|
1544
|
+
benefits: (0, import_firestore10.arrayRemove)(benefit),
|
|
1545
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1546
|
+
});
|
|
1547
|
+
return this.getById(technologyId);
|
|
1533
1548
|
}
|
|
1534
1549
|
/**
|
|
1535
|
-
*
|
|
1550
|
+
* Vraća sve blokirajuće uslove za tehnologiju
|
|
1551
|
+
* @param technologyId - ID tehnologije
|
|
1552
|
+
* @returns Lista blokirajućih uslova
|
|
1536
1553
|
*/
|
|
1537
|
-
async
|
|
1538
|
-
const
|
|
1539
|
-
|
|
1540
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
1541
|
-
};
|
|
1542
|
-
const docRef = (0, import_firestore6.doc)(this.getProductsRef(technologyId), productId);
|
|
1543
|
-
await (0, import_firestore6.updateDoc)(docRef, updateData);
|
|
1544
|
-
return this.getById(technologyId, productId);
|
|
1554
|
+
async getBlockingConditions(technologyId) {
|
|
1555
|
+
const technology = await this.getById(technologyId);
|
|
1556
|
+
return (technology == null ? void 0 : technology.blockingConditions) || [];
|
|
1545
1557
|
}
|
|
1546
1558
|
/**
|
|
1547
|
-
*
|
|
1559
|
+
* Vraća sve kontraindikacije za tehnologiju
|
|
1560
|
+
* @param technologyId - ID tehnologije
|
|
1561
|
+
* @returns Lista kontraindikacija
|
|
1548
1562
|
*/
|
|
1549
|
-
async
|
|
1550
|
-
await this.
|
|
1551
|
-
|
|
1552
|
-
});
|
|
1563
|
+
async getContraindications(technologyId) {
|
|
1564
|
+
const technology = await this.getById(technologyId);
|
|
1565
|
+
return (technology == null ? void 0 : technology.contraindications) || [];
|
|
1553
1566
|
}
|
|
1554
1567
|
/**
|
|
1555
|
-
*
|
|
1568
|
+
* Vraća sve benefite za tehnologiju
|
|
1569
|
+
* @param technologyId - ID tehnologije
|
|
1570
|
+
* @returns Lista benefita
|
|
1556
1571
|
*/
|
|
1557
|
-
async
|
|
1558
|
-
const
|
|
1559
|
-
|
|
1560
|
-
if (!docSnap.exists()) return null;
|
|
1561
|
-
return {
|
|
1562
|
-
id: docSnap.id,
|
|
1563
|
-
...docSnap.data()
|
|
1564
|
-
};
|
|
1565
|
-
}
|
|
1566
|
-
};
|
|
1567
|
-
|
|
1568
|
-
// src/services/documentation-templates/documentation-template.service.ts
|
|
1569
|
-
var import_firestore7 = require("firebase/firestore");
|
|
1570
|
-
var DocumentationTemplateService = class extends BaseService {
|
|
1571
|
-
constructor() {
|
|
1572
|
-
super(...arguments);
|
|
1573
|
-
this.collectionRef = (0, import_firestore7.collection)(
|
|
1574
|
-
this.db,
|
|
1575
|
-
DOCUMENTATION_TEMPLATES_COLLECTION
|
|
1576
|
-
);
|
|
1572
|
+
async getBenefits(technologyId) {
|
|
1573
|
+
const technology = await this.getById(technologyId);
|
|
1574
|
+
return (technology == null ? void 0 : technology.benefits) || [];
|
|
1577
1575
|
}
|
|
1578
1576
|
/**
|
|
1579
|
-
*
|
|
1580
|
-
* @param
|
|
1581
|
-
* @param
|
|
1582
|
-
* @returns
|
|
1577
|
+
* Ažurira zahteve sertifikacije za tehnologiju
|
|
1578
|
+
* @param technologyId - ID tehnologije
|
|
1579
|
+
* @param certificationRequirement - Novi zahtevi sertifikacije
|
|
1580
|
+
* @returns Ažurirana tehnologija
|
|
1583
1581
|
*/
|
|
1584
|
-
async
|
|
1585
|
-
const
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
const now = Date.now();
|
|
1592
|
-
const template = {
|
|
1593
|
-
id: templateId,
|
|
1594
|
-
title: validatedData.title,
|
|
1595
|
-
description: validatedData.description,
|
|
1596
|
-
elements: elementsWithIds,
|
|
1597
|
-
createdAt: now,
|
|
1598
|
-
updatedAt: now,
|
|
1599
|
-
createdBy: userId,
|
|
1600
|
-
version: 1,
|
|
1601
|
-
isActive: true,
|
|
1602
|
-
tags: validatedData.tags || [],
|
|
1603
|
-
isUserForm: validatedData.isUserForm || false,
|
|
1604
|
-
isRequired: validatedData.isRequired || false,
|
|
1605
|
-
sortingOrder: validatedData.sortingOrder || 0
|
|
1606
|
-
};
|
|
1607
|
-
const docRef = (0, import_firestore7.doc)(this.collectionRef, templateId);
|
|
1608
|
-
await (0, import_firestore7.setDoc)(docRef, template);
|
|
1609
|
-
return template;
|
|
1582
|
+
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
1583
|
+
const docRef = (0, import_firestore10.doc)(this.getTechnologiesRef(), technologyId);
|
|
1584
|
+
await (0, import_firestore10.updateDoc)(docRef, {
|
|
1585
|
+
certificationRequirement,
|
|
1586
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1587
|
+
});
|
|
1588
|
+
return this.getById(technologyId);
|
|
1610
1589
|
}
|
|
1611
1590
|
/**
|
|
1612
|
-
*
|
|
1613
|
-
* @param
|
|
1614
|
-
* @
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
const docSnap = await (0, import_firestore7.getDoc)(docRef);
|
|
1620
|
-
if (!docSnap.exists()) {
|
|
1621
|
-
return null;
|
|
1622
|
-
}
|
|
1623
|
-
const currentTemplate = docSnap.data();
|
|
1624
|
-
if (version === void 0) {
|
|
1625
|
-
return currentTemplate;
|
|
1626
|
-
}
|
|
1627
|
-
if (currentTemplate.version === version) {
|
|
1628
|
-
return currentTemplate;
|
|
1629
|
-
}
|
|
1630
|
-
try {
|
|
1631
|
-
const versionTemplate = await this.getTemplateVersion(
|
|
1632
|
-
templateId,
|
|
1633
|
-
version
|
|
1634
|
-
);
|
|
1635
|
-
if (versionTemplate) {
|
|
1636
|
-
return versionTemplate;
|
|
1637
|
-
}
|
|
1638
|
-
} catch (error) {
|
|
1639
|
-
console.error(`Error getting template version ${version}:`, error);
|
|
1640
|
-
}
|
|
1641
|
-
return null;
|
|
1591
|
+
* Vraća zahteve sertifikacije za tehnologiju
|
|
1592
|
+
* @param technologyId - ID tehnologije
|
|
1593
|
+
* @returns Zahtevi sertifikacije ili null ako tehnologija ne postoji
|
|
1594
|
+
*/
|
|
1595
|
+
async getCertificationRequirement(technologyId) {
|
|
1596
|
+
const technology = await this.getById(technologyId);
|
|
1597
|
+
return (technology == null ? void 0 : technology.certificationRequirement) || null;
|
|
1642
1598
|
}
|
|
1643
1599
|
/**
|
|
1644
|
-
*
|
|
1645
|
-
*
|
|
1646
|
-
* @param
|
|
1647
|
-
* @
|
|
1600
|
+
* Proverava da li doktor ima odgovarajuću sertifikaciju za izvođenje tehnologije
|
|
1601
|
+
*
|
|
1602
|
+
* @param requiredCertification - Zahtevana sertifikacija za tehnologiju
|
|
1603
|
+
* @param practitionerCertification - Sertifikacija zdravstvenog radnika
|
|
1604
|
+
* @returns true ako zdravstveni radnik ima odgovarajuću sertifikaciju, false ako nema
|
|
1605
|
+
*
|
|
1606
|
+
* @example
|
|
1607
|
+
* const isValid = technologyService.validateCertification(
|
|
1608
|
+
* {
|
|
1609
|
+
* minimumLevel: CertificationLevel.DOCTOR,
|
|
1610
|
+
* requiredSpecialties: [CertificationSpecialty.INJECTABLES]
|
|
1611
|
+
* },
|
|
1612
|
+
* {
|
|
1613
|
+
* level: CertificationLevel.SPECIALIST,
|
|
1614
|
+
* specialties: [CertificationSpecialty.INJECTABLES, CertificationSpecialty.LASER]
|
|
1615
|
+
* }
|
|
1616
|
+
* );
|
|
1648
1617
|
*/
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
console.log("Validated data", validatedData);
|
|
1653
|
-
const template = await this.getTemplateById(templateId);
|
|
1654
|
-
if (!template) {
|
|
1655
|
-
throw new Error(`Template with ID ${templateId} not found`);
|
|
1656
|
-
}
|
|
1657
|
-
const versionsCollectionRef = (0, import_firestore7.collection)(
|
|
1658
|
-
this.db,
|
|
1659
|
-
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
1618
|
+
validateCertification(requiredCertification, practitionerCertification) {
|
|
1619
|
+
const doctorLevel = Object.values(CertificationLevel).indexOf(
|
|
1620
|
+
practitionerCertification.level
|
|
1660
1621
|
);
|
|
1661
|
-
const
|
|
1662
|
-
|
|
1663
|
-
template.version.toString()
|
|
1622
|
+
const requiredLevel = Object.values(CertificationLevel).indexOf(
|
|
1623
|
+
requiredCertification.minimumLevel
|
|
1664
1624
|
);
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
if (
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1625
|
+
if (doctorLevel < requiredLevel) return false;
|
|
1626
|
+
const requiredSpecialties = requiredCertification.requiredSpecialties || [];
|
|
1627
|
+
if (requiredSpecialties.length > 0) {
|
|
1628
|
+
const doctorSpecialties = practitionerCertification.specialties;
|
|
1629
|
+
const hasAllRequiredSpecialties = requiredSpecialties.every(
|
|
1630
|
+
(requiredSpecialty) => doctorSpecialties.includes(requiredSpecialty)
|
|
1631
|
+
);
|
|
1632
|
+
if (!hasAllRequiredSpecialties) return false;
|
|
1672
1633
|
}
|
|
1673
|
-
|
|
1674
|
-
elements: updatedElements,
|
|
1675
|
-
updatedAt: Date.now(),
|
|
1676
|
-
version: template.version + 1
|
|
1677
|
-
};
|
|
1678
|
-
if (validatedData.title !== void 0)
|
|
1679
|
-
updatePayload.title = validatedData.title;
|
|
1680
|
-
if (validatedData.description !== void 0)
|
|
1681
|
-
updatePayload.description = validatedData.description;
|
|
1682
|
-
if (validatedData.isActive !== void 0)
|
|
1683
|
-
updatePayload.isActive = validatedData.isActive;
|
|
1684
|
-
if (validatedData.tags !== void 0)
|
|
1685
|
-
updatePayload.tags = validatedData.tags;
|
|
1686
|
-
updatePayload.isUserForm = (_a = validatedData.isUserForm) != null ? _a : false;
|
|
1687
|
-
updatePayload.isRequired = (_b = validatedData.isRequired) != null ? _b : false;
|
|
1688
|
-
updatePayload.sortingOrder = (_c = validatedData.sortingOrder) != null ? _c : 0;
|
|
1689
|
-
const docRef = (0, import_firestore7.doc)(this.collectionRef, templateId);
|
|
1690
|
-
console.log("Update payload", updatePayload);
|
|
1691
|
-
await (0, import_firestore7.updateDoc)(docRef, updatePayload);
|
|
1692
|
-
return { ...template, ...updatePayload };
|
|
1634
|
+
return true;
|
|
1693
1635
|
}
|
|
1694
1636
|
/**
|
|
1695
|
-
*
|
|
1696
|
-
*
|
|
1697
|
-
*
|
|
1698
|
-
* @
|
|
1637
|
+
* Vraća sve tehnologije koje je zdravstveni radnik sertifikovan da izvodi
|
|
1638
|
+
* zajedno sa listama dozvoljenih familija, kategorija i podkategorija
|
|
1639
|
+
*
|
|
1640
|
+
* @param practitioner - Profil zdravstvenog radnika
|
|
1641
|
+
* @returns Objekat koji sadrži:
|
|
1642
|
+
* - technologies: Lista tehnologija koje zdravstveni radnik može da izvodi
|
|
1643
|
+
* - families: Lista familija procedura koje zdravstveni radnik može da izvodi
|
|
1644
|
+
* - categories: Lista ID-eva kategorija koje zdravstveni radnik može da izvodi
|
|
1645
|
+
* - subcategories: Lista ID-eva podkategorija koje zdravstveni radnik može da izvodi
|
|
1646
|
+
*
|
|
1647
|
+
* @example
|
|
1648
|
+
* const practitioner = {
|
|
1649
|
+
* certification: {
|
|
1650
|
+
* level: CertificationLevel.DOCTOR,
|
|
1651
|
+
* specialties: [CertificationSpecialty.INJECTABLES]
|
|
1652
|
+
* }
|
|
1653
|
+
* };
|
|
1654
|
+
* const allowedTechnologies = await technologyService.getAllowedTechnologies(practitioner);
|
|
1655
|
+
* console.log(allowedTechnologies.families); // [ProcedureFamily.AESTHETICS]
|
|
1656
|
+
* console.log(allowedTechnologies.categories); // ["category1", "category2"]
|
|
1657
|
+
* console.log(allowedTechnologies.subcategories); // ["subcategory1", "subcategory2"]
|
|
1699
1658
|
*/
|
|
1700
|
-
async
|
|
1701
|
-
const
|
|
1702
|
-
|
|
1703
|
-
|
|
1659
|
+
async getAllowedTechnologies(practitioner) {
|
|
1660
|
+
const allTechnologies = await this.getAll();
|
|
1661
|
+
const allowedTechnologies = allTechnologies.filter(
|
|
1662
|
+
(technology) => this.validateCertification(
|
|
1663
|
+
technology.certificationRequirement,
|
|
1664
|
+
practitioner.certification
|
|
1665
|
+
)
|
|
1704
1666
|
);
|
|
1705
|
-
const
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1667
|
+
const families = [...new Set(allowedTechnologies.map((t) => t.family))];
|
|
1668
|
+
const categories = [
|
|
1669
|
+
...new Set(allowedTechnologies.map((t) => t.categoryId))
|
|
1670
|
+
];
|
|
1671
|
+
const subcategories = [
|
|
1672
|
+
...new Set(allowedTechnologies.map((t) => t.subcategoryId))
|
|
1673
|
+
];
|
|
1674
|
+
return {
|
|
1675
|
+
technologies: allowedTechnologies,
|
|
1676
|
+
families,
|
|
1677
|
+
categories,
|
|
1678
|
+
subcategories
|
|
1679
|
+
};
|
|
1710
1680
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1681
|
+
};
|
|
1682
|
+
|
|
1683
|
+
// src/backoffice/types/static/blocking-condition.types.ts
|
|
1684
|
+
var BlockingCondition = /* @__PURE__ */ ((BlockingCondition2) => {
|
|
1685
|
+
BlockingCondition2["PREGNANCY"] = "pregnancy";
|
|
1686
|
+
BlockingCondition2["BREASTFEEDING"] = "breastfeeding";
|
|
1687
|
+
BlockingCondition2["ACTIVE_INFECTION"] = "active_infection";
|
|
1688
|
+
BlockingCondition2["SKIN_CONDITION"] = "skin_condition";
|
|
1689
|
+
BlockingCondition2["AUTOIMMUNE_DISEASE"] = "autoimmune_disease";
|
|
1690
|
+
BlockingCondition2["BLOOD_THINNERS"] = "blood_thinners";
|
|
1691
|
+
BlockingCondition2["RECENT_SURGERY"] = "recent_surgery";
|
|
1692
|
+
BlockingCondition2["DIABETES"] = "diabetes";
|
|
1693
|
+
BlockingCondition2["HEART_CONDITION"] = "heart_condition";
|
|
1694
|
+
BlockingCondition2["HIGH_BLOOD_PRESSURE"] = "high_blood_pressure";
|
|
1695
|
+
BlockingCondition2["KELOID_SCARRING"] = "keloid_scarring";
|
|
1696
|
+
BlockingCondition2["METAL_IMPLANTS"] = "metal_implants";
|
|
1697
|
+
BlockingCondition2["PACEMAKER"] = "pacemaker";
|
|
1698
|
+
BlockingCondition2["CANCER"] = "cancer";
|
|
1699
|
+
BlockingCondition2["EPILEPSY"] = "epilepsy";
|
|
1700
|
+
return BlockingCondition2;
|
|
1701
|
+
})(BlockingCondition || {});
|
|
1702
|
+
|
|
1703
|
+
// src/backoffice/types/static/contraindication.types.ts
|
|
1704
|
+
var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
1705
|
+
Contraindication2["SENSITIVE_SKIN"] = "sensitive_skin";
|
|
1706
|
+
Contraindication2["RECENT_TANNING"] = "recent_tanning";
|
|
1707
|
+
Contraindication2["RECENT_BOTOX"] = "recent_botox";
|
|
1708
|
+
Contraindication2["RECENT_FILLERS"] = "recent_fillers";
|
|
1709
|
+
Contraindication2["SKIN_ALLERGIES"] = "skin_allergies";
|
|
1710
|
+
Contraindication2["MEDICATIONS"] = "medications";
|
|
1711
|
+
Contraindication2["RECENT_CHEMICAL_PEEL"] = "recent_chemical_peel";
|
|
1712
|
+
Contraindication2["RECENT_LASER"] = "recent_laser";
|
|
1713
|
+
Contraindication2["SKIN_INFLAMMATION"] = "skin_inflammation";
|
|
1714
|
+
Contraindication2["OPEN_WOUNDS"] = "open_wounds";
|
|
1715
|
+
Contraindication2["HERPES_SIMPLEX"] = "herpes_simplex";
|
|
1716
|
+
Contraindication2["COLD_SORES"] = "cold_sores";
|
|
1717
|
+
return Contraindication2;
|
|
1718
|
+
})(Contraindication || {});
|
|
1719
|
+
|
|
1720
|
+
// src/backoffice/types/static/procedure-family.types.ts
|
|
1721
|
+
var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
|
|
1722
|
+
ProcedureFamily2["AESTHETICS"] = "aesthetics";
|
|
1723
|
+
ProcedureFamily2["SURGERY"] = "surgery";
|
|
1724
|
+
return ProcedureFamily2;
|
|
1725
|
+
})(ProcedureFamily || {});
|
|
1726
|
+
|
|
1727
|
+
// src/backoffice/types/static/treatment-benefit.types.ts
|
|
1728
|
+
var TreatmentBenefit = /* @__PURE__ */ ((TreatmentBenefit2) => {
|
|
1729
|
+
TreatmentBenefit2["WRINKLE_REDUCTION"] = "wrinkle_reduction";
|
|
1730
|
+
TreatmentBenefit2["SKIN_TIGHTENING"] = "skin_tightening";
|
|
1731
|
+
TreatmentBenefit2["COLLAGEN_PRODUCTION"] = "collagen_production";
|
|
1732
|
+
TreatmentBenefit2["ACNE_REDUCTION"] = "acne_reduction";
|
|
1733
|
+
TreatmentBenefit2["SCAR_REDUCTION"] = "scar_reduction";
|
|
1734
|
+
TreatmentBenefit2["PIGMENTATION_IMPROVEMENT"] = "pigmentation_improvement";
|
|
1735
|
+
TreatmentBenefit2["HAIR_REMOVAL"] = "hair_removal";
|
|
1736
|
+
TreatmentBenefit2["MUSCLE_TONING"] = "muscle_toning";
|
|
1737
|
+
TreatmentBenefit2["FAT_REDUCTION"] = "fat_reduction";
|
|
1738
|
+
TreatmentBenefit2["CELLULITE_REDUCTION"] = "cellulite_reduction";
|
|
1739
|
+
TreatmentBenefit2["SKIN_REJUVENATION"] = "skin_rejuvenation";
|
|
1740
|
+
TreatmentBenefit2["PORE_REDUCTION"] = "pore_reduction";
|
|
1741
|
+
TreatmentBenefit2["TEXTURE_IMPROVEMENT"] = "texture_improvement";
|
|
1742
|
+
TreatmentBenefit2["HYDRATION_BOOST"] = "hydration_boost";
|
|
1743
|
+
TreatmentBenefit2["CIRCULATION_IMPROVEMENT"] = "circulation_improvement";
|
|
1744
|
+
return TreatmentBenefit2;
|
|
1745
|
+
})(TreatmentBenefit || {});
|
|
1746
|
+
|
|
1747
|
+
// src/backoffice/validations/schemas.ts
|
|
1748
|
+
var import_zod2 = require("zod");
|
|
1749
|
+
var blockingConditionSchema = import_zod2.z.nativeEnum(BlockingCondition);
|
|
1750
|
+
var contraindicationSchema = import_zod2.z.nativeEnum(Contraindication);
|
|
1751
|
+
var treatmentBenefitSchema = import_zod2.z.nativeEnum(TreatmentBenefit);
|
|
1752
|
+
var procedureFamilySchema = import_zod2.z.nativeEnum(ProcedureFamily);
|
|
1753
|
+
var timeUnitSchema = import_zod2.z.nativeEnum(TimeUnit);
|
|
1754
|
+
var requirementTypeSchema = import_zod2.z.nativeEnum(RequirementType);
|
|
1755
|
+
var certificationLevelSchema = import_zod2.z.nativeEnum(CertificationLevel);
|
|
1756
|
+
var certificationSpecialtySchema = import_zod2.z.nativeEnum(
|
|
1757
|
+
CertificationSpecialty
|
|
1758
|
+
);
|
|
1759
|
+
var certificationRequirementSchema = import_zod2.z.object({
|
|
1760
|
+
minimumLevel: certificationLevelSchema,
|
|
1761
|
+
requiredSpecialties: import_zod2.z.array(certificationSpecialtySchema).max(5, "Maximum 5 specialties allowed").optional()
|
|
1762
|
+
});
|
|
1763
|
+
var timeframeSchema = import_zod2.z.object({
|
|
1764
|
+
duration: import_zod2.z.number().min(1, "Duration must be positive"),
|
|
1765
|
+
unit: timeUnitSchema,
|
|
1766
|
+
notifyAt: import_zod2.z.array(import_zod2.z.number()).min(1, "At least one notification point is required")
|
|
1767
|
+
});
|
|
1768
|
+
var requirementSchema = import_zod2.z.object({
|
|
1769
|
+
name: import_zod2.z.string().min(1, "Name is required").max(100, "Name is too long"),
|
|
1770
|
+
description: import_zod2.z.string().min(1, "Description is required"),
|
|
1771
|
+
type: requirementTypeSchema,
|
|
1772
|
+
timeframe: timeframeSchema,
|
|
1773
|
+
importance: import_zod2.z.enum(["low", "medium", "high"]),
|
|
1774
|
+
isActive: import_zod2.z.boolean().default(true)
|
|
1775
|
+
});
|
|
1776
|
+
var technologyRequirementsSchema = import_zod2.z.object({
|
|
1777
|
+
pre: import_zod2.z.array(requirementSchema),
|
|
1778
|
+
post: import_zod2.z.array(requirementSchema)
|
|
1779
|
+
});
|
|
1780
|
+
var technologySchema = import_zod2.z.object({
|
|
1781
|
+
name: import_zod2.z.string().min(1, "Name is required").max(100, "Name is too long"),
|
|
1782
|
+
description: import_zod2.z.string().max(1e3, "Description is too long").optional(),
|
|
1783
|
+
technicalDetails: import_zod2.z.string().max(2e3, "Technical details are too long").optional(),
|
|
1784
|
+
family: procedureFamilySchema,
|
|
1785
|
+
categoryId: import_zod2.z.string().min(1, "Category ID is required"),
|
|
1786
|
+
subcategoryId: import_zod2.z.string().min(1, "Subcategory ID is required"),
|
|
1787
|
+
requirements: technologyRequirementsSchema.default({
|
|
1788
|
+
pre: [],
|
|
1789
|
+
post: []
|
|
1790
|
+
}),
|
|
1791
|
+
blockingConditions: import_zod2.z.array(blockingConditionSchema),
|
|
1792
|
+
contraindications: import_zod2.z.array(contraindicationSchema),
|
|
1793
|
+
documentationTemplates: import_zod2.z.array(documentTemplateSchema),
|
|
1794
|
+
benefits: import_zod2.z.array(treatmentBenefitSchema),
|
|
1795
|
+
certificationRequirement: certificationRequirementSchema,
|
|
1796
|
+
isActive: import_zod2.z.boolean().default(true)
|
|
1797
|
+
});
|
|
1798
|
+
var categorySchema = import_zod2.z.object({
|
|
1799
|
+
name: import_zod2.z.string().min(1, "Name is required").max(100, "Name is too long"),
|
|
1800
|
+
description: import_zod2.z.string().optional(),
|
|
1801
|
+
family: procedureFamilySchema,
|
|
1802
|
+
isActive: import_zod2.z.boolean().default(true)
|
|
1803
|
+
});
|
|
1804
|
+
var subcategorySchema = import_zod2.z.object({
|
|
1805
|
+
name: import_zod2.z.string().min(1, "Name is required").max(100, "Name is too long"),
|
|
1806
|
+
description: import_zod2.z.string().optional(),
|
|
1807
|
+
categoryId: import_zod2.z.string().min(1, "Category ID is required"),
|
|
1808
|
+
isActive: import_zod2.z.boolean().default(true)
|
|
1809
|
+
});
|
|
1810
|
+
var categoryUpdateSchema = categorySchema.partial();
|
|
1811
|
+
var subcategoryUpdateSchema = subcategorySchema.partial();
|
|
1812
|
+
var technologyUpdateSchema = technologySchema.partial();
|
|
1813
|
+
var requirementUpdateSchema = requirementSchema.partial();
|
|
1814
|
+
|
|
1815
|
+
// src/backoffice/constants/certification.constants.ts
|
|
1816
|
+
var DEFAULT_CERTIFICATION_REQUIREMENT2 = {
|
|
1817
|
+
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
1818
|
+
requiredSpecialties: []
|
|
1819
|
+
};
|
|
1820
|
+
|
|
1821
|
+
// src/backoffice/errors/backoffice.errors.ts
|
|
1822
|
+
var BackofficeError = class extends Error {
|
|
1823
|
+
constructor(message) {
|
|
1824
|
+
super(message);
|
|
1825
|
+
this.name = "BackofficeError";
|
|
1826
|
+
}
|
|
1827
|
+
};
|
|
1828
|
+
var CategoryError = class extends BackofficeError {
|
|
1829
|
+
constructor(message) {
|
|
1830
|
+
super(message);
|
|
1831
|
+
this.name = "CategoryError";
|
|
1832
|
+
}
|
|
1833
|
+
};
|
|
1834
|
+
var CategoryNotFoundError = class extends CategoryError {
|
|
1835
|
+
constructor(id) {
|
|
1836
|
+
super(`Kategorija sa ID-em ${id} nije prona\u0111ena`);
|
|
1837
|
+
this.name = "CategoryNotFoundError";
|
|
1838
|
+
}
|
|
1839
|
+
};
|
|
1840
|
+
var InvalidCategoryDataError = class extends CategoryError {
|
|
1841
|
+
constructor(message) {
|
|
1842
|
+
super(`Neva\u017Ee\u0107i podaci za kategoriju: ${message}`);
|
|
1843
|
+
this.name = "InvalidCategoryDataError";
|
|
1844
|
+
}
|
|
1845
|
+
};
|
|
1846
|
+
var SubcategoryError = class extends BackofficeError {
|
|
1847
|
+
constructor(message) {
|
|
1848
|
+
super(message);
|
|
1849
|
+
this.name = "SubcategoryError";
|
|
1850
|
+
}
|
|
1851
|
+
};
|
|
1852
|
+
var SubcategoryNotFoundError = class extends SubcategoryError {
|
|
1853
|
+
constructor(id) {
|
|
1854
|
+
super(`Podkategorija sa ID-em ${id} nije prona\u0111ena`);
|
|
1855
|
+
this.name = "SubcategoryNotFoundError";
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
var InvalidSubcategoryDataError = class extends SubcategoryError {
|
|
1859
|
+
constructor(message) {
|
|
1860
|
+
super(`Neva\u017Ee\u0107i podaci za podkategoriju: ${message}`);
|
|
1861
|
+
this.name = "InvalidSubcategoryDataError";
|
|
1862
|
+
}
|
|
1863
|
+
};
|
|
1864
|
+
var TechnologyError = class extends BackofficeError {
|
|
1865
|
+
constructor(message) {
|
|
1866
|
+
super(message);
|
|
1867
|
+
this.name = "TechnologyError";
|
|
1728
1868
|
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
const docRef = (0, import_firestore7.doc)(this.collectionRef, templateId);
|
|
1735
|
-
await (0, import_firestore7.deleteDoc)(docRef);
|
|
1869
|
+
};
|
|
1870
|
+
var TechnologyNotFoundError = class extends TechnologyError {
|
|
1871
|
+
constructor(id) {
|
|
1872
|
+
super(`Tehnologija sa ID-em ${id} nije prona\u0111ena`);
|
|
1873
|
+
this.name = "TechnologyNotFoundError";
|
|
1736
1874
|
}
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
*/
|
|
1743
|
-
async getActiveTemplates(pageSize = 20, lastDoc) {
|
|
1744
|
-
let q = (0, import_firestore7.query)(
|
|
1745
|
-
this.collectionRef,
|
|
1746
|
-
(0, import_firestore7.where)("isActive", "==", true),
|
|
1747
|
-
(0, import_firestore7.orderBy)("updatedAt", "desc"),
|
|
1748
|
-
(0, import_firestore7.limit)(pageSize)
|
|
1749
|
-
);
|
|
1750
|
-
if (lastDoc) {
|
|
1751
|
-
q = (0, import_firestore7.query)(q, (0, import_firestore7.startAfter)(lastDoc));
|
|
1752
|
-
}
|
|
1753
|
-
const querySnapshot = await (0, import_firestore7.getDocs)(q);
|
|
1754
|
-
const templates = [];
|
|
1755
|
-
let lastVisible = null;
|
|
1756
|
-
querySnapshot.forEach((doc10) => {
|
|
1757
|
-
templates.push(doc10.data());
|
|
1758
|
-
lastVisible = doc10;
|
|
1759
|
-
});
|
|
1760
|
-
return {
|
|
1761
|
-
templates,
|
|
1762
|
-
lastDoc: lastVisible
|
|
1763
|
-
};
|
|
1875
|
+
};
|
|
1876
|
+
var InvalidTechnologyDataError = class extends TechnologyError {
|
|
1877
|
+
constructor(message) {
|
|
1878
|
+
super(`Neva\u017Ee\u0107i podaci za tehnologiju: ${message}`);
|
|
1879
|
+
this.name = "InvalidTechnologyDataError";
|
|
1764
1880
|
}
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
* @returns Array of templates and the last document for pagination
|
|
1771
|
-
*/
|
|
1772
|
-
async getTemplatesByTags(tags, pageSize = 20, lastDoc) {
|
|
1773
|
-
let q = (0, import_firestore7.query)(
|
|
1774
|
-
this.collectionRef,
|
|
1775
|
-
(0, import_firestore7.where)("isActive", "==", true),
|
|
1776
|
-
(0, import_firestore7.where)("tags", "array-contains-any", tags),
|
|
1777
|
-
(0, import_firestore7.orderBy)("updatedAt", "desc"),
|
|
1778
|
-
(0, import_firestore7.limit)(pageSize)
|
|
1779
|
-
);
|
|
1780
|
-
if (lastDoc) {
|
|
1781
|
-
q = (0, import_firestore7.query)(q, (0, import_firestore7.startAfter)(lastDoc));
|
|
1782
|
-
}
|
|
1783
|
-
const querySnapshot = await (0, import_firestore7.getDocs)(q);
|
|
1784
|
-
const templates = [];
|
|
1785
|
-
let lastVisible = null;
|
|
1786
|
-
querySnapshot.forEach((doc10) => {
|
|
1787
|
-
templates.push(doc10.data());
|
|
1788
|
-
lastVisible = doc10;
|
|
1789
|
-
});
|
|
1790
|
-
return {
|
|
1791
|
-
templates,
|
|
1792
|
-
lastDoc: lastVisible
|
|
1793
|
-
};
|
|
1881
|
+
};
|
|
1882
|
+
var RequirementError = class extends BackofficeError {
|
|
1883
|
+
constructor(message) {
|
|
1884
|
+
super(message);
|
|
1885
|
+
this.name = "RequirementError";
|
|
1794
1886
|
}
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
* @returns Array of templates and the last document for pagination
|
|
1801
|
-
*/
|
|
1802
|
-
async getTemplatesByCreator(userId, pageSize = 20, lastDoc) {
|
|
1803
|
-
let q = (0, import_firestore7.query)(
|
|
1804
|
-
this.collectionRef,
|
|
1805
|
-
(0, import_firestore7.where)("createdBy", "==", userId),
|
|
1806
|
-
(0, import_firestore7.orderBy)("updatedAt", "desc"),
|
|
1807
|
-
(0, import_firestore7.limit)(pageSize)
|
|
1808
|
-
);
|
|
1809
|
-
if (lastDoc) {
|
|
1810
|
-
q = (0, import_firestore7.query)(q, (0, import_firestore7.startAfter)(lastDoc));
|
|
1811
|
-
}
|
|
1812
|
-
const querySnapshot = await (0, import_firestore7.getDocs)(q);
|
|
1813
|
-
const templates = [];
|
|
1814
|
-
let lastVisible = null;
|
|
1815
|
-
querySnapshot.forEach((doc10) => {
|
|
1816
|
-
templates.push(doc10.data());
|
|
1817
|
-
lastVisible = doc10;
|
|
1818
|
-
});
|
|
1819
|
-
return {
|
|
1820
|
-
templates,
|
|
1821
|
-
lastDoc: lastVisible
|
|
1822
|
-
};
|
|
1887
|
+
};
|
|
1888
|
+
var RequirementNotFoundError = class extends RequirementError {
|
|
1889
|
+
constructor(id) {
|
|
1890
|
+
super(`Zahtev sa ID-em ${id} nije prona\u0111en`);
|
|
1891
|
+
this.name = "RequirementNotFoundError";
|
|
1823
1892
|
}
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
async getAllTemplatesForSelection(options) {
|
|
1830
|
-
let q = (0, import_firestore7.query)(
|
|
1831
|
-
this.collectionRef,
|
|
1832
|
-
(0, import_firestore7.where)("isActive", "==", true),
|
|
1833
|
-
(0, import_firestore7.orderBy)("updatedAt", "desc")
|
|
1834
|
-
);
|
|
1835
|
-
if ((options == null ? void 0 : options.isUserForm) !== void 0) {
|
|
1836
|
-
q = (0, import_firestore7.query)(q, (0, import_firestore7.where)("isUserForm", "==", options.isUserForm));
|
|
1837
|
-
}
|
|
1838
|
-
if ((options == null ? void 0 : options.isRequired) !== void 0) {
|
|
1839
|
-
q = (0, import_firestore7.query)(q, (0, import_firestore7.where)("isRequired", "==", options.isRequired));
|
|
1840
|
-
}
|
|
1841
|
-
const querySnapshot = await (0, import_firestore7.getDocs)(q);
|
|
1842
|
-
const templates = [];
|
|
1843
|
-
querySnapshot.forEach((doc10) => {
|
|
1844
|
-
templates.push(doc10.data());
|
|
1845
|
-
});
|
|
1846
|
-
return templates;
|
|
1893
|
+
};
|
|
1894
|
+
var InvalidRequirementDataError = class extends RequirementError {
|
|
1895
|
+
constructor(message) {
|
|
1896
|
+
super(`Neva\u017Ee\u0107i podaci za zahtev: ${message}`);
|
|
1897
|
+
this.name = "InvalidRequirementDataError";
|
|
1847
1898
|
}
|
|
1848
1899
|
};
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
// src/services/media/media.service.ts
|
|
1854
|
-
var import_firestore8 = require("firebase/firestore");
|
|
1855
|
-
var import_storage2 = require("firebase/storage");
|
|
1856
|
-
var import_firestore9 = require("firebase/firestore");
|
|
1857
|
-
|
|
1858
|
-
// src/backoffice/services/documentation-template.service.ts
|
|
1859
|
-
var DocumentationTemplateService2 = class {
|
|
1860
|
-
/**
|
|
1861
|
-
* Constructor for DocumentationTemplateService
|
|
1862
|
-
* @param db - Firestore instance
|
|
1863
|
-
* @param auth - Firebase Auth instance
|
|
1864
|
-
* @param app - Firebase App instance
|
|
1865
|
-
*/
|
|
1866
|
-
constructor(db, auth, app) {
|
|
1867
|
-
this.apiService = new DocumentationTemplateService(db, auth, app);
|
|
1900
|
+
var InvalidTimeframeError = class extends RequirementError {
|
|
1901
|
+
constructor(message) {
|
|
1902
|
+
super(`Invalid timeframe: ${message}`);
|
|
1903
|
+
this.name = "InvalidTimeframeError";
|
|
1868
1904
|
}
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
*/
|
|
1875
|
-
async createTemplate(data, userId) {
|
|
1876
|
-
return this.apiService.createTemplate(data, userId);
|
|
1905
|
+
};
|
|
1906
|
+
var RelationshipError = class extends BackofficeError {
|
|
1907
|
+
constructor(message) {
|
|
1908
|
+
super(message);
|
|
1909
|
+
this.name = "RelationshipError";
|
|
1877
1910
|
}
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
*/
|
|
1884
|
-
async getTemplateById(templateId, version) {
|
|
1885
|
-
return this.apiService.getTemplateById(templateId, version);
|
|
1911
|
+
};
|
|
1912
|
+
var InvalidHierarchyError = class extends RelationshipError {
|
|
1913
|
+
constructor(message) {
|
|
1914
|
+
super(`Invalid hierarchy: ${message}`);
|
|
1915
|
+
this.name = "InvalidHierarchyError";
|
|
1886
1916
|
}
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
*/
|
|
1893
|
-
async updateTemplate(templateId, data) {
|
|
1894
|
-
return this.apiService.updateTemplate(templateId, data);
|
|
1917
|
+
};
|
|
1918
|
+
var CircularReferenceError = class extends RelationshipError {
|
|
1919
|
+
constructor(message) {
|
|
1920
|
+
super(`Circular reference detected: ${message}`);
|
|
1921
|
+
this.name = "CircularReferenceError";
|
|
1895
1922
|
}
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
return this.apiService.deleteTemplate(templateId);
|
|
1923
|
+
};
|
|
1924
|
+
var BlockingConditionError = class extends BackofficeError {
|
|
1925
|
+
constructor(message) {
|
|
1926
|
+
super(message);
|
|
1927
|
+
this.name = "BlockingConditionError";
|
|
1902
1928
|
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
*/
|
|
1909
|
-
async getActiveTemplates(pageSize = 20, lastDoc) {
|
|
1910
|
-
return this.apiService.getActiveTemplates(pageSize, lastDoc);
|
|
1929
|
+
};
|
|
1930
|
+
var InvalidBlockingConditionError = class extends BlockingConditionError {
|
|
1931
|
+
constructor(condition) {
|
|
1932
|
+
super(`Neva\u017Ee\u0107i blokiraju\u0107i uslov: ${condition}`);
|
|
1933
|
+
this.name = "InvalidBlockingConditionError";
|
|
1911
1934
|
}
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
* @returns Array of templates and the last document for pagination
|
|
1918
|
-
*/
|
|
1919
|
-
async getTemplatesByTags(tags, pageSize = 20, lastDoc) {
|
|
1920
|
-
return this.apiService.getTemplatesByTags(tags, pageSize, lastDoc);
|
|
1935
|
+
};
|
|
1936
|
+
var ContraindicationError = class extends BackofficeError {
|
|
1937
|
+
constructor(message) {
|
|
1938
|
+
super(message);
|
|
1939
|
+
this.name = "ContraindicationError";
|
|
1921
1940
|
}
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
* @returns Array of templates and the last document for pagination
|
|
1928
|
-
*/
|
|
1929
|
-
async getTemplatesByCreator(userId, pageSize = 20, lastDoc) {
|
|
1930
|
-
return this.apiService.getTemplatesByCreator(userId, pageSize, lastDoc);
|
|
1941
|
+
};
|
|
1942
|
+
var InvalidContraindicationError = class extends ContraindicationError {
|
|
1943
|
+
constructor(contraindication) {
|
|
1944
|
+
super(`Neva\u017Ee\u0107a kontraindikacija: ${contraindication}`);
|
|
1945
|
+
this.name = "InvalidContraindicationError";
|
|
1931
1946
|
}
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
*/
|
|
1938
|
-
async getTemplateVersion(templateId, versionNumber) {
|
|
1939
|
-
return this.apiService.getTemplateVersion(templateId, versionNumber);
|
|
1947
|
+
};
|
|
1948
|
+
var TreatmentBenefitError = class extends BackofficeError {
|
|
1949
|
+
constructor(message) {
|
|
1950
|
+
super(message);
|
|
1951
|
+
this.name = "TreatmentBenefitError";
|
|
1940
1952
|
}
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
async getTemplateVersions(templateId) {
|
|
1947
|
-
return this.apiService.getTemplateOldVersions(templateId);
|
|
1953
|
+
};
|
|
1954
|
+
var InvalidTreatmentBenefitError = class extends TreatmentBenefitError {
|
|
1955
|
+
constructor(benefit) {
|
|
1956
|
+
super(`Neva\u017Ee\u0107i benefit tretmana: ${benefit}`);
|
|
1957
|
+
this.name = "InvalidTreatmentBenefitError";
|
|
1948
1958
|
}
|
|
1949
1959
|
};
|
|
1950
1960
|
// Annotate the CommonJS export names for ESM import in node:
|