@blackcode_sa/metaestetics-api 1.5.28 → 1.5.30

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.
Files changed (49) hide show
  1. package/dist/admin/index.d.mts +1324 -1
  2. package/dist/admin/index.d.ts +1324 -1
  3. package/dist/admin/index.js +1674 -2
  4. package/dist/admin/index.mjs +1668 -2
  5. package/dist/backoffice/index.d.mts +99 -7
  6. package/dist/backoffice/index.d.ts +99 -7
  7. package/dist/index.d.mts +4036 -2372
  8. package/dist/index.d.ts +4036 -2372
  9. package/dist/index.js +2331 -2009
  10. package/dist/index.mjs +2279 -1954
  11. package/package.json +2 -1
  12. package/src/admin/aggregation/README.md +79 -0
  13. package/src/admin/aggregation/clinic/README.md +52 -0
  14. package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +642 -0
  15. package/src/admin/aggregation/patient/README.md +27 -0
  16. package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -0
  17. package/src/admin/aggregation/practitioner/README.md +42 -0
  18. package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -0
  19. package/src/admin/aggregation/procedure/README.md +43 -0
  20. package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +508 -0
  21. package/src/admin/index.ts +60 -4
  22. package/src/admin/mailing/README.md +95 -0
  23. package/src/admin/mailing/base.mailing.service.ts +131 -0
  24. package/src/admin/mailing/index.ts +2 -0
  25. package/src/admin/mailing/practitionerInvite/index.ts +1 -0
  26. package/src/admin/mailing/practitionerInvite/practitionerInvite.mailing.ts +256 -0
  27. package/src/admin/mailing/practitionerInvite/templates/invitation.template.ts +101 -0
  28. package/src/index.ts +28 -4
  29. package/src/services/README.md +106 -0
  30. package/src/services/clinic/README.md +87 -0
  31. package/src/services/clinic/clinic.service.ts +197 -107
  32. package/src/services/clinic/utils/clinic.utils.ts +68 -119
  33. package/src/services/clinic/utils/filter.utils.d.ts +23 -0
  34. package/src/services/clinic/utils/filter.utils.ts +264 -0
  35. package/src/services/practitioner/README.md +145 -0
  36. package/src/services/practitioner/practitioner.service.ts +439 -104
  37. package/src/services/procedure/README.md +88 -0
  38. package/src/services/procedure/procedure.service.ts +521 -311
  39. package/src/services/reviews/reviews.service.ts +842 -0
  40. package/src/types/clinic/index.ts +24 -56
  41. package/src/types/practitioner/index.ts +34 -33
  42. package/src/types/procedure/index.ts +32 -0
  43. package/src/types/profile/index.ts +1 -1
  44. package/src/types/reviews/index.ts +126 -0
  45. package/src/validations/clinic.schema.ts +37 -64
  46. package/src/validations/practitioner.schema.ts +42 -32
  47. package/src/validations/procedure.schema.ts +11 -3
  48. package/src/validations/reviews.schema.ts +189 -0
  49. package/src/services/clinic/utils/review.utils.ts +0 -93
@@ -1,5 +1,982 @@
1
1
  import { Timestamp } from 'firebase/firestore';
2
2
  import * as admin from 'firebase-admin';
3
+ import * as mailgun from 'mailgun-js';
4
+
5
+ /**
6
+ * Enum for element types in documentation templates
7
+ */
8
+ declare enum DocumentElementType {
9
+ HEADING = "heading",
10
+ PARAGRAPH = "paragraph",
11
+ LIST = "list",
12
+ DYNAMIC_TEXT = "dynamic_text",
13
+ BINARY_CHOICE = "binary_choice",
14
+ MULTIPLE_CHOICE = "multiple_choice",
15
+ SINGLE_CHOICE = "single_choice",
16
+ RATING_SCALE = "rating_scale",
17
+ TEXT_INPUT = "text_input",
18
+ DATE_PICKER = "date_picker",
19
+ SIGNATURE = "signature",
20
+ FILE_UPLOAD = "file_upload"
21
+ }
22
+ /**
23
+ * Enum for list types
24
+ */
25
+ declare enum ListType {
26
+ ORDERED = "ordered",
27
+ UNORDERED = "unordered"
28
+ }
29
+ /**
30
+ * Enum for heading levels
31
+ */
32
+ declare enum HeadingLevel {
33
+ H1 = "h1",
34
+ H2 = "h2",
35
+ H3 = "h3",
36
+ H4 = "h4",
37
+ H5 = "h5",
38
+ H6 = "h6"
39
+ }
40
+ /**
41
+ * Base interface for all document elements
42
+ */
43
+ interface BaseDocumentElement {
44
+ id: string;
45
+ type: DocumentElementType;
46
+ required?: boolean;
47
+ }
48
+ /**
49
+ * Interface for heading element
50
+ */
51
+ interface HeadingElement extends BaseDocumentElement {
52
+ type: DocumentElementType.HEADING;
53
+ text: string;
54
+ level: HeadingLevel;
55
+ }
56
+ /**
57
+ * Interface for paragraph element
58
+ */
59
+ interface ParagraphElement extends BaseDocumentElement {
60
+ type: DocumentElementType.PARAGRAPH;
61
+ text: string;
62
+ }
63
+ /**
64
+ * Interface for list element
65
+ */
66
+ interface ListElement extends BaseDocumentElement {
67
+ type: DocumentElementType.LIST;
68
+ items: string[];
69
+ listType: ListType;
70
+ }
71
+ /**
72
+ * Interface for dynamic text element
73
+ */
74
+ interface DynamicTextElement extends BaseDocumentElement {
75
+ type: DocumentElementType.DYNAMIC_TEXT;
76
+ text: string;
77
+ }
78
+ /**
79
+ * Interface for binary choice element (Yes/No)
80
+ */
81
+ interface BinaryChoiceElement extends BaseDocumentElement {
82
+ type: DocumentElementType.BINARY_CHOICE;
83
+ question: string;
84
+ defaultValue?: boolean;
85
+ }
86
+ /**
87
+ * Interface for multiple choice element
88
+ */
89
+ interface MultipleChoiceElement extends BaseDocumentElement {
90
+ type: DocumentElementType.MULTIPLE_CHOICE;
91
+ question: string;
92
+ options: string[];
93
+ defaultValues?: string[];
94
+ }
95
+ /**
96
+ * Interface for single choice element
97
+ */
98
+ interface SingleChoiceElement extends BaseDocumentElement {
99
+ type: DocumentElementType.SINGLE_CHOICE;
100
+ question: string;
101
+ options: string[];
102
+ defaultValue?: string;
103
+ }
104
+ /**
105
+ * Interface for rating scale element
106
+ */
107
+ interface RatingScaleElement extends BaseDocumentElement {
108
+ type: DocumentElementType.RATING_SCALE;
109
+ question: string;
110
+ min: number;
111
+ max: number;
112
+ labels?: {
113
+ [key: number]: string;
114
+ };
115
+ defaultValue?: number;
116
+ }
117
+ /**
118
+ * Interface for text input element
119
+ */
120
+ interface TextInputElement extends BaseDocumentElement {
121
+ type: DocumentElementType.TEXT_INPUT;
122
+ label: string;
123
+ placeholder?: string;
124
+ multiline?: boolean;
125
+ defaultValue?: string;
126
+ }
127
+ /**
128
+ * Interface for date picker element
129
+ */
130
+ interface DatePickerElement extends BaseDocumentElement {
131
+ type: DocumentElementType.DATE_PICKER;
132
+ label: string;
133
+ defaultValue?: string;
134
+ }
135
+ /**
136
+ * Interface for signature element
137
+ */
138
+ interface SignatureElement extends BaseDocumentElement {
139
+ type: DocumentElementType.SIGNATURE;
140
+ label: string;
141
+ }
142
+ /**
143
+ * Interface for file upload element
144
+ */
145
+ interface FileUploadElement extends BaseDocumentElement {
146
+ type: DocumentElementType.FILE_UPLOAD;
147
+ label: string;
148
+ allowedFileTypes?: string[];
149
+ maxFileSizeMB?: number;
150
+ }
151
+ /**
152
+ * Union type for all document elements
153
+ */
154
+ type DocumentElement = HeadingElement | ParagraphElement | ListElement | DynamicTextElement | BinaryChoiceElement | MultipleChoiceElement | SingleChoiceElement | RatingScaleElement | TextInputElement | DatePickerElement | SignatureElement | FileUploadElement;
155
+ /**
156
+ * Interface for document template
157
+ */
158
+ interface DocumentTemplate {
159
+ id: string;
160
+ title: string;
161
+ description?: string;
162
+ createdAt: number;
163
+ updatedAt: number;
164
+ createdBy: string;
165
+ elements: DocumentElement[];
166
+ tags?: string[];
167
+ version: number;
168
+ isActive: boolean;
169
+ }
170
+
171
+ /**
172
+ * Nivoi sertifikacije medicinskog osoblja, poređani od najnižeg do najvišeg
173
+ */
174
+ declare enum CertificationLevel {
175
+ AESTHETICIAN = "aesthetician",// Osnovni estetičar
176
+ NURSE_ASSISTANT = "nurse_assistant",// Medicinski tehničar
177
+ NURSE = "nurse",// Medicinska sestra
178
+ NURSE_PRACTITIONER = "nurse_practitioner",// Viša medicinska sestra
179
+ PHYSICIAN_ASSISTANT = "physician_assistant",// Lekar asistent
180
+ DOCTOR = "doctor",// Doktor medicine
181
+ SPECIALIST = "specialist",// Specijalista
182
+ PLASTIC_SURGEON = "plastic_surgeon"
183
+ }
184
+ /**
185
+ * Dodatne specijalizacije potrebne za određene procedure
186
+ */
187
+ declare enum CertificationSpecialty {
188
+ LASER = "laser",// Sertifikat za laserske tretmane
189
+ INJECTABLES = "injectables",// Sertifikat za injekcione tretmane
190
+ CHEMICAL_PEELS = "chemical_peels",// Sertifikat za hemijske pilinge
191
+ MICRODERMABRASION = "microdermabrasion",// Sertifikat za mikrodermoabraziju
192
+ BODY_CONTOURING = "body_contouring",// Sertifikat za konturiranje tela
193
+ SKIN_CARE = "skin_care",// Sertifikat za negu kože
194
+ WOUND_CARE = "wound_care",// Sertifikat za tretman rana
195
+ ANESTHESIA = "anesthesia"
196
+ }
197
+ /**
198
+ * Zahtevi sertifikacije za izvođenje procedura
199
+ */
200
+ interface CertificationRequirement {
201
+ /** Minimalni nivo sertifikacije potreban za proceduru */
202
+ minimumLevel: CertificationLevel;
203
+ /** Dodatne specijalizacije potrebne za proceduru */
204
+ requiredSpecialties?: CertificationSpecialty[];
205
+ }
206
+
207
+ /**
208
+ * Condensed clinic review information
209
+ * @description Used for aggregated data attached to clinic documents
210
+ */
211
+ interface ClinicReviewInfo {
212
+ totalReviews: number;
213
+ averageRating: number;
214
+ cleanliness: number;
215
+ facilities: number;
216
+ staffFriendliness: number;
217
+ waitingTime: number;
218
+ accessibility: number;
219
+ recommendationPercentage: number;
220
+ }
221
+ /**
222
+ * Condensed practitioner review information
223
+ * @description Used for aggregated data attached to practitioner documents
224
+ */
225
+ interface PractitionerReviewInfo {
226
+ totalReviews: number;
227
+ averageRating: number;
228
+ knowledgeAndExpertise: number;
229
+ communicationSkills: number;
230
+ bedSideManner: number;
231
+ thoroughness: number;
232
+ trustworthiness: number;
233
+ recommendationPercentage: number;
234
+ }
235
+ /**
236
+ * Condensed procedure review information
237
+ * @description Used for aggregated data attached to procedure documents
238
+ */
239
+ interface ProcedureReviewInfo {
240
+ totalReviews: number;
241
+ averageRating: number;
242
+ effectivenessOfTreatment: number;
243
+ outcomeExplanation: number;
244
+ painManagement: number;
245
+ followUpCare: number;
246
+ valueForMoney: number;
247
+ recommendationPercentage: number;
248
+ }
249
+
250
+ /**
251
+ * Familije procedura u sistemu
252
+ * Predstavlja najviši nivo hijerarhije i deli procedure na estetske i hirurške
253
+ *
254
+ * @enum
255
+ * @property AESTHETICS - Estetske procedure (neivazivne i minimalno invazivne)
256
+ * @property SURGERY - Hirurške procedure (invazivne)
257
+ */
258
+ declare enum ProcedureFamily {
259
+ /** Estetske procedure koje ne zahtevaju hirurški zahvat */
260
+ AESTHETICS = "aesthetics",
261
+ /** Hirurške procedure koje zahtevaju operativni zahvat */
262
+ SURGERY = "surgery"
263
+ }
264
+
265
+ /**
266
+ * Kategorija procedura
267
+ * Kategorije su prvi nivo hijerarhije nakon procedure family
268
+ * One grupišu slične podkategorije u okviru familije procedura
269
+ *
270
+ * @property id - Jedinstveni identifikator kategorije
271
+ * @property name - Naziv kategorije
272
+ * @property description - Detaljan opis kategorije i njene namene
273
+ * @property family - Familija procedura kojoj kategorija pripada (aesthetics/surgery)
274
+ * @property isActive - Da li je kategorija aktivna u sistemu
275
+ * @property createdAt - Datum kreiranja
276
+ * @property updatedAt - Datum poslednjeg ažuriranja
277
+ */
278
+ interface Category {
279
+ /** Jedinstveni identifikator kategorije (automatski generisan od strane Firestore) */
280
+ id?: string;
281
+ /** Naziv kategorije */
282
+ name: string;
283
+ /** Detaljan opis kategorije i njene namene */
284
+ description: string;
285
+ /** Tip procedure kojoj kategorija pripada */
286
+ family: ProcedureFamily;
287
+ /** Datum kreiranja kategorije */
288
+ createdAt: Date;
289
+ /** Datum poslednjeg ažuriranja kategorije */
290
+ updatedAt: Date;
291
+ /** Flag koji označava da li je kategorija aktivna */
292
+ isActive: boolean;
293
+ }
294
+
295
+ /**
296
+ * Podkategorija procedura
297
+ * Podkategorije su drugi nivo hijerarhije i pripadaju određenoj kategoriji
298
+ * One grupišu slične tehnologije u okviru kategorije
299
+ *
300
+ * @property id - Jedinstveni identifikator podkategorije
301
+ * @property name - Naziv podkategorije
302
+ * @property description - Detaljan opis podkategorije i njene namene
303
+ * @property categoryId - ID kategorije kojoj podkategorija pripada
304
+ * @property isActive - Da li je podkategorija aktivna u sistemu
305
+ * @property createdAt - Datum kreiranja
306
+ * @property updatedAt - Datum poslednjeg ažuriranja
307
+ */
308
+ interface Subcategory {
309
+ /** Jedinstveni identifikator podkategorije (automatski generisan od strane Firestore) */
310
+ id?: string;
311
+ /** Naziv podkategorije */
312
+ name: string;
313
+ /** Detaljniji opis podkategorije */
314
+ description?: string;
315
+ /** ID kategorije kojoj podkategorija pripada */
316
+ categoryId: string;
317
+ /** Flag koji označava da li je podkategorija aktivna */
318
+ isActive: boolean;
319
+ /** Datum kreiranja podkategorije */
320
+ createdAt: Date;
321
+ /** Datum poslednjeg ažuriranja podkategorije */
322
+ updatedAt: Date;
323
+ }
324
+
325
+ /**
326
+ * Jedinica mere za vremenski period
327
+ */
328
+ declare enum TimeUnit {
329
+ HOURS = "hours",
330
+ DAYS = "days"
331
+ }
332
+ /**
333
+ * Tip zahteva - da li se odnosi na period pre ili posle procedure
334
+ */
335
+ declare enum RequirementType {
336
+ PRE = "pre",
337
+ POST = "post"
338
+ }
339
+ /**
340
+ * Nivo važnosti zahteva
341
+ */
342
+ type RequirementImportance = "low" | "medium" | "high";
343
+ /**
344
+ * Vremenski okvir za zahtev
345
+ * @property duration - Trajanje u odabranoj jedinici vremena
346
+ * @property unit - Jedinica vremena (sati ili dani)
347
+ * @property notifyAt - Lista trenutaka kada treba poslati obaveštenje (u istoj jedinici)
348
+ */
349
+ interface TimeFrame {
350
+ duration: number;
351
+ unit: TimeUnit;
352
+ notifyAt: number[];
353
+ }
354
+ /**
355
+ * Zahtev koji se može povezati sa tehnologijom
356
+ * Može biti zahtev pre procedure (pre) ili posle procedure (post)
357
+ *
358
+ * @property id - Jedinstveni identifikator zahteva
359
+ * @property type - Tip zahteva (pre/post)
360
+ * @property name - Naziv zahteva
361
+ * @property description - Detaljan opis zahteva
362
+ * @property timeframe - Vremenski okvir za zahtev
363
+ * @property importance - Nivo važnosti zahteva
364
+ * @property isActive - Da li je zahtev aktivan u sistemu
365
+ * @property createdAt - Datum kreiranja
366
+ * @property updatedAt - Datum poslednjeg ažuriranja
367
+ */
368
+ interface Requirement {
369
+ id: string;
370
+ type: RequirementType;
371
+ name: string;
372
+ description: string;
373
+ timeframe: TimeFrame;
374
+ importance: RequirementImportance;
375
+ isActive: boolean;
376
+ createdAt: Date;
377
+ updatedAt: Date;
378
+ }
379
+
380
+ /**
381
+ * Blokirajući uslovi koji mogu sprečiti proceduru
382
+ * Ovi uslovi predstavljaju apsolutne kontraindikacije koje onemogućavaju izvođenje procedure
383
+ */
384
+ declare enum BlockingCondition {
385
+ PREGNANCY = "pregnancy",
386
+ BREASTFEEDING = "breastfeeding",
387
+ ACTIVE_INFECTION = "active_infection",
388
+ SKIN_CONDITION = "skin_condition",
389
+ AUTOIMMUNE_DISEASE = "autoimmune_disease",
390
+ BLOOD_THINNERS = "blood_thinners",
391
+ RECENT_SURGERY = "recent_surgery",
392
+ DIABETES = "diabetes",
393
+ HEART_CONDITION = "heart_condition",
394
+ HIGH_BLOOD_PRESSURE = "high_blood_pressure",
395
+ KELOID_SCARRING = "keloid_scarring",
396
+ METAL_IMPLANTS = "metal_implants",
397
+ PACEMAKER = "pacemaker",
398
+ CANCER = "cancer",
399
+ EPILEPSY = "epilepsy"
400
+ }
401
+
402
+ /**
403
+ * Kontraindikacije koje mogu uticati na proceduru
404
+ * Ovi uslovi predstavljaju relativne kontraindikacije koje zahtevaju posebnu pažnju
405
+ */
406
+ declare enum Contraindication {
407
+ SENSITIVE_SKIN = "sensitive_skin",
408
+ RECENT_TANNING = "recent_tanning",
409
+ RECENT_BOTOX = "recent_botox",
410
+ RECENT_FILLERS = "recent_fillers",
411
+ SKIN_ALLERGIES = "skin_allergies",
412
+ MEDICATIONS = "medications",
413
+ RECENT_CHEMICAL_PEEL = "recent_chemical_peel",
414
+ RECENT_LASER = "recent_laser",
415
+ SKIN_INFLAMMATION = "skin_inflammation",
416
+ OPEN_WOUNDS = "open_wounds",
417
+ HERPES_SIMPLEX = "herpes_simplex",
418
+ COLD_SORES = "cold_sores"
419
+ }
420
+
421
+ /**
422
+ * Benefiti koji se mogu očekivati od procedure
423
+ * Lista mogućih pozitivnih efekata i rezultata tretmana
424
+ */
425
+ declare enum TreatmentBenefit {
426
+ WRINKLE_REDUCTION = "wrinkle_reduction",
427
+ SKIN_TIGHTENING = "skin_tightening",
428
+ COLLAGEN_PRODUCTION = "collagen_production",
429
+ ACNE_REDUCTION = "acne_reduction",
430
+ SCAR_REDUCTION = "scar_reduction",
431
+ PIGMENTATION_IMPROVEMENT = "pigmentation_improvement",
432
+ HAIR_REMOVAL = "hair_removal",
433
+ MUSCLE_TONING = "muscle_toning",
434
+ FAT_REDUCTION = "fat_reduction",
435
+ CELLULITE_REDUCTION = "cellulite_reduction",
436
+ SKIN_REJUVENATION = "skin_rejuvenation",
437
+ PORE_REDUCTION = "pore_reduction",
438
+ TEXTURE_IMPROVEMENT = "texture_improvement",
439
+ HYDRATION_BOOST = "hydration_boost",
440
+ CIRCULATION_IMPROVEMENT = "circulation_improvement"
441
+ }
442
+
443
+ /**
444
+ * Technology used in medical procedures
445
+ * Technologies are now a top-level collection that reference their full path in the hierarchy
446
+ * through family, category, and subcategory IDs
447
+ *
448
+ * @property id - Unique identifier of the technology
449
+ * @property name - Name of the technology
450
+ * @property description - Detailed description of the technology and its application
451
+ * @property family - The procedure family this technology belongs to (aesthetics/surgery)
452
+ * @property categoryId - ID of the category this technology belongs to
453
+ * @property subcategoryId - ID of the subcategory this technology belongs to
454
+ * @property technicalDetails - Technical specifications and details
455
+ * @property requirements - List of pre and post procedure requirements
456
+ * @property blockingConditions - List of conditions that prevent the procedure
457
+ * @property contraindications - List of conditions requiring special attention
458
+ * @property benefits - List of expected benefits from the procedure
459
+ * @property certificationRequirement - Required certification level and specialties
460
+ * @property documentationTemplates - List of documentation templates required for this technology
461
+ * @property isActive - Whether the technology is active in the system
462
+ * @property createdAt - Creation date
463
+ * @property updatedAt - Last update date
464
+ */
465
+ interface Technology {
466
+ id?: string;
467
+ name: string;
468
+ description: string;
469
+ family: ProcedureFamily;
470
+ categoryId: string;
471
+ subcategoryId: string;
472
+ technicalDetails?: string;
473
+ requirements: {
474
+ pre: Requirement[];
475
+ post: Requirement[];
476
+ };
477
+ blockingConditions: BlockingCondition[];
478
+ contraindications: Contraindication[];
479
+ benefits: TreatmentBenefit[];
480
+ certificationRequirement: CertificationRequirement;
481
+ documentationTemplates?: DocumentTemplate[];
482
+ isActive: boolean;
483
+ createdAt: Date;
484
+ updatedAt: Date;
485
+ }
486
+
487
+ /**
488
+ * Product used in procedures
489
+ * Can be consumables, equipment, or any other product needed for performing procedures
490
+ *
491
+ * @property id - Unique identifier of the product
492
+ * @property name - Name of the product
493
+ * @property description - Detailed description of the product and its purpose
494
+ * @property brandId - ID of the brand that manufactures this product
495
+ * @property technologyId - ID of the technology this product is used with
496
+ * @property technicalDetails - Technical details and specifications
497
+ * @property warnings - List of warnings related to product use
498
+ * @property dosage - Dosage information (if applicable)
499
+ * @property composition - Product composition
500
+ * @property indications - List of indications for use
501
+ * @property contraindications - List of contraindications
502
+ * @property isActive - Whether the product is active in the system
503
+ * @property createdAt - Creation date
504
+ * @property updatedAt - Last update date
505
+ */
506
+ interface Product {
507
+ id?: string;
508
+ name: string;
509
+ brandId: string;
510
+ technologyId: string;
511
+ createdAt: Date;
512
+ updatedAt: Date;
513
+ isActive: boolean;
514
+ description?: string;
515
+ technicalDetails?: string;
516
+ warnings?: string[];
517
+ dosage?: string;
518
+ composition?: string;
519
+ indications?: string[];
520
+ contraindications?: string[];
521
+ }
522
+
523
+ declare enum PricingMeasure {
524
+ PER_ML = "per_ml",
525
+ PER_ZONE = "per_zone",
526
+ PER_AREA = "per_area",
527
+ PER_SESSION = "per_session",
528
+ PER_TREATMENT = "per_treatment",
529
+ PER_PACKAGE = "per_package"
530
+ }
531
+ declare enum Currency {
532
+ EUR = "EUR",
533
+ USD = "USD",
534
+ GBP = "GBP",
535
+ CHF = "CHF",
536
+ AUD = "AUD"
537
+ }
538
+
539
+ /**
540
+ * Procedure represents a specific medical procedure that can be performed by a practitioner in a clinic
541
+ * It inherits properties from technology and adds clinic/practitioner specific details
542
+ */
543
+ interface Procedure {
544
+ /** Unique identifier of the procedure */
545
+ id: string;
546
+ /** Name of the procedure */
547
+ name: string;
548
+ /** Detailed description of the procedure */
549
+ description: string;
550
+ /** Family of procedures this belongs to (aesthetics/surgery) */
551
+ family: ProcedureFamily;
552
+ /** Category this procedure belongs to */
553
+ category: Category;
554
+ /** Subcategory this procedure belongs to */
555
+ subcategory: Subcategory;
556
+ /** Technology used in this procedure */
557
+ technology: Technology;
558
+ /** Product used in this procedure */
559
+ product: Product;
560
+ /** Price of the procedure */
561
+ price: number;
562
+ /** Currency for the price */
563
+ currency: Currency;
564
+ /** How the price is measured (per ml, per zone, etc.) */
565
+ pricingMeasure: PricingMeasure;
566
+ /** Duration of the procedure in minutes */
567
+ duration: number;
568
+ /** Blocking conditions that prevent this procedure */
569
+ blockingConditions: BlockingCondition[];
570
+ /** Treatment benefits of this procedure */
571
+ treatmentBenefits: TreatmentBenefit[];
572
+ /** Pre-procedure requirements */
573
+ preRequirements: Requirement[];
574
+ /** Post-procedure requirements */
575
+ postRequirements: Requirement[];
576
+ /** Certification requirements for performing this procedure */
577
+ certificationRequirement: CertificationRequirement;
578
+ /** Documentation templates required for this procedure */
579
+ documentationTemplates: DocumentTemplate[];
580
+ /** ID of the practitioner who performs this procedure */
581
+ practitionerId: string;
582
+ /** ID of the clinic branch where this procedure is performed */
583
+ clinicBranchId: string;
584
+ /** Aggregated clinic information */
585
+ clinicInfo: ClinicInfo;
586
+ /** Aggregated doctor information */
587
+ doctorInfo: DoctorInfo;
588
+ /** Aggregated review information for this procedure */
589
+ reviewInfo: ProcedureReviewInfo;
590
+ /** Whether this procedure is active */
591
+ isActive: boolean;
592
+ /** When this procedure was created */
593
+ createdAt: Date;
594
+ /** When this procedure was last updated */
595
+ updatedAt: Date;
596
+ }
597
+ /**
598
+ * Aggregated summary information for a procedure.
599
+ * Used in arrays within Clinic and Practitioner documents for quick display.
600
+ */
601
+ interface ProcedureSummaryInfo {
602
+ id: string;
603
+ name: string;
604
+ description?: string;
605
+ photo?: string;
606
+ family: ProcedureFamily;
607
+ categoryName: string;
608
+ subcategoryName: string;
609
+ technologyName: string;
610
+ price: number;
611
+ pricingMeasure: PricingMeasure;
612
+ currency: Currency;
613
+ duration: number;
614
+ clinicId: string;
615
+ clinicName: string;
616
+ practitionerId: string;
617
+ practitionerName: string;
618
+ }
619
+
620
+ /**
621
+ * Osnovne informacije o zdravstvenom radniku
622
+ */
623
+ interface PractitionerBasicInfo {
624
+ firstName: string;
625
+ lastName: string;
626
+ title: string;
627
+ email: string;
628
+ phoneNumber: string;
629
+ dateOfBirth: Timestamp | Date;
630
+ gender: "male" | "female" | "other";
631
+ profileImageUrl?: string;
632
+ bio?: string;
633
+ languages: string[];
634
+ }
635
+ /**
636
+ * Sertifikacija zdravstvenog radnika
637
+ */
638
+ interface PractitionerCertification {
639
+ level: CertificationLevel;
640
+ specialties: CertificationSpecialty[];
641
+ licenseNumber: string;
642
+ issuingAuthority: string;
643
+ issueDate: Timestamp | Date;
644
+ expiryDate?: Timestamp | Date;
645
+ verificationStatus: "pending" | "verified" | "rejected";
646
+ }
647
+ /**
648
+ * Interfejs za radno vreme zdravstvenog radnika u klinici
649
+ */
650
+ interface PractitionerClinicWorkingHours {
651
+ clinicId: string;
652
+ workingHours: {
653
+ monday: {
654
+ start: string;
655
+ end: string;
656
+ } | null;
657
+ tuesday: {
658
+ start: string;
659
+ end: string;
660
+ } | null;
661
+ wednesday: {
662
+ start: string;
663
+ end: string;
664
+ } | null;
665
+ thursday: {
666
+ start: string;
667
+ end: string;
668
+ } | null;
669
+ friday: {
670
+ start: string;
671
+ end: string;
672
+ } | null;
673
+ saturday: {
674
+ start: string;
675
+ end: string;
676
+ } | null;
677
+ sunday: {
678
+ start: string;
679
+ end: string;
680
+ } | null;
681
+ };
682
+ isActive: boolean;
683
+ createdAt: Timestamp | Date;
684
+ updatedAt: Timestamp | Date;
685
+ }
686
+ /**
687
+ * Status of practitioner profile
688
+ */
689
+ declare enum PractitionerStatus {
690
+ DRAFT = "draft",
691
+ ACTIVE = "active"
692
+ }
693
+ /**
694
+ * Token status for practitioner invitations
695
+ */
696
+ declare enum PractitionerTokenStatus {
697
+ ACTIVE = "active",
698
+ USED = "used",
699
+ EXPIRED = "expired",
700
+ REVOKED = "revoked"
701
+ }
702
+ /**
703
+ * Interfejs za zdravstvenog radnika
704
+ */
705
+ interface Practitioner {
706
+ id: string;
707
+ userRef: string;
708
+ basicInfo: PractitionerBasicInfo;
709
+ certification: PractitionerCertification;
710
+ clinics: string[];
711
+ clinicWorkingHours: PractitionerClinicWorkingHours[];
712
+ clinicsInfo: ClinicInfo[];
713
+ procedures: string[];
714
+ proceduresInfo: ProcedureSummaryInfo[];
715
+ reviewInfo: PractitionerReviewInfo;
716
+ isActive: boolean;
717
+ isVerified: boolean;
718
+ status: PractitionerStatus;
719
+ createdAt: Timestamp;
720
+ updatedAt: Timestamp;
721
+ }
722
+ /**
723
+ * Token za pozivanje zdravstvenog radnika
724
+ */
725
+ interface PractitionerToken {
726
+ id: string;
727
+ token: string;
728
+ practitionerId: string;
729
+ email: string;
730
+ clinicId: string;
731
+ status: PractitionerTokenStatus;
732
+ createdBy: string;
733
+ createdAt: Timestamp;
734
+ expiresAt: Timestamp;
735
+ usedBy?: string;
736
+ usedAt?: Timestamp;
737
+ }
738
+
739
+ /**
740
+ * Interfejs za gamifikaciju
741
+ */
742
+ interface GamificationInfo {
743
+ /** Nivo korisnika */
744
+ level: number;
745
+ /** Trenutni poeni */
746
+ points: number;
747
+ }
748
+ /**
749
+ * Interfejs za doktora pacijenta
750
+ */
751
+ interface PatientDoctor {
752
+ userRef: string;
753
+ assignedAt: Timestamp;
754
+ assignedBy?: string;
755
+ isActive: boolean;
756
+ notes?: string;
757
+ }
758
+ /**
759
+ * Interfejs za kliniku pacijenta
760
+ */
761
+ interface PatientClinic {
762
+ clinicId: string;
763
+ assignedAt: Timestamp;
764
+ assignedBy?: string;
765
+ isActive: boolean;
766
+ notes?: string;
767
+ }
768
+ /**
769
+ * Glavni interfejs za Patient profil (top-level kolekcija)
770
+ */
771
+ interface PatientProfile {
772
+ id: string;
773
+ userRef: string;
774
+ displayName: string;
775
+ profilePhoto: string | null;
776
+ gamification: GamificationInfo;
777
+ expoTokens: string[];
778
+ isActive: boolean;
779
+ isVerified: boolean;
780
+ phoneNumber?: string | null;
781
+ dateOfBirth?: Timestamp | null;
782
+ doctors: PatientDoctor[];
783
+ clinics: PatientClinic[];
784
+ doctorIds: string[];
785
+ clinicIds: string[];
786
+ createdAt: Timestamp;
787
+ updatedAt: Timestamp;
788
+ }
789
+
790
+ /**
791
+ * Interface for clinic profile information
792
+ */
793
+ interface ClinicInfo {
794
+ id: string;
795
+ featuredPhoto: string;
796
+ name: string;
797
+ description?: string | null;
798
+ location: ClinicLocation;
799
+ contactInfo: ClinicContactInfo;
800
+ }
801
+
802
+ /**
803
+ * Enum for all possible clinic tags
804
+ */
805
+ declare enum ClinicTag {
806
+ PARKING = "parking",
807
+ WIFI = "wifi",
808
+ WHEELCHAIR_ACCESS = "wheelchair_access",
809
+ CAFE = "cafe",
810
+ PHARMACY = "pharmacy",
811
+ WAITING_ROOM = "waiting_room",
812
+ CARD_PAYMENT = "card_payment",
813
+ INSURANCE = "insurance",
814
+ CHILDREN_AREA = "children_area",
815
+ TV = "tv",
816
+ AIR_CONDITIONING = "air_conditioning",
817
+ WATER_DISPENSER = "water_dispenser",
818
+ VENDING_MACHINE = "vending_machine",
819
+ ELEVATOR = "elevator",
820
+ RAMP = "ramp",
821
+ HANDICAP_PARKING = "handicap_parking",
822
+ BRAILLE = "braille",
823
+ SIGN_LANGUAGE = "sign_language",
824
+ EMERGENCY_SERVICE = "emergency_service",
825
+ LAB = "lab",
826
+ XRAY = "xray",
827
+ ULTRASOUND = "ultrasound",
828
+ DENTAL = "dental",
829
+ PEDIATRIC = "pediatric",
830
+ GYNECOLOGY = "gynecology",
831
+ CARDIOLOGY = "cardiology",
832
+ DERMATOLOGY = "dermatology",
833
+ ORTHOPEDIC = "orthopedic",
834
+ OPHTHALMOLOGY = "ophthalmology",
835
+ TELEMEDICINE = "telemedicine",
836
+ HOME_VISITS = "home_visits",
837
+ ONLINE_BOOKING = "online_booking",
838
+ MOBILE_APP = "mobile_app",
839
+ SMS_NOTIFICATIONS = "sms_notifications",
840
+ EMAIL_NOTIFICATIONS = "email_notifications",
841
+ ENGLISH = "english",
842
+ SERBIAN = "serbian",
843
+ GERMAN = "german",
844
+ RUSSIAN = "russian",
845
+ CHINESE = "chinese",
846
+ SPANISH = "spanish",
847
+ FRENCH = "french",
848
+ OPEN_24_7 = "open_24_7",
849
+ WEEKEND_HOURS = "weekend_hours",
850
+ NIGHT_SHIFT = "night_shift",
851
+ HOLIDAY_HOURS = "holiday_hours"
852
+ }
853
+
854
+ /**
855
+ * Interface for clinic contact information
856
+ */
857
+ interface ClinicContactInfo {
858
+ email: string;
859
+ phoneNumber: string;
860
+ alternativePhoneNumber?: string | null;
861
+ website?: string | null;
862
+ }
863
+ /**
864
+ * Interface for clinic location
865
+ */
866
+ interface ClinicLocation {
867
+ address: string;
868
+ city: string;
869
+ country: string;
870
+ postalCode: string;
871
+ latitude: number;
872
+ longitude: number;
873
+ geohash?: string | null;
874
+ }
875
+ /**
876
+ * Interface for working hours
877
+ */
878
+ interface WorkingHours {
879
+ monday: {
880
+ open: string;
881
+ close: string;
882
+ breaks?: {
883
+ start: string;
884
+ end: string;
885
+ }[];
886
+ } | null;
887
+ tuesday: {
888
+ open: string;
889
+ close: string;
890
+ breaks?: {
891
+ start: string;
892
+ end: string;
893
+ }[];
894
+ } | null;
895
+ wednesday: {
896
+ open: string;
897
+ close: string;
898
+ breaks?: {
899
+ start: string;
900
+ end: string;
901
+ }[];
902
+ } | null;
903
+ thursday: {
904
+ open: string;
905
+ close: string;
906
+ breaks?: {
907
+ start: string;
908
+ end: string;
909
+ }[];
910
+ } | null;
911
+ friday: {
912
+ open: string;
913
+ close: string;
914
+ breaks?: {
915
+ start: string;
916
+ end: string;
917
+ }[];
918
+ } | null;
919
+ saturday: {
920
+ open: string;
921
+ close: string;
922
+ breaks?: {
923
+ start: string;
924
+ end: string;
925
+ }[];
926
+ } | null;
927
+ sunday: {
928
+ open: string;
929
+ close: string;
930
+ breaks?: {
931
+ start: string;
932
+ end: string;
933
+ }[];
934
+ } | null;
935
+ }
936
+ /**
937
+ * Interface for doctor information
938
+ */
939
+ interface DoctorInfo {
940
+ id: string;
941
+ name: string;
942
+ description?: string;
943
+ photo: string;
944
+ rating: number;
945
+ services: string[];
946
+ }
947
+ /**
948
+ * Interface for service information
949
+ */
950
+ /**
951
+ * Interface for clinic
952
+ */
953
+ interface Clinic {
954
+ id: string;
955
+ clinicGroupId: string;
956
+ name: string;
957
+ description?: string;
958
+ location: ClinicLocation;
959
+ contactInfo: ClinicContactInfo;
960
+ workingHours: WorkingHours;
961
+ tags: ClinicTag[];
962
+ featuredPhotos: string[];
963
+ coverPhoto: string | null;
964
+ photosWithTags?: {
965
+ url: string;
966
+ tag: string;
967
+ }[];
968
+ doctors: string[];
969
+ doctorsInfo: DoctorInfo[];
970
+ procedures: string[];
971
+ proceduresInfo: ProcedureSummaryInfo[];
972
+ reviewInfo: ClinicReviewInfo;
973
+ admins: string[];
974
+ createdAt: Timestamp;
975
+ updatedAt: Timestamp;
976
+ isActive: boolean;
977
+ isVerified: boolean;
978
+ logo?: string;
979
+ }
3
980
 
4
981
  declare enum UserRole {
5
982
  PATIENT = "patient",
@@ -152,4 +1129,350 @@ declare class NotificationsAdmin {
152
1129
  cleanupOldNotifications(daysOld?: number, batchSize?: number): Promise<void>;
153
1130
  }
154
1131
 
155
- export { type AppointmentNotification, type AppointmentReminderNotification, type BaseNotification, NOTIFICATIONS_COLLECTION, type Notification, NotificationStatus, NotificationType, NotificationsAdmin, type PostRequirementNotification, type PreRequirementNotification, UserRole };
1132
+ /**
1133
+ * @class ClinicAggregationService
1134
+ * @description Handles aggregation tasks related to clinic data updates.
1135
+ * This service is intended to be used primarily by background functions (e.g., Cloud Functions)
1136
+ * triggered by changes in the clinics collection.
1137
+ */
1138
+ declare class ClinicAggregationService {
1139
+ private db;
1140
+ /**
1141
+ * Constructor for ClinicAggregationService.
1142
+ * @param firestore Optional Firestore instance. If not provided, it uses the default admin SDK instance.
1143
+ */
1144
+ constructor(firestore?: admin.firestore.Firestore);
1145
+ /**
1146
+ * Adds clinic information to a clinic group when a new clinic is created
1147
+ * @param clinicGroupId - ID of the parent clinic group
1148
+ * @param clinicInfo - The clinic information to add to the group
1149
+ * @returns {Promise<void>}
1150
+ * @throws Will throw an error if the batch write fails
1151
+ */
1152
+ addClinicToClinicGroup(clinicGroupId: string, clinicInfo: ClinicInfo): Promise<void>;
1153
+ /**
1154
+ * Updates the ClinicInfo within the clinicsInfo array for multiple practitioners.
1155
+ * This method is designed to be called when a clinic's core information changes.
1156
+ * @param practitionerIds - IDs of practitioners associated with the clinic.
1157
+ * @param clinicInfo - The updated ClinicInfo object to aggregate.
1158
+ * @returns {Promise<void>}
1159
+ * @throws Will throw an error if the batch write fails.
1160
+ */
1161
+ updateClinicInfoInPractitioners(practitionerIds: string[], clinicInfo: ClinicInfo): Promise<void>;
1162
+ /**
1163
+ * Updates the aggregated clinicInfo field within relevant Procedure documents.
1164
+ * @param procedureIds IDs of procedures performed at the clinic.
1165
+ * @param clinicInfo The updated ClinicInfo object.
1166
+ */
1167
+ updateClinicInfoInProcedures(procedureIds: string[], clinicInfo: ClinicInfo): Promise<void>;
1168
+ /**
1169
+ * Updates the aggregated clinicsInfo array within the parent ClinicGroup document.
1170
+ * @param clinicGroupId The ID of the parent clinic group.
1171
+ * @param clinicInfo The updated ClinicInfo object.
1172
+ */
1173
+ updateClinicInfoInClinicGroup(clinicGroupId: string, clinicInfo: ClinicInfo): Promise<void>;
1174
+ /**
1175
+ * Updates relevant clinic information within Patient documents.
1176
+ * NOTE: PatientProfile stores an array of PatientClinic objects, which only contain
1177
+ * clinicId, assignedAt, assignedBy, isActive, notes. It does *not* store aggregated
1178
+ * ClinicInfo (like name, photo). Therefore, this method currently has limited use
1179
+ * for general clinic info updates. It might be relevant if Clinic.isActive status changes.
1180
+ *
1181
+ * @param patientIds IDs of patients associated with the clinic (e.g., from PatientProfile.clinicIds).
1182
+ * @param clinicInfo The updated ClinicInfo object (primarily for logging/context).
1183
+ * @param clinicIsActive The current active status of the updated clinic.
1184
+ */
1185
+ updateClinicInfoInPatients(patientIds: string[], clinicInfo: ClinicInfo, clinicIsActive: boolean): Promise<void>;
1186
+ /**
1187
+ * Updates the eventLocation for upcoming calendar events associated with a specific clinic.
1188
+ * Uses a collection group query to find relevant events across all potential parent collections.
1189
+ *
1190
+ * @param clinicId The ID of the clinic whose location might have changed.
1191
+ * @param newLocation The new ClinicLocation object.
1192
+ */
1193
+ updateClinicLocationInCalendarEvents(clinicId: string, newLocation: ClinicLocation): Promise<void>;
1194
+ /**
1195
+ * Updates clinic info in all upcoming calendar events associated with a specific clinic.
1196
+ * @param clinicId The ID of the clinic whose info has been updated.
1197
+ * @param clinicInfo The updated ClinicInfo object.
1198
+ */
1199
+ updateClinicInfoInCalendarEvents(clinicId: string, clinicInfo: ClinicInfo): Promise<void>;
1200
+ /**
1201
+ * Removes clinic from practitioners when a clinic is deleted.
1202
+ * @param practitionerIds IDs of practitioners associated with the clinic.
1203
+ * @param clinicId The ID of the deleted clinic.
1204
+ */
1205
+ removeClinicFromPractitioners(practitionerIds: string[], clinicId: string): Promise<void>;
1206
+ /**
1207
+ * Inactivates all procedures associated with a deleted clinic
1208
+ * @param procedureIds IDs of procedures associated with the clinic
1209
+ */
1210
+ inactivateProceduresForClinic(procedureIds: string[]): Promise<void>;
1211
+ /**
1212
+ * Removes clinic from clinic group when a clinic is deleted
1213
+ * @param clinicGroupId ID of the parent clinic group
1214
+ * @param clinicId ID of the deleted clinic
1215
+ */
1216
+ removeClinicFromClinicGroup(clinicGroupId: string, clinicId: string): Promise<void>;
1217
+ /**
1218
+ * Removes clinic from patients when a clinic is deleted
1219
+ * @param patientIds IDs of patients associated with the clinic
1220
+ * @param clinicId ID of the deleted clinic
1221
+ */
1222
+ removeClinicFromPatients(patientIds: string[], clinicId: string): Promise<void>;
1223
+ /**
1224
+ * Cancels all upcoming calendar events associated with a deleted clinic
1225
+ * @param clinicId ID of the deleted clinic
1226
+ */
1227
+ cancelUpcomingCalendarEventsForClinic(clinicId: string): Promise<void>;
1228
+ }
1229
+
1230
+ /**
1231
+ * @class PractitionerAggregationService
1232
+ * @description Handles aggregation tasks related to practitioner data updates/deletions.
1233
+ */
1234
+ declare class PractitionerAggregationService {
1235
+ private db;
1236
+ constructor(firestore?: admin.firestore.Firestore);
1237
+ /**
1238
+ * Adds practitioner information to a clinic when a new practitioner is created
1239
+ * @param clinicId - ID of the clinic to update
1240
+ * @param doctorInfo - Doctor information to add to the clinic
1241
+ * @returns {Promise<void>}
1242
+ */
1243
+ addPractitionerToClinic(clinicId: string, doctorInfo: DoctorInfo): Promise<void>;
1244
+ /**
1245
+ * Updates practitioner information in associated clinics
1246
+ * @param clinicIds - IDs of clinics associated with the practitioner
1247
+ * @param doctorInfo - Updated doctor information
1248
+ * @returns {Promise<void>}
1249
+ */
1250
+ updatePractitionerInfoInClinics(clinicIds: string[], doctorInfo: DoctorInfo): Promise<void>;
1251
+ /**
1252
+ * Updates practitioner information in associated procedures
1253
+ * @param procedureIds - IDs of procedures associated with the practitioner
1254
+ * @param doctorInfo - Updated doctor information
1255
+ * @returns {Promise<void>}
1256
+ */
1257
+ updatePractitionerInfoInProcedures(procedureIds: string[], doctorInfo: DoctorInfo): Promise<void>;
1258
+ /**
1259
+ * Updates practitioner information in calendar events
1260
+ * @param practitionerId - ID of the practitioner
1261
+ * @param practitionerInfo - Updated practitioner information
1262
+ * @returns {Promise<void>}
1263
+ */
1264
+ updatePractitionerInfoInCalendarEvents(practitionerId: string, practitionerInfo: DoctorInfo): Promise<void>;
1265
+ /**
1266
+ * Removes practitioner from clinics when a practitioner is deleted
1267
+ * @param clinicIds - IDs of clinics associated with the practitioner
1268
+ * @param practitionerId - ID of the deleted practitioner
1269
+ * @returns {Promise<void>}
1270
+ */
1271
+ removePractitionerFromClinics(clinicIds: string[], practitionerId: string): Promise<void>;
1272
+ /**
1273
+ * Cancels all upcoming calendar events for a deleted practitioner
1274
+ * @param practitionerId - ID of the deleted practitioner
1275
+ * @returns {Promise<void>}
1276
+ */
1277
+ cancelUpcomingCalendarEventsForPractitioner(practitionerId: string): Promise<void>;
1278
+ /**
1279
+ * Removes practitioner from patients when a practitioner is deleted
1280
+ * @param patientIds - IDs of patients associated with the practitioner
1281
+ * @param practitionerId - ID of the deleted practitioner
1282
+ * @returns {Promise<void>}
1283
+ */
1284
+ removePractitionerFromPatients(patientIds: string[], practitionerId: string): Promise<void>;
1285
+ /**
1286
+ * Inactivates all procedures associated with a deleted practitioner
1287
+ * @param procedureIds - IDs of procedures provided by the practitioner
1288
+ * @returns {Promise<void>}
1289
+ */
1290
+ inactivateProceduresForPractitioner(procedureIds: string[]): Promise<void>;
1291
+ }
1292
+
1293
+ /**
1294
+ * @class ProcedureAggregationService
1295
+ * @description Handles aggregation tasks related to procedure data updates/deletions.
1296
+ */
1297
+ declare class ProcedureAggregationService {
1298
+ private db;
1299
+ constructor(firestore?: admin.firestore.Firestore);
1300
+ /**
1301
+ * Adds procedure information to a practitioner when a new procedure is created
1302
+ * @param practitionerId - ID of the practitioner who performs the procedure
1303
+ * @param procedureSummary - Summary information about the procedure
1304
+ * @returns {Promise<void>}
1305
+ */
1306
+ addProcedureToPractitioner(practitionerId: string, procedureSummary: ProcedureSummaryInfo): Promise<void>;
1307
+ /**
1308
+ * Adds procedure information to a clinic when a new procedure is created
1309
+ * @param clinicId - ID of the clinic where the procedure is performed
1310
+ * @param procedureSummary - Summary information about the procedure
1311
+ * @returns {Promise<void>}
1312
+ */
1313
+ addProcedureToClinic(clinicId: string, procedureSummary: ProcedureSummaryInfo): Promise<void>;
1314
+ /**
1315
+ * Updates procedure information in a practitioner document
1316
+ * @param practitionerId - ID of the practitioner who performs the procedure
1317
+ * @param procedureSummary - Updated summary information about the procedure
1318
+ * @returns {Promise<void>}
1319
+ */
1320
+ updateProcedureInfoInPractitioner(practitionerId: string, procedureSummary: ProcedureSummaryInfo): Promise<void>;
1321
+ /**
1322
+ * Updates procedure information in a clinic document
1323
+ * @param clinicId - ID of the clinic where the procedure is performed
1324
+ * @param procedureSummary - Updated summary information about the procedure
1325
+ * @returns {Promise<void>}
1326
+ */
1327
+ updateProcedureInfoInClinic(clinicId: string, procedureSummary: ProcedureSummaryInfo): Promise<void>;
1328
+ /**
1329
+ * Updates procedure information in calendar events
1330
+ * @param procedureId - ID of the procedure
1331
+ * @param procedureInfo - Updated procedure information
1332
+ * @returns {Promise<void>}
1333
+ */
1334
+ updateProcedureInfoInCalendarEvents(procedureId: string, procedureInfo: any): Promise<void>;
1335
+ /**
1336
+ * Cancels all upcoming calendar events for a procedure
1337
+ * @param procedureId - ID of the procedure
1338
+ * @returns {Promise<void>}
1339
+ */
1340
+ cancelUpcomingCalendarEventsForProcedure(procedureId: string): Promise<void>;
1341
+ /**
1342
+ * Removes procedure from a practitioner when a procedure is deleted or inactivated
1343
+ * @param practitionerId - ID of the practitioner who performs the procedure
1344
+ * @param procedureId - ID of the procedure
1345
+ * @returns {Promise<void>}
1346
+ */
1347
+ removeProcedureFromPractitioner(practitionerId: string, procedureId: string): Promise<void>;
1348
+ /**
1349
+ * Removes procedure from a clinic when a procedure is deleted or inactivated
1350
+ * @param clinicId - ID of the clinic where the procedure is performed
1351
+ * @param procedureId - ID of the procedure
1352
+ * @returns {Promise<void>}
1353
+ */
1354
+ removeProcedureFromClinic(clinicId: string, procedureId: string): Promise<void>;
1355
+ }
1356
+
1357
+ /**
1358
+ * @class PatientAggregationService
1359
+ * @description Handles aggregation tasks related to patient data updates/deletions.
1360
+ */
1361
+ declare class PatientAggregationService {
1362
+ private db;
1363
+ constructor(firestore?: admin.firestore.Firestore);
1364
+ /**
1365
+ * Updates patient information in calendar events
1366
+ * @param patientId - ID of the patient
1367
+ * @param patientInfo - Updated patient information
1368
+ * @returns {Promise<void>}
1369
+ */
1370
+ updatePatientInfoInCalendarEvents(patientId: string, patientInfo: any): Promise<void>;
1371
+ /**
1372
+ * Cancels all upcoming calendar events associated with a deleted patient
1373
+ * @param patientId - ID of the deleted patient
1374
+ * @returns {Promise<void>}
1375
+ */
1376
+ cancelUpcomingCalendarEventsForPatient(patientId: string): Promise<void>;
1377
+ }
1378
+
1379
+ /**
1380
+ * Base mailing service class that provides common functionality for all mailing services
1381
+ */
1382
+ declare class BaseMailingService {
1383
+ protected db: FirebaseFirestore.Firestore;
1384
+ protected mailgunClient: mailgun.Mailgun;
1385
+ /**
1386
+ * Constructor for BaseMailingService
1387
+ * @param firestore Firestore instance provided by the caller
1388
+ * @param mailgunClient Mailgun client instance provided by the caller
1389
+ */
1390
+ constructor(firestore: FirebaseFirestore.Firestore, mailgunClient: mailgun.Mailgun);
1391
+ /**
1392
+ * Sends an email using Mailgun
1393
+ * @param data Email data to send, including the 'from' address
1394
+ * @returns Promise with the sending result
1395
+ */
1396
+ protected sendEmail(data: mailgun.messages.SendData): Promise<mailgun.messages.SendResponse>;
1397
+ /**
1398
+ * Logs email sending attempt to Firestore for tracking
1399
+ * @param emailData Email data that was sent
1400
+ * @param success Whether the email was sent successfully
1401
+ * @param error Error object if the email failed to send
1402
+ */
1403
+ protected logEmailAttempt(emailData: {
1404
+ to: string;
1405
+ subject: string;
1406
+ templateName?: string;
1407
+ }, success: boolean, error?: any): Promise<void>;
1408
+ /**
1409
+ * Renders a simple HTML email template with variables
1410
+ * @param template HTML template string
1411
+ * @param variables Key-value pairs to replace in the template
1412
+ * @returns Rendered HTML string
1413
+ */
1414
+ protected renderTemplate(template: string, variables: Record<string, string>): string;
1415
+ }
1416
+
1417
+ /**
1418
+ * Interface for the data required to send a practitioner invitation email
1419
+ */
1420
+ interface PractitionerInviteEmailData {
1421
+ /** The token object from the practitioner service */
1422
+ token: {
1423
+ id: string;
1424
+ token: string;
1425
+ practitionerId: string;
1426
+ email: string;
1427
+ clinicId: string;
1428
+ expiresAt: admin.firestore.Timestamp;
1429
+ };
1430
+ /** Practitioner basic info */
1431
+ practitioner: {
1432
+ firstName: string;
1433
+ lastName: string;
1434
+ };
1435
+ /** Clinic info */
1436
+ clinic: {
1437
+ name: string;
1438
+ contactEmail: string;
1439
+ contactName?: string;
1440
+ };
1441
+ /** Config options */
1442
+ options?: {
1443
+ registrationUrl?: string;
1444
+ customSubject?: string;
1445
+ fromAddress?: string;
1446
+ };
1447
+ }
1448
+ /**
1449
+ * Service for sending practitioner invitation emails
1450
+ */
1451
+ declare class PractitionerInviteMailingService extends BaseMailingService {
1452
+ private readonly DEFAULT_REGISTRATION_URL;
1453
+ private readonly DEFAULT_SUBJECT;
1454
+ private readonly DEFAULT_FROM_ADDRESS;
1455
+ /**
1456
+ * Constructor for PractitionerInviteMailingService
1457
+ * @param firestore Firestore instance provided by the caller
1458
+ * @param mailgunClient Mailgun client instance provided by the caller
1459
+ */
1460
+ constructor(firestore: FirebaseFirestore.Firestore, mailgunClient: mailgun.Mailgun);
1461
+ /**
1462
+ * Sends a practitioner invitation email
1463
+ * @param data The practitioner invitation data
1464
+ * @returns Promise resolved when email is sent
1465
+ */
1466
+ sendInvitationEmail(data: PractitionerInviteEmailData): Promise<mailgun.messages.SendResponse>;
1467
+ /**
1468
+ * Handles the practitioner token creation event from Cloud Functions
1469
+ * Fetches necessary data using defined types and collection constants,
1470
+ * and sends the invitation email.
1471
+ * @param tokenData The fully typed token object including its id
1472
+ * @param fromAddress The 'from' email address to use, obtained from config
1473
+ * @returns Promise resolved when the email is sent
1474
+ */
1475
+ handleTokenCreationEvent(tokenData: PractitionerToken, fromAddress: string): Promise<void>;
1476
+ }
1477
+
1478
+ export { type AppointmentNotification, type AppointmentReminderNotification, BaseMailingService, type BaseNotification, type Clinic, ClinicAggregationService, type ClinicInfo, type ClinicLocation, type DoctorInfo, NOTIFICATIONS_COLLECTION, type Notification, NotificationStatus, NotificationType, NotificationsAdmin, type PatientProfile as Patient, PatientAggregationService, type PostRequirementNotification, type Practitioner, PractitionerAggregationService, PractitionerInviteMailingService, type PractitionerToken, type PreRequirementNotification, type Procedure, ProcedureAggregationService, type ProcedureSummaryInfo, UserRole };