@blackcode_sa/metaestetics-api 1.5.28 → 1.5.29

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 (34) hide show
  1. package/dist/admin/index.d.mts +1199 -1
  2. package/dist/admin/index.d.ts +1199 -1
  3. package/dist/admin/index.js +1337 -2
  4. package/dist/admin/index.mjs +1333 -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 +4035 -2364
  8. package/dist/index.d.ts +4035 -2364
  9. package/dist/index.js +2616 -1929
  10. package/dist/index.mjs +2646 -1952
  11. package/package.json +1 -1
  12. package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +642 -0
  13. package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -0
  14. package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -0
  15. package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +508 -0
  16. package/src/admin/index.ts +53 -4
  17. package/src/index.ts +28 -4
  18. package/src/services/clinic/clinic.service.ts +320 -107
  19. package/src/services/clinic/utils/clinic.utils.ts +66 -117
  20. package/src/services/clinic/utils/filter.utils.d.ts +23 -0
  21. package/src/services/clinic/utils/filter.utils.ts +264 -0
  22. package/src/services/practitioner/practitioner.service.ts +616 -5
  23. package/src/services/procedure/procedure.service.ts +599 -352
  24. package/src/services/reviews/reviews.service.ts +842 -0
  25. package/src/types/clinic/index.ts +24 -56
  26. package/src/types/practitioner/index.ts +34 -33
  27. package/src/types/procedure/index.ts +32 -0
  28. package/src/types/profile/index.ts +1 -1
  29. package/src/types/reviews/index.ts +126 -0
  30. package/src/validations/clinic.schema.ts +37 -64
  31. package/src/validations/practitioner.schema.ts +42 -32
  32. package/src/validations/procedure.schema.ts +11 -3
  33. package/src/validations/reviews.schema.ts +189 -0
  34. package/src/services/clinic/utils/review.utils.ts +0 -93
@@ -6,6 +6,8 @@ import type {
6
6
  PricingMeasure,
7
7
  } from "../../backoffice/types/static/pricing.types";
8
8
  import type { ClinicInfo } from "../profile";
9
+ import { ClinicReviewInfo } from "../reviews";
10
+ import { ProcedureSummaryInfo } from "../procedure";
9
11
 
10
12
  export const CLINIC_GROUPS_COLLECTION = "clinic_groups";
11
13
  export const CLINIC_ADMINS_COLLECTION = "clinic_admins";
@@ -254,37 +256,23 @@ export interface DoctorInfo {
254
256
  /**
255
257
  * Interface for service information
256
258
  */
257
- export interface ServiceInfo {
258
- id: string;
259
- name: string;
260
- description?: string;
261
- photo: string;
262
- procedureFamily: ProcedureFamily;
263
- category: string;
264
- subCategory: string;
265
- technology: string;
266
- rating: number;
267
- doctors: string[]; // Used for search and filtering
268
- price: number;
269
- pricingMeasure: PricingMeasure;
270
- currency: Currency;
271
- duration: number; // Duration in minutes
272
- treatmentBenefits: TreatmentBenefit[];
273
- }
274
-
275
- /**
276
- * Interface for review information
277
- */
278
- export interface ReviewInfo {
279
- id: string;
280
- rating: number;
281
- text: string;
282
- patientId: string;
283
- patientName: string;
284
- patientPhoto: string;
285
- createdAt: Timestamp;
286
- updatedAt: Timestamp;
287
- }
259
+ // export interface ServiceInfo { // <-- Comment out or remove old ServiceInfo
260
+ // id: string;
261
+ // name: string;
262
+ // description?: string;
263
+ // photo: string;
264
+ // procedureFamily: ProcedureFamily;
265
+ // category: string;
266
+ // subCategory: string;
267
+ // technology: string;
268
+ // rating: number;
269
+ // doctors: string[]; // Used for search and filtering
270
+ // price: number;
271
+ // pricingMeasure: PricingMeasure;
272
+ // currency: Currency;
273
+ // duration: number; // Duration in minutes
274
+ // treatmentBenefits: TreatmentBenefit[];
275
+ // }
288
276
 
289
277
  /**
290
278
  * Interface for clinic
@@ -303,14 +291,9 @@ export interface Clinic {
303
291
  photosWithTags?: { url: string; tag: string }[];
304
292
  doctors: string[];
305
293
  doctorsInfo: DoctorInfo[];
306
- services: string[];
307
- servicesInfo: ServiceInfo[];
308
- reviews: string[];
309
- reviewsInfo: ReviewInfo[];
310
- rating: {
311
- average: number;
312
- count: number;
313
- } | null;
294
+ procedures: string[];
295
+ proceduresInfo: ProcedureSummaryInfo[]; // <-- Use the new type instead of servicesInfo
296
+ reviewInfo: ClinicReviewInfo; // Aggregated review information
314
297
  admins: string[];
315
298
  createdAt: Timestamp;
316
299
  updatedAt: Timestamp;
@@ -333,7 +316,8 @@ export interface CreateClinicData {
333
316
  coverPhoto: string | null;
334
317
  photosWithTags?: { url: string; tag: string }[];
335
318
  doctors: string[];
336
- services: string[];
319
+ procedures: string[];
320
+ proceduresInfo?: ProcedureSummaryInfo[]; // <-- Add this
337
321
  admins: string[];
338
322
  isActive: boolean;
339
323
  isVerified: boolean;
@@ -420,19 +404,3 @@ export interface ClinicBranchSetupData {
420
404
  export interface ClinicTags {
421
405
  tags: ClinicTag[];
422
406
  }
423
-
424
- /**
425
- * Interface for clinic review
426
- */
427
-
428
- // TODO: Add more fields and information about the review (when you start working with review system)
429
- export interface ClinicReview {
430
- id: string;
431
- clinicId: string;
432
- patientId: string;
433
- rating: number; // 1-5
434
- comment: string;
435
- createdAt: Timestamp;
436
- updatedAt: Timestamp;
437
- isVerified: boolean;
438
- }
@@ -1,11 +1,19 @@
1
- import { Timestamp, FieldValue } from 'firebase/firestore';
1
+ import { Timestamp, FieldValue } from "firebase/firestore";
2
2
  import {
3
3
  CertificationLevel,
4
4
  CertificationSpecialty,
5
- } from '../../backoffice/types/static/certification.types';
5
+ } from "../../backoffice/types/static/certification.types";
6
+ import { PractitionerReviewInfo } from "../reviews";
7
+ import { ClinicInfo } from "../profile";
8
+ import { ProcedureFamily } from "../../backoffice/types/static/procedure-family.types";
9
+ import {
10
+ Currency,
11
+ PricingMeasure,
12
+ } from "../../backoffice/types/static/pricing.types";
13
+ import { ProcedureSummaryInfo } from "../procedure";
6
14
 
7
- export const PRACTITIONERS_COLLECTION = 'practitioners';
8
- export const REGISTER_TOKENS_COLLECTION = 'register_tokens';
15
+ export const PRACTITIONERS_COLLECTION = "practitioners";
16
+ export const REGISTER_TOKENS_COLLECTION = "register_tokens";
9
17
 
10
18
  /**
11
19
  * Osnovne informacije o zdravstvenom radniku
@@ -16,8 +24,8 @@ export interface PractitionerBasicInfo {
16
24
  title: string;
17
25
  email: string;
18
26
  phoneNumber: string;
19
- dateOfBirth: Timestamp;
20
- gender: 'male' | 'female' | 'other';
27
+ dateOfBirth: Timestamp | Date;
28
+ gender: "male" | "female" | "other";
21
29
  profileImageUrl?: string;
22
30
  bio?: string;
23
31
  languages: string[];
@@ -31,9 +39,9 @@ export interface PractitionerCertification {
31
39
  specialties: CertificationSpecialty[];
32
40
  licenseNumber: string;
33
41
  issuingAuthority: string;
34
- issueDate: Timestamp;
35
- expiryDate?: Timestamp;
36
- verificationStatus: 'pending' | 'verified' | 'rejected';
42
+ issueDate: Timestamp | Date;
43
+ expiryDate?: Timestamp | Date;
44
+ verificationStatus: "pending" | "verified" | "rejected";
37
45
  }
38
46
 
39
47
  /**
@@ -51,26 +59,26 @@ export interface PractitionerClinicWorkingHours {
51
59
  sunday: { start: string; end: string } | null;
52
60
  };
53
61
  isActive: boolean;
54
- createdAt: Timestamp;
55
- updatedAt: Timestamp;
62
+ createdAt: Timestamp | Date;
63
+ updatedAt: Timestamp | Date;
56
64
  }
57
65
 
58
66
  /**
59
67
  * Status of practitioner profile
60
68
  */
61
69
  export enum PractitionerStatus {
62
- DRAFT = 'draft',
63
- ACTIVE = 'active',
70
+ DRAFT = "draft",
71
+ ACTIVE = "active",
64
72
  }
65
73
 
66
74
  /**
67
75
  * Token status for practitioner invitations
68
76
  */
69
77
  export enum PractitionerTokenStatus {
70
- ACTIVE = 'active',
71
- USED = 'used',
72
- EXPIRED = 'expired',
73
- REVOKED = 'revoked',
78
+ ACTIVE = "active",
79
+ USED = "used",
80
+ EXPIRED = "expired",
81
+ REVOKED = "revoked",
74
82
  }
75
83
 
76
84
  /**
@@ -83,6 +91,10 @@ export interface Practitioner {
83
91
  certification: PractitionerCertification;
84
92
  clinics: string[]; // Reference na klinike gde radi
85
93
  clinicWorkingHours: PractitionerClinicWorkingHours[]; // Radno vreme za svaku kliniku
94
+ clinicsInfo: ClinicInfo[]; // Aggregated clinic information
95
+ procedures: string[]; // Reference na procedure koje izvodi
96
+ proceduresInfo: ProcedureSummaryInfo[]; // Aggregated procedure information
97
+ reviewInfo: PractitionerReviewInfo; // Aggregated review information
86
98
  isActive: boolean;
87
99
  isVerified: boolean;
88
100
  status: PractitionerStatus;
@@ -99,6 +111,7 @@ export interface CreatePractitionerData {
99
111
  certification: PractitionerCertification;
100
112
  clinics?: string[];
101
113
  clinicWorkingHours?: PractitionerClinicWorkingHours[];
114
+ clinicsInfo?: ClinicInfo[];
102
115
  isActive: boolean;
103
116
  isVerified: boolean;
104
117
  status?: PractitionerStatus;
@@ -112,6 +125,7 @@ export interface CreateDraftPractitionerData {
112
125
  certification: PractitionerCertification;
113
126
  clinics?: string[];
114
127
  clinicWorkingHours?: PractitionerClinicWorkingHours[];
128
+ clinicsInfo?: ClinicInfo[];
115
129
  isActive?: boolean;
116
130
  isVerified?: boolean;
117
131
  }
@@ -119,8 +133,10 @@ export interface CreateDraftPractitionerData {
119
133
  /**
120
134
  * Tip za ažuriranje zdravstvenog radnika
121
135
  */
122
- export interface UpdatePractitionerData extends Partial<CreatePractitionerData> {
136
+ export interface UpdatePractitionerData
137
+ extends Partial<CreatePractitionerData> {
123
138
  updatedAt?: FieldValue;
139
+ proceduresInfo?: ProcedureSummaryInfo[];
124
140
  }
125
141
 
126
142
  /**
@@ -135,21 +151,6 @@ export interface PractitionerClinicProcedures {
135
151
  updatedAt: Timestamp;
136
152
  }
137
153
 
138
- /**
139
- * Interfejs za recenziju zdravstvenog radnika
140
- */
141
- export interface PractitionerReview {
142
- id: string;
143
- practitionerId: string;
144
- patientId: string;
145
- clinicId: string;
146
- rating: number; // 1-5
147
- comment: string;
148
- createdAt: Timestamp;
149
- updatedAt: Timestamp;
150
- isVerified: boolean;
151
- }
152
-
153
154
  /**
154
155
  * Interfejs za radno vreme zdravstvenog radnika u klinici
155
156
  */
@@ -15,6 +15,7 @@ import { DocumentTemplate } from "../documentation-templates";
15
15
  import { ClinicInfo } from "../profile";
16
16
  import { DoctorInfo } from "../clinic";
17
17
  import { PRACTITIONERS_COLLECTION } from "../practitioner";
18
+ import { ProcedureReviewInfo } from "../reviews";
18
19
 
19
20
  /**
20
21
  * Procedure represents a specific medical procedure that can be performed by a practitioner in a clinic
@@ -65,6 +66,8 @@ export interface Procedure {
65
66
  clinicInfo: ClinicInfo;
66
67
  /** Aggregated doctor information */
67
68
  doctorInfo: DoctorInfo;
69
+ /** Aggregated review information for this procedure */
70
+ reviewInfo: ProcedureReviewInfo;
68
71
  /** Whether this procedure is active */
69
72
  isActive: boolean;
70
73
  /** When this procedure was created */
@@ -103,9 +106,38 @@ export interface UpdateProcedureData {
103
106
  pricingMeasure?: PricingMeasure;
104
107
  duration?: number;
105
108
  isActive?: boolean;
109
+ practitionerId?: string;
110
+ categoryId?: string;
111
+ subcategoryId?: string;
112
+ technologyId?: string;
113
+ productId?: string;
114
+ clinicBranchId?: string;
106
115
  }
107
116
 
108
117
  /**
109
118
  * Collection name for procedures in Firestore
110
119
  */
111
120
  export const PROCEDURES_COLLECTION = "procedures";
121
+
122
+ /**
123
+ * Aggregated summary information for a procedure.
124
+ * Used in arrays within Clinic and Practitioner documents for quick display.
125
+ */
126
+ export interface ProcedureSummaryInfo {
127
+ id: string;
128
+ name: string;
129
+ description?: string;
130
+ photo?: string; // Still using empty string if no source found
131
+ family: ProcedureFamily;
132
+ categoryName: string; // Use names for aggregation
133
+ subcategoryName: string; // Use names for aggregation
134
+ technologyName: string; // Use names for aggregation
135
+ price: number;
136
+ pricingMeasure: PricingMeasure;
137
+ currency: Currency;
138
+ duration: number;
139
+ clinicId: string;
140
+ clinicName: string;
141
+ practitionerId: string;
142
+ practitionerName: string;
143
+ }
@@ -9,7 +9,7 @@ export interface ClinicInfo {
9
9
  id: string;
10
10
  featuredPhoto: string;
11
11
  name: string;
12
- description: string;
12
+ description?: string | null;
13
13
  location: ClinicLocation;
14
14
  contactInfo: ClinicContactInfo;
15
15
  }
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Review system type definitions
3
+ */
4
+
5
+ /**
6
+ * Base review interface with common properties
7
+ */
8
+ interface BaseReview {
9
+ id: string;
10
+ fullReviewId: string;
11
+ patientId: string;
12
+ createdAt: Date;
13
+ updatedAt: Date;
14
+ comment: string;
15
+ isVerified: boolean;
16
+ isPublished: boolean;
17
+ }
18
+
19
+ /**
20
+ * Clinic review interface
21
+ * @description Full review for a clinic
22
+ */
23
+ export interface ClinicReview extends BaseReview {
24
+ clinicId: string;
25
+ cleanliness: number; // 1-5 stars
26
+ facilities: number; // 1-5 stars
27
+ staffFriendliness: number; // 1-5 stars
28
+ waitingTime: number; // 1-5 stars
29
+ accessibility: number; // 1-5 stars
30
+ overallRating: number; // Average of all ratings
31
+ wouldRecommend: boolean;
32
+ }
33
+
34
+ /**
35
+ * Practitioner review interface
36
+ * @description Full review for a healthcare practitioner
37
+ */
38
+ export interface PractitionerReview extends BaseReview {
39
+ practitionerId: string;
40
+ knowledgeAndExpertise: number; // 1-5 stars
41
+ communicationSkills: number; // 1-5 stars
42
+ bedSideManner: number; // 1-5 stars
43
+ thoroughness: number; // 1-5 stars
44
+ trustworthiness: number; // 1-5 stars
45
+ overallRating: number; // Average of all ratings
46
+ wouldRecommend: boolean;
47
+ }
48
+
49
+ /**
50
+ * Procedure review interface
51
+ * @description Full review for a medical procedure
52
+ */
53
+ export interface ProcedureReview extends BaseReview {
54
+ procedureId: string;
55
+ effectivenessOfTreatment: number; // 1-5 stars
56
+ outcomeExplanation: number; // 1-5 stars
57
+ painManagement: number; // 1-5 stars
58
+ followUpCare: number; // 1-5 stars
59
+ valueForMoney: number; // 1-5 stars
60
+ overallRating: number; // Average of all ratings
61
+ wouldRecommend: boolean;
62
+ }
63
+
64
+ /**
65
+ * Condensed clinic review information
66
+ * @description Used for aggregated data attached to clinic documents
67
+ */
68
+ export interface ClinicReviewInfo {
69
+ totalReviews: number;
70
+ averageRating: number;
71
+ cleanliness: number;
72
+ facilities: number;
73
+ staffFriendliness: number;
74
+ waitingTime: number;
75
+ accessibility: number;
76
+ recommendationPercentage: number;
77
+ }
78
+
79
+ /**
80
+ * Condensed practitioner review information
81
+ * @description Used for aggregated data attached to practitioner documents
82
+ */
83
+ export interface PractitionerReviewInfo {
84
+ totalReviews: number;
85
+ averageRating: number;
86
+ knowledgeAndExpertise: number;
87
+ communicationSkills: number;
88
+ bedSideManner: number;
89
+ thoroughness: number;
90
+ trustworthiness: number;
91
+ recommendationPercentage: number;
92
+ }
93
+
94
+ /**
95
+ * Condensed procedure review information
96
+ * @description Used for aggregated data attached to procedure documents
97
+ */
98
+ export interface ProcedureReviewInfo {
99
+ totalReviews: number;
100
+ averageRating: number;
101
+ effectivenessOfTreatment: number;
102
+ outcomeExplanation: number;
103
+ painManagement: number;
104
+ followUpCare: number;
105
+ valueForMoney: number;
106
+ recommendationPercentage: number;
107
+ }
108
+
109
+ /**
110
+ * Crown review object
111
+ * @description Combined review data for clinic, practitioner, and procedure
112
+ */
113
+ export interface Review {
114
+ id: string;
115
+ appointmentId: string;
116
+ patientId: string;
117
+ createdAt: Date;
118
+ updatedAt: Date;
119
+ clinicReview?: ClinicReview;
120
+ practitionerReview?: PractitionerReview;
121
+ procedureReview?: ProcedureReview;
122
+ overallComment: string;
123
+ overallRating: number; // Average of all available ratings
124
+ }
125
+
126
+ export const REVIEWS_COLLECTION = "reviews";
@@ -13,6 +13,8 @@ import {
13
13
  Currency,
14
14
  PricingMeasure,
15
15
  } from "../backoffice/types/static/pricing.types";
16
+ import { procedureSummaryInfoSchema } from "./practitioner.schema";
17
+ import { clinicReviewInfoSchema } from "./reviews.schema";
16
18
 
17
19
  /**
18
20
  * Validaciona šema za kontakt informacije
@@ -91,7 +93,7 @@ export const adminInfoSchema = z.object({
91
93
  });
92
94
 
93
95
  /**
94
- * Validaciona šema za osnovne informacije o klinici
96
+ * Validaciona šema za osnovne informacije o klinici (for aggregation)
95
97
  */
96
98
  export const clinicInfoSchema = z.object({
97
99
  id: z.string(),
@@ -103,7 +105,7 @@ export const clinicInfoSchema = z.object({
103
105
  });
104
106
 
105
107
  /**
106
- * Validaciona šema za informacije o doktoru
108
+ * Validaciona šema za informacije o doktoru (for aggregation in Clinic)
107
109
  */
108
110
  export const doctorInfoSchema = z.object({
109
111
  id: z.string(),
@@ -111,43 +113,30 @@ export const doctorInfoSchema = z.object({
111
113
  description: z.string().nullable().optional(),
112
114
  photo: z.string(),
113
115
  rating: z.number().min(0).max(5),
114
- services: z.array(z.string()),
116
+ services: z.array(z.string()), // List of procedure IDs practitioner offers
115
117
  });
116
118
 
117
119
  /**
118
- * Validaciona šema za informacije o usluzi
120
+ * @deprecated Replaced by procedureSummaryInfoSchema.
121
+ * Validaciona šema za informacije o usluzi (Old aggregation schema)
119
122
  */
120
- export const serviceInfoSchema = z.object({
121
- id: z.string(),
122
- name: z.string(),
123
- description: z.string().nullable().optional(),
124
- photo: z.string(),
125
- procedureFamily: z.nativeEnum(ProcedureFamily),
126
- category: z.string(),
127
- subCategory: z.string(),
128
- technology: z.string(),
129
- rating: z.number().min(0).max(5),
130
- doctors: z.array(z.string()),
131
- price: z.number().min(0),
132
- pricingMeasure: z.nativeEnum(PricingMeasure),
133
- currency: z.nativeEnum(Currency),
134
- duration: z.number().min(0),
135
- treatmentBenefits: z.array(z.nativeEnum(TreatmentBenefit)),
136
- });
137
-
138
- /**
139
- * Validaciona šema za informacije o recenziji
140
- */
141
- export const reviewInfoSchema = z.object({
142
- id: z.string(),
143
- rating: z.number().min(1).max(5),
144
- text: z.string(),
145
- patientId: z.string(),
146
- patientName: z.string(),
147
- patientPhoto: z.string(),
148
- createdAt: z.instanceof(Date).or(z.instanceof(Timestamp)), // Timestamp
149
- updatedAt: z.instanceof(Date).or(z.instanceof(Timestamp)), // Timestamp
150
- });
123
+ // export const serviceInfoSchema = z.object({
124
+ // id: z.string(),
125
+ // name: z.string(),
126
+ // description: z.string().nullable().optional(),
127
+ // photo: z.string(),
128
+ // procedureFamily: z.nativeEnum(ProcedureFamily),
129
+ // category: z.string(),
130
+ // subCategory: z.string(),
131
+ // technology: z.string(),
132
+ // rating: z.number().min(0).max(5),
133
+ // doctors: z.array(z.string()),
134
+ // price: z.number().min(0),
135
+ // pricingMeasure: z.nativeEnum(PricingMeasure),
136
+ // currency: z.nativeEnum(Currency),
137
+ // duration: z.number().min(0),
138
+ // treatmentBenefits: z.array(z.nativeEnum(TreatmentBenefit)),
139
+ // });
151
140
 
152
141
  /**
153
142
  * Validaciona šema za administratora klinike
@@ -215,20 +204,6 @@ export const clinicGroupSchema = z.object({
215
204
  businessIdentificationNumber: z.string().optional().nullable(),
216
205
  });
217
206
 
218
- /**
219
- * Validaciona šema za recenziju klinike
220
- */
221
- export const clinicReviewSchema = z.object({
222
- id: z.string(),
223
- clinicId: z.string(),
224
- patientId: z.string(),
225
- rating: z.number().min(1).max(5),
226
- comment: z.string(),
227
- createdAt: z.instanceof(Date).or(z.instanceof(Timestamp)), // Timestamp
228
- updatedAt: z.instanceof(Date).or(z.instanceof(Timestamp)), // Timestamp
229
- isVerified: z.boolean(),
230
- });
231
-
232
207
  /**
233
208
  * Validaciona šema za kliniku
234
209
  */
@@ -251,18 +226,13 @@ export const clinicSchema = z.object({
251
226
  })
252
227
  )
253
228
  .optional(),
254
- doctors: z.array(z.string()),
255
- doctorsInfo: z.array(doctorInfoSchema),
256
- services: z.array(z.string()),
257
- servicesInfo: z.array(serviceInfoSchema),
258
- reviews: z.array(z.string()),
259
- reviewsInfo: z.array(reviewInfoSchema),
260
- rating: z
261
- .object({
262
- average: z.number().min(0).max(5),
263
- count: z.number().min(0),
264
- })
265
- .nullable(),
229
+ doctors: z.array(z.string()), // List of practitioner IDs
230
+ doctorsInfo: z.array(doctorInfoSchema), // Aggregated doctor info
231
+ procedures: z.array(z.string()), // List of procedure IDs offered by clinic
232
+ proceduresInfo: z.array(procedureSummaryInfoSchema), // Use the correct schema for aggregated procedure info
233
+ // services: z.array(z.string()), // Likely deprecated, procedures covers this
234
+ // servicesInfo: z.array(serviceInfoSchema), // Deprecated, use proceduresInfo
235
+ reviewInfo: clinicReviewInfoSchema,
266
236
  admins: z.array(z.string()),
267
237
  createdAt: z.instanceof(Date).or(z.instanceof(Timestamp)), // Timestamp
268
238
  updatedAt: z.instanceof(Date).or(z.instanceof(Timestamp)), // Timestamp
@@ -282,6 +252,7 @@ export const createClinicAdminSchema = z.object({
282
252
  contactInfo: contactPersonSchema,
283
253
  roleTitle: z.string(),
284
254
  isActive: z.boolean(),
255
+ // clinicsManagedInfo is aggregated, not provided on creation
285
256
  });
286
257
 
287
258
  /**
@@ -305,6 +276,7 @@ export const createClinicGroupSchema = z.object({
305
276
  calendarSyncEnabled: z.boolean().optional(),
306
277
  autoConfirmAppointments: z.boolean().optional(),
307
278
  businessIdentificationNumber: z.string().optional().nullable(),
279
+ // clinics, clinicsInfo, admins, adminsInfo, adminTokens are managed internally
308
280
  });
309
281
 
310
282
  /**
@@ -327,9 +299,10 @@ export const createClinicSchema = z.object({
327
299
  })
328
300
  )
329
301
  .optional(),
330
- doctors: z.array(z.string()),
331
- services: z.array(z.string()),
332
- admins: z.array(z.string()),
302
+ // doctors, doctorsInfo, procedures, proceduresInfo are managed internally/aggregated
303
+ // doctors: z.array(z.string()),
304
+ // services: z.array(z.string()), // Deprecated
305
+ admins: z.array(z.string()), // Should likely just be creator ID initially
333
306
  isActive: z.boolean(),
334
307
  isVerified: z.boolean(),
335
308
  logo: z.string().optional(),