@blackcode_sa/metaestetics-api 1.11.3 → 1.12.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.
Files changed (53) hide show
  1. package/dist/admin/index.d.mts +378 -334
  2. package/dist/admin/index.d.ts +378 -334
  3. package/dist/backoffice/index.d.mts +1198 -430
  4. package/dist/backoffice/index.d.ts +1198 -430
  5. package/dist/backoffice/index.js +1128 -245
  6. package/dist/backoffice/index.mjs +1119 -209
  7. package/dist/index.d.mts +4478 -4031
  8. package/dist/index.d.ts +4478 -4031
  9. package/dist/index.js +1974 -757
  10. package/dist/index.mjs +1735 -490
  11. package/package.json +1 -1
  12. package/src/backoffice/expo-safe/index.ts +4 -0
  13. package/src/backoffice/services/README.md +40 -0
  14. package/src/backoffice/services/brand.service.ts +85 -6
  15. package/src/backoffice/services/category.service.ts +92 -10
  16. package/src/backoffice/services/constants.service.ts +308 -0
  17. package/src/backoffice/services/documentation-template.service.ts +56 -2
  18. package/src/backoffice/services/index.ts +1 -0
  19. package/src/backoffice/services/product.service.ts +126 -5
  20. package/src/backoffice/services/requirement.service.ts +13 -0
  21. package/src/backoffice/services/subcategory.service.ts +184 -13
  22. package/src/backoffice/services/technology.service.ts +344 -129
  23. package/src/backoffice/types/admin-constants.types.ts +69 -0
  24. package/src/backoffice/types/brand.types.ts +1 -0
  25. package/src/backoffice/types/index.ts +2 -0
  26. package/src/backoffice/types/procedure-product.types.ts +38 -0
  27. package/src/backoffice/types/product.types.ts +31 -4
  28. package/src/backoffice/types/static/contraindication.types.ts +1 -0
  29. package/src/backoffice/types/static/treatment-benefit.types.ts +1 -0
  30. package/src/backoffice/types/technology.types.ts +113 -4
  31. package/src/backoffice/validations/schemas.ts +35 -9
  32. package/src/services/appointment/appointment.service.ts +0 -5
  33. package/src/services/appointment/utils/appointment.utils.ts +124 -113
  34. package/src/services/base.service.ts +10 -3
  35. package/src/services/documentation-templates/documentation-template.service.ts +116 -0
  36. package/src/services/media/media.service.ts +2 -2
  37. package/src/services/practitioner/practitioner.service.ts +201 -83
  38. package/src/services/procedure/README.md +76 -1
  39. package/src/services/procedure/procedure.service.ts +538 -235
  40. package/src/types/appointment/index.ts +2 -3
  41. package/src/types/clinic/index.ts +1 -6
  42. package/src/types/patient/medical-info.types.ts +3 -3
  43. package/src/types/procedure/index.ts +39 -20
  44. package/src/validations/clinic.schema.ts +1 -6
  45. package/src/validations/patient/medical-info.schema.ts +7 -2
  46. package/src/validations/procedure-product.schema.ts +41 -0
  47. package/src/validations/procedure.schema.ts +59 -8
  48. package/src/backoffice/services/__tests__/brand.service.test.ts +0 -196
  49. package/src/backoffice/services/__tests__/category.service.test.ts +0 -201
  50. package/src/backoffice/services/__tests__/product.service.test.ts +0 -358
  51. package/src/backoffice/services/__tests__/requirement.service.test.ts +0 -226
  52. package/src/backoffice/services/__tests__/subcategory.service.test.ts +0 -181
  53. package/src/backoffice/services/__tests__/technology.service.test.ts +0 -1097
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @file Defines types for dynamically managed administrative constants,
3
+ * such as treatment benefits and contraindications. These are stored in
4
+ * the 'admin-constants' collection in Firestore.
5
+ */
6
+
7
+ /**
8
+ * Represents a single dynamic treatment benefit.
9
+ * These are positive effects or results a patient can expect from a treatment.
10
+ */
11
+ export interface TreatmentBenefitDynamic {
12
+ /**
13
+ * A unique identifier for the benefit, typically in snake_case.
14
+ * @example "wrinkle_reduction"
15
+ */
16
+ id: string;
17
+
18
+ /**
19
+ * A human-readable name for the treatment benefit.
20
+ * @example "Wrinkle Reduction"
21
+ */
22
+ name: string;
23
+
24
+ /**
25
+ * A detailed description of the benefit.
26
+ */
27
+ description?: string;
28
+ }
29
+
30
+ /**
31
+ * Defines the structure of the document storing all treatment benefits
32
+ * in the 'admin-constants' collection.
33
+ * The document ID for this type should be 'treatment-benefits'.
34
+ */
35
+ export interface TreatmentBenefitsDocument {
36
+ benefits: TreatmentBenefitDynamic[];
37
+ }
38
+
39
+ /**
40
+ * Represents a single dynamic contraindication.
41
+ * These are conditions or factors that can affect a procedure and require special attention.
42
+ */
43
+ export interface ContraindicationDynamic {
44
+ /**
45
+ * A unique identifier for the contraindication, typically in snake_case.
46
+ * @example "sensitive_skin"
47
+ */
48
+ id: string;
49
+
50
+ /**
51
+ * A human-readable name for the contraindication.
52
+ * @example "Sensitive Skin"
53
+ */
54
+ name: string;
55
+
56
+ /**
57
+ * A detailed description of the contraindication.
58
+ */
59
+ description?: string;
60
+ }
61
+
62
+ /**
63
+ * Defines the structure of the document storing all contraindications
64
+ * in the 'admin-constants' collection.
65
+ * The document ID for this type should be 'contraindications'.
66
+ */
67
+ export interface ContraindicationsDocument {
68
+ contraindications: ContraindicationDynamic[];
69
+ }
@@ -14,6 +14,7 @@
14
14
  export interface Brand {
15
15
  id?: string;
16
16
  name: string;
17
+ name_lowercase: string;
17
18
  manufacturer: string;
18
19
  createdAt: Date;
19
20
  updatedAt: Date;
@@ -1,3 +1,4 @@
1
+ export * from "./admin-constants.types";
1
2
  export * from "./brand.types";
2
3
  export * from "./category.types";
3
4
  export * from "./documentation-templates.types";
@@ -6,3 +7,4 @@ export * from "./requirement.types";
6
7
  export * from "./subcategory.types";
7
8
  export * from "./technology.types";
8
9
  export * from "./static";
10
+ export * from "./procedure-product.types";
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @fileoverview Defines the ProcedureProduct type, which represents a product associated with a procedure,
3
+ * including its pricing information. This is used to allow procedures to have multiple products with different prices.
4
+ * @packageDocumentation
5
+ */
6
+ import { Product } from "./product.types";
7
+ import { Currency, PricingMeasure } from "./static/pricing.types";
8
+
9
+ /**
10
+ * Represents a product associated with a procedure, including its specific pricing information.
11
+ */
12
+ export interface ProcedureProduct {
13
+ /**
14
+ * The product used in the procedure.
15
+ * @see {@link Product}
16
+ */
17
+ product: Product;
18
+
19
+ /**
20
+ * The price of the procedure when using this specific product.
21
+ */
22
+ price: number;
23
+
24
+ /**
25
+ * The currency for the price of this product.
26
+ * @see {@link Currency}
27
+ */
28
+ currency: Currency;
29
+
30
+ /**
31
+ * How the price is measured (e.g., per ml, per zone).
32
+ * @see {@link PricingMeasure}
33
+ */
34
+ pricingMeasure: PricingMeasure;
35
+
36
+ // Default product
37
+ isDefault?: boolean;
38
+ }
@@ -1,3 +1,5 @@
1
+ import type { ContraindicationDynamic } from "./admin-constants.types";
2
+
1
3
  /**
2
4
  * Product used in procedures
3
5
  * Can be consumables, equipment, or any other product needed for performing procedures
@@ -24,6 +26,8 @@ export interface Product {
24
26
  brandName: string;
25
27
  technologyId: string;
26
28
  technologyName: string;
29
+ categoryId: string;
30
+ subcategoryId: string;
27
31
  createdAt: Date;
28
32
  updatedAt: Date;
29
33
  isActive: boolean;
@@ -33,7 +37,7 @@ export interface Product {
33
37
  dosage?: string;
34
38
  composition?: string;
35
39
  indications?: string[];
36
- contraindications?: string[];
40
+ contraindications?: ContraindicationDynamic[];
37
41
  }
38
42
 
39
43
  /**
@@ -61,10 +65,33 @@ export interface IProductService {
61
65
  ): Promise<Product>;
62
66
 
63
67
  /**
64
- * Gets all products for a technology
65
- * @param technologyId - ID of the technology
68
+ * Gets a paginated list of all products, with optional filters.
69
+ */
70
+ getAll(options: {
71
+ rowsPerPage: number;
72
+ lastVisible?: any;
73
+ categoryId?: string;
74
+ subcategoryId?: string;
75
+ technologyId?: string;
76
+ }): Promise<{ products: Product[]; lastVisible: any }>;
77
+
78
+ /**
79
+ * Gets the total count of active products, with optional filters.
80
+ */
81
+ getProductsCount(options: {
82
+ categoryId?: string;
83
+ subcategoryId?: string;
84
+ technologyId?: string;
85
+ }): Promise<number>;
86
+
87
+ /**
88
+ * Gets counts of active products grouped by category, subcategory, and technology.
66
89
  */
67
- getAllByTechnology(technologyId: string): Promise<Product[]>;
90
+ getProductCounts(): Promise<{
91
+ byCategory: Record<string, number>;
92
+ bySubcategory: Record<string, number>;
93
+ byTechnology: Record<string, number>;
94
+ }>;
68
95
 
69
96
  /**
70
97
  * Gets all products for a brand
@@ -1,4 +1,5 @@
1
1
  /**
2
+ * @deprecated
2
3
  * Kontraindikacije koje mogu uticati na proceduru
3
4
  * Ovi uslovi predstavljaju relativne kontraindikacije koje zahtevaju posebnu pažnju
4
5
  */
@@ -1,4 +1,5 @@
1
1
  /**
2
+ * @deprecated
2
3
  * Benefiti koji se mogu očekivati od procedure
3
4
  * Lista mogućih pozitivnih efekata i rezultata tretmana
4
5
  */
@@ -1,10 +1,10 @@
1
1
  import { Requirement } from "./requirement.types";
2
2
  import { BlockingCondition } from "./static/blocking-condition.types";
3
- import { Contraindication } from "./static/contraindication.types";
4
- import { TreatmentBenefit } from "./static/treatment-benefit.types";
5
3
  import { CertificationRequirement } from "./static/certification.types";
6
4
  import { DocumentTemplate } from "../../types/documentation-templates";
7
5
  import { ProcedureFamily } from "./static/procedure-family.types";
6
+ import { ContraindicationDynamic } from "./admin-constants.types";
7
+ import { TreatmentBenefitDynamic } from "./admin-constants.types";
8
8
 
9
9
  /**
10
10
  * Reference to a documentation template with metadata
@@ -65,8 +65,8 @@ export interface Technology {
65
65
  post: Requirement[];
66
66
  };
67
67
  blockingConditions: BlockingCondition[];
68
- contraindications: Contraindication[];
69
- benefits: TreatmentBenefit[];
68
+ contraindications: ContraindicationDynamic[];
69
+ benefits: TreatmentBenefitDynamic[];
70
70
  certificationRequirement: CertificationRequirement;
71
71
  documentationTemplates?: TechnologyDocumentationTemplate[];
72
72
  isActive: boolean;
@@ -78,3 +78,112 @@ export interface Technology {
78
78
  * Collection in Firestore database where technologies are stored
79
79
  */
80
80
  export const TECHNOLOGIES_COLLECTION = "technologies";
81
+
82
+ /**
83
+ * Interface for the TechnologyService class
84
+ */
85
+ export interface ITechnologyService {
86
+ create(
87
+ technology: Omit<Technology, "id" | "createdAt" | "updatedAt">
88
+ ): Promise<Technology>;
89
+ getTechnologyCounts(active?: boolean): Promise<Record<string, number>>;
90
+ getTechnologyCountsByCategory(
91
+ active?: boolean
92
+ ): Promise<Record<string, number>>;
93
+ getAll(options?: {
94
+ active?: boolean;
95
+ limit?: number;
96
+ lastVisible?: any;
97
+ }): Promise<{ technologies: Technology[]; lastVisible: any }>;
98
+ getAllByCategoryId(
99
+ categoryId: string,
100
+ options?: { active?: boolean; limit?: number; lastVisible?: any }
101
+ ): Promise<{ technologies: Technology[]; lastVisible: any }>;
102
+ getAllBySubcategoryId(
103
+ subcategoryId: string,
104
+ options?: { active?: boolean; limit?: number; lastVisible?: any }
105
+ ): Promise<{ technologies: Technology[]; lastVisible: any }>;
106
+ update(
107
+ id: string,
108
+ technology: Partial<Omit<Technology, "id" | "createdAt">>
109
+ ): Promise<Technology | null>;
110
+ delete(id: string): Promise<void>;
111
+ reactivate(id: string): Promise<void>;
112
+ getById(id: string): Promise<Technology | null>;
113
+ addRequirement(
114
+ technologyId: string,
115
+ requirement: Requirement
116
+ ): Promise<Technology | null>;
117
+ removeRequirement(
118
+ technologyId: string,
119
+ requirement: Requirement
120
+ ): Promise<Technology | null>;
121
+ getRequirements(
122
+ technologyId: string,
123
+ type?: "pre" | "post"
124
+ ): Promise<Requirement[]>;
125
+ updateRequirement(
126
+ technologyId: string,
127
+ oldRequirement: Requirement,
128
+ newRequirement: Requirement
129
+ ): Promise<Technology | null>;
130
+ addBlockingCondition(
131
+ technologyId: string,
132
+ condition: BlockingCondition
133
+ ): Promise<Technology | null>;
134
+ removeBlockingCondition(
135
+ technologyId: string,
136
+ condition: BlockingCondition
137
+ ): Promise<Technology | null>;
138
+ addContraindication(
139
+ technologyId: string,
140
+ contraindication: ContraindicationDynamic
141
+ ): Promise<Technology | null>;
142
+ removeContraindication(
143
+ technologyId: string,
144
+ contraindication: ContraindicationDynamic
145
+ ): Promise<Technology | null>;
146
+ updateContraindication(
147
+ technologyId: string,
148
+ contraindication: ContraindicationDynamic
149
+ ): Promise<Technology | null>;
150
+ addBenefit(
151
+ technologyId: string,
152
+ benefit: TreatmentBenefitDynamic
153
+ ): Promise<Technology | null>;
154
+ removeBenefit(
155
+ technologyId: string,
156
+ benefit: TreatmentBenefitDynamic
157
+ ): Promise<Technology | null>;
158
+ updateBenefit(
159
+ technologyId: string,
160
+ benefit: TreatmentBenefitDynamic
161
+ ): Promise<Technology | null>;
162
+ getBlockingConditions(technologyId: string): Promise<BlockingCondition[]>;
163
+ getContraindications(
164
+ technologyId: string
165
+ ): Promise<ContraindicationDynamic[]>;
166
+ getBenefits(technologyId: string): Promise<TreatmentBenefitDynamic[]>;
167
+ updateCertificationRequirement(
168
+ technologyId: string,
169
+ certificationRequirement: CertificationRequirement
170
+ ): Promise<Technology | null>;
171
+ getCertificationRequirement(
172
+ technologyId: string
173
+ ): Promise<CertificationRequirement | null>;
174
+ validateCertification(
175
+ requiredCertification: CertificationRequirement,
176
+ practitionerCertification: any
177
+ ): boolean;
178
+ getAllowedTechnologies(practitioner: any): Promise<{
179
+ technologies: Technology[];
180
+ families: ProcedureFamily[];
181
+ categories: string[];
182
+ subcategories: string[];
183
+ }>;
184
+ getAllForFilterBySubcategoryId(
185
+ categoryId: string,
186
+ subcategoryId: string
187
+ ): Promise<Technology[]>;
188
+ getAllForFilter(): Promise<Technology[]>;
189
+ }
@@ -1,27 +1,53 @@
1
1
  import { z } from "zod";
2
2
  import { ProcedureFamily } from "../types/static/procedure-family.types";
3
3
  import { BlockingCondition } from "../types/static/blocking-condition.types";
4
- import { Contraindication } from "../types/static/contraindication.types";
5
- import { TreatmentBenefit } from "../types/static/treatment-benefit.types";
6
4
  import { TimeUnit, RequirementType } from "../types/requirement.types";
7
5
  import {
8
6
  CertificationLevel,
9
7
  CertificationSpecialty,
10
8
  } from "../types/static/certification.types";
11
- import {
12
- DocumentElementType,
13
- HeadingLevel,
14
- ListType,
15
- } from "../types/documentation-templates.types";
9
+
16
10
  import { documentTemplateSchema } from "../../validations/documentation-templates.schema";
17
11
 
12
+ /**
13
+ * Zod validation schema for a single dynamic contraindication.
14
+ * @see ContraindicationDynamic in admin-constants.types.ts
15
+ */
16
+ export const contraindicationDynamicSchema = z.object({
17
+ id: z
18
+ .string()
19
+ .min(1, "Contraindication ID is required")
20
+ .regex(
21
+ /^[a-z0-9_]+$/,
22
+ "ID must be in snake_case (lowercase, numbers, and underscores only)"
23
+ ),
24
+ name: z.string().min(1, "Contraindication name is required"),
25
+ description: z.string().optional(),
26
+ });
27
+
28
+ /**
29
+ * Zod validation schema for a single dynamic treatment benefit.
30
+ * @see TreatmentBenefitDynamic in admin-constants.types.ts
31
+ */
32
+ export const treatmentBenefitDynamicSchema = z.object({
33
+ id: z
34
+ .string()
35
+ .min(1, "Benefit ID is required")
36
+ .regex(
37
+ /^[a-z0-9_]+$/,
38
+ "ID must be in snake_case (lowercase, numbers, and underscores only)"
39
+ ),
40
+ name: z.string().min(1, "Benefit name is required"),
41
+ description: z.string().optional(),
42
+ });
43
+
18
44
  /**
19
45
  * Base validation schemas for enums
20
46
  */
21
47
  export const blockingConditionSchemaBackoffice =
22
48
  z.nativeEnum(BlockingCondition);
23
- export const contraindicationSchemaBackoffice = z.nativeEnum(Contraindication);
24
- export const treatmentBenefitSchemaBackoffice = z.nativeEnum(TreatmentBenefit);
49
+ export const contraindicationSchemaBackoffice = contraindicationDynamicSchema;
50
+ export const treatmentBenefitSchemaBackoffice = treatmentBenefitDynamicSchema;
25
51
  export const procedureFamilySchemaBackoffice = z.nativeEnum(ProcedureFamily);
26
52
  export const timeUnitSchemaBackoffice = z.nativeEnum(TimeUnit);
27
53
  export const requirementTypeSchema = z.nativeEnum(RequirementType);
@@ -21,18 +21,15 @@ import { BaseService } from "../base.service";
21
21
  import {
22
22
  Appointment,
23
23
  AppointmentStatus,
24
- CreateAppointmentData,
25
24
  UpdateAppointmentData,
26
25
  SearchAppointmentsParams,
27
26
  PaymentStatus,
28
27
  AppointmentMediaItem,
29
28
  PatientReviewInfo,
30
- LinkedFormInfo,
31
29
  type CreateAppointmentHttpData,
32
30
  APPOINTMENTS_COLLECTION,
33
31
  } from "../../types/appointment";
34
32
  import {
35
- createAppointmentSchema,
36
33
  updateAppointmentSchema,
37
34
  searchAppointmentsSchema,
38
35
  rescheduleAppointmentSchema,
@@ -47,8 +44,6 @@ import { FilledDocumentService } from "../documentation-templates/filled-documen
47
44
 
48
45
  // Import utility functions
49
46
  import {
50
- fetchAggregatedInfoUtil,
51
- createAppointmentUtil,
52
47
  updateAppointmentUtil,
53
48
  getAppointmentByIdUtil,
54
49
  searchAppointmentsUtil,