@blackcode_sa/metaestetics-api 1.8.6 → 1.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1878,685 +1878,6 @@ var AppointmentService = class extends BaseService {
1878
1878
  }
1879
1879
  };
1880
1880
 
1881
- // src/services/auth/utils/firebase.utils.ts
1882
- import { fetchSignInMethodsForEmail } from "firebase/auth";
1883
- var checkEmailExists = async (auth, email) => {
1884
- try {
1885
- const methods = await fetchSignInMethodsForEmail(auth, email);
1886
- return methods.length > 0;
1887
- } catch (error) {
1888
- console.warn(
1889
- "[FIREBASE] Could not check email existence, allowing signup to proceed:",
1890
- error
1891
- );
1892
- return false;
1893
- }
1894
- };
1895
- var cleanupFirebaseUser = async (firebaseUser) => {
1896
- try {
1897
- console.log("[FIREBASE] Cleaning up Firebase user", {
1898
- uid: firebaseUser.uid
1899
- });
1900
- await firebaseUser.delete();
1901
- console.log("[FIREBASE] Firebase user cleanup successful");
1902
- } catch (cleanupError) {
1903
- console.error("[FIREBASE] Failed to cleanup Firebase user:", cleanupError);
1904
- }
1905
- };
1906
-
1907
- // src/services/auth/utils/error.utils.ts
1908
- import { z as z4 } from "zod";
1909
-
1910
- // src/errors/auth.errors.ts
1911
- var AuthError = class extends Error {
1912
- constructor(message, code, status = 400) {
1913
- super(message);
1914
- this.code = code;
1915
- this.status = status;
1916
- this.name = "AuthError";
1917
- }
1918
- };
1919
- var AUTH_ERRORS = {
1920
- // Basic validation errors
1921
- INVALID_EMAIL: new AuthError(
1922
- "Email address is not in a valid format",
1923
- "AUTH/INVALID_EMAIL",
1924
- 400
1925
- ),
1926
- INVALID_PASSWORD: new AuthError(
1927
- "Password must contain at least 8 characters, one uppercase letter, one number, and one special character",
1928
- "AUTH/INVALID_PASSWORD",
1929
- 400
1930
- ),
1931
- INVALID_ROLE: new AuthError(
1932
- "Specified user role is not valid",
1933
- "AUTH/INVALID_ROLE",
1934
- 400
1935
- ),
1936
- // Authentication errors
1937
- NOT_AUTHENTICATED: new AuthError(
1938
- "User is not authenticated",
1939
- "AUTH/NOT_AUTHENTICATED",
1940
- 401
1941
- ),
1942
- SESSION_EXPIRED: new AuthError(
1943
- "Your session has expired. Please sign in again",
1944
- "AUTH/SESSION_EXPIRED",
1945
- 401
1946
- ),
1947
- INVALID_TOKEN: new AuthError(
1948
- "Invalid authentication token",
1949
- "AUTH/INVALID_TOKEN",
1950
- 401
1951
- ),
1952
- // User state errors
1953
- USER_NOT_FOUND: new AuthError(
1954
- "User not found in the system",
1955
- "AUTH/USER_NOT_FOUND",
1956
- 404
1957
- ),
1958
- EMAIL_ALREADY_EXISTS: new AuthError(
1959
- "An account with this email already exists",
1960
- "AUTH/EMAIL_EXISTS",
1961
- 409
1962
- ),
1963
- USER_DISABLED: new AuthError(
1964
- "This account has been disabled",
1965
- "AUTH/USER_DISABLED",
1966
- 403
1967
- ),
1968
- // Rate limiting and security
1969
- TOO_MANY_REQUESTS: new AuthError(
1970
- "Too many login attempts. Please try again later",
1971
- "AUTH/TOO_MANY_REQUESTS",
1972
- 429
1973
- ),
1974
- ACCOUNT_LOCKED: new AuthError(
1975
- "Account temporarily locked due to too many failed login attempts",
1976
- "AUTH/ACCOUNT_LOCKED",
1977
- 403
1978
- ),
1979
- // Social auth specific
1980
- POPUP_CLOSED: new AuthError(
1981
- "Authentication popup was closed before completion",
1982
- "AUTH/POPUP_CLOSED",
1983
- 400
1984
- ),
1985
- POPUP_BLOCKED: new AuthError(
1986
- "Authentication popup was blocked by the browser",
1987
- "AUTH/POPUP_BLOCKED",
1988
- 400
1989
- ),
1990
- ACCOUNT_EXISTS: new AuthError(
1991
- "An account already exists with different credentials",
1992
- "AUTH/ACCOUNT_EXISTS",
1993
- 409
1994
- ),
1995
- // Anonymous auth specific
1996
- NOT_ANONYMOUS: new AuthError(
1997
- "Current user is not anonymous",
1998
- "AUTH/NOT_ANONYMOUS_USER",
1999
- 400
2000
- ),
2001
- ANONYMOUS_UPGRADE_FAILED: new AuthError(
2002
- "Failed to upgrade anonymous account",
2003
- "AUTH/ANONYMOUS_UPGRADE_FAILED",
2004
- 400
2005
- ),
2006
- // General errors
2007
- VALIDATION_ERROR: new AuthError(
2008
- "Data validation error occurred",
2009
- "AUTH/VALIDATION_ERROR",
2010
- 400
2011
- ),
2012
- OPERATION_NOT_ALLOWED: new AuthError(
2013
- "This operation is not allowed",
2014
- "AUTH/OPERATION_NOT_ALLOWED",
2015
- 403
2016
- ),
2017
- NETWORK_ERROR: new AuthError(
2018
- "Network error occurred. Please check your connection",
2019
- "AUTH/NETWORK_ERROR",
2020
- 503
2021
- ),
2022
- REQUIRES_RECENT_LOGIN: new AuthError(
2023
- "This operation requires recent authentication. Please sign in again",
2024
- "AUTH/REQUIRES_RECENT_LOGIN",
2025
- 401
2026
- ),
2027
- INVALID_PROVIDER: new AuthError(
2028
- "Invalid authentication provider",
2029
- "AUTH/INVALID_PROVIDER",
2030
- 400
2031
- ),
2032
- INVALID_CREDENTIAL: new AuthError(
2033
- "The provided credentials are invalid or expired",
2034
- "AUTH/INVALID_CREDENTIAL",
2035
- 401
2036
- ),
2037
- // Resource not found
2038
- NOT_FOUND: new AuthError(
2039
- "The requested resource was not found",
2040
- "AUTH/NOT_FOUND",
2041
- 404
2042
- ),
2043
- // Detailed password validation errors
2044
- PASSWORD_LENGTH_ERROR: new AuthError(
2045
- "Password must be at least 8 characters long",
2046
- "AUTH/PASSWORD_LENGTH_ERROR",
2047
- 400
2048
- ),
2049
- PASSWORD_UPPERCASE_ERROR: new AuthError(
2050
- "Password must contain at least one uppercase letter",
2051
- "AUTH/PASSWORD_UPPERCASE_ERROR",
2052
- 400
2053
- ),
2054
- PASSWORD_NUMBER_ERROR: new AuthError(
2055
- "Password must contain at least one number",
2056
- "AUTH/PASSWORD_NUMBER_ERROR",
2057
- 400
2058
- ),
2059
- PASSWORD_SPECIAL_CHAR_ERROR: new AuthError(
2060
- "Password must contain at least one special character",
2061
- "AUTH/PASSWORD_SPECIAL_CHAR_ERROR",
2062
- 400
2063
- ),
2064
- // Detailed email validation errors
2065
- EMAIL_FORMAT_ERROR: new AuthError(
2066
- "Invalid email format. Please enter a valid email address",
2067
- "AUTH/EMAIL_FORMAT_ERROR",
2068
- 400
2069
- ),
2070
- PASSWORD_VALIDATION_ERROR: new AuthError(
2071
- "Password validation failed. Please check all requirements",
2072
- "AUTH/PASSWORD_VALIDATION_ERROR",
2073
- 400
2074
- ),
2075
- // Password reset specific errors
2076
- EXPIRED_ACTION_CODE: new AuthError(
2077
- "Kod za resetovanje lozinke je istekao. Molimo zatra\u017Eite novi link za resetovanje.",
2078
- "AUTH/EXPIRED_ACTION_CODE",
2079
- 400
2080
- ),
2081
- INVALID_ACTION_CODE: new AuthError(
2082
- "Kod za resetovanje lozinke je neva\u017Ee\u0107i ili je ve\u0107 iskori\u0161\u0107en. Molimo zatra\u017Eite novi link za resetovanje.",
2083
- "AUTH/INVALID_ACTION_CODE",
2084
- 400
2085
- ),
2086
- WEAK_PASSWORD: new AuthError(
2087
- "Lozinka je previ\u0161e slaba. Molimo koristite ja\u010Du lozinku.",
2088
- "AUTH/WEAK_PASSWORD",
2089
- 400
2090
- )
2091
- };
2092
-
2093
- // src/services/auth/utils/error.utils.ts
2094
- var handleFirebaseError = (error) => {
2095
- const firebaseError = error;
2096
- switch (firebaseError.code) {
2097
- case "auth/email-already-in-use" /* EMAIL_ALREADY_IN_USE */:
2098
- return AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
2099
- case "auth/weak-password":
2100
- return new Error(
2101
- "Password is too weak. Please choose a stronger password."
2102
- );
2103
- case "auth/invalid-email":
2104
- return new Error("Please enter a valid email address.");
2105
- case "auth/network-request-failed":
2106
- return new Error(
2107
- "Network error. Please check your internet connection and try again."
2108
- );
2109
- default:
2110
- return new Error(
2111
- `Account creation failed: ${firebaseError.message || "Unknown error"}`
2112
- );
2113
- }
2114
- };
2115
- var handleSignupError = (error) => {
2116
- if (error instanceof z4.ZodError) {
2117
- const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
2118
- return new Error(`Validation failed: ${errorMessages}`);
2119
- }
2120
- if (error.code && error.code.startsWith("auth/")) {
2121
- return handleFirebaseError(error);
2122
- }
2123
- if (error.message && error.message.includes("token")) {
2124
- return new Error("Invalid or expired invitation token");
2125
- }
2126
- if (error.message && error.message.includes("validation")) {
2127
- return new Error(`Invalid practitioner data: ${error.message}`);
2128
- }
2129
- return new Error(
2130
- `Registration failed: ${error.message || "Unknown error occurred"}`
2131
- );
2132
- };
2133
- var extractErrorMessage = (error) => {
2134
- if (error instanceof Error) {
2135
- return error.message;
2136
- }
2137
- if (typeof error === "string") {
2138
- return error;
2139
- }
2140
- if (error == null ? void 0 : error.message) {
2141
- return error.message;
2142
- }
2143
- return "Unknown error occurred";
2144
- };
2145
-
2146
- // src/backoffice/types/static/certification.types.ts
2147
- var CertificationLevel = /* @__PURE__ */ ((CertificationLevel2) => {
2148
- CertificationLevel2["AESTHETICIAN"] = "aesthetician";
2149
- CertificationLevel2["NURSE_ASSISTANT"] = "nurse_assistant";
2150
- CertificationLevel2["NURSE"] = "nurse";
2151
- CertificationLevel2["NURSE_PRACTITIONER"] = "nurse_practitioner";
2152
- CertificationLevel2["PHYSICIAN_ASSISTANT"] = "physician_assistant";
2153
- CertificationLevel2["DOCTOR"] = "doctor";
2154
- CertificationLevel2["SPECIALIST"] = "specialist";
2155
- CertificationLevel2["PLASTIC_SURGEON"] = "plastic_surgeon";
2156
- return CertificationLevel2;
2157
- })(CertificationLevel || {});
2158
- var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
2159
- CertificationSpecialty3["LASER"] = "laser";
2160
- CertificationSpecialty3["INJECTABLES"] = "injectables";
2161
- CertificationSpecialty3["CHEMICAL_PEELS"] = "chemical_peels";
2162
- CertificationSpecialty3["MICRODERMABRASION"] = "microdermabrasion";
2163
- CertificationSpecialty3["BODY_CONTOURING"] = "body_contouring";
2164
- CertificationSpecialty3["SKIN_CARE"] = "skin_care";
2165
- CertificationSpecialty3["WOUND_CARE"] = "wound_care";
2166
- CertificationSpecialty3["ANESTHESIA"] = "anesthesia";
2167
- return CertificationSpecialty3;
2168
- })(CertificationSpecialty || {});
2169
-
2170
- // src/services/auth/utils/practitioner.utils.ts
2171
- import { z as z8 } from "zod";
2172
-
2173
- // src/validations/practitioner.schema.ts
2174
- import { z as z7 } from "zod";
2175
- import { Timestamp as Timestamp3 } from "firebase/firestore";
2176
-
2177
- // src/validations/reviews.schema.ts
2178
- import { z as z5 } from "zod";
2179
- var baseReviewSchema = z5.object({
2180
- id: z5.string().min(1),
2181
- patientId: z5.string().min(1),
2182
- fullReviewId: z5.string().min(1),
2183
- createdAt: z5.date(),
2184
- updatedAt: z5.date(),
2185
- comment: z5.string().min(1).max(2e3),
2186
- isVerified: z5.boolean(),
2187
- isPublished: z5.boolean()
2188
- });
2189
- var baseReviewCreateSchema = z5.object({
2190
- patientId: z5.string().min(1),
2191
- comment: z5.string().min(1).max(2e3),
2192
- isVerified: z5.boolean().default(false),
2193
- isPublished: z5.boolean().default(true)
2194
- });
2195
- var clinicReviewSchema = baseReviewSchema.extend({
2196
- clinicId: z5.string().min(1),
2197
- cleanliness: z5.number().min(1).max(5),
2198
- facilities: z5.number().min(1).max(5),
2199
- staffFriendliness: z5.number().min(1).max(5),
2200
- waitingTime: z5.number().min(1).max(5),
2201
- accessibility: z5.number().min(1).max(5),
2202
- overallRating: z5.number().min(1).max(5),
2203
- wouldRecommend: z5.boolean()
2204
- });
2205
- var createClinicReviewSchema = baseReviewCreateSchema.extend({
2206
- clinicId: z5.string().min(1),
2207
- cleanliness: z5.number().min(1).max(5),
2208
- facilities: z5.number().min(1).max(5),
2209
- staffFriendliness: z5.number().min(1).max(5),
2210
- waitingTime: z5.number().min(1).max(5),
2211
- accessibility: z5.number().min(1).max(5),
2212
- wouldRecommend: z5.boolean()
2213
- });
2214
- var practitionerReviewSchema = baseReviewSchema.extend({
2215
- practitionerId: z5.string().min(1),
2216
- knowledgeAndExpertise: z5.number().min(1).max(5),
2217
- communicationSkills: z5.number().min(1).max(5),
2218
- bedSideManner: z5.number().min(1).max(5),
2219
- thoroughness: z5.number().min(1).max(5),
2220
- trustworthiness: z5.number().min(1).max(5),
2221
- overallRating: z5.number().min(1).max(5),
2222
- wouldRecommend: z5.boolean()
2223
- });
2224
- var createPractitionerReviewSchema = baseReviewCreateSchema.extend({
2225
- practitionerId: z5.string().min(1),
2226
- knowledgeAndExpertise: z5.number().min(1).max(5),
2227
- communicationSkills: z5.number().min(1).max(5),
2228
- bedSideManner: z5.number().min(1).max(5),
2229
- thoroughness: z5.number().min(1).max(5),
2230
- trustworthiness: z5.number().min(1).max(5),
2231
- wouldRecommend: z5.boolean()
2232
- });
2233
- var procedureReviewSchema = baseReviewSchema.extend({
2234
- procedureId: z5.string().min(1),
2235
- effectivenessOfTreatment: z5.number().min(1).max(5),
2236
- outcomeExplanation: z5.number().min(1).max(5),
2237
- painManagement: z5.number().min(1).max(5),
2238
- followUpCare: z5.number().min(1).max(5),
2239
- valueForMoney: z5.number().min(1).max(5),
2240
- overallRating: z5.number().min(1).max(5),
2241
- wouldRecommend: z5.boolean()
2242
- });
2243
- var createProcedureReviewSchema = baseReviewCreateSchema.extend({
2244
- procedureId: z5.string().min(1),
2245
- effectivenessOfTreatment: z5.number().min(1).max(5),
2246
- outcomeExplanation: z5.number().min(1).max(5),
2247
- painManagement: z5.number().min(1).max(5),
2248
- followUpCare: z5.number().min(1).max(5),
2249
- valueForMoney: z5.number().min(1).max(5),
2250
- wouldRecommend: z5.boolean()
2251
- });
2252
- var clinicReviewInfoSchema = z5.object({
2253
- totalReviews: z5.number().min(0),
2254
- averageRating: z5.number().min(0).max(5),
2255
- cleanliness: z5.number().min(0).max(5),
2256
- facilities: z5.number().min(0).max(5),
2257
- staffFriendliness: z5.number().min(0).max(5),
2258
- waitingTime: z5.number().min(0).max(5),
2259
- accessibility: z5.number().min(0).max(5),
2260
- recommendationPercentage: z5.number().min(0).max(100)
2261
- });
2262
- var practitionerReviewInfoSchema = z5.object({
2263
- totalReviews: z5.number().min(0),
2264
- averageRating: z5.number().min(0).max(5),
2265
- knowledgeAndExpertise: z5.number().min(0).max(5),
2266
- communicationSkills: z5.number().min(0).max(5),
2267
- bedSideManner: z5.number().min(0).max(5),
2268
- thoroughness: z5.number().min(0).max(5),
2269
- trustworthiness: z5.number().min(0).max(5),
2270
- recommendationPercentage: z5.number().min(0).max(100)
2271
- });
2272
- var procedureReviewInfoSchema = z5.object({
2273
- totalReviews: z5.number().min(0),
2274
- averageRating: z5.number().min(0).max(5),
2275
- effectivenessOfTreatment: z5.number().min(0).max(5),
2276
- outcomeExplanation: z5.number().min(0).max(5),
2277
- painManagement: z5.number().min(0).max(5),
2278
- followUpCare: z5.number().min(0).max(5),
2279
- valueForMoney: z5.number().min(0).max(5),
2280
- recommendationPercentage: z5.number().min(0).max(100)
2281
- });
2282
- var reviewSchema = z5.object({
2283
- id: z5.string().min(1),
2284
- appointmentId: z5.string().min(1),
2285
- patientId: z5.string().min(1),
2286
- createdAt: z5.date(),
2287
- updatedAt: z5.date(),
2288
- clinicReview: clinicReviewSchema.optional(),
2289
- practitionerReview: practitionerReviewSchema.optional(),
2290
- procedureReview: procedureReviewSchema.optional(),
2291
- overallComment: z5.string().min(1).max(2e3),
2292
- overallRating: z5.number().min(1).max(5)
2293
- });
2294
- var createReviewSchema = z5.object({
2295
- patientId: z5.string().min(1),
2296
- clinicReview: createClinicReviewSchema.optional(),
2297
- practitionerReview: createPractitionerReviewSchema.optional(),
2298
- procedureReview: createProcedureReviewSchema.optional(),
2299
- overallComment: z5.string().min(1).max(2e3)
2300
- }).refine(
2301
- (data) => {
2302
- return data.clinicReview || data.practitionerReview || data.procedureReview;
2303
- },
2304
- {
2305
- message: "At least one review type (clinic, practitioner, or procedure) must be provided",
2306
- path: ["reviewType"]
2307
- }
2308
- );
2309
-
2310
- // src/validations/shared.schema.ts
2311
- import { z as z6 } from "zod";
2312
-
2313
- // src/backoffice/types/static/procedure-family.types.ts
2314
- var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
2315
- ProcedureFamily2["AESTHETICS"] = "aesthetics";
2316
- ProcedureFamily2["SURGERY"] = "surgery";
2317
- return ProcedureFamily2;
2318
- })(ProcedureFamily || {});
2319
-
2320
- // src/validations/shared.schema.ts
2321
- var sharedClinicContactInfoSchema = z6.object({
2322
- email: z6.string().email(),
2323
- phoneNumber: z6.string(),
2324
- alternativePhoneNumber: z6.string().nullable().optional(),
2325
- website: z6.string().nullable().optional()
2326
- });
2327
- var sharedClinicLocationSchema = z6.object({
2328
- address: z6.string(),
2329
- city: z6.string(),
2330
- country: z6.string(),
2331
- postalCode: z6.string(),
2332
- latitude: z6.number().min(-90).max(90),
2333
- longitude: z6.number().min(-180).max(180),
2334
- geohash: z6.string().nullable().optional()
2335
- });
2336
- var procedureSummaryInfoSchema = z6.object({
2337
- id: z6.string().min(1),
2338
- name: z6.string().min(1),
2339
- description: z6.string().optional(),
2340
- photo: z6.string().optional(),
2341
- family: z6.nativeEnum(ProcedureFamily),
2342
- categoryName: z6.string(),
2343
- subcategoryName: z6.string(),
2344
- technologyName: z6.string(),
2345
- price: z6.number().nonnegative(),
2346
- pricingMeasure: z6.nativeEnum(PricingMeasure),
2347
- currency: z6.nativeEnum(Currency),
2348
- duration: z6.number().int().positive(),
2349
- clinicId: z6.string().min(1),
2350
- clinicName: z6.string().min(1),
2351
- practitionerId: z6.string().min(1),
2352
- practitionerName: z6.string().min(1)
2353
- });
2354
- var clinicInfoSchema = z6.object({
2355
- id: z6.string(),
2356
- featuredPhoto: z6.string(),
2357
- name: z6.string(),
2358
- description: z6.string().nullable().optional(),
2359
- location: sharedClinicLocationSchema,
2360
- contactInfo: sharedClinicContactInfoSchema
2361
- });
2362
- var doctorInfoSchema = z6.object({
2363
- id: z6.string(),
2364
- name: z6.string(),
2365
- description: z6.string().nullable().optional(),
2366
- photo: z6.string(),
2367
- rating: z6.number().min(0).max(5),
2368
- services: z6.array(z6.string())
2369
- // List of procedure IDs practitioner offers
2370
- });
2371
-
2372
- // src/validations/practitioner.schema.ts
2373
- var practitionerBasicInfoSchema = z7.object({
2374
- firstName: z7.string().min(2).max(50),
2375
- lastName: z7.string().min(2).max(50),
2376
- title: z7.string().min(2).max(100),
2377
- email: z7.string().email(),
2378
- phoneNumber: z7.string().regex(/^\+?[1-9]\d{1,14}$/, "Invalid phone number").nullable(),
2379
- dateOfBirth: z7.instanceof(Timestamp3).or(z7.date()).nullable(),
2380
- gender: z7.enum(["male", "female", "other"]),
2381
- profileImageUrl: mediaResourceSchema.optional().nullable(),
2382
- bio: z7.string().max(1e3).optional(),
2383
- languages: z7.array(z7.string()).min(1)
2384
- });
2385
- var practitionerCertificationSchema = z7.object({
2386
- level: z7.nativeEnum(CertificationLevel),
2387
- specialties: z7.array(z7.nativeEnum(CertificationSpecialty)),
2388
- licenseNumber: z7.string().min(3).max(50),
2389
- issuingAuthority: z7.string().min(2).max(100),
2390
- issueDate: z7.instanceof(Timestamp3).or(z7.date()),
2391
- expiryDate: z7.instanceof(Timestamp3).or(z7.date()).optional().nullable(),
2392
- verificationStatus: z7.enum(["pending", "verified", "rejected"])
2393
- });
2394
- var timeSlotSchema = z7.object({
2395
- start: z7.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format"),
2396
- end: z7.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format")
2397
- }).nullable();
2398
- var practitionerWorkingHoursSchema = z7.object({
2399
- practitionerId: z7.string().min(1),
2400
- clinicId: z7.string().min(1),
2401
- monday: timeSlotSchema,
2402
- tuesday: timeSlotSchema,
2403
- wednesday: timeSlotSchema,
2404
- thursday: timeSlotSchema,
2405
- friday: timeSlotSchema,
2406
- saturday: timeSlotSchema,
2407
- sunday: timeSlotSchema,
2408
- createdAt: z7.instanceof(Timestamp3).or(z7.date()),
2409
- updatedAt: z7.instanceof(Timestamp3).or(z7.date())
2410
- });
2411
- var practitionerClinicWorkingHoursSchema = z7.object({
2412
- clinicId: z7.string().min(1),
2413
- workingHours: z7.object({
2414
- monday: timeSlotSchema,
2415
- tuesday: timeSlotSchema,
2416
- wednesday: timeSlotSchema,
2417
- thursday: timeSlotSchema,
2418
- friday: timeSlotSchema,
2419
- saturday: timeSlotSchema,
2420
- sunday: timeSlotSchema
2421
- }),
2422
- isActive: z7.boolean(),
2423
- createdAt: z7.instanceof(Timestamp3).or(z7.date()),
2424
- updatedAt: z7.instanceof(Timestamp3).or(z7.date())
2425
- });
2426
- var practitionerSchema = z7.object({
2427
- id: z7.string().min(1),
2428
- userRef: z7.string().min(1),
2429
- basicInfo: practitionerBasicInfoSchema,
2430
- certification: practitionerCertificationSchema,
2431
- clinics: z7.array(z7.string()),
2432
- clinicWorkingHours: z7.array(practitionerClinicWorkingHoursSchema),
2433
- clinicsInfo: z7.array(clinicInfoSchema),
2434
- procedures: z7.array(z7.string()),
2435
- freeConsultations: z7.record(z7.string(), z7.string()).optional().nullable(),
2436
- proceduresInfo: z7.array(procedureSummaryInfoSchema),
2437
- reviewInfo: practitionerReviewInfoSchema,
2438
- isActive: z7.boolean(),
2439
- isVerified: z7.boolean(),
2440
- status: z7.nativeEnum(PractitionerStatus),
2441
- createdAt: z7.instanceof(Timestamp3).or(z7.date()),
2442
- updatedAt: z7.instanceof(Timestamp3).or(z7.date())
2443
- });
2444
- var createPractitionerSchema = z7.object({
2445
- userRef: z7.string().min(1),
2446
- basicInfo: practitionerBasicInfoSchema,
2447
- certification: practitionerCertificationSchema,
2448
- clinics: z7.array(z7.string()).optional(),
2449
- clinicWorkingHours: z7.array(practitionerClinicWorkingHoursSchema).optional(),
2450
- clinicsInfo: z7.array(clinicInfoSchema).optional(),
2451
- freeConsultations: z7.record(z7.string(), z7.string()).optional().nullable(),
2452
- proceduresInfo: z7.array(procedureSummaryInfoSchema).optional(),
2453
- isActive: z7.boolean(),
2454
- isVerified: z7.boolean(),
2455
- status: z7.nativeEnum(PractitionerStatus).optional()
2456
- });
2457
- var createDraftPractitionerSchema = z7.object({
2458
- basicInfo: practitionerBasicInfoSchema,
2459
- certification: practitionerCertificationSchema,
2460
- clinics: z7.array(z7.string()).optional(),
2461
- clinicWorkingHours: z7.array(practitionerClinicWorkingHoursSchema).optional(),
2462
- clinicsInfo: z7.array(clinicInfoSchema).optional(),
2463
- freeConsultations: z7.record(z7.string(), z7.string()).optional().nullable(),
2464
- proceduresInfo: z7.array(procedureSummaryInfoSchema).optional(),
2465
- isActive: z7.boolean().optional().default(false),
2466
- isVerified: z7.boolean().optional().default(false)
2467
- });
2468
- var practitionerTokenSchema = z7.object({
2469
- id: z7.string().min(1),
2470
- token: z7.string().min(6),
2471
- practitionerId: z7.string().min(1),
2472
- email: z7.string().email(),
2473
- clinicId: z7.string().min(1),
2474
- status: z7.nativeEnum(PractitionerTokenStatus),
2475
- createdBy: z7.string().min(1),
2476
- createdAt: z7.instanceof(Timestamp3).or(z7.date()),
2477
- expiresAt: z7.instanceof(Timestamp3).or(z7.date()),
2478
- usedBy: z7.string().optional(),
2479
- usedAt: z7.instanceof(Timestamp3).or(z7.date()).optional()
2480
- });
2481
- var createPractitionerTokenSchema = z7.object({
2482
- practitionerId: z7.string().min(1),
2483
- email: z7.string().email(),
2484
- clinicId: z7.string().min(1),
2485
- expiresAt: z7.date().optional()
2486
- });
2487
- var practitionerSignupSchema = z7.object({
2488
- email: z7.string().email(),
2489
- password: z7.string().min(8),
2490
- firstName: z7.string().min(2).max(50).optional(),
2491
- lastName: z7.string().min(2).max(50).optional(),
2492
- token: z7.string().optional(),
2493
- profileData: z7.object({
2494
- basicInfo: z7.object({
2495
- phoneNumber: z7.string().optional(),
2496
- profileImageUrl: mediaResourceSchema.optional(),
2497
- gender: z7.enum(["male", "female", "other"]).optional(),
2498
- bio: z7.string().optional()
2499
- }).optional(),
2500
- certification: z7.any().optional()
2501
- }).optional()
2502
- });
2503
-
2504
- // src/services/auth/utils/practitioner.utils.ts
2505
- var profileDataSchema = z8.object({
2506
- basicInfo: practitionerBasicInfoSchema.partial().optional(),
2507
- certification: practitionerCertificationSchema.partial().optional()
2508
- }).partial();
2509
- var buildPractitionerData = (data, userRef) => {
2510
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
2511
- const basicInfo = {
2512
- firstName: data.firstName || "Name",
2513
- lastName: data.lastName || "Surname",
2514
- email: data.email,
2515
- phoneNumber: ((_b = (_a = data.profileData) == null ? void 0 : _a.basicInfo) == null ? void 0 : _b.phoneNumber) || null,
2516
- profileImageUrl: ((_d = (_c = data.profileData) == null ? void 0 : _c.basicInfo) == null ? void 0 : _d.profileImageUrl) || "",
2517
- gender: ((_f = (_e = data.profileData) == null ? void 0 : _e.basicInfo) == null ? void 0 : _f.gender) || "other",
2518
- bio: ((_h = (_g = data.profileData) == null ? void 0 : _g.basicInfo) == null ? void 0 : _h.bio) || "",
2519
- title: "Practitioner",
2520
- dateOfBirth: ((_j = (_i = data.profileData) == null ? void 0 : _i.basicInfo) == null ? void 0 : _j.dateOfBirth) || /* @__PURE__ */ new Date(),
2521
- languages: ((_l = (_k = data.profileData) == null ? void 0 : _k.basicInfo) == null ? void 0 : _l.languages) || ["English"]
2522
- };
2523
- const certification = ((_m = data.profileData) == null ? void 0 : _m.certification) || {
2524
- level: "aesthetician" /* AESTHETICIAN */,
2525
- specialties: [],
2526
- licenseNumber: "Pending",
2527
- issuingAuthority: "Pending",
2528
- issueDate: /* @__PURE__ */ new Date(),
2529
- verificationStatus: "pending"
2530
- };
2531
- return {
2532
- userRef,
2533
- basicInfo,
2534
- certification,
2535
- status: "active" /* ACTIVE */,
2536
- isActive: true,
2537
- isVerified: false
2538
- };
2539
- };
2540
- var validatePractitionerProfileData = async (profileData) => {
2541
- try {
2542
- await profileDataSchema.parseAsync(profileData);
2543
- } catch (error) {
2544
- if (error instanceof z8.ZodError) {
2545
- const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
2546
- throw new Error(
2547
- `Practitioner profile validation failed: ${errorMessages}`
2548
- );
2549
- }
2550
- throw error;
2551
- }
2552
- };
2553
- var isPractitionerDataComplete = (practitioner) => {
2554
- const { basicInfo, certification } = practitioner;
2555
- const hasRequiredBasicInfo = basicInfo.firstName && basicInfo.lastName && basicInfo.email && basicInfo.phoneNumber;
2556
- const hasRequiredCertification = certification.licenseNumber && certification.licenseNumber !== "Pending" && certification.issuingAuthority && certification.issuingAuthority !== "Pending";
2557
- return !!(hasRequiredBasicInfo && hasRequiredCertification);
2558
- };
2559
-
2560
1881
  // src/services/auth/auth.service.ts
2561
1882
  import {
2562
1883
  signInWithEmailAndPassword,
@@ -2718,18 +2039,18 @@ var REVIEWS_COLLECTION = "reviews";
2718
2039
  import { z as z23 } from "zod";
2719
2040
 
2720
2041
  // src/validations/schemas.ts
2721
- import { z as z9 } from "zod";
2722
- var emailSchema = z9.string().email("Invalid email format").min(5, "Email must be at least 5 characters").max(255, "Email must be less than 255 characters");
2723
- var passwordSchema = z9.string().min(8, "Password must be at least 8 characters").max(100, "Password must be less than 100 characters").regex(
2042
+ import { z as z4 } from "zod";
2043
+ var emailSchema = z4.string().email("Invalid email format").min(5, "Email must be at least 5 characters").max(255, "Email must be less than 255 characters");
2044
+ var passwordSchema = z4.string().min(8, "Password must be at least 8 characters").max(100, "Password must be less than 100 characters").regex(
2724
2045
  /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d\w\W]{8,}$/,
2725
2046
  "Password must contain at least one uppercase letter, one lowercase letter, and one number"
2726
2047
  );
2727
- var userRoleSchema = z9.nativeEnum(UserRole);
2728
- var userRolesSchema = z9.array(userRoleSchema).min(1, "User must have at least one role").max(3, "User cannot have more than 3 roles");
2729
- var clinicAdminOptionsSchema = z9.object({
2730
- isGroupOwner: z9.boolean(),
2731
- groupToken: z9.string().optional(),
2732
- groupId: z9.string().optional()
2048
+ var userRoleSchema = z4.nativeEnum(UserRole);
2049
+ var userRolesSchema = z4.array(userRoleSchema).min(1, "User must have at least one role").max(3, "User cannot have more than 3 roles");
2050
+ var clinicAdminOptionsSchema = z4.object({
2051
+ isGroupOwner: z4.boolean(),
2052
+ groupToken: z4.string().optional(),
2053
+ groupId: z4.string().optional()
2733
2054
  }).refine(
2734
2055
  (data) => {
2735
2056
  if (!data.isGroupOwner && (!data.groupToken || !data.groupId)) {
@@ -2744,22 +2065,205 @@ var clinicAdminOptionsSchema = z9.object({
2744
2065
  message: "Invalid clinic admin options configuration"
2745
2066
  }
2746
2067
  );
2747
- var createUserOptionsSchema = z9.object({
2068
+ var createUserOptionsSchema = z4.object({
2748
2069
  clinicAdminData: clinicAdminOptionsSchema.optional()
2749
2070
  });
2750
- var userSchema = z9.object({
2751
- uid: z9.string(),
2752
- email: z9.string().email().nullable(),
2753
- roles: z9.array(userRoleSchema),
2754
- isAnonymous: z9.boolean(),
2755
- createdAt: z9.any(),
2756
- updatedAt: z9.any(),
2757
- lastLoginAt: z9.any(),
2758
- patientProfile: z9.string().optional(),
2759
- practitionerProfile: z9.string().optional(),
2760
- adminProfile: z9.string().optional()
2071
+ var userSchema = z4.object({
2072
+ uid: z4.string(),
2073
+ email: z4.string().email().nullable(),
2074
+ roles: z4.array(userRoleSchema),
2075
+ isAnonymous: z4.boolean(),
2076
+ createdAt: z4.any(),
2077
+ updatedAt: z4.any(),
2078
+ lastLoginAt: z4.any(),
2079
+ patientProfile: z4.string().optional(),
2080
+ practitionerProfile: z4.string().optional(),
2081
+ adminProfile: z4.string().optional()
2761
2082
  });
2762
2083
 
2084
+ // src/errors/auth.errors.ts
2085
+ var AuthError = class extends Error {
2086
+ constructor(message, code, status = 400) {
2087
+ super(message);
2088
+ this.code = code;
2089
+ this.status = status;
2090
+ this.name = "AuthError";
2091
+ }
2092
+ };
2093
+ var AUTH_ERRORS = {
2094
+ // Basic validation errors
2095
+ INVALID_EMAIL: new AuthError(
2096
+ "Email address is not in a valid format",
2097
+ "AUTH/INVALID_EMAIL",
2098
+ 400
2099
+ ),
2100
+ INVALID_PASSWORD: new AuthError(
2101
+ "Password must contain at least 8 characters, one uppercase letter, one number, and one special character",
2102
+ "AUTH/INVALID_PASSWORD",
2103
+ 400
2104
+ ),
2105
+ INVALID_ROLE: new AuthError(
2106
+ "Specified user role is not valid",
2107
+ "AUTH/INVALID_ROLE",
2108
+ 400
2109
+ ),
2110
+ // Authentication errors
2111
+ NOT_AUTHENTICATED: new AuthError(
2112
+ "User is not authenticated",
2113
+ "AUTH/NOT_AUTHENTICATED",
2114
+ 401
2115
+ ),
2116
+ SESSION_EXPIRED: new AuthError(
2117
+ "Your session has expired. Please sign in again",
2118
+ "AUTH/SESSION_EXPIRED",
2119
+ 401
2120
+ ),
2121
+ INVALID_TOKEN: new AuthError(
2122
+ "Invalid authentication token",
2123
+ "AUTH/INVALID_TOKEN",
2124
+ 401
2125
+ ),
2126
+ // User state errors
2127
+ USER_NOT_FOUND: new AuthError(
2128
+ "User not found in the system",
2129
+ "AUTH/USER_NOT_FOUND",
2130
+ 404
2131
+ ),
2132
+ EMAIL_ALREADY_EXISTS: new AuthError(
2133
+ "An account with this email already exists",
2134
+ "AUTH/EMAIL_EXISTS",
2135
+ 409
2136
+ ),
2137
+ USER_DISABLED: new AuthError(
2138
+ "This account has been disabled",
2139
+ "AUTH/USER_DISABLED",
2140
+ 403
2141
+ ),
2142
+ // Rate limiting and security
2143
+ TOO_MANY_REQUESTS: new AuthError(
2144
+ "Too many login attempts. Please try again later",
2145
+ "AUTH/TOO_MANY_REQUESTS",
2146
+ 429
2147
+ ),
2148
+ ACCOUNT_LOCKED: new AuthError(
2149
+ "Account temporarily locked due to too many failed login attempts",
2150
+ "AUTH/ACCOUNT_LOCKED",
2151
+ 403
2152
+ ),
2153
+ // Social auth specific
2154
+ POPUP_CLOSED: new AuthError(
2155
+ "Authentication popup was closed before completion",
2156
+ "AUTH/POPUP_CLOSED",
2157
+ 400
2158
+ ),
2159
+ POPUP_BLOCKED: new AuthError(
2160
+ "Authentication popup was blocked by the browser",
2161
+ "AUTH/POPUP_BLOCKED",
2162
+ 400
2163
+ ),
2164
+ ACCOUNT_EXISTS: new AuthError(
2165
+ "An account already exists with different credentials",
2166
+ "AUTH/ACCOUNT_EXISTS",
2167
+ 409
2168
+ ),
2169
+ // Anonymous auth specific
2170
+ NOT_ANONYMOUS: new AuthError(
2171
+ "Current user is not anonymous",
2172
+ "AUTH/NOT_ANONYMOUS_USER",
2173
+ 400
2174
+ ),
2175
+ ANONYMOUS_UPGRADE_FAILED: new AuthError(
2176
+ "Failed to upgrade anonymous account",
2177
+ "AUTH/ANONYMOUS_UPGRADE_FAILED",
2178
+ 400
2179
+ ),
2180
+ // General errors
2181
+ VALIDATION_ERROR: new AuthError(
2182
+ "Data validation error occurred",
2183
+ "AUTH/VALIDATION_ERROR",
2184
+ 400
2185
+ ),
2186
+ OPERATION_NOT_ALLOWED: new AuthError(
2187
+ "This operation is not allowed",
2188
+ "AUTH/OPERATION_NOT_ALLOWED",
2189
+ 403
2190
+ ),
2191
+ NETWORK_ERROR: new AuthError(
2192
+ "Network error occurred. Please check your connection",
2193
+ "AUTH/NETWORK_ERROR",
2194
+ 503
2195
+ ),
2196
+ REQUIRES_RECENT_LOGIN: new AuthError(
2197
+ "This operation requires recent authentication. Please sign in again",
2198
+ "AUTH/REQUIRES_RECENT_LOGIN",
2199
+ 401
2200
+ ),
2201
+ INVALID_PROVIDER: new AuthError(
2202
+ "Invalid authentication provider",
2203
+ "AUTH/INVALID_PROVIDER",
2204
+ 400
2205
+ ),
2206
+ INVALID_CREDENTIAL: new AuthError(
2207
+ "The provided credentials are invalid or expired",
2208
+ "AUTH/INVALID_CREDENTIAL",
2209
+ 401
2210
+ ),
2211
+ // Resource not found
2212
+ NOT_FOUND: new AuthError(
2213
+ "The requested resource was not found",
2214
+ "AUTH/NOT_FOUND",
2215
+ 404
2216
+ ),
2217
+ // Detailed password validation errors
2218
+ PASSWORD_LENGTH_ERROR: new AuthError(
2219
+ "Password must be at least 8 characters long",
2220
+ "AUTH/PASSWORD_LENGTH_ERROR",
2221
+ 400
2222
+ ),
2223
+ PASSWORD_UPPERCASE_ERROR: new AuthError(
2224
+ "Password must contain at least one uppercase letter",
2225
+ "AUTH/PASSWORD_UPPERCASE_ERROR",
2226
+ 400
2227
+ ),
2228
+ PASSWORD_NUMBER_ERROR: new AuthError(
2229
+ "Password must contain at least one number",
2230
+ "AUTH/PASSWORD_NUMBER_ERROR",
2231
+ 400
2232
+ ),
2233
+ PASSWORD_SPECIAL_CHAR_ERROR: new AuthError(
2234
+ "Password must contain at least one special character",
2235
+ "AUTH/PASSWORD_SPECIAL_CHAR_ERROR",
2236
+ 400
2237
+ ),
2238
+ // Detailed email validation errors
2239
+ EMAIL_FORMAT_ERROR: new AuthError(
2240
+ "Invalid email format. Please enter a valid email address",
2241
+ "AUTH/EMAIL_FORMAT_ERROR",
2242
+ 400
2243
+ ),
2244
+ PASSWORD_VALIDATION_ERROR: new AuthError(
2245
+ "Password validation failed. Please check all requirements",
2246
+ "AUTH/PASSWORD_VALIDATION_ERROR",
2247
+ 400
2248
+ ),
2249
+ // Password reset specific errors
2250
+ EXPIRED_ACTION_CODE: new AuthError(
2251
+ "Kod za resetovanje lozinke je istekao. Molimo zatra\u017Eite novi link za resetovanje.",
2252
+ "AUTH/EXPIRED_ACTION_CODE",
2253
+ 400
2254
+ ),
2255
+ INVALID_ACTION_CODE: new AuthError(
2256
+ "Kod za resetovanje lozinke je neva\u017Ee\u0107i ili je ve\u0107 iskori\u0161\u0107en. Molimo zatra\u017Eite novi link za resetovanje.",
2257
+ "AUTH/INVALID_ACTION_CODE",
2258
+ 400
2259
+ ),
2260
+ WEAK_PASSWORD: new AuthError(
2261
+ "Lozinka je previ\u0161e slaba. Molimo koristite ja\u010Du lozinku.",
2262
+ "AUTH/WEAK_PASSWORD",
2263
+ 400
2264
+ )
2265
+ };
2266
+
2763
2267
  // src/services/user/user.service.ts
2764
2268
  import {
2765
2269
  collection as collection11,
@@ -2868,7 +2372,7 @@ var USER_ERRORS = {
2868
2372
  };
2869
2373
 
2870
2374
  // src/services/user/user.service.ts
2871
- import { z as z19 } from "zod";
2375
+ import { z as z17 } from "zod";
2872
2376
 
2873
2377
  // src/services/patient/patient.service.ts
2874
2378
  import {
@@ -2880,7 +2384,7 @@ import {
2880
2384
  } from "firebase/firestore";
2881
2385
 
2882
2386
  // src/services/media/media.service.ts
2883
- import { Timestamp as Timestamp4 } from "firebase/firestore";
2387
+ import { Timestamp as Timestamp3 } from "firebase/firestore";
2884
2388
  import {
2885
2389
  ref,
2886
2390
  uploadBytes,
@@ -2941,7 +2445,7 @@ var MediaService = class extends BaseService {
2941
2445
  url: downloadURL,
2942
2446
  contentType: file.type,
2943
2447
  size: file.size,
2944
- createdAt: Timestamp4.now(),
2448
+ createdAt: Timestamp3.now(),
2945
2449
  accessLevel,
2946
2450
  ownerId,
2947
2451
  collectionName,
@@ -3050,8 +2554,8 @@ var MediaService = class extends BaseService {
3050
2554
  );
3051
2555
  const metadataDocRef = doc2(this.db, MEDIA_METADATA_COLLECTION, mediaId);
3052
2556
  try {
3053
- await updateDoc2(metadataDocRef, { updatedAt: Timestamp4.now() });
3054
- return { ...metadata, updatedAt: Timestamp4.now() };
2557
+ await updateDoc2(metadataDocRef, { updatedAt: Timestamp3.now() });
2558
+ return { ...metadata, updatedAt: Timestamp3.now() };
3055
2559
  } catch (error) {
3056
2560
  console.error(
3057
2561
  `[MediaService] Error updating timestamp for media ID ${mediaId}:`,
@@ -3089,7 +2593,7 @@ var MediaService = class extends BaseService {
3089
2593
  accessLevel: newAccessLevel,
3090
2594
  path: newStoragePath,
3091
2595
  url: newDownloadURL,
3092
- updatedAt: Timestamp4.now()
2596
+ updatedAt: Timestamp3.now()
3093
2597
  };
3094
2598
  const metadataDocRef = doc2(this.db, MEDIA_METADATA_COLLECTION, mediaId);
3095
2599
  console.log(
@@ -3196,7 +2700,7 @@ var MediaService = class extends BaseService {
3196
2700
  };
3197
2701
 
3198
2702
  // src/services/patient/patient.service.ts
3199
- import { Timestamp as Timestamp13 } from "firebase/firestore";
2703
+ import { Timestamp as Timestamp12 } from "firebase/firestore";
3200
2704
 
3201
2705
  // src/services/patient/utils/clinic.utils.ts
3202
2706
  import {
@@ -3270,11 +2774,11 @@ import {
3270
2774
  } from "firebase/firestore";
3271
2775
 
3272
2776
  // src/validations/patient.schema.ts
3273
- import { z as z12 } from "zod";
3274
- import { Timestamp as Timestamp6 } from "firebase/firestore";
2777
+ import { z as z7 } from "zod";
2778
+ import { Timestamp as Timestamp5 } from "firebase/firestore";
3275
2779
 
3276
2780
  // src/validations/patient/medical-info.schema.ts
3277
- import { z as z11 } from "zod";
2781
+ import { z as z6 } from "zod";
3278
2782
 
3279
2783
  // src/backoffice/types/static/blocking-condition.types.ts
3280
2784
  var BlockingCondition = /* @__PURE__ */ ((BlockingCondition2) => {
@@ -3314,85 +2818,85 @@ var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
3314
2818
  })(Contraindication || {});
3315
2819
 
3316
2820
  // src/validations/common.schema.ts
3317
- import { z as z10 } from "zod";
3318
- import { Timestamp as Timestamp5 } from "firebase/firestore";
3319
- var timestampSchema = z10.union([
3320
- z10.object({
3321
- seconds: z10.number(),
3322
- nanoseconds: z10.number()
2821
+ import { z as z5 } from "zod";
2822
+ import { Timestamp as Timestamp4 } from "firebase/firestore";
2823
+ var timestampSchema = z5.union([
2824
+ z5.object({
2825
+ seconds: z5.number(),
2826
+ nanoseconds: z5.number()
3323
2827
  }),
3324
- z10.instanceof(Timestamp5),
3325
- z10.instanceof(Date)
2828
+ z5.instanceof(Timestamp4),
2829
+ z5.instanceof(Date)
3326
2830
  // Add support for Date objects that Firestore returns on client
3327
2831
  ]).transform((data) => {
3328
- if (data instanceof Timestamp5) {
2832
+ if (data instanceof Timestamp4) {
3329
2833
  return data;
3330
2834
  }
3331
2835
  if (data instanceof Date) {
3332
- return Timestamp5.fromDate(data);
2836
+ return Timestamp4.fromDate(data);
3333
2837
  }
3334
- return new Timestamp5(data.seconds, data.nanoseconds);
2838
+ return new Timestamp4(data.seconds, data.nanoseconds);
3335
2839
  });
3336
2840
 
3337
2841
  // src/validations/patient/medical-info.schema.ts
3338
- var allergySubtypeSchema = z11.union([
3339
- z11.nativeEnum(MedicationAllergySubtype),
3340
- z11.nativeEnum(FoodAllergySubtype),
3341
- z11.nativeEnum(EnvironmentalAllergySubtype),
3342
- z11.nativeEnum(CosmeticAllergySubtype),
3343
- z11.literal("other")
2842
+ var allergySubtypeSchema = z6.union([
2843
+ z6.nativeEnum(MedicationAllergySubtype),
2844
+ z6.nativeEnum(FoodAllergySubtype),
2845
+ z6.nativeEnum(EnvironmentalAllergySubtype),
2846
+ z6.nativeEnum(CosmeticAllergySubtype),
2847
+ z6.literal("other")
3344
2848
  ]);
3345
- var allergySchema = z11.object({
3346
- type: z11.nativeEnum(AllergyType),
2849
+ var allergySchema = z6.object({
2850
+ type: z6.nativeEnum(AllergyType),
3347
2851
  subtype: allergySubtypeSchema,
3348
- name: z11.string().optional().nullable(),
3349
- severity: z11.enum(["mild", "moderate", "severe"]).optional(),
3350
- reaction: z11.string().optional().nullable(),
2852
+ name: z6.string().optional().nullable(),
2853
+ severity: z6.enum(["mild", "moderate", "severe"]).optional(),
2854
+ reaction: z6.string().optional().nullable(),
3351
2855
  diagnosed: timestampSchema.optional().nullable(),
3352
- notes: z11.string().optional().nullable()
2856
+ notes: z6.string().optional().nullable()
3353
2857
  });
3354
- var vitalStatsSchema = z11.object({
3355
- height: z11.number().positive().optional(),
3356
- weight: z11.number().positive().optional(),
3357
- bloodType: z11.enum(["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"]).optional(),
3358
- bloodPressure: z11.object({
3359
- systolic: z11.number().min(70).max(200),
3360
- diastolic: z11.number().min(40).max(130),
2858
+ var vitalStatsSchema = z6.object({
2859
+ height: z6.number().positive().optional(),
2860
+ weight: z6.number().positive().optional(),
2861
+ bloodType: z6.enum(["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"]).optional(),
2862
+ bloodPressure: z6.object({
2863
+ systolic: z6.number().min(70).max(200),
2864
+ diastolic: z6.number().min(40).max(130),
3361
2865
  lastMeasured: timestampSchema
3362
2866
  }).optional()
3363
2867
  });
3364
- var blockingConditionSchema = z11.object({
3365
- condition: z11.nativeEnum(BlockingCondition),
2868
+ var blockingConditionSchema = z6.object({
2869
+ condition: z6.nativeEnum(BlockingCondition),
3366
2870
  diagnosedAt: timestampSchema,
3367
- notes: z11.string().optional().nullable(),
3368
- isActive: z11.boolean()
2871
+ notes: z6.string().optional().nullable(),
2872
+ isActive: z6.boolean()
3369
2873
  });
3370
- var contraindicationSchema = z11.object({
3371
- condition: z11.nativeEnum(Contraindication),
2874
+ var contraindicationSchema = z6.object({
2875
+ condition: z6.nativeEnum(Contraindication),
3372
2876
  lastOccurrence: timestampSchema,
3373
- frequency: z11.enum(["rare", "occasional", "frequent"]),
3374
- notes: z11.string().optional().nullable(),
3375
- isActive: z11.boolean()
2877
+ frequency: z6.enum(["rare", "occasional", "frequent"]),
2878
+ notes: z6.string().optional().nullable(),
2879
+ isActive: z6.boolean()
3376
2880
  });
3377
- var medicationSchema = z11.object({
3378
- name: z11.string().min(1),
3379
- dosage: z11.string().min(1),
3380
- frequency: z11.string().min(1),
2881
+ var medicationSchema = z6.object({
2882
+ name: z6.string().min(1),
2883
+ dosage: z6.string().min(1),
2884
+ frequency: z6.string().min(1),
3381
2885
  startDate: timestampSchema.optional().nullable(),
3382
2886
  endDate: timestampSchema.optional().nullable(),
3383
- prescribedBy: z11.string().optional().nullable()
2887
+ prescribedBy: z6.string().optional().nullable()
3384
2888
  });
3385
- var patientMedicalInfoSchema = z11.object({
3386
- patientId: z11.string(),
2889
+ var patientMedicalInfoSchema = z6.object({
2890
+ patientId: z6.string(),
3387
2891
  vitalStats: vitalStatsSchema,
3388
- blockingConditions: z11.array(blockingConditionSchema),
3389
- contraindications: z11.array(contraindicationSchema),
3390
- allergies: z11.array(allergySchema),
3391
- currentMedications: z11.array(medicationSchema),
3392
- emergencyNotes: z11.string().optional(),
2892
+ blockingConditions: z6.array(blockingConditionSchema),
2893
+ contraindications: z6.array(contraindicationSchema),
2894
+ allergies: z6.array(allergySchema),
2895
+ currentMedications: z6.array(medicationSchema),
2896
+ emergencyNotes: z6.string().optional(),
3393
2897
  lastUpdated: timestampSchema,
3394
- updatedBy: z11.string(),
3395
- verifiedBy: z11.string().optional(),
2898
+ updatedBy: z6.string(),
2899
+ verifiedBy: z6.string().optional(),
3396
2900
  verifiedAt: timestampSchema.optional()
3397
2901
  });
3398
2902
  var createPatientMedicalInfoSchema = patientMedicalInfoSchema.omit({
@@ -3406,155 +2910,155 @@ var updatePatientMedicalInfoSchema = createPatientMedicalInfoSchema.partial();
3406
2910
  var updateVitalStatsSchema = vitalStatsSchema;
3407
2911
  var addAllergySchema = allergySchema;
3408
2912
  var updateAllergySchema = allergySchema.partial().extend({
3409
- allergyIndex: z11.number().min(0)
2913
+ allergyIndex: z6.number().min(0)
3410
2914
  });
3411
2915
  var addBlockingConditionSchema = blockingConditionSchema;
3412
2916
  var updateBlockingConditionSchema = blockingConditionSchema.partial().extend({
3413
- conditionIndex: z11.number().min(0)
2917
+ conditionIndex: z6.number().min(0)
3414
2918
  });
3415
2919
  var addContraindicationSchema = contraindicationSchema;
3416
2920
  var updateContraindicationSchema = contraindicationSchema.partial().extend({
3417
- contraindicationIndex: z11.number().min(0)
2921
+ contraindicationIndex: z6.number().min(0)
3418
2922
  });
3419
2923
  var addMedicationSchema = medicationSchema;
3420
2924
  var updateMedicationSchema = medicationSchema.partial().extend({
3421
- medicationIndex: z11.number().min(0)
2925
+ medicationIndex: z6.number().min(0)
3422
2926
  });
3423
2927
 
3424
2928
  // src/validations/patient.schema.ts
3425
- var locationDataSchema = z12.object({
3426
- latitude: z12.number().min(-90).max(90),
3427
- longitude: z12.number().min(-180).max(180),
3428
- geohash: z12.string().optional()
2929
+ var locationDataSchema = z7.object({
2930
+ latitude: z7.number().min(-90).max(90),
2931
+ longitude: z7.number().min(-180).max(180),
2932
+ geohash: z7.string().optional()
3429
2933
  });
3430
- var addressDataSchema = z12.object({
3431
- address: z12.string(),
3432
- city: z12.string(),
3433
- country: z12.string(),
3434
- postalCode: z12.string()
2934
+ var addressDataSchema = z7.object({
2935
+ address: z7.string(),
2936
+ city: z7.string(),
2937
+ country: z7.string(),
2938
+ postalCode: z7.string()
3435
2939
  });
3436
- var emergencyContactSchema = z12.object({
3437
- name: z12.string(),
3438
- relationship: z12.string(),
3439
- phoneNumber: z12.string(),
3440
- isNotifiable: z12.boolean()
2940
+ var emergencyContactSchema = z7.object({
2941
+ name: z7.string(),
2942
+ relationship: z7.string(),
2943
+ phoneNumber: z7.string(),
2944
+ isNotifiable: z7.boolean()
3441
2945
  });
3442
- var gamificationSchema = z12.object({
3443
- level: z12.number(),
3444
- points: z12.number()
2946
+ var gamificationSchema = z7.object({
2947
+ level: z7.number(),
2948
+ points: z7.number()
3445
2949
  });
3446
- var patientLocationInfoSchema = z12.object({
3447
- patientId: z12.string(),
3448
- userRef: z12.string().optional(),
2950
+ var patientLocationInfoSchema = z7.object({
2951
+ patientId: z7.string(),
2952
+ userRef: z7.string().optional(),
3449
2953
  locationData: locationDataSchema,
3450
- createdAt: z12.instanceof(Timestamp6),
3451
- updatedAt: z12.instanceof(Timestamp6)
2954
+ createdAt: z7.instanceof(Timestamp5),
2955
+ updatedAt: z7.instanceof(Timestamp5)
3452
2956
  });
3453
- var createPatientLocationInfoSchema = z12.object({
3454
- patientId: z12.string(),
3455
- userRef: z12.string().optional(),
2957
+ var createPatientLocationInfoSchema = z7.object({
2958
+ patientId: z7.string(),
2959
+ userRef: z7.string().optional(),
3456
2960
  locationData: locationDataSchema
3457
2961
  });
3458
- var patientSensitiveInfoSchema = z12.object({
3459
- patientId: z12.string(),
3460
- userRef: z12.string().optional(),
3461
- photoUrl: z12.string().nullable().optional(),
3462
- firstName: z12.string().min(2),
3463
- lastName: z12.string().min(2),
3464
- dateOfBirth: z12.instanceof(Timestamp6).nullable(),
3465
- gender: z12.nativeEnum(Gender),
3466
- email: z12.string().email().optional(),
3467
- phoneNumber: z12.string().optional(),
3468
- alternativePhoneNumber: z12.string().optional(),
2962
+ var patientSensitiveInfoSchema = z7.object({
2963
+ patientId: z7.string(),
2964
+ userRef: z7.string().optional(),
2965
+ photoUrl: z7.string().nullable().optional(),
2966
+ firstName: z7.string().min(2),
2967
+ lastName: z7.string().min(2),
2968
+ dateOfBirth: z7.instanceof(Timestamp5).nullable(),
2969
+ gender: z7.nativeEnum(Gender),
2970
+ email: z7.string().email().optional(),
2971
+ phoneNumber: z7.string().optional(),
2972
+ alternativePhoneNumber: z7.string().optional(),
3469
2973
  addressData: addressDataSchema.optional(),
3470
- emergencyContacts: z12.array(emergencyContactSchema).optional(),
3471
- createdAt: z12.instanceof(Timestamp6),
3472
- updatedAt: z12.instanceof(Timestamp6)
2974
+ emergencyContacts: z7.array(emergencyContactSchema).optional(),
2975
+ createdAt: z7.instanceof(Timestamp5),
2976
+ updatedAt: z7.instanceof(Timestamp5)
3473
2977
  });
3474
- var patientDoctorSchema = z12.object({
3475
- userRef: z12.string(),
3476
- assignedAt: z12.instanceof(Timestamp6),
3477
- assignedBy: z12.string().optional(),
3478
- isActive: z12.boolean(),
3479
- notes: z12.string().optional()
2978
+ var patientDoctorSchema = z7.object({
2979
+ userRef: z7.string(),
2980
+ assignedAt: z7.instanceof(Timestamp5),
2981
+ assignedBy: z7.string().optional(),
2982
+ isActive: z7.boolean(),
2983
+ notes: z7.string().optional()
3480
2984
  });
3481
- var patientClinicSchema = z12.object({
3482
- clinicId: z12.string(),
3483
- assignedAt: z12.instanceof(Timestamp6),
3484
- assignedBy: z12.string().optional(),
3485
- isActive: z12.boolean(),
3486
- notes: z12.string().optional()
2985
+ var patientClinicSchema = z7.object({
2986
+ clinicId: z7.string(),
2987
+ assignedAt: z7.instanceof(Timestamp5),
2988
+ assignedBy: z7.string().optional(),
2989
+ isActive: z7.boolean(),
2990
+ notes: z7.string().optional()
3487
2991
  });
3488
- var patientProfileSchema = z12.object({
3489
- id: z12.string(),
3490
- userRef: z12.string().optional(),
3491
- displayName: z12.string(),
2992
+ var patientProfileSchema = z7.object({
2993
+ id: z7.string(),
2994
+ userRef: z7.string().optional(),
2995
+ displayName: z7.string(),
3492
2996
  gamification: gamificationSchema,
3493
- expoTokens: z12.array(z12.string()),
3494
- isActive: z12.boolean(),
3495
- isVerified: z12.boolean(),
3496
- isManual: z12.boolean().default(false),
2997
+ expoTokens: z7.array(z7.string()),
2998
+ isActive: z7.boolean(),
2999
+ isVerified: z7.boolean(),
3000
+ isManual: z7.boolean().default(false),
3497
3001
  // Default to false if missing
3498
- phoneNumber: z12.string().nullable().optional(),
3499
- dateOfBirth: z12.instanceof(Timestamp6).nullable().optional(),
3500
- doctors: z12.array(patientDoctorSchema),
3501
- clinics: z12.array(patientClinicSchema),
3502
- doctorIds: z12.array(z12.string()),
3503
- clinicIds: z12.array(z12.string()),
3504
- createdAt: z12.instanceof(Timestamp6),
3505
- updatedAt: z12.instanceof(Timestamp6)
3002
+ phoneNumber: z7.string().nullable().optional(),
3003
+ dateOfBirth: z7.instanceof(Timestamp5).nullable().optional(),
3004
+ doctors: z7.array(patientDoctorSchema),
3005
+ clinics: z7.array(patientClinicSchema),
3006
+ doctorIds: z7.array(z7.string()),
3007
+ clinicIds: z7.array(z7.string()),
3008
+ createdAt: z7.instanceof(Timestamp5),
3009
+ updatedAt: z7.instanceof(Timestamp5)
3506
3010
  });
3507
- var createPatientProfileSchema = z12.object({
3508
- userRef: z12.string().optional(),
3509
- displayName: z12.string(),
3510
- expoTokens: z12.array(z12.string()),
3011
+ var createPatientProfileSchema = z7.object({
3012
+ userRef: z7.string().optional(),
3013
+ displayName: z7.string(),
3014
+ expoTokens: z7.array(z7.string()),
3511
3015
  gamification: gamificationSchema.optional(),
3512
- isActive: z12.boolean(),
3513
- isVerified: z12.boolean(),
3514
- isManual: z12.boolean().default(false),
3515
- doctors: z12.array(patientDoctorSchema).optional(),
3516
- clinics: z12.array(patientClinicSchema).optional(),
3517
- doctorIds: z12.array(z12.string()).optional(),
3518
- clinicIds: z12.array(z12.string()).optional()
3016
+ isActive: z7.boolean(),
3017
+ isVerified: z7.boolean(),
3018
+ isManual: z7.boolean().default(false),
3019
+ doctors: z7.array(patientDoctorSchema).optional(),
3020
+ clinics: z7.array(patientClinicSchema).optional(),
3021
+ doctorIds: z7.array(z7.string()).optional(),
3022
+ clinicIds: z7.array(z7.string()).optional()
3519
3023
  });
3520
- var createPatientSensitiveInfoSchema = z12.object({
3521
- patientId: z12.string(),
3522
- userRef: z12.string().optional(),
3024
+ var createPatientSensitiveInfoSchema = z7.object({
3025
+ patientId: z7.string(),
3026
+ userRef: z7.string().optional(),
3523
3027
  photoUrl: mediaResourceSchema.nullable().optional(),
3524
- firstName: z12.string().min(2),
3525
- lastName: z12.string().min(2),
3526
- dateOfBirth: z12.instanceof(Timestamp6).nullable(),
3527
- gender: z12.nativeEnum(Gender),
3528
- email: z12.string().email().optional(),
3529
- phoneNumber: z12.string().optional(),
3530
- alternativePhoneNumber: z12.string().optional(),
3028
+ firstName: z7.string().min(2),
3029
+ lastName: z7.string().min(2),
3030
+ dateOfBirth: z7.instanceof(Timestamp5).nullable(),
3031
+ gender: z7.nativeEnum(Gender),
3032
+ email: z7.string().email().optional(),
3033
+ phoneNumber: z7.string().optional(),
3034
+ alternativePhoneNumber: z7.string().optional(),
3531
3035
  addressData: addressDataSchema.optional(),
3532
- emergencyContacts: z12.array(emergencyContactSchema).optional()
3036
+ emergencyContacts: z7.array(emergencyContactSchema).optional()
3533
3037
  });
3534
- var createManualPatientSchema = z12.object({
3535
- clinicId: z12.string().min(1, "Clinic ID is required"),
3536
- firstName: z12.string().min(2, "First name is required"),
3537
- lastName: z12.string().min(2, "Last name is required"),
3538
- dateOfBirth: z12.instanceof(Timestamp6).nullable(),
3539
- gender: z12.nativeEnum(Gender),
3540
- phoneNumber: z12.string().optional(),
3541
- email: z12.string().email().optional(),
3038
+ var createManualPatientSchema = z7.object({
3039
+ clinicId: z7.string().min(1, "Clinic ID is required"),
3040
+ firstName: z7.string().min(2, "First name is required"),
3041
+ lastName: z7.string().min(2, "Last name is required"),
3042
+ dateOfBirth: z7.instanceof(Timestamp5).nullable(),
3043
+ gender: z7.nativeEnum(Gender),
3044
+ phoneNumber: z7.string().optional(),
3045
+ email: z7.string().email().optional(),
3542
3046
  addressData: addressDataSchema.optional(),
3543
- notes: z12.string().optional()
3047
+ notes: z7.string().optional()
3544
3048
  });
3545
- var searchPatientsSchema = z12.object({
3546
- clinicId: z12.string().optional(),
3547
- practitionerId: z12.string().optional()
3049
+ var searchPatientsSchema = z7.object({
3050
+ clinicId: z7.string().optional(),
3051
+ practitionerId: z7.string().optional()
3548
3052
  }).refine((data) => data.clinicId || data.practitionerId, {
3549
3053
  message: "At least one of clinicId or practitionerId must be provided",
3550
3054
  path: []
3551
3055
  // Optional: specify a path like ['clinicId'] or ['practitionerId']
3552
3056
  });
3553
- var requesterInfoSchema = z12.object({
3554
- id: z12.string(),
3555
- role: z12.enum(["clinic_admin", "practitioner"]),
3556
- associatedClinicId: z12.string().optional(),
3557
- associatedPractitionerId: z12.string().optional()
3057
+ var requesterInfoSchema = z7.object({
3058
+ id: z7.string(),
3059
+ role: z7.enum(["clinic_admin", "practitioner"]),
3060
+ associatedClinicId: z7.string().optional(),
3061
+ associatedPractitionerId: z7.string().optional()
3558
3062
  }).refine(
3559
3063
  (data) => {
3560
3064
  if (data.role === "clinic_admin") {
@@ -3571,7 +3075,7 @@ var requesterInfoSchema = z12.object({
3571
3075
  );
3572
3076
 
3573
3077
  // src/services/patient/utils/sensitive.utils.ts
3574
- import { z as z14 } from "zod";
3078
+ import { z as z11 } from "zod";
3575
3079
 
3576
3080
  // src/services/patient/utils/practitioner.utils.ts
3577
3081
  import {
@@ -3703,52 +3207,249 @@ var getPractitionerProfileByUserRef = async (db, userRef) => {
3703
3207
  `Failed to retrieve practitioner by userRef: ${error instanceof Error ? error.message : String(error)}`
3704
3208
  );
3705
3209
  }
3706
- };
3210
+ };
3211
+
3212
+ // src/services/clinic/utils/admin.utils.ts
3213
+ import {
3214
+ collection as collection6,
3215
+ doc as doc5,
3216
+ getDoc as getDoc5,
3217
+ getDocs as getDocs6,
3218
+ query as query6,
3219
+ where as where6,
3220
+ updateDoc as updateDoc3,
3221
+ setDoc as setDoc3,
3222
+ deleteDoc as deleteDoc2,
3223
+ Timestamp as Timestamp7,
3224
+ serverTimestamp as serverTimestamp3
3225
+ } from "firebase/firestore";
3226
+
3227
+ // src/validations/clinic.schema.ts
3228
+ import { z as z10 } from "zod";
3229
+ import { Timestamp as Timestamp6 } from "firebase/firestore";
3230
+
3231
+ // src/validations/reviews.schema.ts
3232
+ import { z as z8 } from "zod";
3233
+ var baseReviewSchema = z8.object({
3234
+ id: z8.string().min(1),
3235
+ patientId: z8.string().min(1),
3236
+ fullReviewId: z8.string().min(1),
3237
+ createdAt: z8.date(),
3238
+ updatedAt: z8.date(),
3239
+ comment: z8.string().min(1).max(2e3),
3240
+ isVerified: z8.boolean(),
3241
+ isPublished: z8.boolean()
3242
+ });
3243
+ var baseReviewCreateSchema = z8.object({
3244
+ patientId: z8.string().min(1),
3245
+ comment: z8.string().min(1).max(2e3),
3246
+ isVerified: z8.boolean().default(false),
3247
+ isPublished: z8.boolean().default(true)
3248
+ });
3249
+ var clinicReviewSchema = baseReviewSchema.extend({
3250
+ clinicId: z8.string().min(1),
3251
+ cleanliness: z8.number().min(1).max(5),
3252
+ facilities: z8.number().min(1).max(5),
3253
+ staffFriendliness: z8.number().min(1).max(5),
3254
+ waitingTime: z8.number().min(1).max(5),
3255
+ accessibility: z8.number().min(1).max(5),
3256
+ overallRating: z8.number().min(1).max(5),
3257
+ wouldRecommend: z8.boolean()
3258
+ });
3259
+ var createClinicReviewSchema = baseReviewCreateSchema.extend({
3260
+ clinicId: z8.string().min(1),
3261
+ cleanliness: z8.number().min(1).max(5),
3262
+ facilities: z8.number().min(1).max(5),
3263
+ staffFriendliness: z8.number().min(1).max(5),
3264
+ waitingTime: z8.number().min(1).max(5),
3265
+ accessibility: z8.number().min(1).max(5),
3266
+ wouldRecommend: z8.boolean()
3267
+ });
3268
+ var practitionerReviewSchema = baseReviewSchema.extend({
3269
+ practitionerId: z8.string().min(1),
3270
+ knowledgeAndExpertise: z8.number().min(1).max(5),
3271
+ communicationSkills: z8.number().min(1).max(5),
3272
+ bedSideManner: z8.number().min(1).max(5),
3273
+ thoroughness: z8.number().min(1).max(5),
3274
+ trustworthiness: z8.number().min(1).max(5),
3275
+ overallRating: z8.number().min(1).max(5),
3276
+ wouldRecommend: z8.boolean()
3277
+ });
3278
+ var createPractitionerReviewSchema = baseReviewCreateSchema.extend({
3279
+ practitionerId: z8.string().min(1),
3280
+ knowledgeAndExpertise: z8.number().min(1).max(5),
3281
+ communicationSkills: z8.number().min(1).max(5),
3282
+ bedSideManner: z8.number().min(1).max(5),
3283
+ thoroughness: z8.number().min(1).max(5),
3284
+ trustworthiness: z8.number().min(1).max(5),
3285
+ wouldRecommend: z8.boolean()
3286
+ });
3287
+ var procedureReviewSchema = baseReviewSchema.extend({
3288
+ procedureId: z8.string().min(1),
3289
+ effectivenessOfTreatment: z8.number().min(1).max(5),
3290
+ outcomeExplanation: z8.number().min(1).max(5),
3291
+ painManagement: z8.number().min(1).max(5),
3292
+ followUpCare: z8.number().min(1).max(5),
3293
+ valueForMoney: z8.number().min(1).max(5),
3294
+ overallRating: z8.number().min(1).max(5),
3295
+ wouldRecommend: z8.boolean()
3296
+ });
3297
+ var createProcedureReviewSchema = baseReviewCreateSchema.extend({
3298
+ procedureId: z8.string().min(1),
3299
+ effectivenessOfTreatment: z8.number().min(1).max(5),
3300
+ outcomeExplanation: z8.number().min(1).max(5),
3301
+ painManagement: z8.number().min(1).max(5),
3302
+ followUpCare: z8.number().min(1).max(5),
3303
+ valueForMoney: z8.number().min(1).max(5),
3304
+ wouldRecommend: z8.boolean()
3305
+ });
3306
+ var clinicReviewInfoSchema = z8.object({
3307
+ totalReviews: z8.number().min(0),
3308
+ averageRating: z8.number().min(0).max(5),
3309
+ cleanliness: z8.number().min(0).max(5),
3310
+ facilities: z8.number().min(0).max(5),
3311
+ staffFriendliness: z8.number().min(0).max(5),
3312
+ waitingTime: z8.number().min(0).max(5),
3313
+ accessibility: z8.number().min(0).max(5),
3314
+ recommendationPercentage: z8.number().min(0).max(100)
3315
+ });
3316
+ var practitionerReviewInfoSchema = z8.object({
3317
+ totalReviews: z8.number().min(0),
3318
+ averageRating: z8.number().min(0).max(5),
3319
+ knowledgeAndExpertise: z8.number().min(0).max(5),
3320
+ communicationSkills: z8.number().min(0).max(5),
3321
+ bedSideManner: z8.number().min(0).max(5),
3322
+ thoroughness: z8.number().min(0).max(5),
3323
+ trustworthiness: z8.number().min(0).max(5),
3324
+ recommendationPercentage: z8.number().min(0).max(100)
3325
+ });
3326
+ var procedureReviewInfoSchema = z8.object({
3327
+ totalReviews: z8.number().min(0),
3328
+ averageRating: z8.number().min(0).max(5),
3329
+ effectivenessOfTreatment: z8.number().min(0).max(5),
3330
+ outcomeExplanation: z8.number().min(0).max(5),
3331
+ painManagement: z8.number().min(0).max(5),
3332
+ followUpCare: z8.number().min(0).max(5),
3333
+ valueForMoney: z8.number().min(0).max(5),
3334
+ recommendationPercentage: z8.number().min(0).max(100)
3335
+ });
3336
+ var reviewSchema = z8.object({
3337
+ id: z8.string().min(1),
3338
+ appointmentId: z8.string().min(1),
3339
+ patientId: z8.string().min(1),
3340
+ createdAt: z8.date(),
3341
+ updatedAt: z8.date(),
3342
+ clinicReview: clinicReviewSchema.optional(),
3343
+ practitionerReview: practitionerReviewSchema.optional(),
3344
+ procedureReview: procedureReviewSchema.optional(),
3345
+ overallComment: z8.string().min(1).max(2e3),
3346
+ overallRating: z8.number().min(1).max(5)
3347
+ });
3348
+ var createReviewSchema = z8.object({
3349
+ patientId: z8.string().min(1),
3350
+ clinicReview: createClinicReviewSchema.optional(),
3351
+ practitionerReview: createPractitionerReviewSchema.optional(),
3352
+ procedureReview: createProcedureReviewSchema.optional(),
3353
+ overallComment: z8.string().min(1).max(2e3)
3354
+ }).refine(
3355
+ (data) => {
3356
+ return data.clinicReview || data.practitionerReview || data.procedureReview;
3357
+ },
3358
+ {
3359
+ message: "At least one review type (clinic, practitioner, or procedure) must be provided",
3360
+ path: ["reviewType"]
3361
+ }
3362
+ );
3707
3363
 
3708
- // src/services/clinic/utils/admin.utils.ts
3709
- import {
3710
- collection as collection6,
3711
- doc as doc5,
3712
- getDoc as getDoc5,
3713
- getDocs as getDocs6,
3714
- query as query6,
3715
- where as where6,
3716
- updateDoc as updateDoc3,
3717
- setDoc as setDoc3,
3718
- deleteDoc as deleteDoc2,
3719
- Timestamp as Timestamp8,
3720
- serverTimestamp as serverTimestamp3
3721
- } from "firebase/firestore";
3364
+ // src/validations/shared.schema.ts
3365
+ import { z as z9 } from "zod";
3366
+
3367
+ // src/backoffice/types/static/procedure-family.types.ts
3368
+ var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
3369
+ ProcedureFamily2["AESTHETICS"] = "aesthetics";
3370
+ ProcedureFamily2["SURGERY"] = "surgery";
3371
+ return ProcedureFamily2;
3372
+ })(ProcedureFamily || {});
3373
+
3374
+ // src/validations/shared.schema.ts
3375
+ var sharedClinicContactInfoSchema = z9.object({
3376
+ email: z9.string().email(),
3377
+ phoneNumber: z9.string(),
3378
+ alternativePhoneNumber: z9.string().nullable().optional(),
3379
+ website: z9.string().nullable().optional()
3380
+ });
3381
+ var sharedClinicLocationSchema = z9.object({
3382
+ address: z9.string(),
3383
+ city: z9.string(),
3384
+ country: z9.string(),
3385
+ postalCode: z9.string(),
3386
+ latitude: z9.number().min(-90).max(90),
3387
+ longitude: z9.number().min(-180).max(180),
3388
+ geohash: z9.string().nullable().optional()
3389
+ });
3390
+ var procedureSummaryInfoSchema = z9.object({
3391
+ id: z9.string().min(1),
3392
+ name: z9.string().min(1),
3393
+ description: z9.string().optional(),
3394
+ photo: z9.string().optional(),
3395
+ family: z9.nativeEnum(ProcedureFamily),
3396
+ categoryName: z9.string(),
3397
+ subcategoryName: z9.string(),
3398
+ technologyName: z9.string(),
3399
+ price: z9.number().nonnegative(),
3400
+ pricingMeasure: z9.nativeEnum(PricingMeasure),
3401
+ currency: z9.nativeEnum(Currency),
3402
+ duration: z9.number().int().positive(),
3403
+ clinicId: z9.string().min(1),
3404
+ clinicName: z9.string().min(1),
3405
+ practitionerId: z9.string().min(1),
3406
+ practitionerName: z9.string().min(1)
3407
+ });
3408
+ var clinicInfoSchema = z9.object({
3409
+ id: z9.string(),
3410
+ featuredPhoto: z9.string(),
3411
+ name: z9.string(),
3412
+ description: z9.string().nullable().optional(),
3413
+ location: sharedClinicLocationSchema,
3414
+ contactInfo: sharedClinicContactInfoSchema
3415
+ });
3416
+ var doctorInfoSchema = z9.object({
3417
+ id: z9.string(),
3418
+ name: z9.string(),
3419
+ description: z9.string().nullable().optional(),
3420
+ photo: z9.string(),
3421
+ rating: z9.number().min(0).max(5),
3422
+ services: z9.array(z9.string())
3423
+ // List of procedure IDs practitioner offers
3424
+ });
3722
3425
 
3723
3426
  // src/validations/clinic.schema.ts
3724
- import { z as z13 } from "zod";
3725
- import { Timestamp as Timestamp7 } from "firebase/firestore";
3726
- var clinicContactInfoSchema = z13.object({
3727
- email: z13.string().email(),
3728
- phoneNumber: z13.string(),
3729
- alternativePhoneNumber: z13.string().nullable().optional(),
3730
- website: z13.string().nullable().optional()
3427
+ var clinicContactInfoSchema = z10.object({
3428
+ email: z10.string().email(),
3429
+ phoneNumber: z10.string(),
3430
+ alternativePhoneNumber: z10.string().nullable().optional(),
3431
+ website: z10.string().nullable().optional()
3731
3432
  });
3732
- var clinicLocationSchema = z13.object({
3733
- address: z13.string(),
3734
- city: z13.string(),
3735
- country: z13.string(),
3736
- postalCode: z13.string(),
3737
- latitude: z13.number().min(-90).max(90),
3738
- longitude: z13.number().min(-180).max(180),
3739
- geohash: z13.string().nullable().optional()
3433
+ var clinicLocationSchema = z10.object({
3434
+ address: z10.string(),
3435
+ city: z10.string(),
3436
+ country: z10.string(),
3437
+ postalCode: z10.string(),
3438
+ latitude: z10.number().min(-90).max(90),
3439
+ longitude: z10.number().min(-180).max(180),
3440
+ geohash: z10.string().nullable().optional()
3740
3441
  });
3741
- var workingHoursTimeSchema = z13.object({
3742
- open: z13.string(),
3743
- close: z13.string(),
3744
- breaks: z13.array(
3745
- z13.object({
3746
- start: z13.string(),
3747
- end: z13.string()
3442
+ var workingHoursTimeSchema = z10.object({
3443
+ open: z10.string(),
3444
+ close: z10.string(),
3445
+ breaks: z10.array(
3446
+ z10.object({
3447
+ start: z10.string(),
3448
+ end: z10.string()
3748
3449
  })
3749
3450
  ).optional()
3750
3451
  });
3751
- var workingHoursSchema = z13.object({
3452
+ var workingHoursSchema = z10.object({
3752
3453
  monday: workingHoursTimeSchema.nullable(),
3753
3454
  tuesday: workingHoursTimeSchema.nullable(),
3754
3455
  wednesday: workingHoursTimeSchema.nullable(),
@@ -3757,255 +3458,255 @@ var workingHoursSchema = z13.object({
3757
3458
  saturday: workingHoursTimeSchema.nullable(),
3758
3459
  sunday: workingHoursTimeSchema.nullable()
3759
3460
  });
3760
- var clinicTagsSchema = z13.object({
3761
- tags: z13.array(z13.nativeEnum(ClinicTag))
3461
+ var clinicTagsSchema = z10.object({
3462
+ tags: z10.array(z10.nativeEnum(ClinicTag))
3762
3463
  });
3763
- var contactPersonSchema = z13.object({
3764
- firstName: z13.string(),
3765
- lastName: z13.string(),
3766
- title: z13.string().nullable().optional(),
3767
- email: z13.string().email(),
3768
- phoneNumber: z13.string().nullable().optional()
3464
+ var contactPersonSchema = z10.object({
3465
+ firstName: z10.string(),
3466
+ lastName: z10.string(),
3467
+ title: z10.string().nullable().optional(),
3468
+ email: z10.string().email(),
3469
+ phoneNumber: z10.string().nullable().optional()
3769
3470
  });
3770
- var adminInfoSchema = z13.object({
3771
- id: z13.string(),
3772
- name: z13.string(),
3773
- email: z13.string().email()
3471
+ var adminInfoSchema = z10.object({
3472
+ id: z10.string(),
3473
+ name: z10.string(),
3474
+ email: z10.string().email()
3774
3475
  });
3775
- var clinicAdminSchema = z13.object({
3776
- id: z13.string(),
3777
- userRef: z13.string(),
3778
- clinicGroupId: z13.string(),
3779
- isGroupOwner: z13.boolean(),
3780
- clinicsManaged: z13.array(z13.string()),
3781
- clinicsManagedInfo: z13.array(clinicInfoSchema),
3476
+ var clinicAdminSchema = z10.object({
3477
+ id: z10.string(),
3478
+ userRef: z10.string(),
3479
+ clinicGroupId: z10.string(),
3480
+ isGroupOwner: z10.boolean(),
3481
+ clinicsManaged: z10.array(z10.string()),
3482
+ clinicsManagedInfo: z10.array(clinicInfoSchema),
3782
3483
  contactInfo: contactPersonSchema,
3783
- roleTitle: z13.string(),
3784
- createdAt: z13.instanceof(Date).or(z13.instanceof(Timestamp7)),
3785
- updatedAt: z13.instanceof(Date).or(z13.instanceof(Timestamp7)),
3786
- isActive: z13.boolean()
3484
+ roleTitle: z10.string(),
3485
+ createdAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6)),
3486
+ updatedAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6)),
3487
+ isActive: z10.boolean()
3787
3488
  });
3788
- var adminTokenSchema = z13.object({
3789
- id: z13.string(),
3790
- token: z13.string(),
3791
- email: z13.string().email().optional().nullable(),
3792
- status: z13.nativeEnum(AdminTokenStatus),
3793
- usedByUserRef: z13.string().optional(),
3794
- createdAt: z13.instanceof(Date).or(z13.instanceof(Timestamp7)),
3489
+ var adminTokenSchema = z10.object({
3490
+ id: z10.string(),
3491
+ token: z10.string(),
3492
+ email: z10.string().email().optional().nullable(),
3493
+ status: z10.nativeEnum(AdminTokenStatus),
3494
+ usedByUserRef: z10.string().optional(),
3495
+ createdAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6)),
3795
3496
  // Timestamp
3796
- expiresAt: z13.instanceof(Date).or(z13.instanceof(Timestamp7))
3497
+ expiresAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6))
3797
3498
  // Timestamp
3798
3499
  });
3799
- var createAdminTokenSchema = z13.object({
3800
- expiresInDays: z13.number().min(1).max(30).optional(),
3801
- email: z13.string().email().optional().nullable()
3500
+ var createAdminTokenSchema = z10.object({
3501
+ expiresInDays: z10.number().min(1).max(30).optional(),
3502
+ email: z10.string().email().optional().nullable()
3802
3503
  });
3803
- var clinicGroupSchema = z13.object({
3804
- id: z13.string(),
3805
- name: z13.string(),
3806
- description: z13.string().nullable().optional(),
3504
+ var clinicGroupSchema = z10.object({
3505
+ id: z10.string(),
3506
+ name: z10.string(),
3507
+ description: z10.string().nullable().optional(),
3807
3508
  hqLocation: clinicLocationSchema,
3808
3509
  contactInfo: clinicContactInfoSchema,
3809
3510
  contactPerson: contactPersonSchema,
3810
- clinics: z13.array(z13.string()),
3811
- clinicsInfo: z13.array(clinicInfoSchema),
3812
- admins: z13.array(z13.string()),
3813
- adminsInfo: z13.array(adminInfoSchema),
3814
- adminTokens: z13.array(adminTokenSchema),
3815
- ownerId: z13.string().nullable(),
3816
- createdAt: z13.instanceof(Date).or(z13.instanceof(Timestamp7)),
3511
+ clinics: z10.array(z10.string()),
3512
+ clinicsInfo: z10.array(clinicInfoSchema),
3513
+ admins: z10.array(z10.string()),
3514
+ adminsInfo: z10.array(adminInfoSchema),
3515
+ adminTokens: z10.array(adminTokenSchema),
3516
+ ownerId: z10.string().nullable(),
3517
+ createdAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6)),
3817
3518
  // Timestamp
3818
- updatedAt: z13.instanceof(Date).or(z13.instanceof(Timestamp7)),
3519
+ updatedAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6)),
3819
3520
  // Timestamp
3820
- isActive: z13.boolean(),
3521
+ isActive: z10.boolean(),
3821
3522
  logo: mediaResourceSchema.optional().nullable(),
3822
- practiceType: z13.nativeEnum(PracticeType).optional(),
3823
- languages: z13.array(z13.nativeEnum(Language)).optional(),
3824
- subscriptionModel: z13.nativeEnum(SubscriptionModel),
3825
- calendarSyncEnabled: z13.boolean().optional(),
3826
- autoConfirmAppointments: z13.boolean().optional(),
3827
- businessIdentificationNumber: z13.string().optional().nullable(),
3828
- onboarding: z13.object({
3829
- completed: z13.boolean().optional().default(false),
3830
- step: z13.number().optional().default(1)
3523
+ practiceType: z10.nativeEnum(PracticeType).optional(),
3524
+ languages: z10.array(z10.nativeEnum(Language)).optional(),
3525
+ subscriptionModel: z10.nativeEnum(SubscriptionModel),
3526
+ calendarSyncEnabled: z10.boolean().optional(),
3527
+ autoConfirmAppointments: z10.boolean().optional(),
3528
+ businessIdentificationNumber: z10.string().optional().nullable(),
3529
+ onboarding: z10.object({
3530
+ completed: z10.boolean().optional().default(false),
3531
+ step: z10.number().optional().default(1)
3831
3532
  }).optional()
3832
3533
  });
3833
- var clinicSchema = z13.object({
3834
- id: z13.string(),
3835
- clinicGroupId: z13.string(),
3836
- name: z13.string(),
3837
- description: z13.string().nullable().optional(),
3534
+ var clinicSchema = z10.object({
3535
+ id: z10.string(),
3536
+ clinicGroupId: z10.string(),
3537
+ name: z10.string(),
3538
+ description: z10.string().nullable().optional(),
3838
3539
  location: clinicLocationSchema,
3839
3540
  contactInfo: clinicContactInfoSchema,
3840
3541
  workingHours: workingHoursSchema,
3841
- tags: z13.array(z13.nativeEnum(ClinicTag)),
3842
- featuredPhotos: z13.array(mediaResourceSchema),
3542
+ tags: z10.array(z10.nativeEnum(ClinicTag)),
3543
+ featuredPhotos: z10.array(mediaResourceSchema),
3843
3544
  coverPhoto: mediaResourceSchema.nullable(),
3844
- photosWithTags: z13.array(
3845
- z13.object({
3545
+ photosWithTags: z10.array(
3546
+ z10.object({
3846
3547
  url: mediaResourceSchema,
3847
- tag: z13.string()
3548
+ tag: z10.string()
3848
3549
  })
3849
3550
  ).optional(),
3850
- doctors: z13.array(z13.string()),
3551
+ doctors: z10.array(z10.string()),
3851
3552
  // List of practitioner IDs
3852
- doctorsInfo: z13.array(doctorInfoSchema),
3553
+ doctorsInfo: z10.array(doctorInfoSchema),
3853
3554
  // Aggregated doctor info
3854
- procedures: z13.array(z13.string()),
3555
+ procedures: z10.array(z10.string()),
3855
3556
  // List of procedure IDs offered by clinic
3856
- proceduresInfo: z13.array(procedureSummaryInfoSchema),
3557
+ proceduresInfo: z10.array(procedureSummaryInfoSchema),
3857
3558
  // Use the correct schema for aggregated procedure info
3858
3559
  reviewInfo: clinicReviewInfoSchema,
3859
- admins: z13.array(z13.string()),
3860
- createdAt: z13.instanceof(Date).or(z13.instanceof(Timestamp7)),
3560
+ admins: z10.array(z10.string()),
3561
+ createdAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6)),
3861
3562
  // Timestamp
3862
- updatedAt: z13.instanceof(Date).or(z13.instanceof(Timestamp7)),
3563
+ updatedAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6)),
3863
3564
  // Timestamp
3864
- isActive: z13.boolean(),
3865
- isVerified: z13.boolean(),
3565
+ isActive: z10.boolean(),
3566
+ isVerified: z10.boolean(),
3866
3567
  logo: mediaResourceSchema.optional().nullable()
3867
3568
  });
3868
- var createClinicAdminSchema = z13.object({
3869
- userRef: z13.string(),
3870
- clinicGroupId: z13.string().optional(),
3871
- isGroupOwner: z13.boolean(),
3872
- clinicsManaged: z13.array(z13.string()),
3569
+ var createClinicAdminSchema = z10.object({
3570
+ userRef: z10.string(),
3571
+ clinicGroupId: z10.string().optional(),
3572
+ isGroupOwner: z10.boolean(),
3573
+ clinicsManaged: z10.array(z10.string()),
3873
3574
  contactInfo: contactPersonSchema,
3874
- roleTitle: z13.string(),
3875
- isActive: z13.boolean()
3575
+ roleTitle: z10.string(),
3576
+ isActive: z10.boolean()
3876
3577
  // clinicsManagedInfo is aggregated, not provided on creation
3877
3578
  });
3878
- var createClinicGroupSchema = z13.object({
3879
- name: z13.string(),
3880
- description: z13.string().optional(),
3579
+ var createClinicGroupSchema = z10.object({
3580
+ name: z10.string(),
3581
+ description: z10.string().optional(),
3881
3582
  hqLocation: clinicLocationSchema,
3882
3583
  contactInfo: clinicContactInfoSchema,
3883
3584
  contactPerson: contactPersonSchema,
3884
- ownerId: z13.string().nullable(),
3885
- isActive: z13.boolean(),
3585
+ ownerId: z10.string().nullable(),
3586
+ isActive: z10.boolean(),
3886
3587
  logo: mediaResourceSchema.optional().nullable(),
3887
- practiceType: z13.nativeEnum(PracticeType).optional(),
3888
- languages: z13.array(z13.nativeEnum(Language)).optional(),
3889
- subscriptionModel: z13.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
3890
- calendarSyncEnabled: z13.boolean().optional(),
3891
- autoConfirmAppointments: z13.boolean().optional(),
3892
- businessIdentificationNumber: z13.string().optional().nullable(),
3893
- onboarding: z13.object({
3894
- completed: z13.boolean().optional().default(false),
3895
- step: z13.number().optional().default(1)
3588
+ practiceType: z10.nativeEnum(PracticeType).optional(),
3589
+ languages: z10.array(z10.nativeEnum(Language)).optional(),
3590
+ subscriptionModel: z10.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
3591
+ calendarSyncEnabled: z10.boolean().optional(),
3592
+ autoConfirmAppointments: z10.boolean().optional(),
3593
+ businessIdentificationNumber: z10.string().optional().nullable(),
3594
+ onboarding: z10.object({
3595
+ completed: z10.boolean().optional().default(false),
3596
+ step: z10.number().optional().default(1)
3896
3597
  }).optional()
3897
3598
  // clinics, clinicsInfo, admins, adminsInfo, adminTokens are managed internally
3898
3599
  });
3899
- var createClinicSchema = z13.object({
3900
- clinicGroupId: z13.string(),
3901
- name: z13.string(),
3902
- description: z13.string().optional(),
3600
+ var createClinicSchema = z10.object({
3601
+ clinicGroupId: z10.string(),
3602
+ name: z10.string(),
3603
+ description: z10.string().optional(),
3903
3604
  location: clinicLocationSchema,
3904
3605
  contactInfo: clinicContactInfoSchema,
3905
3606
  workingHours: workingHoursSchema,
3906
- tags: z13.array(z13.nativeEnum(ClinicTag)),
3607
+ tags: z10.array(z10.nativeEnum(ClinicTag)),
3907
3608
  coverPhoto: mediaResourceSchema.nullable().optional(),
3908
- photosWithTags: z13.array(
3909
- z13.object({
3609
+ photosWithTags: z10.array(
3610
+ z10.object({
3910
3611
  url: mediaResourceSchema,
3911
- tag: z13.string()
3612
+ tag: z10.string()
3912
3613
  })
3913
3614
  ).optional(),
3914
- doctors: z13.array(z13.string()).optional().default([]),
3915
- procedures: z13.array(z13.string()).optional().default([]),
3916
- proceduresInfo: z13.array(procedureSummaryInfoSchema).optional(),
3917
- admins: z13.array(z13.string()),
3918
- isActive: z13.boolean().optional().default(true),
3919
- isVerified: z13.boolean().optional().default(false),
3615
+ doctors: z10.array(z10.string()).optional().default([]),
3616
+ procedures: z10.array(z10.string()).optional().default([]),
3617
+ proceduresInfo: z10.array(procedureSummaryInfoSchema).optional(),
3618
+ admins: z10.array(z10.string()),
3619
+ isActive: z10.boolean().optional().default(true),
3620
+ isVerified: z10.boolean().optional().default(false),
3920
3621
  logo: mediaResourceSchema.optional().nullable(),
3921
- featuredPhotos: z13.array(mediaResourceSchema).optional().default([])
3622
+ featuredPhotos: z10.array(mediaResourceSchema).optional().default([])
3922
3623
  });
3923
- var createDefaultClinicGroupSchema = z13.object({
3924
- name: z13.string(),
3925
- ownerId: z13.string().nullable(),
3624
+ var createDefaultClinicGroupSchema = z10.object({
3625
+ name: z10.string(),
3626
+ ownerId: z10.string().nullable(),
3926
3627
  contactPerson: contactPersonSchema,
3927
3628
  contactInfo: clinicContactInfoSchema,
3928
3629
  hqLocation: clinicLocationSchema,
3929
- isActive: z13.boolean(),
3630
+ isActive: z10.boolean(),
3930
3631
  logo: mediaResourceSchema.optional().nullable(),
3931
- practiceType: z13.nativeEnum(PracticeType).optional(),
3932
- languages: z13.array(z13.nativeEnum(Language)).optional(),
3933
- subscriptionModel: z13.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
3934
- onboarding: z13.object({
3935
- completed: z13.boolean().optional().default(false),
3936
- step: z13.number().optional().default(1)
3632
+ practiceType: z10.nativeEnum(PracticeType).optional(),
3633
+ languages: z10.array(z10.nativeEnum(Language)).optional(),
3634
+ subscriptionModel: z10.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
3635
+ onboarding: z10.object({
3636
+ completed: z10.boolean().optional().default(false),
3637
+ step: z10.number().optional().default(1)
3937
3638
  }).optional()
3938
3639
  });
3939
- var clinicAdminSignupSchema = z13.object({
3940
- email: z13.string().email(),
3941
- password: z13.string().min(8),
3942
- firstName: z13.string(),
3943
- lastName: z13.string(),
3944
- title: z13.string(),
3945
- phoneNumber: z13.string(),
3946
- isCreatingNewGroup: z13.boolean(),
3947
- inviteToken: z13.string().optional(),
3948
- clinicGroupData: z13.object({
3949
- name: z13.string(),
3640
+ var clinicAdminSignupSchema = z10.object({
3641
+ email: z10.string().email(),
3642
+ password: z10.string().min(8),
3643
+ firstName: z10.string(),
3644
+ lastName: z10.string(),
3645
+ title: z10.string(),
3646
+ phoneNumber: z10.string(),
3647
+ isCreatingNewGroup: z10.boolean(),
3648
+ inviteToken: z10.string().optional(),
3649
+ clinicGroupData: z10.object({
3650
+ name: z10.string(),
3950
3651
  hqLocation: clinicLocationSchema,
3951
3652
  logo: mediaResourceSchema.optional(),
3952
3653
  contactInfo: clinicContactInfoSchema,
3953
- subscriptionModel: z13.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */)
3654
+ subscriptionModel: z10.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */)
3954
3655
  }).optional()
3955
3656
  });
3956
- var clinicGroupSetupSchema = z13.object({
3957
- languages: z13.array(z13.nativeEnum(Language)),
3958
- practiceType: z13.nativeEnum(PracticeType),
3959
- description: z13.string(),
3657
+ var clinicGroupSetupSchema = z10.object({
3658
+ languages: z10.array(z10.nativeEnum(Language)),
3659
+ practiceType: z10.nativeEnum(PracticeType),
3660
+ description: z10.string(),
3960
3661
  logo: mediaResourceSchema,
3961
- calendarSyncEnabled: z13.boolean(),
3962
- autoConfirmAppointments: z13.boolean(),
3963
- businessIdentificationNumber: z13.string().optional().nullable(),
3964
- onboarding: z13.object({
3965
- completed: z13.boolean().optional().default(false),
3966
- step: z13.number().optional().default(1)
3662
+ calendarSyncEnabled: z10.boolean(),
3663
+ autoConfirmAppointments: z10.boolean(),
3664
+ businessIdentificationNumber: z10.string().optional().nullable(),
3665
+ onboarding: z10.object({
3666
+ completed: z10.boolean().optional().default(false),
3667
+ step: z10.number().optional().default(1)
3967
3668
  }).optional()
3968
3669
  });
3969
- var clinicBranchSetupSchema = z13.object({
3970
- name: z13.string(),
3670
+ var clinicBranchSetupSchema = z10.object({
3671
+ name: z10.string(),
3971
3672
  location: clinicLocationSchema,
3972
- description: z13.string().optional(),
3673
+ description: z10.string().optional(),
3973
3674
  contactInfo: clinicContactInfoSchema,
3974
3675
  workingHours: workingHoursSchema,
3975
- tags: z13.array(z13.nativeEnum(ClinicTag)),
3676
+ tags: z10.array(z10.nativeEnum(ClinicTag)),
3976
3677
  logo: mediaResourceSchema.optional(),
3977
3678
  coverPhoto: mediaResourceSchema.nullable().optional(),
3978
- photosWithTags: z13.array(
3979
- z13.object({
3679
+ photosWithTags: z10.array(
3680
+ z10.object({
3980
3681
  url: mediaResourceSchema,
3981
- tag: z13.string()
3682
+ tag: z10.string()
3982
3683
  })
3983
3684
  ).optional(),
3984
- featuredPhotos: z13.array(mediaResourceSchema).optional()
3685
+ featuredPhotos: z10.array(mediaResourceSchema).optional()
3985
3686
  });
3986
3687
  var updateClinicAdminSchema = createClinicAdminSchema.partial();
3987
3688
  var updateClinicGroupSchema = createClinicGroupSchema.partial();
3988
- var updateClinicSchema = z13.object({
3989
- name: z13.string().optional(),
3990
- description: z13.string().optional(),
3689
+ var updateClinicSchema = z10.object({
3690
+ name: z10.string().optional(),
3691
+ description: z10.string().optional(),
3991
3692
  location: clinicLocationSchema.optional(),
3992
3693
  contactInfo: clinicContactInfoSchema.optional(),
3993
3694
  workingHours: workingHoursSchema.optional(),
3994
- tags: z13.array(z13.nativeEnum(ClinicTag)).optional(),
3695
+ tags: z10.array(z10.nativeEnum(ClinicTag)).optional(),
3995
3696
  coverPhoto: mediaResourceSchema.nullable().optional(),
3996
- photosWithTags: z13.array(
3997
- z13.object({
3697
+ photosWithTags: z10.array(
3698
+ z10.object({
3998
3699
  url: mediaResourceSchema,
3999
- tag: z13.string()
3700
+ tag: z10.string()
4000
3701
  })
4001
3702
  ).optional(),
4002
- doctors: z13.array(z13.string()).optional(),
4003
- procedures: z13.array(z13.string()).optional(),
4004
- proceduresInfo: z13.array(procedureSummaryInfoSchema).optional(),
4005
- isActive: z13.boolean().optional(),
4006
- isVerified: z13.boolean().optional(),
3703
+ doctors: z10.array(z10.string()).optional(),
3704
+ procedures: z10.array(z10.string()).optional(),
3705
+ proceduresInfo: z10.array(procedureSummaryInfoSchema).optional(),
3706
+ isActive: z10.boolean().optional(),
3707
+ isVerified: z10.boolean().optional(),
4007
3708
  logo: mediaResourceSchema.optional().nullable(),
4008
- featuredPhotos: z13.array(mediaResourceSchema).optional()
3709
+ featuredPhotos: z10.array(mediaResourceSchema).optional()
4009
3710
  });
4010
3711
 
4011
3712
  // src/services/clinic/utils/admin.utils.ts
@@ -4101,8 +3802,8 @@ async function createClinicAdmin(db, data, clinicGroupService) {
4101
3802
  try {
4102
3803
  clinicAdminSchema.parse({
4103
3804
  ...adminData,
4104
- createdAt: Timestamp8.now(),
4105
- updatedAt: Timestamp8.now()
3805
+ createdAt: Timestamp7.now(),
3806
+ updatedAt: Timestamp7.now()
4106
3807
  });
4107
3808
  console.log("[CLINIC_ADMIN] Admin object validation passed");
4108
3809
  } catch (schemaError) {
@@ -4422,7 +4123,7 @@ var createSensitiveInfoUtil = async (db, data, requesterId, requesterRoles, medi
4422
4123
  }
4423
4124
  return createdDoc.data();
4424
4125
  } catch (error) {
4425
- if (error instanceof z14.ZodError) {
4126
+ if (error instanceof z11.ZodError) {
4426
4127
  throw new Error("Invalid sensitive info data: " + error.message);
4427
4128
  }
4428
4129
  throw error;
@@ -4566,7 +4267,7 @@ import {
4566
4267
  setDoc as setDoc6,
4567
4268
  serverTimestamp as serverTimestamp6
4568
4269
  } from "firebase/firestore";
4569
- import { z as z15 } from "zod";
4270
+ import { z as z12 } from "zod";
4570
4271
  import { geohashForLocation } from "geofire-common";
4571
4272
  var updatePatientLocationUtil = async (db, patientId, latitude, longitude) => {
4572
4273
  const locationData = {
@@ -4605,7 +4306,7 @@ var createLocationInfoUtil = async (db, data, requesterId) => {
4605
4306
  }
4606
4307
  return locationDoc.data();
4607
4308
  } catch (error) {
4608
- if (error instanceof z15.ZodError) {
4309
+ if (error instanceof z12.ZodError) {
4609
4310
  throw new Error("Invalid location data: " + error.message);
4610
4311
  }
4611
4312
  throw error;
@@ -4648,13 +4349,13 @@ import {
4648
4349
  arrayUnion as arrayUnion2,
4649
4350
  arrayRemove as arrayRemove2,
4650
4351
  serverTimestamp as serverTimestamp7,
4651
- Timestamp as Timestamp9
4352
+ Timestamp as Timestamp8
4652
4353
  } from "firebase/firestore";
4653
4354
  var addDoctorUtil = async (db, patientId, doctorRef, assignedBy) => {
4654
4355
  var _a;
4655
4356
  const newDoctor = {
4656
4357
  userRef: doctorRef,
4657
- assignedAt: Timestamp9.now(),
4358
+ assignedAt: Timestamp8.now(),
4658
4359
  assignedBy,
4659
4360
  isActive: true
4660
4361
  };
@@ -4673,7 +4374,7 @@ var addDoctorUtil = async (db, patientId, doctorRef, assignedBy) => {
4673
4374
  updatedDoctors[existingDoctorIndex] = {
4674
4375
  ...updatedDoctors[existingDoctorIndex],
4675
4376
  isActive: true,
4676
- assignedAt: Timestamp9.now(),
4377
+ assignedAt: Timestamp8.now(),
4677
4378
  assignedBy
4678
4379
  };
4679
4380
  updates.doctors = updatedDoctors;
@@ -4701,7 +4402,7 @@ var addClinicUtil = async (db, patientId, clinicId, assignedBy) => {
4701
4402
  var _a;
4702
4403
  const newClinic = {
4703
4404
  clinicId,
4704
- assignedAt: Timestamp9.now(),
4405
+ assignedAt: Timestamp8.now(),
4705
4406
  assignedBy,
4706
4407
  isActive: true
4707
4408
  };
@@ -4720,7 +4421,7 @@ var addClinicUtil = async (db, patientId, clinicId, assignedBy) => {
4720
4421
  updatedClinics[existingClinicIndex] = {
4721
4422
  ...updatedClinics[existingClinicIndex],
4722
4423
  isActive: true,
4723
- assignedAt: Timestamp9.now(),
4424
+ assignedAt: Timestamp8.now(),
4724
4425
  assignedBy
4725
4426
  };
4726
4427
  updates.clinics = updatedClinics;
@@ -5039,7 +4740,7 @@ import {
5039
4740
  arrayRemove as arrayRemove4,
5040
4741
  serverTimestamp as serverTimestamp9,
5041
4742
  increment,
5042
- Timestamp as Timestamp11,
4743
+ Timestamp as Timestamp10,
5043
4744
  collection as collection8,
5044
4745
  query as query8,
5045
4746
  where as where8,
@@ -5048,7 +4749,7 @@ import {
5048
4749
  startAfter as startAfter5,
5049
4750
  doc as doc8
5050
4751
  } from "firebase/firestore";
5051
- import { z as z16 } from "zod";
4752
+ import { z as z13 } from "zod";
5052
4753
  var createPatientProfileUtil = async (db, data, generateId2) => {
5053
4754
  var _a, _b;
5054
4755
  try {
@@ -5082,8 +4783,8 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
5082
4783
  };
5083
4784
  patientProfileSchema.parse({
5084
4785
  ...patientData,
5085
- createdAt: Timestamp11.now(),
5086
- updatedAt: Timestamp11.now()
4786
+ createdAt: Timestamp10.now(),
4787
+ updatedAt: Timestamp10.now()
5087
4788
  });
5088
4789
  await setDoc8(getPatientDocRef(db, patientId), patientData);
5089
4790
  console.log(`[createPatientProfileUtil] Creating sensitive info document`);
@@ -5151,7 +4852,7 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
5151
4852
  `[createPatientProfileUtil] Error in patient profile creation:`,
5152
4853
  error
5153
4854
  );
5154
- if (error instanceof z16.ZodError) {
4855
+ if (error instanceof z13.ZodError) {
5155
4856
  throw new Error("Invalid patient data: " + error.message);
5156
4857
  }
5157
4858
  throw error;
@@ -5237,12 +4938,12 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
5237
4938
  photoUrl: "",
5238
4939
  firstName: "Name",
5239
4940
  lastName: "Surname",
5240
- dateOfBirth: Timestamp11.now(),
4941
+ dateOfBirth: Timestamp10.now(),
5241
4942
  gender: "prefer_not_to_say" /* PREFER_NOT_TO_SAY */,
5242
4943
  email: "test@example.com",
5243
4944
  phoneNumber: "",
5244
- createdAt: Timestamp11.now(),
5245
- updatedAt: Timestamp11.now()
4945
+ createdAt: Timestamp10.now(),
4946
+ updatedAt: Timestamp10.now()
5246
4947
  };
5247
4948
  await setDoc8(sensitiveInfoRef, defaultSensitiveInfo);
5248
4949
  console.log(
@@ -5256,7 +4957,7 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
5256
4957
  const defaultMedicalInfo = {
5257
4958
  ...DEFAULT_MEDICAL_INFO,
5258
4959
  patientId,
5259
- lastUpdated: Timestamp11.now(),
4960
+ lastUpdated: Timestamp10.now(),
5260
4961
  updatedBy: userRef
5261
4962
  };
5262
4963
  await setDoc8(medicalInfoRef, defaultMedicalInfo);
@@ -5374,33 +5075,33 @@ import {
5374
5075
  where as where9,
5375
5076
  setDoc as setDoc9,
5376
5077
  updateDoc as updateDoc9,
5377
- Timestamp as Timestamp12,
5078
+ Timestamp as Timestamp11,
5378
5079
  collectionGroup
5379
5080
  } from "firebase/firestore";
5380
5081
 
5381
5082
  // src/validations/patient/token.schema.ts
5382
- import { z as z17 } from "zod";
5383
- var patientTokenSchema = z17.object({
5384
- id: z17.string().min(1, "Token ID is required"),
5385
- token: z17.string().min(1, "Token string is required"),
5386
- patientId: z17.string().min(1, "Patient ID is required"),
5387
- email: z17.string().email("Invalid email format"),
5388
- clinicId: z17.string().min(1, "Clinic ID is required"),
5389
- status: z17.nativeEnum(PatientTokenStatus),
5390
- createdBy: z17.string().min(1, "Creator ID is required"),
5391
- createdAt: z17.any(),
5083
+ import { z as z14 } from "zod";
5084
+ var patientTokenSchema = z14.object({
5085
+ id: z14.string().min(1, "Token ID is required"),
5086
+ token: z14.string().min(1, "Token string is required"),
5087
+ patientId: z14.string().min(1, "Patient ID is required"),
5088
+ email: z14.string().email("Invalid email format"),
5089
+ clinicId: z14.string().min(1, "Clinic ID is required"),
5090
+ status: z14.nativeEnum(PatientTokenStatus),
5091
+ createdBy: z14.string().min(1, "Creator ID is required"),
5092
+ createdAt: z14.any(),
5392
5093
  // Assuming Timestamp validated elsewhere
5393
- expiresAt: z17.any(),
5094
+ expiresAt: z14.any(),
5394
5095
  // Assuming Timestamp validated elsewhere
5395
- usedBy: z17.string().optional(),
5396
- usedAt: z17.any().optional()
5096
+ usedBy: z14.string().optional(),
5097
+ usedAt: z14.any().optional()
5397
5098
  // Assuming Timestamp validated elsewhere
5398
5099
  });
5399
- var createPatientTokenSchema = z17.object({
5400
- patientId: z17.string().min(1, "Patient ID is required"),
5401
- clinicId: z17.string().min(1, "Clinic ID is required"),
5402
- email: z17.string().email("Invalid email format"),
5403
- expiresAt: z17.date().optional()
5100
+ var createPatientTokenSchema = z14.object({
5101
+ patientId: z14.string().min(1, "Patient ID is required"),
5102
+ clinicId: z14.string().min(1, "Clinic ID is required"),
5103
+ email: z14.string().email("Invalid email format"),
5104
+ expiresAt: z14.date().optional()
5404
5105
  });
5405
5106
 
5406
5107
  // src/services/patient/utils/token.utils.ts
@@ -5424,8 +5125,8 @@ var createPatientTokenUtil = async (db, data, createdBy, generateId2) => {
5424
5125
  clinicId: validatedData.clinicId,
5425
5126
  status: "active" /* ACTIVE */,
5426
5127
  createdBy,
5427
- createdAt: Timestamp12.now(),
5428
- expiresAt: Timestamp12.fromDate(expiration)
5128
+ createdAt: Timestamp11.now(),
5129
+ expiresAt: Timestamp11.fromDate(expiration)
5429
5130
  };
5430
5131
  patientTokenSchema.parse(token);
5431
5132
  const tokenRef = doc9(
@@ -5451,7 +5152,7 @@ var validatePatientTokenUtil = async (db, tokenString) => {
5451
5152
  tokensRef,
5452
5153
  where9("token", "==", tokenString),
5453
5154
  where9("status", "==", "active" /* ACTIVE */),
5454
- where9("expiresAt", ">", Timestamp12.now())
5155
+ where9("expiresAt", ">", Timestamp11.now())
5455
5156
  );
5456
5157
  const tokenSnapshot = await getDocs9(q);
5457
5158
  if (!tokenSnapshot.empty) {
@@ -5471,7 +5172,7 @@ var markPatientTokenAsUsedUtil = async (db, tokenId, patientId, userId) => {
5471
5172
  await updateDoc9(tokenRef, {
5472
5173
  status: "used" /* USED */,
5473
5174
  usedBy: userId,
5474
- usedAt: Timestamp12.now()
5175
+ usedAt: Timestamp11.now()
5475
5176
  });
5476
5177
  };
5477
5178
  var getActiveInviteTokensByClinicUtil = async (db, clinicId) => {
@@ -5479,7 +5180,7 @@ var getActiveInviteTokensByClinicUtil = async (db, clinicId) => {
5479
5180
  collectionGroup(db, INVITE_TOKENS_COLLECTION),
5480
5181
  where9("clinicId", "==", clinicId),
5481
5182
  where9("status", "==", "active" /* ACTIVE */),
5482
- where9("expiresAt", ">", Timestamp12.now())
5183
+ where9("expiresAt", ">", Timestamp11.now())
5483
5184
  );
5484
5185
  const querySnapshot = await getDocs9(tokensQuery);
5485
5186
  if (querySnapshot.empty) {
@@ -5497,7 +5198,7 @@ var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
5497
5198
  const q = query9(
5498
5199
  tokensRef,
5499
5200
  where9("status", "==", "active" /* ACTIVE */),
5500
- where9("expiresAt", ">", Timestamp12.now())
5201
+ where9("expiresAt", ">", Timestamp11.now())
5501
5202
  );
5502
5203
  const querySnapshot = await getDocs9(q);
5503
5204
  if (querySnapshot.empty) {
@@ -5540,7 +5241,7 @@ var PatientService = class extends BaseService {
5540
5241
  }
5541
5242
  const patientId = this.generateId();
5542
5243
  const batch = writeBatch(this.db);
5543
- const now = Timestamp13.now();
5244
+ const now = Timestamp12.now();
5544
5245
  const patientProfileRef = getPatientDocRef(this.db, patientId);
5545
5246
  const newProfile = {
5546
5247
  id: patientId,
@@ -6305,7 +6006,169 @@ import {
6305
6006
  arrayUnion as arrayUnion6,
6306
6007
  arrayRemove as arrayRemove5
6307
6008
  } from "firebase/firestore";
6308
- import { z as z18 } from "zod";
6009
+
6010
+ // src/validations/practitioner.schema.ts
6011
+ import { z as z15 } from "zod";
6012
+ import { Timestamp as Timestamp13 } from "firebase/firestore";
6013
+
6014
+ // src/backoffice/types/static/certification.types.ts
6015
+ var CertificationLevel = /* @__PURE__ */ ((CertificationLevel2) => {
6016
+ CertificationLevel2["AESTHETICIAN"] = "aesthetician";
6017
+ CertificationLevel2["NURSE_ASSISTANT"] = "nurse_assistant";
6018
+ CertificationLevel2["NURSE"] = "nurse";
6019
+ CertificationLevel2["NURSE_PRACTITIONER"] = "nurse_practitioner";
6020
+ CertificationLevel2["PHYSICIAN_ASSISTANT"] = "physician_assistant";
6021
+ CertificationLevel2["DOCTOR"] = "doctor";
6022
+ CertificationLevel2["SPECIALIST"] = "specialist";
6023
+ CertificationLevel2["PLASTIC_SURGEON"] = "plastic_surgeon";
6024
+ return CertificationLevel2;
6025
+ })(CertificationLevel || {});
6026
+ var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
6027
+ CertificationSpecialty3["LASER"] = "laser";
6028
+ CertificationSpecialty3["INJECTABLES"] = "injectables";
6029
+ CertificationSpecialty3["CHEMICAL_PEELS"] = "chemical_peels";
6030
+ CertificationSpecialty3["MICRODERMABRASION"] = "microdermabrasion";
6031
+ CertificationSpecialty3["BODY_CONTOURING"] = "body_contouring";
6032
+ CertificationSpecialty3["SKIN_CARE"] = "skin_care";
6033
+ CertificationSpecialty3["WOUND_CARE"] = "wound_care";
6034
+ CertificationSpecialty3["ANESTHESIA"] = "anesthesia";
6035
+ return CertificationSpecialty3;
6036
+ })(CertificationSpecialty || {});
6037
+
6038
+ // src/validations/practitioner.schema.ts
6039
+ var practitionerBasicInfoSchema = z15.object({
6040
+ firstName: z15.string().min(2).max(50),
6041
+ lastName: z15.string().min(2).max(50),
6042
+ title: z15.string().min(2).max(100),
6043
+ email: z15.string().email(),
6044
+ phoneNumber: z15.string().regex(/^\+?[1-9]\d{1,14}$/, "Invalid phone number").nullable(),
6045
+ dateOfBirth: z15.instanceof(Timestamp13).or(z15.date()).nullable(),
6046
+ gender: z15.enum(["male", "female", "other"]),
6047
+ profileImageUrl: mediaResourceSchema.optional().nullable(),
6048
+ bio: z15.string().max(1e3).optional(),
6049
+ languages: z15.array(z15.string()).min(1)
6050
+ });
6051
+ var practitionerCertificationSchema = z15.object({
6052
+ level: z15.nativeEnum(CertificationLevel),
6053
+ specialties: z15.array(z15.nativeEnum(CertificationSpecialty)),
6054
+ licenseNumber: z15.string().min(3).max(50),
6055
+ issuingAuthority: z15.string().min(2).max(100),
6056
+ issueDate: z15.instanceof(Timestamp13).or(z15.date()),
6057
+ expiryDate: z15.instanceof(Timestamp13).or(z15.date()).optional().nullable(),
6058
+ verificationStatus: z15.enum(["pending", "verified", "rejected"])
6059
+ });
6060
+ var timeSlotSchema = z15.object({
6061
+ start: z15.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format"),
6062
+ end: z15.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format")
6063
+ }).nullable();
6064
+ var practitionerWorkingHoursSchema = z15.object({
6065
+ practitionerId: z15.string().min(1),
6066
+ clinicId: z15.string().min(1),
6067
+ monday: timeSlotSchema,
6068
+ tuesday: timeSlotSchema,
6069
+ wednesday: timeSlotSchema,
6070
+ thursday: timeSlotSchema,
6071
+ friday: timeSlotSchema,
6072
+ saturday: timeSlotSchema,
6073
+ sunday: timeSlotSchema,
6074
+ createdAt: z15.instanceof(Timestamp13).or(z15.date()),
6075
+ updatedAt: z15.instanceof(Timestamp13).or(z15.date())
6076
+ });
6077
+ var practitionerClinicWorkingHoursSchema = z15.object({
6078
+ clinicId: z15.string().min(1),
6079
+ workingHours: z15.object({
6080
+ monday: timeSlotSchema,
6081
+ tuesday: timeSlotSchema,
6082
+ wednesday: timeSlotSchema,
6083
+ thursday: timeSlotSchema,
6084
+ friday: timeSlotSchema,
6085
+ saturday: timeSlotSchema,
6086
+ sunday: timeSlotSchema
6087
+ }),
6088
+ isActive: z15.boolean(),
6089
+ createdAt: z15.instanceof(Timestamp13).or(z15.date()),
6090
+ updatedAt: z15.instanceof(Timestamp13).or(z15.date())
6091
+ });
6092
+ var practitionerSchema = z15.object({
6093
+ id: z15.string().min(1),
6094
+ userRef: z15.string().min(1),
6095
+ basicInfo: practitionerBasicInfoSchema,
6096
+ certification: practitionerCertificationSchema,
6097
+ clinics: z15.array(z15.string()),
6098
+ clinicWorkingHours: z15.array(practitionerClinicWorkingHoursSchema),
6099
+ clinicsInfo: z15.array(clinicInfoSchema),
6100
+ procedures: z15.array(z15.string()),
6101
+ freeConsultations: z15.record(z15.string(), z15.string()).optional().nullable(),
6102
+ proceduresInfo: z15.array(procedureSummaryInfoSchema),
6103
+ reviewInfo: practitionerReviewInfoSchema,
6104
+ isActive: z15.boolean(),
6105
+ isVerified: z15.boolean(),
6106
+ status: z15.nativeEnum(PractitionerStatus),
6107
+ createdAt: z15.instanceof(Timestamp13).or(z15.date()),
6108
+ updatedAt: z15.instanceof(Timestamp13).or(z15.date())
6109
+ });
6110
+ var createPractitionerSchema = z15.object({
6111
+ userRef: z15.string().min(1),
6112
+ basicInfo: practitionerBasicInfoSchema,
6113
+ certification: practitionerCertificationSchema,
6114
+ clinics: z15.array(z15.string()).optional(),
6115
+ clinicWorkingHours: z15.array(practitionerClinicWorkingHoursSchema).optional(),
6116
+ clinicsInfo: z15.array(clinicInfoSchema).optional(),
6117
+ freeConsultations: z15.record(z15.string(), z15.string()).optional().nullable(),
6118
+ proceduresInfo: z15.array(procedureSummaryInfoSchema).optional(),
6119
+ isActive: z15.boolean(),
6120
+ isVerified: z15.boolean(),
6121
+ status: z15.nativeEnum(PractitionerStatus).optional()
6122
+ });
6123
+ var createDraftPractitionerSchema = z15.object({
6124
+ basicInfo: practitionerBasicInfoSchema,
6125
+ certification: practitionerCertificationSchema,
6126
+ clinics: z15.array(z15.string()).optional(),
6127
+ clinicWorkingHours: z15.array(practitionerClinicWorkingHoursSchema).optional(),
6128
+ clinicsInfo: z15.array(clinicInfoSchema).optional(),
6129
+ freeConsultations: z15.record(z15.string(), z15.string()).optional().nullable(),
6130
+ proceduresInfo: z15.array(procedureSummaryInfoSchema).optional(),
6131
+ isActive: z15.boolean().optional().default(false),
6132
+ isVerified: z15.boolean().optional().default(false)
6133
+ });
6134
+ var practitionerTokenSchema = z15.object({
6135
+ id: z15.string().min(1),
6136
+ token: z15.string().min(6),
6137
+ practitionerId: z15.string().min(1),
6138
+ email: z15.string().email(),
6139
+ clinicId: z15.string().min(1),
6140
+ status: z15.nativeEnum(PractitionerTokenStatus),
6141
+ createdBy: z15.string().min(1),
6142
+ createdAt: z15.instanceof(Timestamp13).or(z15.date()),
6143
+ expiresAt: z15.instanceof(Timestamp13).or(z15.date()),
6144
+ usedBy: z15.string().optional(),
6145
+ usedAt: z15.instanceof(Timestamp13).or(z15.date()).optional()
6146
+ });
6147
+ var createPractitionerTokenSchema = z15.object({
6148
+ practitionerId: z15.string().min(1),
6149
+ email: z15.string().email(),
6150
+ clinicId: z15.string().min(1),
6151
+ expiresAt: z15.date().optional()
6152
+ });
6153
+ var practitionerSignupSchema = z15.object({
6154
+ email: z15.string().email(),
6155
+ password: z15.string().min(8),
6156
+ firstName: z15.string().min(2).max(50).optional(),
6157
+ lastName: z15.string().min(2).max(50).optional(),
6158
+ token: z15.string().optional(),
6159
+ profileData: z15.object({
6160
+ basicInfo: z15.object({
6161
+ phoneNumber: z15.string().optional(),
6162
+ profileImageUrl: mediaResourceSchema.optional(),
6163
+ gender: z15.enum(["male", "female", "other"]).optional(),
6164
+ bio: z15.string().optional()
6165
+ }).optional(),
6166
+ certification: z15.any().optional()
6167
+ }).optional()
6168
+ });
6169
+
6170
+ // src/services/practitioner/practitioner.service.ts
6171
+ import { z as z16 } from "zod";
6309
6172
  import { distanceBetween } from "geofire-common";
6310
6173
  var PractitionerService = class extends BaseService {
6311
6174
  constructor(db, auth, app, clinicService, procedureService) {
@@ -6435,7 +6298,7 @@ var PractitionerService = class extends BaseService {
6435
6298
  }
6436
6299
  return createdPractitioner;
6437
6300
  } catch (error) {
6438
- if (error instanceof z18.ZodError) {
6301
+ if (error instanceof z16.ZodError) {
6439
6302
  throw new Error(`Invalid practitioner data: ${error.message}`);
6440
6303
  }
6441
6304
  console.error("Error creating practitioner:", error);
@@ -6551,7 +6414,7 @@ var PractitionerService = class extends BaseService {
6551
6414
  await setDoc10(doc11(this.db, tokenPath), token);
6552
6415
  return { practitioner: savedPractitioner, token };
6553
6416
  } catch (error) {
6554
- if (error instanceof z18.ZodError) {
6417
+ if (error instanceof z16.ZodError) {
6555
6418
  throw new Error("Invalid practitioner data: " + error.message);
6556
6419
  }
6557
6420
  throw error;
@@ -6604,7 +6467,7 @@ var PractitionerService = class extends BaseService {
6604
6467
  await setDoc10(doc11(this.db, tokenPath), token);
6605
6468
  return token;
6606
6469
  } catch (error) {
6607
- if (error instanceof z18.ZodError) {
6470
+ if (error instanceof z16.ZodError) {
6608
6471
  throw new Error("Invalid token data: " + error.message);
6609
6472
  }
6610
6473
  throw error;
@@ -6798,7 +6661,7 @@ var PractitionerService = class extends BaseService {
6798
6661
  }
6799
6662
  return updatedPractitioner;
6800
6663
  } catch (error) {
6801
- if (error instanceof z18.ZodError) {
6664
+ if (error instanceof z16.ZodError) {
6802
6665
  throw new Error(`Invalid practitioner update data: ${error.message}`);
6803
6666
  }
6804
6667
  console.error(`Error updating practitioner ${practitionerId}:`, error);
@@ -7581,7 +7444,7 @@ var UserService = class extends BaseService {
7581
7444
  });
7582
7445
  return this.getUserById(uid);
7583
7446
  } catch (error) {
7584
- if (error instanceof z19.ZodError) {
7447
+ if (error instanceof z17.ZodError) {
7585
7448
  throw USER_ERRORS.VALIDATION_ERROR;
7586
7449
  }
7587
7450
  throw error;
@@ -7678,7 +7541,7 @@ import {
7678
7541
  Timestamp as Timestamp16
7679
7542
  } from "firebase/firestore";
7680
7543
  import { geohashForLocation as geohashForLocation2 } from "geofire-common";
7681
- import { z as z20 } from "zod";
7544
+ import { z as z18 } from "zod";
7682
7545
 
7683
7546
  // src/services/clinic/utils/photos.utils.ts
7684
7547
  import {
@@ -7882,7 +7745,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
7882
7745
  });
7883
7746
  return groupData;
7884
7747
  } catch (error) {
7885
- if (error instanceof z20.ZodError) {
7748
+ if (error instanceof z18.ZodError) {
7886
7749
  console.error(
7887
7750
  "[CLINIC_GROUP] Zod validation error:",
7888
7751
  JSON.stringify(error.errors, null, 2)
@@ -8338,7 +8201,7 @@ import {
8338
8201
  import {
8339
8202
  geohashForLocation as geohashForLocation4
8340
8203
  } from "geofire-common";
8341
- import { z as z22 } from "zod";
8204
+ import { z as z20 } from "zod";
8342
8205
 
8343
8206
  // src/services/clinic/utils/clinic.utils.ts
8344
8207
  import {
@@ -8359,7 +8222,7 @@ import {
8359
8222
  distanceBetween as distanceBetween2,
8360
8223
  geohashQueryBounds
8361
8224
  } from "geofire-common";
8362
- import { z as z21 } from "zod";
8225
+ import { z as z19 } from "zod";
8363
8226
  async function getClinic(db, clinicId) {
8364
8227
  const docRef = doc14(db, CLINICS_COLLECTION, clinicId);
8365
8228
  const docSnap = await getDoc17(docRef);
@@ -9136,7 +8999,7 @@ var ClinicService = class extends BaseService {
9136
8999
  if (!savedClinic) throw new Error("Failed to retrieve created clinic");
9137
9000
  return savedClinic;
9138
9001
  } catch (error) {
9139
- if (error instanceof z22.ZodError) {
9002
+ if (error instanceof z20.ZodError) {
9140
9003
  throw new Error("Invalid clinic data: " + error.message);
9141
9004
  }
9142
9005
  console.error("Error creating clinic:", error);
@@ -9216,7 +9079,7 @@ var ClinicService = class extends BaseService {
9216
9079
  if (!updatedClinic) throw new Error("Failed to retrieve updated clinic");
9217
9080
  return updatedClinic;
9218
9081
  } catch (error) {
9219
- if (error instanceof z22.ZodError) {
9082
+ if (error instanceof z20.ZodError) {
9220
9083
  throw new Error("Invalid clinic update data: " + error.message);
9221
9084
  }
9222
9085
  console.error(`Error updating clinic ${clinicId}:`, error);
@@ -9379,6 +9242,125 @@ var ClinicService = class extends BaseService {
9379
9242
  }
9380
9243
  };
9381
9244
 
9245
+ // src/services/auth/utils/firebase.utils.ts
9246
+ import { fetchSignInMethodsForEmail } from "firebase/auth";
9247
+ var checkEmailExists = async (auth, email) => {
9248
+ try {
9249
+ const methods = await fetchSignInMethodsForEmail(auth, email);
9250
+ return methods.length > 0;
9251
+ } catch (error) {
9252
+ console.warn(
9253
+ "[FIREBASE] Could not check email existence, allowing signup to proceed:",
9254
+ error
9255
+ );
9256
+ return false;
9257
+ }
9258
+ };
9259
+ var cleanupFirebaseUser = async (firebaseUser) => {
9260
+ try {
9261
+ console.log("[FIREBASE] Cleaning up Firebase user", {
9262
+ uid: firebaseUser.uid
9263
+ });
9264
+ await firebaseUser.delete();
9265
+ console.log("[FIREBASE] Firebase user cleanup successful");
9266
+ } catch (cleanupError) {
9267
+ console.error("[FIREBASE] Failed to cleanup Firebase user:", cleanupError);
9268
+ }
9269
+ };
9270
+
9271
+ // src/services/auth/utils/error.utils.ts
9272
+ import { z as z21 } from "zod";
9273
+ var handleFirebaseError = (error) => {
9274
+ const firebaseError = error;
9275
+ switch (firebaseError.code) {
9276
+ case "auth/email-already-in-use" /* EMAIL_ALREADY_IN_USE */:
9277
+ return AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
9278
+ case "auth/weak-password":
9279
+ return new Error(
9280
+ "Password is too weak. Please choose a stronger password."
9281
+ );
9282
+ case "auth/invalid-email":
9283
+ return new Error("Please enter a valid email address.");
9284
+ case "auth/network-request-failed":
9285
+ return new Error(
9286
+ "Network error. Please check your internet connection and try again."
9287
+ );
9288
+ default:
9289
+ return new Error(
9290
+ `Account creation failed: ${firebaseError.message || "Unknown error"}`
9291
+ );
9292
+ }
9293
+ };
9294
+ var handleSignupError = (error) => {
9295
+ if (error instanceof z21.ZodError) {
9296
+ const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
9297
+ return new Error(`Validation failed: ${errorMessages}`);
9298
+ }
9299
+ if (error.code && error.code.startsWith("auth/")) {
9300
+ return handleFirebaseError(error);
9301
+ }
9302
+ if (error.message && error.message.includes("token")) {
9303
+ return new Error("Invalid or expired invitation token");
9304
+ }
9305
+ if (error.message && error.message.includes("validation")) {
9306
+ return new Error(`Invalid practitioner data: ${error.message}`);
9307
+ }
9308
+ return new Error(
9309
+ `Registration failed: ${error.message || "Unknown error occurred"}`
9310
+ );
9311
+ };
9312
+
9313
+ // src/services/auth/utils/practitioner.utils.ts
9314
+ import { z as z22 } from "zod";
9315
+ var profileDataSchema = z22.object({
9316
+ basicInfo: practitionerBasicInfoSchema.partial().optional(),
9317
+ certification: practitionerCertificationSchema.partial().optional()
9318
+ }).partial();
9319
+ var buildPractitionerData = (data, userRef) => {
9320
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
9321
+ const basicInfo = {
9322
+ firstName: data.firstName || "Name",
9323
+ lastName: data.lastName || "Surname",
9324
+ email: data.email,
9325
+ phoneNumber: ((_b = (_a = data.profileData) == null ? void 0 : _a.basicInfo) == null ? void 0 : _b.phoneNumber) || null,
9326
+ profileImageUrl: ((_d = (_c = data.profileData) == null ? void 0 : _c.basicInfo) == null ? void 0 : _d.profileImageUrl) || "",
9327
+ gender: ((_f = (_e = data.profileData) == null ? void 0 : _e.basicInfo) == null ? void 0 : _f.gender) || "other",
9328
+ bio: ((_h = (_g = data.profileData) == null ? void 0 : _g.basicInfo) == null ? void 0 : _h.bio) || "",
9329
+ title: "Practitioner",
9330
+ dateOfBirth: ((_j = (_i = data.profileData) == null ? void 0 : _i.basicInfo) == null ? void 0 : _j.dateOfBirth) || /* @__PURE__ */ new Date(),
9331
+ languages: ((_l = (_k = data.profileData) == null ? void 0 : _k.basicInfo) == null ? void 0 : _l.languages) || ["English"]
9332
+ };
9333
+ const certification = ((_m = data.profileData) == null ? void 0 : _m.certification) || {
9334
+ level: "aesthetician" /* AESTHETICIAN */,
9335
+ specialties: [],
9336
+ licenseNumber: "Pending",
9337
+ issuingAuthority: "Pending",
9338
+ issueDate: /* @__PURE__ */ new Date(),
9339
+ verificationStatus: "pending"
9340
+ };
9341
+ return {
9342
+ userRef,
9343
+ basicInfo,
9344
+ certification,
9345
+ status: "active" /* ACTIVE */,
9346
+ isActive: true,
9347
+ isVerified: false
9348
+ };
9349
+ };
9350
+ var validatePractitionerProfileData = async (profileData) => {
9351
+ try {
9352
+ await profileDataSchema.parseAsync(profileData);
9353
+ } catch (error) {
9354
+ if (error instanceof z22.ZodError) {
9355
+ const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
9356
+ throw new Error(
9357
+ `Practitioner profile validation failed: ${errorMessages}`
9358
+ );
9359
+ }
9360
+ throw error;
9361
+ }
9362
+ };
9363
+
9382
9364
  // src/services/auth/auth.service.ts
9383
9365
  var AuthService = class extends BaseService {
9384
9366
  constructor(db, auth, app, userService) {
@@ -17398,11 +17380,8 @@ export {
17398
17380
  beforeAfterPerZoneSchema,
17399
17381
  billingPerZoneSchema,
17400
17382
  blockingConditionSchema,
17401
- buildPractitionerData,
17402
17383
  calendarEventSchema,
17403
17384
  calendarEventTimeSchema,
17404
- checkEmailExists,
17405
- cleanupFirebaseUser,
17406
17385
  clinicAdminOptionsSchema,
17407
17386
  clinicAdminSchema,
17408
17387
  clinicAdminSignupSchema,
@@ -17450,7 +17429,6 @@ export {
17450
17429
  documentTemplateSchema,
17451
17430
  emailSchema,
17452
17431
  emergencyContactSchema,
17453
- extractErrorMessage,
17454
17432
  filledDocumentSchema,
17455
17433
  filledDocumentStatusSchema,
17456
17434
  finalBillingSchema,
@@ -17462,10 +17440,7 @@ export {
17462
17440
  getFirebaseFunctions,
17463
17441
  getFirebaseInstance,
17464
17442
  getFirebaseStorage,
17465
- handleFirebaseError,
17466
- handleSignupError,
17467
17443
  initializeFirebase,
17468
- isPractitionerDataComplete,
17469
17444
  linkedFormInfoSchema,
17470
17445
  locationDataSchema,
17471
17446
  mediaResourceSchema,
@@ -17537,7 +17512,6 @@ export {
17537
17512
  userRoleSchema,
17538
17513
  userRolesSchema,
17539
17514
  userSchema,
17540
- validatePractitionerProfileData,
17541
17515
  vitalStatsSchema,
17542
17516
  workingHoursSchema
17543
17517
  };