@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.d.mts +1 -67
- package/dist/index.d.ts +1 -67
- package/dist/index.js +1329 -1363
- package/dist/index.mjs +1115 -1141
- package/package.json +1 -1
- package/src/admin/calendar/README.md +7 -0
- package/src/services/auth/index.ts +1 -1
- package/src/services/calendar/index.ts +0 -1
package/dist/index.js
CHANGED
|
@@ -146,11 +146,8 @@ __export(index_exports, {
|
|
|
146
146
|
beforeAfterPerZoneSchema: () => beforeAfterPerZoneSchema,
|
|
147
147
|
billingPerZoneSchema: () => billingPerZoneSchema,
|
|
148
148
|
blockingConditionSchema: () => blockingConditionSchema,
|
|
149
|
-
buildPractitionerData: () => buildPractitionerData,
|
|
150
149
|
calendarEventSchema: () => calendarEventSchema,
|
|
151
150
|
calendarEventTimeSchema: () => calendarEventTimeSchema,
|
|
152
|
-
checkEmailExists: () => checkEmailExists,
|
|
153
|
-
cleanupFirebaseUser: () => cleanupFirebaseUser,
|
|
154
151
|
clinicAdminOptionsSchema: () => clinicAdminOptionsSchema,
|
|
155
152
|
clinicAdminSchema: () => clinicAdminSchema,
|
|
156
153
|
clinicAdminSignupSchema: () => clinicAdminSignupSchema,
|
|
@@ -198,7 +195,6 @@ __export(index_exports, {
|
|
|
198
195
|
documentTemplateSchema: () => documentTemplateSchema,
|
|
199
196
|
emailSchema: () => emailSchema,
|
|
200
197
|
emergencyContactSchema: () => emergencyContactSchema,
|
|
201
|
-
extractErrorMessage: () => extractErrorMessage,
|
|
202
198
|
filledDocumentSchema: () => filledDocumentSchema,
|
|
203
199
|
filledDocumentStatusSchema: () => filledDocumentStatusSchema,
|
|
204
200
|
finalBillingSchema: () => finalBillingSchema,
|
|
@@ -210,10 +206,7 @@ __export(index_exports, {
|
|
|
210
206
|
getFirebaseFunctions: () => getFirebaseFunctions,
|
|
211
207
|
getFirebaseInstance: () => getFirebaseInstance,
|
|
212
208
|
getFirebaseStorage: () => getFirebaseStorage,
|
|
213
|
-
handleFirebaseError: () => handleFirebaseError,
|
|
214
|
-
handleSignupError: () => handleSignupError,
|
|
215
209
|
initializeFirebase: () => initializeFirebase,
|
|
216
|
-
isPractitionerDataComplete: () => isPractitionerDataComplete,
|
|
217
210
|
linkedFormInfoSchema: () => linkedFormInfoSchema,
|
|
218
211
|
locationDataSchema: () => locationDataSchema,
|
|
219
212
|
mediaResourceSchema: () => mediaResourceSchema,
|
|
@@ -285,7 +278,6 @@ __export(index_exports, {
|
|
|
285
278
|
userRoleSchema: () => userRoleSchema,
|
|
286
279
|
userRolesSchema: () => userRolesSchema,
|
|
287
280
|
userSchema: () => userSchema,
|
|
288
|
-
validatePractitionerProfileData: () => validatePractitionerProfileData,
|
|
289
281
|
vitalStatsSchema: () => vitalStatsSchema,
|
|
290
282
|
workingHoursSchema: () => workingHoursSchema
|
|
291
283
|
});
|
|
@@ -2145,685 +2137,6 @@ var AppointmentService = class extends BaseService {
|
|
|
2145
2137
|
}
|
|
2146
2138
|
};
|
|
2147
2139
|
|
|
2148
|
-
// src/services/auth/utils/firebase.utils.ts
|
|
2149
|
-
var import_auth = require("firebase/auth");
|
|
2150
|
-
var checkEmailExists = async (auth, email) => {
|
|
2151
|
-
try {
|
|
2152
|
-
const methods = await (0, import_auth.fetchSignInMethodsForEmail)(auth, email);
|
|
2153
|
-
return methods.length > 0;
|
|
2154
|
-
} catch (error) {
|
|
2155
|
-
console.warn(
|
|
2156
|
-
"[FIREBASE] Could not check email existence, allowing signup to proceed:",
|
|
2157
|
-
error
|
|
2158
|
-
);
|
|
2159
|
-
return false;
|
|
2160
|
-
}
|
|
2161
|
-
};
|
|
2162
|
-
var cleanupFirebaseUser = async (firebaseUser) => {
|
|
2163
|
-
try {
|
|
2164
|
-
console.log("[FIREBASE] Cleaning up Firebase user", {
|
|
2165
|
-
uid: firebaseUser.uid
|
|
2166
|
-
});
|
|
2167
|
-
await firebaseUser.delete();
|
|
2168
|
-
console.log("[FIREBASE] Firebase user cleanup successful");
|
|
2169
|
-
} catch (cleanupError) {
|
|
2170
|
-
console.error("[FIREBASE] Failed to cleanup Firebase user:", cleanupError);
|
|
2171
|
-
}
|
|
2172
|
-
};
|
|
2173
|
-
|
|
2174
|
-
// src/services/auth/utils/error.utils.ts
|
|
2175
|
-
var import_zod4 = require("zod");
|
|
2176
|
-
|
|
2177
|
-
// src/errors/auth.errors.ts
|
|
2178
|
-
var AuthError = class extends Error {
|
|
2179
|
-
constructor(message, code, status = 400) {
|
|
2180
|
-
super(message);
|
|
2181
|
-
this.code = code;
|
|
2182
|
-
this.status = status;
|
|
2183
|
-
this.name = "AuthError";
|
|
2184
|
-
}
|
|
2185
|
-
};
|
|
2186
|
-
var AUTH_ERRORS = {
|
|
2187
|
-
// Basic validation errors
|
|
2188
|
-
INVALID_EMAIL: new AuthError(
|
|
2189
|
-
"Email address is not in a valid format",
|
|
2190
|
-
"AUTH/INVALID_EMAIL",
|
|
2191
|
-
400
|
|
2192
|
-
),
|
|
2193
|
-
INVALID_PASSWORD: new AuthError(
|
|
2194
|
-
"Password must contain at least 8 characters, one uppercase letter, one number, and one special character",
|
|
2195
|
-
"AUTH/INVALID_PASSWORD",
|
|
2196
|
-
400
|
|
2197
|
-
),
|
|
2198
|
-
INVALID_ROLE: new AuthError(
|
|
2199
|
-
"Specified user role is not valid",
|
|
2200
|
-
"AUTH/INVALID_ROLE",
|
|
2201
|
-
400
|
|
2202
|
-
),
|
|
2203
|
-
// Authentication errors
|
|
2204
|
-
NOT_AUTHENTICATED: new AuthError(
|
|
2205
|
-
"User is not authenticated",
|
|
2206
|
-
"AUTH/NOT_AUTHENTICATED",
|
|
2207
|
-
401
|
|
2208
|
-
),
|
|
2209
|
-
SESSION_EXPIRED: new AuthError(
|
|
2210
|
-
"Your session has expired. Please sign in again",
|
|
2211
|
-
"AUTH/SESSION_EXPIRED",
|
|
2212
|
-
401
|
|
2213
|
-
),
|
|
2214
|
-
INVALID_TOKEN: new AuthError(
|
|
2215
|
-
"Invalid authentication token",
|
|
2216
|
-
"AUTH/INVALID_TOKEN",
|
|
2217
|
-
401
|
|
2218
|
-
),
|
|
2219
|
-
// User state errors
|
|
2220
|
-
USER_NOT_FOUND: new AuthError(
|
|
2221
|
-
"User not found in the system",
|
|
2222
|
-
"AUTH/USER_NOT_FOUND",
|
|
2223
|
-
404
|
|
2224
|
-
),
|
|
2225
|
-
EMAIL_ALREADY_EXISTS: new AuthError(
|
|
2226
|
-
"An account with this email already exists",
|
|
2227
|
-
"AUTH/EMAIL_EXISTS",
|
|
2228
|
-
409
|
|
2229
|
-
),
|
|
2230
|
-
USER_DISABLED: new AuthError(
|
|
2231
|
-
"This account has been disabled",
|
|
2232
|
-
"AUTH/USER_DISABLED",
|
|
2233
|
-
403
|
|
2234
|
-
),
|
|
2235
|
-
// Rate limiting and security
|
|
2236
|
-
TOO_MANY_REQUESTS: new AuthError(
|
|
2237
|
-
"Too many login attempts. Please try again later",
|
|
2238
|
-
"AUTH/TOO_MANY_REQUESTS",
|
|
2239
|
-
429
|
|
2240
|
-
),
|
|
2241
|
-
ACCOUNT_LOCKED: new AuthError(
|
|
2242
|
-
"Account temporarily locked due to too many failed login attempts",
|
|
2243
|
-
"AUTH/ACCOUNT_LOCKED",
|
|
2244
|
-
403
|
|
2245
|
-
),
|
|
2246
|
-
// Social auth specific
|
|
2247
|
-
POPUP_CLOSED: new AuthError(
|
|
2248
|
-
"Authentication popup was closed before completion",
|
|
2249
|
-
"AUTH/POPUP_CLOSED",
|
|
2250
|
-
400
|
|
2251
|
-
),
|
|
2252
|
-
POPUP_BLOCKED: new AuthError(
|
|
2253
|
-
"Authentication popup was blocked by the browser",
|
|
2254
|
-
"AUTH/POPUP_BLOCKED",
|
|
2255
|
-
400
|
|
2256
|
-
),
|
|
2257
|
-
ACCOUNT_EXISTS: new AuthError(
|
|
2258
|
-
"An account already exists with different credentials",
|
|
2259
|
-
"AUTH/ACCOUNT_EXISTS",
|
|
2260
|
-
409
|
|
2261
|
-
),
|
|
2262
|
-
// Anonymous auth specific
|
|
2263
|
-
NOT_ANONYMOUS: new AuthError(
|
|
2264
|
-
"Current user is not anonymous",
|
|
2265
|
-
"AUTH/NOT_ANONYMOUS_USER",
|
|
2266
|
-
400
|
|
2267
|
-
),
|
|
2268
|
-
ANONYMOUS_UPGRADE_FAILED: new AuthError(
|
|
2269
|
-
"Failed to upgrade anonymous account",
|
|
2270
|
-
"AUTH/ANONYMOUS_UPGRADE_FAILED",
|
|
2271
|
-
400
|
|
2272
|
-
),
|
|
2273
|
-
// General errors
|
|
2274
|
-
VALIDATION_ERROR: new AuthError(
|
|
2275
|
-
"Data validation error occurred",
|
|
2276
|
-
"AUTH/VALIDATION_ERROR",
|
|
2277
|
-
400
|
|
2278
|
-
),
|
|
2279
|
-
OPERATION_NOT_ALLOWED: new AuthError(
|
|
2280
|
-
"This operation is not allowed",
|
|
2281
|
-
"AUTH/OPERATION_NOT_ALLOWED",
|
|
2282
|
-
403
|
|
2283
|
-
),
|
|
2284
|
-
NETWORK_ERROR: new AuthError(
|
|
2285
|
-
"Network error occurred. Please check your connection",
|
|
2286
|
-
"AUTH/NETWORK_ERROR",
|
|
2287
|
-
503
|
|
2288
|
-
),
|
|
2289
|
-
REQUIRES_RECENT_LOGIN: new AuthError(
|
|
2290
|
-
"This operation requires recent authentication. Please sign in again",
|
|
2291
|
-
"AUTH/REQUIRES_RECENT_LOGIN",
|
|
2292
|
-
401
|
|
2293
|
-
),
|
|
2294
|
-
INVALID_PROVIDER: new AuthError(
|
|
2295
|
-
"Invalid authentication provider",
|
|
2296
|
-
"AUTH/INVALID_PROVIDER",
|
|
2297
|
-
400
|
|
2298
|
-
),
|
|
2299
|
-
INVALID_CREDENTIAL: new AuthError(
|
|
2300
|
-
"The provided credentials are invalid or expired",
|
|
2301
|
-
"AUTH/INVALID_CREDENTIAL",
|
|
2302
|
-
401
|
|
2303
|
-
),
|
|
2304
|
-
// Resource not found
|
|
2305
|
-
NOT_FOUND: new AuthError(
|
|
2306
|
-
"The requested resource was not found",
|
|
2307
|
-
"AUTH/NOT_FOUND",
|
|
2308
|
-
404
|
|
2309
|
-
),
|
|
2310
|
-
// Detailed password validation errors
|
|
2311
|
-
PASSWORD_LENGTH_ERROR: new AuthError(
|
|
2312
|
-
"Password must be at least 8 characters long",
|
|
2313
|
-
"AUTH/PASSWORD_LENGTH_ERROR",
|
|
2314
|
-
400
|
|
2315
|
-
),
|
|
2316
|
-
PASSWORD_UPPERCASE_ERROR: new AuthError(
|
|
2317
|
-
"Password must contain at least one uppercase letter",
|
|
2318
|
-
"AUTH/PASSWORD_UPPERCASE_ERROR",
|
|
2319
|
-
400
|
|
2320
|
-
),
|
|
2321
|
-
PASSWORD_NUMBER_ERROR: new AuthError(
|
|
2322
|
-
"Password must contain at least one number",
|
|
2323
|
-
"AUTH/PASSWORD_NUMBER_ERROR",
|
|
2324
|
-
400
|
|
2325
|
-
),
|
|
2326
|
-
PASSWORD_SPECIAL_CHAR_ERROR: new AuthError(
|
|
2327
|
-
"Password must contain at least one special character",
|
|
2328
|
-
"AUTH/PASSWORD_SPECIAL_CHAR_ERROR",
|
|
2329
|
-
400
|
|
2330
|
-
),
|
|
2331
|
-
// Detailed email validation errors
|
|
2332
|
-
EMAIL_FORMAT_ERROR: new AuthError(
|
|
2333
|
-
"Invalid email format. Please enter a valid email address",
|
|
2334
|
-
"AUTH/EMAIL_FORMAT_ERROR",
|
|
2335
|
-
400
|
|
2336
|
-
),
|
|
2337
|
-
PASSWORD_VALIDATION_ERROR: new AuthError(
|
|
2338
|
-
"Password validation failed. Please check all requirements",
|
|
2339
|
-
"AUTH/PASSWORD_VALIDATION_ERROR",
|
|
2340
|
-
400
|
|
2341
|
-
),
|
|
2342
|
-
// Password reset specific errors
|
|
2343
|
-
EXPIRED_ACTION_CODE: new AuthError(
|
|
2344
|
-
"Kod za resetovanje lozinke je istekao. Molimo zatra\u017Eite novi link za resetovanje.",
|
|
2345
|
-
"AUTH/EXPIRED_ACTION_CODE",
|
|
2346
|
-
400
|
|
2347
|
-
),
|
|
2348
|
-
INVALID_ACTION_CODE: new AuthError(
|
|
2349
|
-
"Kod za resetovanje lozinke je neva\u017Ee\u0107i ili je ve\u0107 iskori\u0161\u0107en. Molimo zatra\u017Eite novi link za resetovanje.",
|
|
2350
|
-
"AUTH/INVALID_ACTION_CODE",
|
|
2351
|
-
400
|
|
2352
|
-
),
|
|
2353
|
-
WEAK_PASSWORD: new AuthError(
|
|
2354
|
-
"Lozinka je previ\u0161e slaba. Molimo koristite ja\u010Du lozinku.",
|
|
2355
|
-
"AUTH/WEAK_PASSWORD",
|
|
2356
|
-
400
|
|
2357
|
-
)
|
|
2358
|
-
};
|
|
2359
|
-
|
|
2360
|
-
// src/services/auth/utils/error.utils.ts
|
|
2361
|
-
var handleFirebaseError = (error) => {
|
|
2362
|
-
const firebaseError = error;
|
|
2363
|
-
switch (firebaseError.code) {
|
|
2364
|
-
case "auth/email-already-in-use" /* EMAIL_ALREADY_IN_USE */:
|
|
2365
|
-
return AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
|
|
2366
|
-
case "auth/weak-password":
|
|
2367
|
-
return new Error(
|
|
2368
|
-
"Password is too weak. Please choose a stronger password."
|
|
2369
|
-
);
|
|
2370
|
-
case "auth/invalid-email":
|
|
2371
|
-
return new Error("Please enter a valid email address.");
|
|
2372
|
-
case "auth/network-request-failed":
|
|
2373
|
-
return new Error(
|
|
2374
|
-
"Network error. Please check your internet connection and try again."
|
|
2375
|
-
);
|
|
2376
|
-
default:
|
|
2377
|
-
return new Error(
|
|
2378
|
-
`Account creation failed: ${firebaseError.message || "Unknown error"}`
|
|
2379
|
-
);
|
|
2380
|
-
}
|
|
2381
|
-
};
|
|
2382
|
-
var handleSignupError = (error) => {
|
|
2383
|
-
if (error instanceof import_zod4.z.ZodError) {
|
|
2384
|
-
const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
|
|
2385
|
-
return new Error(`Validation failed: ${errorMessages}`);
|
|
2386
|
-
}
|
|
2387
|
-
if (error.code && error.code.startsWith("auth/")) {
|
|
2388
|
-
return handleFirebaseError(error);
|
|
2389
|
-
}
|
|
2390
|
-
if (error.message && error.message.includes("token")) {
|
|
2391
|
-
return new Error("Invalid or expired invitation token");
|
|
2392
|
-
}
|
|
2393
|
-
if (error.message && error.message.includes("validation")) {
|
|
2394
|
-
return new Error(`Invalid practitioner data: ${error.message}`);
|
|
2395
|
-
}
|
|
2396
|
-
return new Error(
|
|
2397
|
-
`Registration failed: ${error.message || "Unknown error occurred"}`
|
|
2398
|
-
);
|
|
2399
|
-
};
|
|
2400
|
-
var extractErrorMessage = (error) => {
|
|
2401
|
-
if (error instanceof Error) {
|
|
2402
|
-
return error.message;
|
|
2403
|
-
}
|
|
2404
|
-
if (typeof error === "string") {
|
|
2405
|
-
return error;
|
|
2406
|
-
}
|
|
2407
|
-
if (error == null ? void 0 : error.message) {
|
|
2408
|
-
return error.message;
|
|
2409
|
-
}
|
|
2410
|
-
return "Unknown error occurred";
|
|
2411
|
-
};
|
|
2412
|
-
|
|
2413
|
-
// src/backoffice/types/static/certification.types.ts
|
|
2414
|
-
var CertificationLevel = /* @__PURE__ */ ((CertificationLevel2) => {
|
|
2415
|
-
CertificationLevel2["AESTHETICIAN"] = "aesthetician";
|
|
2416
|
-
CertificationLevel2["NURSE_ASSISTANT"] = "nurse_assistant";
|
|
2417
|
-
CertificationLevel2["NURSE"] = "nurse";
|
|
2418
|
-
CertificationLevel2["NURSE_PRACTITIONER"] = "nurse_practitioner";
|
|
2419
|
-
CertificationLevel2["PHYSICIAN_ASSISTANT"] = "physician_assistant";
|
|
2420
|
-
CertificationLevel2["DOCTOR"] = "doctor";
|
|
2421
|
-
CertificationLevel2["SPECIALIST"] = "specialist";
|
|
2422
|
-
CertificationLevel2["PLASTIC_SURGEON"] = "plastic_surgeon";
|
|
2423
|
-
return CertificationLevel2;
|
|
2424
|
-
})(CertificationLevel || {});
|
|
2425
|
-
var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
|
|
2426
|
-
CertificationSpecialty3["LASER"] = "laser";
|
|
2427
|
-
CertificationSpecialty3["INJECTABLES"] = "injectables";
|
|
2428
|
-
CertificationSpecialty3["CHEMICAL_PEELS"] = "chemical_peels";
|
|
2429
|
-
CertificationSpecialty3["MICRODERMABRASION"] = "microdermabrasion";
|
|
2430
|
-
CertificationSpecialty3["BODY_CONTOURING"] = "body_contouring";
|
|
2431
|
-
CertificationSpecialty3["SKIN_CARE"] = "skin_care";
|
|
2432
|
-
CertificationSpecialty3["WOUND_CARE"] = "wound_care";
|
|
2433
|
-
CertificationSpecialty3["ANESTHESIA"] = "anesthesia";
|
|
2434
|
-
return CertificationSpecialty3;
|
|
2435
|
-
})(CertificationSpecialty || {});
|
|
2436
|
-
|
|
2437
|
-
// src/services/auth/utils/practitioner.utils.ts
|
|
2438
|
-
var import_zod8 = require("zod");
|
|
2439
|
-
|
|
2440
|
-
// src/validations/practitioner.schema.ts
|
|
2441
|
-
var import_zod7 = require("zod");
|
|
2442
|
-
var import_firestore3 = require("firebase/firestore");
|
|
2443
|
-
|
|
2444
|
-
// src/validations/reviews.schema.ts
|
|
2445
|
-
var import_zod5 = require("zod");
|
|
2446
|
-
var baseReviewSchema = import_zod5.z.object({
|
|
2447
|
-
id: import_zod5.z.string().min(1),
|
|
2448
|
-
patientId: import_zod5.z.string().min(1),
|
|
2449
|
-
fullReviewId: import_zod5.z.string().min(1),
|
|
2450
|
-
createdAt: import_zod5.z.date(),
|
|
2451
|
-
updatedAt: import_zod5.z.date(),
|
|
2452
|
-
comment: import_zod5.z.string().min(1).max(2e3),
|
|
2453
|
-
isVerified: import_zod5.z.boolean(),
|
|
2454
|
-
isPublished: import_zod5.z.boolean()
|
|
2455
|
-
});
|
|
2456
|
-
var baseReviewCreateSchema = import_zod5.z.object({
|
|
2457
|
-
patientId: import_zod5.z.string().min(1),
|
|
2458
|
-
comment: import_zod5.z.string().min(1).max(2e3),
|
|
2459
|
-
isVerified: import_zod5.z.boolean().default(false),
|
|
2460
|
-
isPublished: import_zod5.z.boolean().default(true)
|
|
2461
|
-
});
|
|
2462
|
-
var clinicReviewSchema = baseReviewSchema.extend({
|
|
2463
|
-
clinicId: import_zod5.z.string().min(1),
|
|
2464
|
-
cleanliness: import_zod5.z.number().min(1).max(5),
|
|
2465
|
-
facilities: import_zod5.z.number().min(1).max(5),
|
|
2466
|
-
staffFriendliness: import_zod5.z.number().min(1).max(5),
|
|
2467
|
-
waitingTime: import_zod5.z.number().min(1).max(5),
|
|
2468
|
-
accessibility: import_zod5.z.number().min(1).max(5),
|
|
2469
|
-
overallRating: import_zod5.z.number().min(1).max(5),
|
|
2470
|
-
wouldRecommend: import_zod5.z.boolean()
|
|
2471
|
-
});
|
|
2472
|
-
var createClinicReviewSchema = baseReviewCreateSchema.extend({
|
|
2473
|
-
clinicId: import_zod5.z.string().min(1),
|
|
2474
|
-
cleanliness: import_zod5.z.number().min(1).max(5),
|
|
2475
|
-
facilities: import_zod5.z.number().min(1).max(5),
|
|
2476
|
-
staffFriendliness: import_zod5.z.number().min(1).max(5),
|
|
2477
|
-
waitingTime: import_zod5.z.number().min(1).max(5),
|
|
2478
|
-
accessibility: import_zod5.z.number().min(1).max(5),
|
|
2479
|
-
wouldRecommend: import_zod5.z.boolean()
|
|
2480
|
-
});
|
|
2481
|
-
var practitionerReviewSchema = baseReviewSchema.extend({
|
|
2482
|
-
practitionerId: import_zod5.z.string().min(1),
|
|
2483
|
-
knowledgeAndExpertise: import_zod5.z.number().min(1).max(5),
|
|
2484
|
-
communicationSkills: import_zod5.z.number().min(1).max(5),
|
|
2485
|
-
bedSideManner: import_zod5.z.number().min(1).max(5),
|
|
2486
|
-
thoroughness: import_zod5.z.number().min(1).max(5),
|
|
2487
|
-
trustworthiness: import_zod5.z.number().min(1).max(5),
|
|
2488
|
-
overallRating: import_zod5.z.number().min(1).max(5),
|
|
2489
|
-
wouldRecommend: import_zod5.z.boolean()
|
|
2490
|
-
});
|
|
2491
|
-
var createPractitionerReviewSchema = baseReviewCreateSchema.extend({
|
|
2492
|
-
practitionerId: import_zod5.z.string().min(1),
|
|
2493
|
-
knowledgeAndExpertise: import_zod5.z.number().min(1).max(5),
|
|
2494
|
-
communicationSkills: import_zod5.z.number().min(1).max(5),
|
|
2495
|
-
bedSideManner: import_zod5.z.number().min(1).max(5),
|
|
2496
|
-
thoroughness: import_zod5.z.number().min(1).max(5),
|
|
2497
|
-
trustworthiness: import_zod5.z.number().min(1).max(5),
|
|
2498
|
-
wouldRecommend: import_zod5.z.boolean()
|
|
2499
|
-
});
|
|
2500
|
-
var procedureReviewSchema = baseReviewSchema.extend({
|
|
2501
|
-
procedureId: import_zod5.z.string().min(1),
|
|
2502
|
-
effectivenessOfTreatment: import_zod5.z.number().min(1).max(5),
|
|
2503
|
-
outcomeExplanation: import_zod5.z.number().min(1).max(5),
|
|
2504
|
-
painManagement: import_zod5.z.number().min(1).max(5),
|
|
2505
|
-
followUpCare: import_zod5.z.number().min(1).max(5),
|
|
2506
|
-
valueForMoney: import_zod5.z.number().min(1).max(5),
|
|
2507
|
-
overallRating: import_zod5.z.number().min(1).max(5),
|
|
2508
|
-
wouldRecommend: import_zod5.z.boolean()
|
|
2509
|
-
});
|
|
2510
|
-
var createProcedureReviewSchema = baseReviewCreateSchema.extend({
|
|
2511
|
-
procedureId: import_zod5.z.string().min(1),
|
|
2512
|
-
effectivenessOfTreatment: import_zod5.z.number().min(1).max(5),
|
|
2513
|
-
outcomeExplanation: import_zod5.z.number().min(1).max(5),
|
|
2514
|
-
painManagement: import_zod5.z.number().min(1).max(5),
|
|
2515
|
-
followUpCare: import_zod5.z.number().min(1).max(5),
|
|
2516
|
-
valueForMoney: import_zod5.z.number().min(1).max(5),
|
|
2517
|
-
wouldRecommend: import_zod5.z.boolean()
|
|
2518
|
-
});
|
|
2519
|
-
var clinicReviewInfoSchema = import_zod5.z.object({
|
|
2520
|
-
totalReviews: import_zod5.z.number().min(0),
|
|
2521
|
-
averageRating: import_zod5.z.number().min(0).max(5),
|
|
2522
|
-
cleanliness: import_zod5.z.number().min(0).max(5),
|
|
2523
|
-
facilities: import_zod5.z.number().min(0).max(5),
|
|
2524
|
-
staffFriendliness: import_zod5.z.number().min(0).max(5),
|
|
2525
|
-
waitingTime: import_zod5.z.number().min(0).max(5),
|
|
2526
|
-
accessibility: import_zod5.z.number().min(0).max(5),
|
|
2527
|
-
recommendationPercentage: import_zod5.z.number().min(0).max(100)
|
|
2528
|
-
});
|
|
2529
|
-
var practitionerReviewInfoSchema = import_zod5.z.object({
|
|
2530
|
-
totalReviews: import_zod5.z.number().min(0),
|
|
2531
|
-
averageRating: import_zod5.z.number().min(0).max(5),
|
|
2532
|
-
knowledgeAndExpertise: import_zod5.z.number().min(0).max(5),
|
|
2533
|
-
communicationSkills: import_zod5.z.number().min(0).max(5),
|
|
2534
|
-
bedSideManner: import_zod5.z.number().min(0).max(5),
|
|
2535
|
-
thoroughness: import_zod5.z.number().min(0).max(5),
|
|
2536
|
-
trustworthiness: import_zod5.z.number().min(0).max(5),
|
|
2537
|
-
recommendationPercentage: import_zod5.z.number().min(0).max(100)
|
|
2538
|
-
});
|
|
2539
|
-
var procedureReviewInfoSchema = import_zod5.z.object({
|
|
2540
|
-
totalReviews: import_zod5.z.number().min(0),
|
|
2541
|
-
averageRating: import_zod5.z.number().min(0).max(5),
|
|
2542
|
-
effectivenessOfTreatment: import_zod5.z.number().min(0).max(5),
|
|
2543
|
-
outcomeExplanation: import_zod5.z.number().min(0).max(5),
|
|
2544
|
-
painManagement: import_zod5.z.number().min(0).max(5),
|
|
2545
|
-
followUpCare: import_zod5.z.number().min(0).max(5),
|
|
2546
|
-
valueForMoney: import_zod5.z.number().min(0).max(5),
|
|
2547
|
-
recommendationPercentage: import_zod5.z.number().min(0).max(100)
|
|
2548
|
-
});
|
|
2549
|
-
var reviewSchema = import_zod5.z.object({
|
|
2550
|
-
id: import_zod5.z.string().min(1),
|
|
2551
|
-
appointmentId: import_zod5.z.string().min(1),
|
|
2552
|
-
patientId: import_zod5.z.string().min(1),
|
|
2553
|
-
createdAt: import_zod5.z.date(),
|
|
2554
|
-
updatedAt: import_zod5.z.date(),
|
|
2555
|
-
clinicReview: clinicReviewSchema.optional(),
|
|
2556
|
-
practitionerReview: practitionerReviewSchema.optional(),
|
|
2557
|
-
procedureReview: procedureReviewSchema.optional(),
|
|
2558
|
-
overallComment: import_zod5.z.string().min(1).max(2e3),
|
|
2559
|
-
overallRating: import_zod5.z.number().min(1).max(5)
|
|
2560
|
-
});
|
|
2561
|
-
var createReviewSchema = import_zod5.z.object({
|
|
2562
|
-
patientId: import_zod5.z.string().min(1),
|
|
2563
|
-
clinicReview: createClinicReviewSchema.optional(),
|
|
2564
|
-
practitionerReview: createPractitionerReviewSchema.optional(),
|
|
2565
|
-
procedureReview: createProcedureReviewSchema.optional(),
|
|
2566
|
-
overallComment: import_zod5.z.string().min(1).max(2e3)
|
|
2567
|
-
}).refine(
|
|
2568
|
-
(data) => {
|
|
2569
|
-
return data.clinicReview || data.practitionerReview || data.procedureReview;
|
|
2570
|
-
},
|
|
2571
|
-
{
|
|
2572
|
-
message: "At least one review type (clinic, practitioner, or procedure) must be provided",
|
|
2573
|
-
path: ["reviewType"]
|
|
2574
|
-
}
|
|
2575
|
-
);
|
|
2576
|
-
|
|
2577
|
-
// src/validations/shared.schema.ts
|
|
2578
|
-
var import_zod6 = require("zod");
|
|
2579
|
-
|
|
2580
|
-
// src/backoffice/types/static/procedure-family.types.ts
|
|
2581
|
-
var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
|
|
2582
|
-
ProcedureFamily2["AESTHETICS"] = "aesthetics";
|
|
2583
|
-
ProcedureFamily2["SURGERY"] = "surgery";
|
|
2584
|
-
return ProcedureFamily2;
|
|
2585
|
-
})(ProcedureFamily || {});
|
|
2586
|
-
|
|
2587
|
-
// src/validations/shared.schema.ts
|
|
2588
|
-
var sharedClinicContactInfoSchema = import_zod6.z.object({
|
|
2589
|
-
email: import_zod6.z.string().email(),
|
|
2590
|
-
phoneNumber: import_zod6.z.string(),
|
|
2591
|
-
alternativePhoneNumber: import_zod6.z.string().nullable().optional(),
|
|
2592
|
-
website: import_zod6.z.string().nullable().optional()
|
|
2593
|
-
});
|
|
2594
|
-
var sharedClinicLocationSchema = import_zod6.z.object({
|
|
2595
|
-
address: import_zod6.z.string(),
|
|
2596
|
-
city: import_zod6.z.string(),
|
|
2597
|
-
country: import_zod6.z.string(),
|
|
2598
|
-
postalCode: import_zod6.z.string(),
|
|
2599
|
-
latitude: import_zod6.z.number().min(-90).max(90),
|
|
2600
|
-
longitude: import_zod6.z.number().min(-180).max(180),
|
|
2601
|
-
geohash: import_zod6.z.string().nullable().optional()
|
|
2602
|
-
});
|
|
2603
|
-
var procedureSummaryInfoSchema = import_zod6.z.object({
|
|
2604
|
-
id: import_zod6.z.string().min(1),
|
|
2605
|
-
name: import_zod6.z.string().min(1),
|
|
2606
|
-
description: import_zod6.z.string().optional(),
|
|
2607
|
-
photo: import_zod6.z.string().optional(),
|
|
2608
|
-
family: import_zod6.z.nativeEnum(ProcedureFamily),
|
|
2609
|
-
categoryName: import_zod6.z.string(),
|
|
2610
|
-
subcategoryName: import_zod6.z.string(),
|
|
2611
|
-
technologyName: import_zod6.z.string(),
|
|
2612
|
-
price: import_zod6.z.number().nonnegative(),
|
|
2613
|
-
pricingMeasure: import_zod6.z.nativeEnum(PricingMeasure),
|
|
2614
|
-
currency: import_zod6.z.nativeEnum(Currency),
|
|
2615
|
-
duration: import_zod6.z.number().int().positive(),
|
|
2616
|
-
clinicId: import_zod6.z.string().min(1),
|
|
2617
|
-
clinicName: import_zod6.z.string().min(1),
|
|
2618
|
-
practitionerId: import_zod6.z.string().min(1),
|
|
2619
|
-
practitionerName: import_zod6.z.string().min(1)
|
|
2620
|
-
});
|
|
2621
|
-
var clinicInfoSchema = import_zod6.z.object({
|
|
2622
|
-
id: import_zod6.z.string(),
|
|
2623
|
-
featuredPhoto: import_zod6.z.string(),
|
|
2624
|
-
name: import_zod6.z.string(),
|
|
2625
|
-
description: import_zod6.z.string().nullable().optional(),
|
|
2626
|
-
location: sharedClinicLocationSchema,
|
|
2627
|
-
contactInfo: sharedClinicContactInfoSchema
|
|
2628
|
-
});
|
|
2629
|
-
var doctorInfoSchema = import_zod6.z.object({
|
|
2630
|
-
id: import_zod6.z.string(),
|
|
2631
|
-
name: import_zod6.z.string(),
|
|
2632
|
-
description: import_zod6.z.string().nullable().optional(),
|
|
2633
|
-
photo: import_zod6.z.string(),
|
|
2634
|
-
rating: import_zod6.z.number().min(0).max(5),
|
|
2635
|
-
services: import_zod6.z.array(import_zod6.z.string())
|
|
2636
|
-
// List of procedure IDs practitioner offers
|
|
2637
|
-
});
|
|
2638
|
-
|
|
2639
|
-
// src/validations/practitioner.schema.ts
|
|
2640
|
-
var practitionerBasicInfoSchema = import_zod7.z.object({
|
|
2641
|
-
firstName: import_zod7.z.string().min(2).max(50),
|
|
2642
|
-
lastName: import_zod7.z.string().min(2).max(50),
|
|
2643
|
-
title: import_zod7.z.string().min(2).max(100),
|
|
2644
|
-
email: import_zod7.z.string().email(),
|
|
2645
|
-
phoneNumber: import_zod7.z.string().regex(/^\+?[1-9]\d{1,14}$/, "Invalid phone number").nullable(),
|
|
2646
|
-
dateOfBirth: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date()).nullable(),
|
|
2647
|
-
gender: import_zod7.z.enum(["male", "female", "other"]),
|
|
2648
|
-
profileImageUrl: mediaResourceSchema.optional().nullable(),
|
|
2649
|
-
bio: import_zod7.z.string().max(1e3).optional(),
|
|
2650
|
-
languages: import_zod7.z.array(import_zod7.z.string()).min(1)
|
|
2651
|
-
});
|
|
2652
|
-
var practitionerCertificationSchema = import_zod7.z.object({
|
|
2653
|
-
level: import_zod7.z.nativeEnum(CertificationLevel),
|
|
2654
|
-
specialties: import_zod7.z.array(import_zod7.z.nativeEnum(CertificationSpecialty)),
|
|
2655
|
-
licenseNumber: import_zod7.z.string().min(3).max(50),
|
|
2656
|
-
issuingAuthority: import_zod7.z.string().min(2).max(100),
|
|
2657
|
-
issueDate: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date()),
|
|
2658
|
-
expiryDate: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date()).optional().nullable(),
|
|
2659
|
-
verificationStatus: import_zod7.z.enum(["pending", "verified", "rejected"])
|
|
2660
|
-
});
|
|
2661
|
-
var timeSlotSchema = import_zod7.z.object({
|
|
2662
|
-
start: import_zod7.z.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format"),
|
|
2663
|
-
end: import_zod7.z.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format")
|
|
2664
|
-
}).nullable();
|
|
2665
|
-
var practitionerWorkingHoursSchema = import_zod7.z.object({
|
|
2666
|
-
practitionerId: import_zod7.z.string().min(1),
|
|
2667
|
-
clinicId: import_zod7.z.string().min(1),
|
|
2668
|
-
monday: timeSlotSchema,
|
|
2669
|
-
tuesday: timeSlotSchema,
|
|
2670
|
-
wednesday: timeSlotSchema,
|
|
2671
|
-
thursday: timeSlotSchema,
|
|
2672
|
-
friday: timeSlotSchema,
|
|
2673
|
-
saturday: timeSlotSchema,
|
|
2674
|
-
sunday: timeSlotSchema,
|
|
2675
|
-
createdAt: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date()),
|
|
2676
|
-
updatedAt: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date())
|
|
2677
|
-
});
|
|
2678
|
-
var practitionerClinicWorkingHoursSchema = import_zod7.z.object({
|
|
2679
|
-
clinicId: import_zod7.z.string().min(1),
|
|
2680
|
-
workingHours: import_zod7.z.object({
|
|
2681
|
-
monday: timeSlotSchema,
|
|
2682
|
-
tuesday: timeSlotSchema,
|
|
2683
|
-
wednesday: timeSlotSchema,
|
|
2684
|
-
thursday: timeSlotSchema,
|
|
2685
|
-
friday: timeSlotSchema,
|
|
2686
|
-
saturday: timeSlotSchema,
|
|
2687
|
-
sunday: timeSlotSchema
|
|
2688
|
-
}),
|
|
2689
|
-
isActive: import_zod7.z.boolean(),
|
|
2690
|
-
createdAt: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date()),
|
|
2691
|
-
updatedAt: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date())
|
|
2692
|
-
});
|
|
2693
|
-
var practitionerSchema = import_zod7.z.object({
|
|
2694
|
-
id: import_zod7.z.string().min(1),
|
|
2695
|
-
userRef: import_zod7.z.string().min(1),
|
|
2696
|
-
basicInfo: practitionerBasicInfoSchema,
|
|
2697
|
-
certification: practitionerCertificationSchema,
|
|
2698
|
-
clinics: import_zod7.z.array(import_zod7.z.string()),
|
|
2699
|
-
clinicWorkingHours: import_zod7.z.array(practitionerClinicWorkingHoursSchema),
|
|
2700
|
-
clinicsInfo: import_zod7.z.array(clinicInfoSchema),
|
|
2701
|
-
procedures: import_zod7.z.array(import_zod7.z.string()),
|
|
2702
|
-
freeConsultations: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.string()).optional().nullable(),
|
|
2703
|
-
proceduresInfo: import_zod7.z.array(procedureSummaryInfoSchema),
|
|
2704
|
-
reviewInfo: practitionerReviewInfoSchema,
|
|
2705
|
-
isActive: import_zod7.z.boolean(),
|
|
2706
|
-
isVerified: import_zod7.z.boolean(),
|
|
2707
|
-
status: import_zod7.z.nativeEnum(PractitionerStatus),
|
|
2708
|
-
createdAt: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date()),
|
|
2709
|
-
updatedAt: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date())
|
|
2710
|
-
});
|
|
2711
|
-
var createPractitionerSchema = import_zod7.z.object({
|
|
2712
|
-
userRef: import_zod7.z.string().min(1),
|
|
2713
|
-
basicInfo: practitionerBasicInfoSchema,
|
|
2714
|
-
certification: practitionerCertificationSchema,
|
|
2715
|
-
clinics: import_zod7.z.array(import_zod7.z.string()).optional(),
|
|
2716
|
-
clinicWorkingHours: import_zod7.z.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
2717
|
-
clinicsInfo: import_zod7.z.array(clinicInfoSchema).optional(),
|
|
2718
|
-
freeConsultations: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.string()).optional().nullable(),
|
|
2719
|
-
proceduresInfo: import_zod7.z.array(procedureSummaryInfoSchema).optional(),
|
|
2720
|
-
isActive: import_zod7.z.boolean(),
|
|
2721
|
-
isVerified: import_zod7.z.boolean(),
|
|
2722
|
-
status: import_zod7.z.nativeEnum(PractitionerStatus).optional()
|
|
2723
|
-
});
|
|
2724
|
-
var createDraftPractitionerSchema = import_zod7.z.object({
|
|
2725
|
-
basicInfo: practitionerBasicInfoSchema,
|
|
2726
|
-
certification: practitionerCertificationSchema,
|
|
2727
|
-
clinics: import_zod7.z.array(import_zod7.z.string()).optional(),
|
|
2728
|
-
clinicWorkingHours: import_zod7.z.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
2729
|
-
clinicsInfo: import_zod7.z.array(clinicInfoSchema).optional(),
|
|
2730
|
-
freeConsultations: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.string()).optional().nullable(),
|
|
2731
|
-
proceduresInfo: import_zod7.z.array(procedureSummaryInfoSchema).optional(),
|
|
2732
|
-
isActive: import_zod7.z.boolean().optional().default(false),
|
|
2733
|
-
isVerified: import_zod7.z.boolean().optional().default(false)
|
|
2734
|
-
});
|
|
2735
|
-
var practitionerTokenSchema = import_zod7.z.object({
|
|
2736
|
-
id: import_zod7.z.string().min(1),
|
|
2737
|
-
token: import_zod7.z.string().min(6),
|
|
2738
|
-
practitionerId: import_zod7.z.string().min(1),
|
|
2739
|
-
email: import_zod7.z.string().email(),
|
|
2740
|
-
clinicId: import_zod7.z.string().min(1),
|
|
2741
|
-
status: import_zod7.z.nativeEnum(PractitionerTokenStatus),
|
|
2742
|
-
createdBy: import_zod7.z.string().min(1),
|
|
2743
|
-
createdAt: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date()),
|
|
2744
|
-
expiresAt: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date()),
|
|
2745
|
-
usedBy: import_zod7.z.string().optional(),
|
|
2746
|
-
usedAt: import_zod7.z.instanceof(import_firestore3.Timestamp).or(import_zod7.z.date()).optional()
|
|
2747
|
-
});
|
|
2748
|
-
var createPractitionerTokenSchema = import_zod7.z.object({
|
|
2749
|
-
practitionerId: import_zod7.z.string().min(1),
|
|
2750
|
-
email: import_zod7.z.string().email(),
|
|
2751
|
-
clinicId: import_zod7.z.string().min(1),
|
|
2752
|
-
expiresAt: import_zod7.z.date().optional()
|
|
2753
|
-
});
|
|
2754
|
-
var practitionerSignupSchema = import_zod7.z.object({
|
|
2755
|
-
email: import_zod7.z.string().email(),
|
|
2756
|
-
password: import_zod7.z.string().min(8),
|
|
2757
|
-
firstName: import_zod7.z.string().min(2).max(50).optional(),
|
|
2758
|
-
lastName: import_zod7.z.string().min(2).max(50).optional(),
|
|
2759
|
-
token: import_zod7.z.string().optional(),
|
|
2760
|
-
profileData: import_zod7.z.object({
|
|
2761
|
-
basicInfo: import_zod7.z.object({
|
|
2762
|
-
phoneNumber: import_zod7.z.string().optional(),
|
|
2763
|
-
profileImageUrl: mediaResourceSchema.optional(),
|
|
2764
|
-
gender: import_zod7.z.enum(["male", "female", "other"]).optional(),
|
|
2765
|
-
bio: import_zod7.z.string().optional()
|
|
2766
|
-
}).optional(),
|
|
2767
|
-
certification: import_zod7.z.any().optional()
|
|
2768
|
-
}).optional()
|
|
2769
|
-
});
|
|
2770
|
-
|
|
2771
|
-
// src/services/auth/utils/practitioner.utils.ts
|
|
2772
|
-
var profileDataSchema = import_zod8.z.object({
|
|
2773
|
-
basicInfo: practitionerBasicInfoSchema.partial().optional(),
|
|
2774
|
-
certification: practitionerCertificationSchema.partial().optional()
|
|
2775
|
-
}).partial();
|
|
2776
|
-
var buildPractitionerData = (data, userRef) => {
|
|
2777
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
2778
|
-
const basicInfo = {
|
|
2779
|
-
firstName: data.firstName || "Name",
|
|
2780
|
-
lastName: data.lastName || "Surname",
|
|
2781
|
-
email: data.email,
|
|
2782
|
-
phoneNumber: ((_b = (_a = data.profileData) == null ? void 0 : _a.basicInfo) == null ? void 0 : _b.phoneNumber) || null,
|
|
2783
|
-
profileImageUrl: ((_d = (_c = data.profileData) == null ? void 0 : _c.basicInfo) == null ? void 0 : _d.profileImageUrl) || "",
|
|
2784
|
-
gender: ((_f = (_e = data.profileData) == null ? void 0 : _e.basicInfo) == null ? void 0 : _f.gender) || "other",
|
|
2785
|
-
bio: ((_h = (_g = data.profileData) == null ? void 0 : _g.basicInfo) == null ? void 0 : _h.bio) || "",
|
|
2786
|
-
title: "Practitioner",
|
|
2787
|
-
dateOfBirth: ((_j = (_i = data.profileData) == null ? void 0 : _i.basicInfo) == null ? void 0 : _j.dateOfBirth) || /* @__PURE__ */ new Date(),
|
|
2788
|
-
languages: ((_l = (_k = data.profileData) == null ? void 0 : _k.basicInfo) == null ? void 0 : _l.languages) || ["English"]
|
|
2789
|
-
};
|
|
2790
|
-
const certification = ((_m = data.profileData) == null ? void 0 : _m.certification) || {
|
|
2791
|
-
level: "aesthetician" /* AESTHETICIAN */,
|
|
2792
|
-
specialties: [],
|
|
2793
|
-
licenseNumber: "Pending",
|
|
2794
|
-
issuingAuthority: "Pending",
|
|
2795
|
-
issueDate: /* @__PURE__ */ new Date(),
|
|
2796
|
-
verificationStatus: "pending"
|
|
2797
|
-
};
|
|
2798
|
-
return {
|
|
2799
|
-
userRef,
|
|
2800
|
-
basicInfo,
|
|
2801
|
-
certification,
|
|
2802
|
-
status: "active" /* ACTIVE */,
|
|
2803
|
-
isActive: true,
|
|
2804
|
-
isVerified: false
|
|
2805
|
-
};
|
|
2806
|
-
};
|
|
2807
|
-
var validatePractitionerProfileData = async (profileData) => {
|
|
2808
|
-
try {
|
|
2809
|
-
await profileDataSchema.parseAsync(profileData);
|
|
2810
|
-
} catch (error) {
|
|
2811
|
-
if (error instanceof import_zod8.z.ZodError) {
|
|
2812
|
-
const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
|
|
2813
|
-
throw new Error(
|
|
2814
|
-
`Practitioner profile validation failed: ${errorMessages}`
|
|
2815
|
-
);
|
|
2816
|
-
}
|
|
2817
|
-
throw error;
|
|
2818
|
-
}
|
|
2819
|
-
};
|
|
2820
|
-
var isPractitionerDataComplete = (practitioner) => {
|
|
2821
|
-
const { basicInfo, certification } = practitioner;
|
|
2822
|
-
const hasRequiredBasicInfo = basicInfo.firstName && basicInfo.lastName && basicInfo.email && basicInfo.phoneNumber;
|
|
2823
|
-
const hasRequiredCertification = certification.licenseNumber && certification.licenseNumber !== "Pending" && certification.issuingAuthority && certification.issuingAuthority !== "Pending";
|
|
2824
|
-
return !!(hasRequiredBasicInfo && hasRequiredCertification);
|
|
2825
|
-
};
|
|
2826
|
-
|
|
2827
2140
|
// src/services/auth/auth.service.ts
|
|
2828
2141
|
var import_auth7 = require("firebase/auth");
|
|
2829
2142
|
var import_firestore28 = require("firebase/firestore");
|
|
@@ -2965,18 +2278,18 @@ var REVIEWS_COLLECTION = "reviews";
|
|
|
2965
2278
|
var import_zod23 = require("zod");
|
|
2966
2279
|
|
|
2967
2280
|
// src/validations/schemas.ts
|
|
2968
|
-
var
|
|
2969
|
-
var emailSchema =
|
|
2970
|
-
var passwordSchema =
|
|
2281
|
+
var import_zod4 = require("zod");
|
|
2282
|
+
var emailSchema = import_zod4.z.string().email("Invalid email format").min(5, "Email must be at least 5 characters").max(255, "Email must be less than 255 characters");
|
|
2283
|
+
var passwordSchema = import_zod4.z.string().min(8, "Password must be at least 8 characters").max(100, "Password must be less than 100 characters").regex(
|
|
2971
2284
|
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d\w\W]{8,}$/,
|
|
2972
2285
|
"Password must contain at least one uppercase letter, one lowercase letter, and one number"
|
|
2973
2286
|
);
|
|
2974
|
-
var userRoleSchema =
|
|
2975
|
-
var userRolesSchema =
|
|
2976
|
-
var clinicAdminOptionsSchema =
|
|
2977
|
-
isGroupOwner:
|
|
2978
|
-
groupToken:
|
|
2979
|
-
groupId:
|
|
2287
|
+
var userRoleSchema = import_zod4.z.nativeEnum(UserRole);
|
|
2288
|
+
var userRolesSchema = import_zod4.z.array(userRoleSchema).min(1, "User must have at least one role").max(3, "User cannot have more than 3 roles");
|
|
2289
|
+
var clinicAdminOptionsSchema = import_zod4.z.object({
|
|
2290
|
+
isGroupOwner: import_zod4.z.boolean(),
|
|
2291
|
+
groupToken: import_zod4.z.string().optional(),
|
|
2292
|
+
groupId: import_zod4.z.string().optional()
|
|
2980
2293
|
}).refine(
|
|
2981
2294
|
(data) => {
|
|
2982
2295
|
if (!data.isGroupOwner && (!data.groupToken || !data.groupId)) {
|
|
@@ -2991,22 +2304,205 @@ var clinicAdminOptionsSchema = import_zod9.z.object({
|
|
|
2991
2304
|
message: "Invalid clinic admin options configuration"
|
|
2992
2305
|
}
|
|
2993
2306
|
);
|
|
2994
|
-
var createUserOptionsSchema =
|
|
2307
|
+
var createUserOptionsSchema = import_zod4.z.object({
|
|
2995
2308
|
clinicAdminData: clinicAdminOptionsSchema.optional()
|
|
2996
2309
|
});
|
|
2997
|
-
var userSchema =
|
|
2998
|
-
uid:
|
|
2999
|
-
email:
|
|
3000
|
-
roles:
|
|
3001
|
-
isAnonymous:
|
|
3002
|
-
createdAt:
|
|
3003
|
-
updatedAt:
|
|
3004
|
-
lastLoginAt:
|
|
3005
|
-
patientProfile:
|
|
3006
|
-
practitionerProfile:
|
|
3007
|
-
adminProfile:
|
|
2310
|
+
var userSchema = import_zod4.z.object({
|
|
2311
|
+
uid: import_zod4.z.string(),
|
|
2312
|
+
email: import_zod4.z.string().email().nullable(),
|
|
2313
|
+
roles: import_zod4.z.array(userRoleSchema),
|
|
2314
|
+
isAnonymous: import_zod4.z.boolean(),
|
|
2315
|
+
createdAt: import_zod4.z.any(),
|
|
2316
|
+
updatedAt: import_zod4.z.any(),
|
|
2317
|
+
lastLoginAt: import_zod4.z.any(),
|
|
2318
|
+
patientProfile: import_zod4.z.string().optional(),
|
|
2319
|
+
practitionerProfile: import_zod4.z.string().optional(),
|
|
2320
|
+
adminProfile: import_zod4.z.string().optional()
|
|
3008
2321
|
});
|
|
3009
2322
|
|
|
2323
|
+
// src/errors/auth.errors.ts
|
|
2324
|
+
var AuthError = class extends Error {
|
|
2325
|
+
constructor(message, code, status = 400) {
|
|
2326
|
+
super(message);
|
|
2327
|
+
this.code = code;
|
|
2328
|
+
this.status = status;
|
|
2329
|
+
this.name = "AuthError";
|
|
2330
|
+
}
|
|
2331
|
+
};
|
|
2332
|
+
var AUTH_ERRORS = {
|
|
2333
|
+
// Basic validation errors
|
|
2334
|
+
INVALID_EMAIL: new AuthError(
|
|
2335
|
+
"Email address is not in a valid format",
|
|
2336
|
+
"AUTH/INVALID_EMAIL",
|
|
2337
|
+
400
|
|
2338
|
+
),
|
|
2339
|
+
INVALID_PASSWORD: new AuthError(
|
|
2340
|
+
"Password must contain at least 8 characters, one uppercase letter, one number, and one special character",
|
|
2341
|
+
"AUTH/INVALID_PASSWORD",
|
|
2342
|
+
400
|
|
2343
|
+
),
|
|
2344
|
+
INVALID_ROLE: new AuthError(
|
|
2345
|
+
"Specified user role is not valid",
|
|
2346
|
+
"AUTH/INVALID_ROLE",
|
|
2347
|
+
400
|
|
2348
|
+
),
|
|
2349
|
+
// Authentication errors
|
|
2350
|
+
NOT_AUTHENTICATED: new AuthError(
|
|
2351
|
+
"User is not authenticated",
|
|
2352
|
+
"AUTH/NOT_AUTHENTICATED",
|
|
2353
|
+
401
|
|
2354
|
+
),
|
|
2355
|
+
SESSION_EXPIRED: new AuthError(
|
|
2356
|
+
"Your session has expired. Please sign in again",
|
|
2357
|
+
"AUTH/SESSION_EXPIRED",
|
|
2358
|
+
401
|
|
2359
|
+
),
|
|
2360
|
+
INVALID_TOKEN: new AuthError(
|
|
2361
|
+
"Invalid authentication token",
|
|
2362
|
+
"AUTH/INVALID_TOKEN",
|
|
2363
|
+
401
|
|
2364
|
+
),
|
|
2365
|
+
// User state errors
|
|
2366
|
+
USER_NOT_FOUND: new AuthError(
|
|
2367
|
+
"User not found in the system",
|
|
2368
|
+
"AUTH/USER_NOT_FOUND",
|
|
2369
|
+
404
|
|
2370
|
+
),
|
|
2371
|
+
EMAIL_ALREADY_EXISTS: new AuthError(
|
|
2372
|
+
"An account with this email already exists",
|
|
2373
|
+
"AUTH/EMAIL_EXISTS",
|
|
2374
|
+
409
|
|
2375
|
+
),
|
|
2376
|
+
USER_DISABLED: new AuthError(
|
|
2377
|
+
"This account has been disabled",
|
|
2378
|
+
"AUTH/USER_DISABLED",
|
|
2379
|
+
403
|
|
2380
|
+
),
|
|
2381
|
+
// Rate limiting and security
|
|
2382
|
+
TOO_MANY_REQUESTS: new AuthError(
|
|
2383
|
+
"Too many login attempts. Please try again later",
|
|
2384
|
+
"AUTH/TOO_MANY_REQUESTS",
|
|
2385
|
+
429
|
|
2386
|
+
),
|
|
2387
|
+
ACCOUNT_LOCKED: new AuthError(
|
|
2388
|
+
"Account temporarily locked due to too many failed login attempts",
|
|
2389
|
+
"AUTH/ACCOUNT_LOCKED",
|
|
2390
|
+
403
|
|
2391
|
+
),
|
|
2392
|
+
// Social auth specific
|
|
2393
|
+
POPUP_CLOSED: new AuthError(
|
|
2394
|
+
"Authentication popup was closed before completion",
|
|
2395
|
+
"AUTH/POPUP_CLOSED",
|
|
2396
|
+
400
|
|
2397
|
+
),
|
|
2398
|
+
POPUP_BLOCKED: new AuthError(
|
|
2399
|
+
"Authentication popup was blocked by the browser",
|
|
2400
|
+
"AUTH/POPUP_BLOCKED",
|
|
2401
|
+
400
|
|
2402
|
+
),
|
|
2403
|
+
ACCOUNT_EXISTS: new AuthError(
|
|
2404
|
+
"An account already exists with different credentials",
|
|
2405
|
+
"AUTH/ACCOUNT_EXISTS",
|
|
2406
|
+
409
|
|
2407
|
+
),
|
|
2408
|
+
// Anonymous auth specific
|
|
2409
|
+
NOT_ANONYMOUS: new AuthError(
|
|
2410
|
+
"Current user is not anonymous",
|
|
2411
|
+
"AUTH/NOT_ANONYMOUS_USER",
|
|
2412
|
+
400
|
|
2413
|
+
),
|
|
2414
|
+
ANONYMOUS_UPGRADE_FAILED: new AuthError(
|
|
2415
|
+
"Failed to upgrade anonymous account",
|
|
2416
|
+
"AUTH/ANONYMOUS_UPGRADE_FAILED",
|
|
2417
|
+
400
|
|
2418
|
+
),
|
|
2419
|
+
// General errors
|
|
2420
|
+
VALIDATION_ERROR: new AuthError(
|
|
2421
|
+
"Data validation error occurred",
|
|
2422
|
+
"AUTH/VALIDATION_ERROR",
|
|
2423
|
+
400
|
|
2424
|
+
),
|
|
2425
|
+
OPERATION_NOT_ALLOWED: new AuthError(
|
|
2426
|
+
"This operation is not allowed",
|
|
2427
|
+
"AUTH/OPERATION_NOT_ALLOWED",
|
|
2428
|
+
403
|
|
2429
|
+
),
|
|
2430
|
+
NETWORK_ERROR: new AuthError(
|
|
2431
|
+
"Network error occurred. Please check your connection",
|
|
2432
|
+
"AUTH/NETWORK_ERROR",
|
|
2433
|
+
503
|
|
2434
|
+
),
|
|
2435
|
+
REQUIRES_RECENT_LOGIN: new AuthError(
|
|
2436
|
+
"This operation requires recent authentication. Please sign in again",
|
|
2437
|
+
"AUTH/REQUIRES_RECENT_LOGIN",
|
|
2438
|
+
401
|
|
2439
|
+
),
|
|
2440
|
+
INVALID_PROVIDER: new AuthError(
|
|
2441
|
+
"Invalid authentication provider",
|
|
2442
|
+
"AUTH/INVALID_PROVIDER",
|
|
2443
|
+
400
|
|
2444
|
+
),
|
|
2445
|
+
INVALID_CREDENTIAL: new AuthError(
|
|
2446
|
+
"The provided credentials are invalid or expired",
|
|
2447
|
+
"AUTH/INVALID_CREDENTIAL",
|
|
2448
|
+
401
|
|
2449
|
+
),
|
|
2450
|
+
// Resource not found
|
|
2451
|
+
NOT_FOUND: new AuthError(
|
|
2452
|
+
"The requested resource was not found",
|
|
2453
|
+
"AUTH/NOT_FOUND",
|
|
2454
|
+
404
|
|
2455
|
+
),
|
|
2456
|
+
// Detailed password validation errors
|
|
2457
|
+
PASSWORD_LENGTH_ERROR: new AuthError(
|
|
2458
|
+
"Password must be at least 8 characters long",
|
|
2459
|
+
"AUTH/PASSWORD_LENGTH_ERROR",
|
|
2460
|
+
400
|
|
2461
|
+
),
|
|
2462
|
+
PASSWORD_UPPERCASE_ERROR: new AuthError(
|
|
2463
|
+
"Password must contain at least one uppercase letter",
|
|
2464
|
+
"AUTH/PASSWORD_UPPERCASE_ERROR",
|
|
2465
|
+
400
|
|
2466
|
+
),
|
|
2467
|
+
PASSWORD_NUMBER_ERROR: new AuthError(
|
|
2468
|
+
"Password must contain at least one number",
|
|
2469
|
+
"AUTH/PASSWORD_NUMBER_ERROR",
|
|
2470
|
+
400
|
|
2471
|
+
),
|
|
2472
|
+
PASSWORD_SPECIAL_CHAR_ERROR: new AuthError(
|
|
2473
|
+
"Password must contain at least one special character",
|
|
2474
|
+
"AUTH/PASSWORD_SPECIAL_CHAR_ERROR",
|
|
2475
|
+
400
|
|
2476
|
+
),
|
|
2477
|
+
// Detailed email validation errors
|
|
2478
|
+
EMAIL_FORMAT_ERROR: new AuthError(
|
|
2479
|
+
"Invalid email format. Please enter a valid email address",
|
|
2480
|
+
"AUTH/EMAIL_FORMAT_ERROR",
|
|
2481
|
+
400
|
|
2482
|
+
),
|
|
2483
|
+
PASSWORD_VALIDATION_ERROR: new AuthError(
|
|
2484
|
+
"Password validation failed. Please check all requirements",
|
|
2485
|
+
"AUTH/PASSWORD_VALIDATION_ERROR",
|
|
2486
|
+
400
|
|
2487
|
+
),
|
|
2488
|
+
// Password reset specific errors
|
|
2489
|
+
EXPIRED_ACTION_CODE: new AuthError(
|
|
2490
|
+
"Kod za resetovanje lozinke je istekao. Molimo zatra\u017Eite novi link za resetovanje.",
|
|
2491
|
+
"AUTH/EXPIRED_ACTION_CODE",
|
|
2492
|
+
400
|
|
2493
|
+
),
|
|
2494
|
+
INVALID_ACTION_CODE: new AuthError(
|
|
2495
|
+
"Kod za resetovanje lozinke je neva\u017Ee\u0107i ili je ve\u0107 iskori\u0161\u0107en. Molimo zatra\u017Eite novi link za resetovanje.",
|
|
2496
|
+
"AUTH/INVALID_ACTION_CODE",
|
|
2497
|
+
400
|
|
2498
|
+
),
|
|
2499
|
+
WEAK_PASSWORD: new AuthError(
|
|
2500
|
+
"Lozinka je previ\u0161e slaba. Molimo koristite ja\u010Du lozinku.",
|
|
2501
|
+
"AUTH/WEAK_PASSWORD",
|
|
2502
|
+
400
|
|
2503
|
+
)
|
|
2504
|
+
};
|
|
2505
|
+
|
|
3010
2506
|
// src/services/user/user.service.ts
|
|
3011
2507
|
var import_firestore22 = require("firebase/firestore");
|
|
3012
2508
|
|
|
@@ -3103,15 +2599,15 @@ var USER_ERRORS = {
|
|
|
3103
2599
|
};
|
|
3104
2600
|
|
|
3105
2601
|
// src/services/user/user.service.ts
|
|
3106
|
-
var
|
|
2602
|
+
var import_zod17 = require("zod");
|
|
3107
2603
|
|
|
3108
2604
|
// src/services/patient/patient.service.ts
|
|
3109
|
-
var
|
|
2605
|
+
var import_firestore18 = require("firebase/firestore");
|
|
3110
2606
|
|
|
3111
2607
|
// src/services/media/media.service.ts
|
|
3112
|
-
var
|
|
2608
|
+
var import_firestore3 = require("firebase/firestore");
|
|
3113
2609
|
var import_storage2 = require("firebase/storage");
|
|
3114
|
-
var
|
|
2610
|
+
var import_firestore4 = require("firebase/firestore");
|
|
3115
2611
|
var MediaAccessLevel = /* @__PURE__ */ ((MediaAccessLevel2) => {
|
|
3116
2612
|
MediaAccessLevel2["PUBLIC"] = "public";
|
|
3117
2613
|
MediaAccessLevel2["PRIVATE"] = "private";
|
|
@@ -3152,14 +2648,14 @@ var MediaService = class extends BaseService {
|
|
|
3152
2648
|
url: downloadURL,
|
|
3153
2649
|
contentType: file.type,
|
|
3154
2650
|
size: file.size,
|
|
3155
|
-
createdAt:
|
|
2651
|
+
createdAt: import_firestore3.Timestamp.now(),
|
|
3156
2652
|
accessLevel,
|
|
3157
2653
|
ownerId,
|
|
3158
2654
|
collectionName,
|
|
3159
2655
|
path: filePath
|
|
3160
2656
|
};
|
|
3161
|
-
const metadataDocRef = (0,
|
|
3162
|
-
await (0,
|
|
2657
|
+
const metadataDocRef = (0, import_firestore4.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
|
|
2658
|
+
await (0, import_firestore4.setDoc)(metadataDocRef, metadata);
|
|
3163
2659
|
console.log("[MediaService] Metadata stored in Firestore:", mediaId);
|
|
3164
2660
|
return metadata;
|
|
3165
2661
|
} catch (error) {
|
|
@@ -3174,8 +2670,8 @@ var MediaService = class extends BaseService {
|
|
|
3174
2670
|
*/
|
|
3175
2671
|
async getMediaMetadata(mediaId) {
|
|
3176
2672
|
console.log(`[MediaService] Getting media metadata for ID: ${mediaId}`);
|
|
3177
|
-
const docRef = (0,
|
|
3178
|
-
const docSnap = await (0,
|
|
2673
|
+
const docRef = (0, import_firestore4.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
|
|
2674
|
+
const docSnap = await (0, import_firestore4.getDoc)(docRef);
|
|
3179
2675
|
if (docSnap.exists()) {
|
|
3180
2676
|
console.log("[MediaService] Metadata found:", docSnap.data());
|
|
3181
2677
|
return docSnap.data();
|
|
@@ -3190,13 +2686,13 @@ var MediaService = class extends BaseService {
|
|
|
3190
2686
|
*/
|
|
3191
2687
|
async getMediaMetadataByUrl(url) {
|
|
3192
2688
|
console.log(`[MediaService] Getting media metadata by URL: ${url}`);
|
|
3193
|
-
const q = (0,
|
|
3194
|
-
(0,
|
|
3195
|
-
(0,
|
|
3196
|
-
(0,
|
|
2689
|
+
const q = (0, import_firestore4.query)(
|
|
2690
|
+
(0, import_firestore4.collection)(this.db, MEDIA_METADATA_COLLECTION),
|
|
2691
|
+
(0, import_firestore4.where)("url", "==", url),
|
|
2692
|
+
(0, import_firestore4.limit)(1)
|
|
3197
2693
|
);
|
|
3198
2694
|
try {
|
|
3199
|
-
const querySnapshot = await (0,
|
|
2695
|
+
const querySnapshot = await (0, import_firestore4.getDocs)(q);
|
|
3200
2696
|
if (!querySnapshot.empty) {
|
|
3201
2697
|
const metadata = querySnapshot.docs[0].data();
|
|
3202
2698
|
console.log("[MediaService] Metadata found by URL:", metadata);
|
|
@@ -3226,8 +2722,8 @@ var MediaService = class extends BaseService {
|
|
|
3226
2722
|
try {
|
|
3227
2723
|
await (0, import_storage2.deleteObject)(storageFileRef);
|
|
3228
2724
|
console.log(`[MediaService] File deleted from Storage: ${metadata.path}`);
|
|
3229
|
-
const metadataDocRef = (0,
|
|
3230
|
-
await (0,
|
|
2725
|
+
const metadataDocRef = (0, import_firestore4.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
|
|
2726
|
+
await (0, import_firestore4.deleteDoc)(metadataDocRef);
|
|
3231
2727
|
console.log(
|
|
3232
2728
|
`[MediaService] Metadata deleted from Firestore for ID: ${mediaId}`
|
|
3233
2729
|
);
|
|
@@ -3259,10 +2755,10 @@ var MediaService = class extends BaseService {
|
|
|
3259
2755
|
console.log(
|
|
3260
2756
|
`[MediaService] Media ID ${mediaId} already has access level ${newAccessLevel}. Updating timestamp only.`
|
|
3261
2757
|
);
|
|
3262
|
-
const metadataDocRef = (0,
|
|
2758
|
+
const metadataDocRef = (0, import_firestore4.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
|
|
3263
2759
|
try {
|
|
3264
|
-
await (0,
|
|
3265
|
-
return { ...metadata, updatedAt:
|
|
2760
|
+
await (0, import_firestore4.updateDoc)(metadataDocRef, { updatedAt: import_firestore3.Timestamp.now() });
|
|
2761
|
+
return { ...metadata, updatedAt: import_firestore3.Timestamp.now() };
|
|
3266
2762
|
} catch (error) {
|
|
3267
2763
|
console.error(
|
|
3268
2764
|
`[MediaService] Error updating timestamp for media ID ${mediaId}:`,
|
|
@@ -3300,14 +2796,14 @@ var MediaService = class extends BaseService {
|
|
|
3300
2796
|
accessLevel: newAccessLevel,
|
|
3301
2797
|
path: newStoragePath,
|
|
3302
2798
|
url: newDownloadURL,
|
|
3303
|
-
updatedAt:
|
|
2799
|
+
updatedAt: import_firestore3.Timestamp.now()
|
|
3304
2800
|
};
|
|
3305
|
-
const metadataDocRef = (0,
|
|
2801
|
+
const metadataDocRef = (0, import_firestore4.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
|
|
3306
2802
|
console.log(
|
|
3307
2803
|
`[MediaService] Updating Firestore metadata for ${mediaId} with new data:`,
|
|
3308
2804
|
updateData
|
|
3309
2805
|
);
|
|
3310
|
-
await (0,
|
|
2806
|
+
await (0, import_firestore4.updateDoc)(metadataDocRef, updateData);
|
|
3311
2807
|
console.log(
|
|
3312
2808
|
`[MediaService] Successfully updated Firestore metadata for ${mediaId}`
|
|
3313
2809
|
);
|
|
@@ -3358,28 +2854,28 @@ var MediaService = class extends BaseService {
|
|
|
3358
2854
|
*/
|
|
3359
2855
|
async listMedia(ownerId, collectionName, accessLevel, count, startAfterId) {
|
|
3360
2856
|
console.log(`[MediaService] Listing media for owner: ${ownerId}`);
|
|
3361
|
-
let qConstraints = [(0,
|
|
2857
|
+
let qConstraints = [(0, import_firestore4.where)("ownerId", "==", ownerId)];
|
|
3362
2858
|
if (collectionName) {
|
|
3363
|
-
qConstraints.push((0,
|
|
2859
|
+
qConstraints.push((0, import_firestore4.where)("collectionName", "==", collectionName));
|
|
3364
2860
|
}
|
|
3365
2861
|
if (accessLevel) {
|
|
3366
|
-
qConstraints.push((0,
|
|
2862
|
+
qConstraints.push((0, import_firestore4.where)("accessLevel", "==", accessLevel));
|
|
3367
2863
|
}
|
|
3368
|
-
qConstraints.push((0,
|
|
2864
|
+
qConstraints.push((0, import_firestore4.orderBy)("createdAt", "desc"));
|
|
3369
2865
|
if (count) {
|
|
3370
|
-
qConstraints.push((0,
|
|
2866
|
+
qConstraints.push((0, import_firestore4.limit)(count));
|
|
3371
2867
|
}
|
|
3372
2868
|
if (startAfterId) {
|
|
3373
2869
|
const startAfterDoc = await this.getMediaMetadata(startAfterId);
|
|
3374
2870
|
if (startAfterDoc) {
|
|
3375
2871
|
}
|
|
3376
2872
|
}
|
|
3377
|
-
const finalQuery = (0,
|
|
3378
|
-
(0,
|
|
2873
|
+
const finalQuery = (0, import_firestore4.query)(
|
|
2874
|
+
(0, import_firestore4.collection)(this.db, MEDIA_METADATA_COLLECTION),
|
|
3379
2875
|
...qConstraints
|
|
3380
2876
|
);
|
|
3381
2877
|
try {
|
|
3382
|
-
const querySnapshot = await (0,
|
|
2878
|
+
const querySnapshot = await (0, import_firestore4.getDocs)(finalQuery);
|
|
3383
2879
|
const mediaList = querySnapshot.docs.map(
|
|
3384
2880
|
(doc37) => doc37.data()
|
|
3385
2881
|
);
|
|
@@ -3407,33 +2903,33 @@ var MediaService = class extends BaseService {
|
|
|
3407
2903
|
};
|
|
3408
2904
|
|
|
3409
2905
|
// src/services/patient/patient.service.ts
|
|
3410
|
-
var
|
|
2906
|
+
var import_firestore19 = require("firebase/firestore");
|
|
3411
2907
|
|
|
3412
2908
|
// src/services/patient/utils/clinic.utils.ts
|
|
3413
|
-
var
|
|
2909
|
+
var import_firestore5 = require("firebase/firestore");
|
|
3414
2910
|
var getPatientsByClinicUtil = async (db, clinicId, options) => {
|
|
3415
2911
|
try {
|
|
3416
2912
|
console.log(
|
|
3417
2913
|
`[getPatientsByClinicUtil] Fetching patients for clinic ID: ${clinicId} with options:`,
|
|
3418
2914
|
options
|
|
3419
2915
|
);
|
|
3420
|
-
const patientsCollection = (0,
|
|
2916
|
+
const patientsCollection = (0, import_firestore5.collection)(db, PATIENTS_COLLECTION);
|
|
3421
2917
|
const constraints = [
|
|
3422
|
-
(0,
|
|
2918
|
+
(0, import_firestore5.where)("clinicIds", "array-contains", clinicId)
|
|
3423
2919
|
];
|
|
3424
|
-
let q = (0,
|
|
2920
|
+
let q = (0, import_firestore5.query)(patientsCollection, ...constraints);
|
|
3425
2921
|
if (options == null ? void 0 : options.limit) {
|
|
3426
|
-
q = (0,
|
|
2922
|
+
q = (0, import_firestore5.query)(q, (0, import_firestore5.limit)(options.limit));
|
|
3427
2923
|
}
|
|
3428
2924
|
if (options == null ? void 0 : options.startAfter) {
|
|
3429
|
-
const startAfterDoc = await (0,
|
|
3430
|
-
(0,
|
|
2925
|
+
const startAfterDoc = await (0, import_firestore5.getDoc)(
|
|
2926
|
+
(0, import_firestore5.doc)(db, PATIENTS_COLLECTION, options.startAfter)
|
|
3431
2927
|
);
|
|
3432
2928
|
if (startAfterDoc.exists()) {
|
|
3433
|
-
q = (0,
|
|
2929
|
+
q = (0, import_firestore5.query)(q, (0, import_firestore5.startAfter)(startAfterDoc));
|
|
3434
2930
|
}
|
|
3435
2931
|
}
|
|
3436
|
-
const patientsSnapshot = await (0,
|
|
2932
|
+
const patientsSnapshot = await (0, import_firestore5.getDocs)(q);
|
|
3437
2933
|
const patients = [];
|
|
3438
2934
|
patientsSnapshot.forEach((doc37) => {
|
|
3439
2935
|
patients.push(doc37.data());
|
|
@@ -3454,17 +2950,17 @@ var getPatientsByClinicUtil = async (db, clinicId, options) => {
|
|
|
3454
2950
|
};
|
|
3455
2951
|
|
|
3456
2952
|
// src/services/patient/utils/docs.utils.ts
|
|
3457
|
-
var
|
|
2953
|
+
var import_firestore12 = require("firebase/firestore");
|
|
3458
2954
|
|
|
3459
2955
|
// src/services/patient/utils/sensitive.utils.ts
|
|
3460
|
-
var
|
|
2956
|
+
var import_firestore11 = require("firebase/firestore");
|
|
3461
2957
|
|
|
3462
2958
|
// src/validations/patient.schema.ts
|
|
3463
|
-
var
|
|
3464
|
-
var
|
|
2959
|
+
var import_zod7 = require("zod");
|
|
2960
|
+
var import_firestore7 = require("firebase/firestore");
|
|
3465
2961
|
|
|
3466
2962
|
// src/validations/patient/medical-info.schema.ts
|
|
3467
|
-
var
|
|
2963
|
+
var import_zod6 = require("zod");
|
|
3468
2964
|
|
|
3469
2965
|
// src/backoffice/types/static/blocking-condition.types.ts
|
|
3470
2966
|
var BlockingCondition = /* @__PURE__ */ ((BlockingCondition2) => {
|
|
@@ -3504,85 +3000,85 @@ var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
|
|
|
3504
3000
|
})(Contraindication || {});
|
|
3505
3001
|
|
|
3506
3002
|
// src/validations/common.schema.ts
|
|
3507
|
-
var
|
|
3508
|
-
var
|
|
3509
|
-
var timestampSchema =
|
|
3510
|
-
|
|
3511
|
-
seconds:
|
|
3512
|
-
nanoseconds:
|
|
3003
|
+
var import_zod5 = require("zod");
|
|
3004
|
+
var import_firestore6 = require("firebase/firestore");
|
|
3005
|
+
var timestampSchema = import_zod5.z.union([
|
|
3006
|
+
import_zod5.z.object({
|
|
3007
|
+
seconds: import_zod5.z.number(),
|
|
3008
|
+
nanoseconds: import_zod5.z.number()
|
|
3513
3009
|
}),
|
|
3514
|
-
|
|
3515
|
-
|
|
3010
|
+
import_zod5.z.instanceof(import_firestore6.Timestamp),
|
|
3011
|
+
import_zod5.z.instanceof(Date)
|
|
3516
3012
|
// Add support for Date objects that Firestore returns on client
|
|
3517
3013
|
]).transform((data) => {
|
|
3518
|
-
if (data instanceof
|
|
3014
|
+
if (data instanceof import_firestore6.Timestamp) {
|
|
3519
3015
|
return data;
|
|
3520
3016
|
}
|
|
3521
3017
|
if (data instanceof Date) {
|
|
3522
|
-
return
|
|
3018
|
+
return import_firestore6.Timestamp.fromDate(data);
|
|
3523
3019
|
}
|
|
3524
|
-
return new
|
|
3020
|
+
return new import_firestore6.Timestamp(data.seconds, data.nanoseconds);
|
|
3525
3021
|
});
|
|
3526
3022
|
|
|
3527
3023
|
// src/validations/patient/medical-info.schema.ts
|
|
3528
|
-
var allergySubtypeSchema =
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3024
|
+
var allergySubtypeSchema = import_zod6.z.union([
|
|
3025
|
+
import_zod6.z.nativeEnum(MedicationAllergySubtype),
|
|
3026
|
+
import_zod6.z.nativeEnum(FoodAllergySubtype),
|
|
3027
|
+
import_zod6.z.nativeEnum(EnvironmentalAllergySubtype),
|
|
3028
|
+
import_zod6.z.nativeEnum(CosmeticAllergySubtype),
|
|
3029
|
+
import_zod6.z.literal("other")
|
|
3534
3030
|
]);
|
|
3535
|
-
var allergySchema =
|
|
3536
|
-
type:
|
|
3031
|
+
var allergySchema = import_zod6.z.object({
|
|
3032
|
+
type: import_zod6.z.nativeEnum(AllergyType),
|
|
3537
3033
|
subtype: allergySubtypeSchema,
|
|
3538
|
-
name:
|
|
3539
|
-
severity:
|
|
3540
|
-
reaction:
|
|
3034
|
+
name: import_zod6.z.string().optional().nullable(),
|
|
3035
|
+
severity: import_zod6.z.enum(["mild", "moderate", "severe"]).optional(),
|
|
3036
|
+
reaction: import_zod6.z.string().optional().nullable(),
|
|
3541
3037
|
diagnosed: timestampSchema.optional().nullable(),
|
|
3542
|
-
notes:
|
|
3038
|
+
notes: import_zod6.z.string().optional().nullable()
|
|
3543
3039
|
});
|
|
3544
|
-
var vitalStatsSchema =
|
|
3545
|
-
height:
|
|
3546
|
-
weight:
|
|
3547
|
-
bloodType:
|
|
3548
|
-
bloodPressure:
|
|
3549
|
-
systolic:
|
|
3550
|
-
diastolic:
|
|
3040
|
+
var vitalStatsSchema = import_zod6.z.object({
|
|
3041
|
+
height: import_zod6.z.number().positive().optional(),
|
|
3042
|
+
weight: import_zod6.z.number().positive().optional(),
|
|
3043
|
+
bloodType: import_zod6.z.enum(["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"]).optional(),
|
|
3044
|
+
bloodPressure: import_zod6.z.object({
|
|
3045
|
+
systolic: import_zod6.z.number().min(70).max(200),
|
|
3046
|
+
diastolic: import_zod6.z.number().min(40).max(130),
|
|
3551
3047
|
lastMeasured: timestampSchema
|
|
3552
3048
|
}).optional()
|
|
3553
3049
|
});
|
|
3554
|
-
var blockingConditionSchema =
|
|
3555
|
-
condition:
|
|
3050
|
+
var blockingConditionSchema = import_zod6.z.object({
|
|
3051
|
+
condition: import_zod6.z.nativeEnum(BlockingCondition),
|
|
3556
3052
|
diagnosedAt: timestampSchema,
|
|
3557
|
-
notes:
|
|
3558
|
-
isActive:
|
|
3053
|
+
notes: import_zod6.z.string().optional().nullable(),
|
|
3054
|
+
isActive: import_zod6.z.boolean()
|
|
3559
3055
|
});
|
|
3560
|
-
var contraindicationSchema =
|
|
3561
|
-
condition:
|
|
3056
|
+
var contraindicationSchema = import_zod6.z.object({
|
|
3057
|
+
condition: import_zod6.z.nativeEnum(Contraindication),
|
|
3562
3058
|
lastOccurrence: timestampSchema,
|
|
3563
|
-
frequency:
|
|
3564
|
-
notes:
|
|
3565
|
-
isActive:
|
|
3059
|
+
frequency: import_zod6.z.enum(["rare", "occasional", "frequent"]),
|
|
3060
|
+
notes: import_zod6.z.string().optional().nullable(),
|
|
3061
|
+
isActive: import_zod6.z.boolean()
|
|
3566
3062
|
});
|
|
3567
|
-
var medicationSchema =
|
|
3568
|
-
name:
|
|
3569
|
-
dosage:
|
|
3570
|
-
frequency:
|
|
3063
|
+
var medicationSchema = import_zod6.z.object({
|
|
3064
|
+
name: import_zod6.z.string().min(1),
|
|
3065
|
+
dosage: import_zod6.z.string().min(1),
|
|
3066
|
+
frequency: import_zod6.z.string().min(1),
|
|
3571
3067
|
startDate: timestampSchema.optional().nullable(),
|
|
3572
3068
|
endDate: timestampSchema.optional().nullable(),
|
|
3573
|
-
prescribedBy:
|
|
3069
|
+
prescribedBy: import_zod6.z.string().optional().nullable()
|
|
3574
3070
|
});
|
|
3575
|
-
var patientMedicalInfoSchema =
|
|
3576
|
-
patientId:
|
|
3071
|
+
var patientMedicalInfoSchema = import_zod6.z.object({
|
|
3072
|
+
patientId: import_zod6.z.string(),
|
|
3577
3073
|
vitalStats: vitalStatsSchema,
|
|
3578
|
-
blockingConditions:
|
|
3579
|
-
contraindications:
|
|
3580
|
-
allergies:
|
|
3581
|
-
currentMedications:
|
|
3582
|
-
emergencyNotes:
|
|
3074
|
+
blockingConditions: import_zod6.z.array(blockingConditionSchema),
|
|
3075
|
+
contraindications: import_zod6.z.array(contraindicationSchema),
|
|
3076
|
+
allergies: import_zod6.z.array(allergySchema),
|
|
3077
|
+
currentMedications: import_zod6.z.array(medicationSchema),
|
|
3078
|
+
emergencyNotes: import_zod6.z.string().optional(),
|
|
3583
3079
|
lastUpdated: timestampSchema,
|
|
3584
|
-
updatedBy:
|
|
3585
|
-
verifiedBy:
|
|
3080
|
+
updatedBy: import_zod6.z.string(),
|
|
3081
|
+
verifiedBy: import_zod6.z.string().optional(),
|
|
3586
3082
|
verifiedAt: timestampSchema.optional()
|
|
3587
3083
|
});
|
|
3588
3084
|
var createPatientMedicalInfoSchema = patientMedicalInfoSchema.omit({
|
|
@@ -3596,155 +3092,155 @@ var updatePatientMedicalInfoSchema = createPatientMedicalInfoSchema.partial();
|
|
|
3596
3092
|
var updateVitalStatsSchema = vitalStatsSchema;
|
|
3597
3093
|
var addAllergySchema = allergySchema;
|
|
3598
3094
|
var updateAllergySchema = allergySchema.partial().extend({
|
|
3599
|
-
allergyIndex:
|
|
3095
|
+
allergyIndex: import_zod6.z.number().min(0)
|
|
3600
3096
|
});
|
|
3601
3097
|
var addBlockingConditionSchema = blockingConditionSchema;
|
|
3602
3098
|
var updateBlockingConditionSchema = blockingConditionSchema.partial().extend({
|
|
3603
|
-
conditionIndex:
|
|
3099
|
+
conditionIndex: import_zod6.z.number().min(0)
|
|
3604
3100
|
});
|
|
3605
3101
|
var addContraindicationSchema = contraindicationSchema;
|
|
3606
3102
|
var updateContraindicationSchema = contraindicationSchema.partial().extend({
|
|
3607
|
-
contraindicationIndex:
|
|
3103
|
+
contraindicationIndex: import_zod6.z.number().min(0)
|
|
3608
3104
|
});
|
|
3609
3105
|
var addMedicationSchema = medicationSchema;
|
|
3610
3106
|
var updateMedicationSchema = medicationSchema.partial().extend({
|
|
3611
|
-
medicationIndex:
|
|
3107
|
+
medicationIndex: import_zod6.z.number().min(0)
|
|
3612
3108
|
});
|
|
3613
3109
|
|
|
3614
3110
|
// src/validations/patient.schema.ts
|
|
3615
|
-
var locationDataSchema =
|
|
3616
|
-
latitude:
|
|
3617
|
-
longitude:
|
|
3618
|
-
geohash:
|
|
3111
|
+
var locationDataSchema = import_zod7.z.object({
|
|
3112
|
+
latitude: import_zod7.z.number().min(-90).max(90),
|
|
3113
|
+
longitude: import_zod7.z.number().min(-180).max(180),
|
|
3114
|
+
geohash: import_zod7.z.string().optional()
|
|
3619
3115
|
});
|
|
3620
|
-
var addressDataSchema =
|
|
3621
|
-
address:
|
|
3622
|
-
city:
|
|
3623
|
-
country:
|
|
3624
|
-
postalCode:
|
|
3116
|
+
var addressDataSchema = import_zod7.z.object({
|
|
3117
|
+
address: import_zod7.z.string(),
|
|
3118
|
+
city: import_zod7.z.string(),
|
|
3119
|
+
country: import_zod7.z.string(),
|
|
3120
|
+
postalCode: import_zod7.z.string()
|
|
3625
3121
|
});
|
|
3626
|
-
var emergencyContactSchema =
|
|
3627
|
-
name:
|
|
3628
|
-
relationship:
|
|
3629
|
-
phoneNumber:
|
|
3630
|
-
isNotifiable:
|
|
3122
|
+
var emergencyContactSchema = import_zod7.z.object({
|
|
3123
|
+
name: import_zod7.z.string(),
|
|
3124
|
+
relationship: import_zod7.z.string(),
|
|
3125
|
+
phoneNumber: import_zod7.z.string(),
|
|
3126
|
+
isNotifiable: import_zod7.z.boolean()
|
|
3631
3127
|
});
|
|
3632
|
-
var gamificationSchema =
|
|
3633
|
-
level:
|
|
3634
|
-
points:
|
|
3128
|
+
var gamificationSchema = import_zod7.z.object({
|
|
3129
|
+
level: import_zod7.z.number(),
|
|
3130
|
+
points: import_zod7.z.number()
|
|
3635
3131
|
});
|
|
3636
|
-
var patientLocationInfoSchema =
|
|
3637
|
-
patientId:
|
|
3638
|
-
userRef:
|
|
3132
|
+
var patientLocationInfoSchema = import_zod7.z.object({
|
|
3133
|
+
patientId: import_zod7.z.string(),
|
|
3134
|
+
userRef: import_zod7.z.string().optional(),
|
|
3639
3135
|
locationData: locationDataSchema,
|
|
3640
|
-
createdAt:
|
|
3641
|
-
updatedAt:
|
|
3136
|
+
createdAt: import_zod7.z.instanceof(import_firestore7.Timestamp),
|
|
3137
|
+
updatedAt: import_zod7.z.instanceof(import_firestore7.Timestamp)
|
|
3642
3138
|
});
|
|
3643
|
-
var createPatientLocationInfoSchema =
|
|
3644
|
-
patientId:
|
|
3645
|
-
userRef:
|
|
3139
|
+
var createPatientLocationInfoSchema = import_zod7.z.object({
|
|
3140
|
+
patientId: import_zod7.z.string(),
|
|
3141
|
+
userRef: import_zod7.z.string().optional(),
|
|
3646
3142
|
locationData: locationDataSchema
|
|
3647
3143
|
});
|
|
3648
|
-
var patientSensitiveInfoSchema =
|
|
3649
|
-
patientId:
|
|
3650
|
-
userRef:
|
|
3651
|
-
photoUrl:
|
|
3652
|
-
firstName:
|
|
3653
|
-
lastName:
|
|
3654
|
-
dateOfBirth:
|
|
3655
|
-
gender:
|
|
3656
|
-
email:
|
|
3657
|
-
phoneNumber:
|
|
3658
|
-
alternativePhoneNumber:
|
|
3144
|
+
var patientSensitiveInfoSchema = import_zod7.z.object({
|
|
3145
|
+
patientId: import_zod7.z.string(),
|
|
3146
|
+
userRef: import_zod7.z.string().optional(),
|
|
3147
|
+
photoUrl: import_zod7.z.string().nullable().optional(),
|
|
3148
|
+
firstName: import_zod7.z.string().min(2),
|
|
3149
|
+
lastName: import_zod7.z.string().min(2),
|
|
3150
|
+
dateOfBirth: import_zod7.z.instanceof(import_firestore7.Timestamp).nullable(),
|
|
3151
|
+
gender: import_zod7.z.nativeEnum(Gender),
|
|
3152
|
+
email: import_zod7.z.string().email().optional(),
|
|
3153
|
+
phoneNumber: import_zod7.z.string().optional(),
|
|
3154
|
+
alternativePhoneNumber: import_zod7.z.string().optional(),
|
|
3659
3155
|
addressData: addressDataSchema.optional(),
|
|
3660
|
-
emergencyContacts:
|
|
3661
|
-
createdAt:
|
|
3662
|
-
updatedAt:
|
|
3156
|
+
emergencyContacts: import_zod7.z.array(emergencyContactSchema).optional(),
|
|
3157
|
+
createdAt: import_zod7.z.instanceof(import_firestore7.Timestamp),
|
|
3158
|
+
updatedAt: import_zod7.z.instanceof(import_firestore7.Timestamp)
|
|
3663
3159
|
});
|
|
3664
|
-
var patientDoctorSchema =
|
|
3665
|
-
userRef:
|
|
3666
|
-
assignedAt:
|
|
3667
|
-
assignedBy:
|
|
3668
|
-
isActive:
|
|
3669
|
-
notes:
|
|
3160
|
+
var patientDoctorSchema = import_zod7.z.object({
|
|
3161
|
+
userRef: import_zod7.z.string(),
|
|
3162
|
+
assignedAt: import_zod7.z.instanceof(import_firestore7.Timestamp),
|
|
3163
|
+
assignedBy: import_zod7.z.string().optional(),
|
|
3164
|
+
isActive: import_zod7.z.boolean(),
|
|
3165
|
+
notes: import_zod7.z.string().optional()
|
|
3670
3166
|
});
|
|
3671
|
-
var patientClinicSchema =
|
|
3672
|
-
clinicId:
|
|
3673
|
-
assignedAt:
|
|
3674
|
-
assignedBy:
|
|
3675
|
-
isActive:
|
|
3676
|
-
notes:
|
|
3167
|
+
var patientClinicSchema = import_zod7.z.object({
|
|
3168
|
+
clinicId: import_zod7.z.string(),
|
|
3169
|
+
assignedAt: import_zod7.z.instanceof(import_firestore7.Timestamp),
|
|
3170
|
+
assignedBy: import_zod7.z.string().optional(),
|
|
3171
|
+
isActive: import_zod7.z.boolean(),
|
|
3172
|
+
notes: import_zod7.z.string().optional()
|
|
3677
3173
|
});
|
|
3678
|
-
var patientProfileSchema =
|
|
3679
|
-
id:
|
|
3680
|
-
userRef:
|
|
3681
|
-
displayName:
|
|
3174
|
+
var patientProfileSchema = import_zod7.z.object({
|
|
3175
|
+
id: import_zod7.z.string(),
|
|
3176
|
+
userRef: import_zod7.z.string().optional(),
|
|
3177
|
+
displayName: import_zod7.z.string(),
|
|
3682
3178
|
gamification: gamificationSchema,
|
|
3683
|
-
expoTokens:
|
|
3684
|
-
isActive:
|
|
3685
|
-
isVerified:
|
|
3686
|
-
isManual:
|
|
3179
|
+
expoTokens: import_zod7.z.array(import_zod7.z.string()),
|
|
3180
|
+
isActive: import_zod7.z.boolean(),
|
|
3181
|
+
isVerified: import_zod7.z.boolean(),
|
|
3182
|
+
isManual: import_zod7.z.boolean().default(false),
|
|
3687
3183
|
// Default to false if missing
|
|
3688
|
-
phoneNumber:
|
|
3689
|
-
dateOfBirth:
|
|
3690
|
-
doctors:
|
|
3691
|
-
clinics:
|
|
3692
|
-
doctorIds:
|
|
3693
|
-
clinicIds:
|
|
3694
|
-
createdAt:
|
|
3695
|
-
updatedAt:
|
|
3184
|
+
phoneNumber: import_zod7.z.string().nullable().optional(),
|
|
3185
|
+
dateOfBirth: import_zod7.z.instanceof(import_firestore7.Timestamp).nullable().optional(),
|
|
3186
|
+
doctors: import_zod7.z.array(patientDoctorSchema),
|
|
3187
|
+
clinics: import_zod7.z.array(patientClinicSchema),
|
|
3188
|
+
doctorIds: import_zod7.z.array(import_zod7.z.string()),
|
|
3189
|
+
clinicIds: import_zod7.z.array(import_zod7.z.string()),
|
|
3190
|
+
createdAt: import_zod7.z.instanceof(import_firestore7.Timestamp),
|
|
3191
|
+
updatedAt: import_zod7.z.instanceof(import_firestore7.Timestamp)
|
|
3696
3192
|
});
|
|
3697
|
-
var createPatientProfileSchema =
|
|
3698
|
-
userRef:
|
|
3699
|
-
displayName:
|
|
3700
|
-
expoTokens:
|
|
3193
|
+
var createPatientProfileSchema = import_zod7.z.object({
|
|
3194
|
+
userRef: import_zod7.z.string().optional(),
|
|
3195
|
+
displayName: import_zod7.z.string(),
|
|
3196
|
+
expoTokens: import_zod7.z.array(import_zod7.z.string()),
|
|
3701
3197
|
gamification: gamificationSchema.optional(),
|
|
3702
|
-
isActive:
|
|
3703
|
-
isVerified:
|
|
3704
|
-
isManual:
|
|
3705
|
-
doctors:
|
|
3706
|
-
clinics:
|
|
3707
|
-
doctorIds:
|
|
3708
|
-
clinicIds:
|
|
3198
|
+
isActive: import_zod7.z.boolean(),
|
|
3199
|
+
isVerified: import_zod7.z.boolean(),
|
|
3200
|
+
isManual: import_zod7.z.boolean().default(false),
|
|
3201
|
+
doctors: import_zod7.z.array(patientDoctorSchema).optional(),
|
|
3202
|
+
clinics: import_zod7.z.array(patientClinicSchema).optional(),
|
|
3203
|
+
doctorIds: import_zod7.z.array(import_zod7.z.string()).optional(),
|
|
3204
|
+
clinicIds: import_zod7.z.array(import_zod7.z.string()).optional()
|
|
3709
3205
|
});
|
|
3710
|
-
var createPatientSensitiveInfoSchema =
|
|
3711
|
-
patientId:
|
|
3712
|
-
userRef:
|
|
3206
|
+
var createPatientSensitiveInfoSchema = import_zod7.z.object({
|
|
3207
|
+
patientId: import_zod7.z.string(),
|
|
3208
|
+
userRef: import_zod7.z.string().optional(),
|
|
3713
3209
|
photoUrl: mediaResourceSchema.nullable().optional(),
|
|
3714
|
-
firstName:
|
|
3715
|
-
lastName:
|
|
3716
|
-
dateOfBirth:
|
|
3717
|
-
gender:
|
|
3718
|
-
email:
|
|
3719
|
-
phoneNumber:
|
|
3720
|
-
alternativePhoneNumber:
|
|
3210
|
+
firstName: import_zod7.z.string().min(2),
|
|
3211
|
+
lastName: import_zod7.z.string().min(2),
|
|
3212
|
+
dateOfBirth: import_zod7.z.instanceof(import_firestore7.Timestamp).nullable(),
|
|
3213
|
+
gender: import_zod7.z.nativeEnum(Gender),
|
|
3214
|
+
email: import_zod7.z.string().email().optional(),
|
|
3215
|
+
phoneNumber: import_zod7.z.string().optional(),
|
|
3216
|
+
alternativePhoneNumber: import_zod7.z.string().optional(),
|
|
3721
3217
|
addressData: addressDataSchema.optional(),
|
|
3722
|
-
emergencyContacts:
|
|
3218
|
+
emergencyContacts: import_zod7.z.array(emergencyContactSchema).optional()
|
|
3723
3219
|
});
|
|
3724
|
-
var createManualPatientSchema =
|
|
3725
|
-
clinicId:
|
|
3726
|
-
firstName:
|
|
3727
|
-
lastName:
|
|
3728
|
-
dateOfBirth:
|
|
3729
|
-
gender:
|
|
3730
|
-
phoneNumber:
|
|
3731
|
-
email:
|
|
3220
|
+
var createManualPatientSchema = import_zod7.z.object({
|
|
3221
|
+
clinicId: import_zod7.z.string().min(1, "Clinic ID is required"),
|
|
3222
|
+
firstName: import_zod7.z.string().min(2, "First name is required"),
|
|
3223
|
+
lastName: import_zod7.z.string().min(2, "Last name is required"),
|
|
3224
|
+
dateOfBirth: import_zod7.z.instanceof(import_firestore7.Timestamp).nullable(),
|
|
3225
|
+
gender: import_zod7.z.nativeEnum(Gender),
|
|
3226
|
+
phoneNumber: import_zod7.z.string().optional(),
|
|
3227
|
+
email: import_zod7.z.string().email().optional(),
|
|
3732
3228
|
addressData: addressDataSchema.optional(),
|
|
3733
|
-
notes:
|
|
3229
|
+
notes: import_zod7.z.string().optional()
|
|
3734
3230
|
});
|
|
3735
|
-
var searchPatientsSchema =
|
|
3736
|
-
clinicId:
|
|
3737
|
-
practitionerId:
|
|
3231
|
+
var searchPatientsSchema = import_zod7.z.object({
|
|
3232
|
+
clinicId: import_zod7.z.string().optional(),
|
|
3233
|
+
practitionerId: import_zod7.z.string().optional()
|
|
3738
3234
|
}).refine((data) => data.clinicId || data.practitionerId, {
|
|
3739
3235
|
message: "At least one of clinicId or practitionerId must be provided",
|
|
3740
3236
|
path: []
|
|
3741
3237
|
// Optional: specify a path like ['clinicId'] or ['practitionerId']
|
|
3742
3238
|
});
|
|
3743
|
-
var requesterInfoSchema =
|
|
3744
|
-
id:
|
|
3745
|
-
role:
|
|
3746
|
-
associatedClinicId:
|
|
3747
|
-
associatedPractitionerId:
|
|
3239
|
+
var requesterInfoSchema = import_zod7.z.object({
|
|
3240
|
+
id: import_zod7.z.string(),
|
|
3241
|
+
role: import_zod7.z.enum(["clinic_admin", "practitioner"]),
|
|
3242
|
+
associatedClinicId: import_zod7.z.string().optional(),
|
|
3243
|
+
associatedPractitionerId: import_zod7.z.string().optional()
|
|
3748
3244
|
}).refine(
|
|
3749
3245
|
(data) => {
|
|
3750
3246
|
if (data.role === "clinic_admin") {
|
|
@@ -3761,33 +3257,33 @@ var requesterInfoSchema = import_zod12.z.object({
|
|
|
3761
3257
|
);
|
|
3762
3258
|
|
|
3763
3259
|
// src/services/patient/utils/sensitive.utils.ts
|
|
3764
|
-
var
|
|
3260
|
+
var import_zod11 = require("zod");
|
|
3765
3261
|
|
|
3766
3262
|
// src/services/patient/utils/practitioner.utils.ts
|
|
3767
|
-
var
|
|
3263
|
+
var import_firestore8 = require("firebase/firestore");
|
|
3768
3264
|
var getPatientsByPractitionerUtil = async (db, practitionerId, options) => {
|
|
3769
3265
|
try {
|
|
3770
3266
|
console.log(
|
|
3771
3267
|
`[getPatientsByPractitionerUtil] Fetching patients for practitioner ID: ${practitionerId} with options:`,
|
|
3772
3268
|
options
|
|
3773
3269
|
);
|
|
3774
|
-
const patientsCollection = (0,
|
|
3270
|
+
const patientsCollection = (0, import_firestore8.collection)(db, PATIENTS_COLLECTION);
|
|
3775
3271
|
const constraints = [
|
|
3776
|
-
(0,
|
|
3272
|
+
(0, import_firestore8.where)("doctorIds", "array-contains", practitionerId)
|
|
3777
3273
|
];
|
|
3778
|
-
let q = (0,
|
|
3274
|
+
let q = (0, import_firestore8.query)(patientsCollection, ...constraints);
|
|
3779
3275
|
if (options == null ? void 0 : options.limit) {
|
|
3780
|
-
q = (0,
|
|
3276
|
+
q = (0, import_firestore8.query)(q, (0, import_firestore8.limit)(options.limit));
|
|
3781
3277
|
}
|
|
3782
3278
|
if (options == null ? void 0 : options.startAfter) {
|
|
3783
|
-
const startAfterDoc = await (0,
|
|
3784
|
-
(0,
|
|
3279
|
+
const startAfterDoc = await (0, import_firestore8.getDoc)(
|
|
3280
|
+
(0, import_firestore8.doc)(db, PATIENTS_COLLECTION, options.startAfter)
|
|
3785
3281
|
);
|
|
3786
3282
|
if (startAfterDoc.exists()) {
|
|
3787
|
-
q = (0,
|
|
3283
|
+
q = (0, import_firestore8.query)(q, (0, import_firestore8.startAfter)(startAfterDoc));
|
|
3788
3284
|
}
|
|
3789
3285
|
}
|
|
3790
|
-
const patientsSnapshot = await (0,
|
|
3286
|
+
const patientsSnapshot = await (0, import_firestore8.getDocs)(q);
|
|
3791
3287
|
const patients = [];
|
|
3792
3288
|
patientsSnapshot.forEach((doc37) => {
|
|
3793
3289
|
patients.push(doc37.data());
|
|
@@ -3820,7 +3316,7 @@ var getPatientsByPractitionerWithDetailsUtil = async (db, practitionerId, option
|
|
|
3820
3316
|
const patientProfilesWithDetails = await Promise.all(
|
|
3821
3317
|
patientProfiles.map(async (profile) => {
|
|
3822
3318
|
try {
|
|
3823
|
-
const sensitiveInfoDoc = await (0,
|
|
3319
|
+
const sensitiveInfoDoc = await (0, import_firestore8.getDoc)(
|
|
3824
3320
|
getSensitiveInfoDocRef(db, profile.id)
|
|
3825
3321
|
);
|
|
3826
3322
|
const sensitiveInfo = sensitiveInfoDoc.exists() ? sensitiveInfoDoc.data() : void 0;
|
|
@@ -3856,13 +3352,13 @@ var getPractitionerProfileByUserRef = async (db, userRef) => {
|
|
|
3856
3352
|
console.log(
|
|
3857
3353
|
`[getPractitionerProfileByUserRef] Fetching practitioner with userRef: ${userRef}`
|
|
3858
3354
|
);
|
|
3859
|
-
const practitionersCollection = (0,
|
|
3860
|
-
const q = (0,
|
|
3355
|
+
const practitionersCollection = (0, import_firestore8.collection)(db, PRACTITIONERS_COLLECTION);
|
|
3356
|
+
const q = (0, import_firestore8.query)(
|
|
3861
3357
|
practitionersCollection,
|
|
3862
|
-
(0,
|
|
3863
|
-
(0,
|
|
3358
|
+
(0, import_firestore8.where)("userRef", "==", userRef),
|
|
3359
|
+
(0, import_firestore8.limit)(1)
|
|
3864
3360
|
);
|
|
3865
|
-
const querySnapshot = await (0,
|
|
3361
|
+
const querySnapshot = await (0, import_firestore8.getDocs)(q);
|
|
3866
3362
|
if (querySnapshot.empty) {
|
|
3867
3363
|
console.log(
|
|
3868
3364
|
`[getPractitionerProfileByUserRef] No practitioner found with userRef: ${userRef}`
|
|
@@ -3884,40 +3380,237 @@ var getPractitionerProfileByUserRef = async (db, userRef) => {
|
|
|
3884
3380
|
`Failed to retrieve practitioner by userRef: ${error instanceof Error ? error.message : String(error)}`
|
|
3885
3381
|
);
|
|
3886
3382
|
}
|
|
3887
|
-
};
|
|
3383
|
+
};
|
|
3384
|
+
|
|
3385
|
+
// src/services/clinic/utils/admin.utils.ts
|
|
3386
|
+
var import_firestore10 = require("firebase/firestore");
|
|
3387
|
+
|
|
3388
|
+
// src/validations/clinic.schema.ts
|
|
3389
|
+
var import_zod10 = require("zod");
|
|
3390
|
+
var import_firestore9 = require("firebase/firestore");
|
|
3391
|
+
|
|
3392
|
+
// src/validations/reviews.schema.ts
|
|
3393
|
+
var import_zod8 = require("zod");
|
|
3394
|
+
var baseReviewSchema = import_zod8.z.object({
|
|
3395
|
+
id: import_zod8.z.string().min(1),
|
|
3396
|
+
patientId: import_zod8.z.string().min(1),
|
|
3397
|
+
fullReviewId: import_zod8.z.string().min(1),
|
|
3398
|
+
createdAt: import_zod8.z.date(),
|
|
3399
|
+
updatedAt: import_zod8.z.date(),
|
|
3400
|
+
comment: import_zod8.z.string().min(1).max(2e3),
|
|
3401
|
+
isVerified: import_zod8.z.boolean(),
|
|
3402
|
+
isPublished: import_zod8.z.boolean()
|
|
3403
|
+
});
|
|
3404
|
+
var baseReviewCreateSchema = import_zod8.z.object({
|
|
3405
|
+
patientId: import_zod8.z.string().min(1),
|
|
3406
|
+
comment: import_zod8.z.string().min(1).max(2e3),
|
|
3407
|
+
isVerified: import_zod8.z.boolean().default(false),
|
|
3408
|
+
isPublished: import_zod8.z.boolean().default(true)
|
|
3409
|
+
});
|
|
3410
|
+
var clinicReviewSchema = baseReviewSchema.extend({
|
|
3411
|
+
clinicId: import_zod8.z.string().min(1),
|
|
3412
|
+
cleanliness: import_zod8.z.number().min(1).max(5),
|
|
3413
|
+
facilities: import_zod8.z.number().min(1).max(5),
|
|
3414
|
+
staffFriendliness: import_zod8.z.number().min(1).max(5),
|
|
3415
|
+
waitingTime: import_zod8.z.number().min(1).max(5),
|
|
3416
|
+
accessibility: import_zod8.z.number().min(1).max(5),
|
|
3417
|
+
overallRating: import_zod8.z.number().min(1).max(5),
|
|
3418
|
+
wouldRecommend: import_zod8.z.boolean()
|
|
3419
|
+
});
|
|
3420
|
+
var createClinicReviewSchema = baseReviewCreateSchema.extend({
|
|
3421
|
+
clinicId: import_zod8.z.string().min(1),
|
|
3422
|
+
cleanliness: import_zod8.z.number().min(1).max(5),
|
|
3423
|
+
facilities: import_zod8.z.number().min(1).max(5),
|
|
3424
|
+
staffFriendliness: import_zod8.z.number().min(1).max(5),
|
|
3425
|
+
waitingTime: import_zod8.z.number().min(1).max(5),
|
|
3426
|
+
accessibility: import_zod8.z.number().min(1).max(5),
|
|
3427
|
+
wouldRecommend: import_zod8.z.boolean()
|
|
3428
|
+
});
|
|
3429
|
+
var practitionerReviewSchema = baseReviewSchema.extend({
|
|
3430
|
+
practitionerId: import_zod8.z.string().min(1),
|
|
3431
|
+
knowledgeAndExpertise: import_zod8.z.number().min(1).max(5),
|
|
3432
|
+
communicationSkills: import_zod8.z.number().min(1).max(5),
|
|
3433
|
+
bedSideManner: import_zod8.z.number().min(1).max(5),
|
|
3434
|
+
thoroughness: import_zod8.z.number().min(1).max(5),
|
|
3435
|
+
trustworthiness: import_zod8.z.number().min(1).max(5),
|
|
3436
|
+
overallRating: import_zod8.z.number().min(1).max(5),
|
|
3437
|
+
wouldRecommend: import_zod8.z.boolean()
|
|
3438
|
+
});
|
|
3439
|
+
var createPractitionerReviewSchema = baseReviewCreateSchema.extend({
|
|
3440
|
+
practitionerId: import_zod8.z.string().min(1),
|
|
3441
|
+
knowledgeAndExpertise: import_zod8.z.number().min(1).max(5),
|
|
3442
|
+
communicationSkills: import_zod8.z.number().min(1).max(5),
|
|
3443
|
+
bedSideManner: import_zod8.z.number().min(1).max(5),
|
|
3444
|
+
thoroughness: import_zod8.z.number().min(1).max(5),
|
|
3445
|
+
trustworthiness: import_zod8.z.number().min(1).max(5),
|
|
3446
|
+
wouldRecommend: import_zod8.z.boolean()
|
|
3447
|
+
});
|
|
3448
|
+
var procedureReviewSchema = baseReviewSchema.extend({
|
|
3449
|
+
procedureId: import_zod8.z.string().min(1),
|
|
3450
|
+
effectivenessOfTreatment: import_zod8.z.number().min(1).max(5),
|
|
3451
|
+
outcomeExplanation: import_zod8.z.number().min(1).max(5),
|
|
3452
|
+
painManagement: import_zod8.z.number().min(1).max(5),
|
|
3453
|
+
followUpCare: import_zod8.z.number().min(1).max(5),
|
|
3454
|
+
valueForMoney: import_zod8.z.number().min(1).max(5),
|
|
3455
|
+
overallRating: import_zod8.z.number().min(1).max(5),
|
|
3456
|
+
wouldRecommend: import_zod8.z.boolean()
|
|
3457
|
+
});
|
|
3458
|
+
var createProcedureReviewSchema = baseReviewCreateSchema.extend({
|
|
3459
|
+
procedureId: import_zod8.z.string().min(1),
|
|
3460
|
+
effectivenessOfTreatment: import_zod8.z.number().min(1).max(5),
|
|
3461
|
+
outcomeExplanation: import_zod8.z.number().min(1).max(5),
|
|
3462
|
+
painManagement: import_zod8.z.number().min(1).max(5),
|
|
3463
|
+
followUpCare: import_zod8.z.number().min(1).max(5),
|
|
3464
|
+
valueForMoney: import_zod8.z.number().min(1).max(5),
|
|
3465
|
+
wouldRecommend: import_zod8.z.boolean()
|
|
3466
|
+
});
|
|
3467
|
+
var clinicReviewInfoSchema = import_zod8.z.object({
|
|
3468
|
+
totalReviews: import_zod8.z.number().min(0),
|
|
3469
|
+
averageRating: import_zod8.z.number().min(0).max(5),
|
|
3470
|
+
cleanliness: import_zod8.z.number().min(0).max(5),
|
|
3471
|
+
facilities: import_zod8.z.number().min(0).max(5),
|
|
3472
|
+
staffFriendliness: import_zod8.z.number().min(0).max(5),
|
|
3473
|
+
waitingTime: import_zod8.z.number().min(0).max(5),
|
|
3474
|
+
accessibility: import_zod8.z.number().min(0).max(5),
|
|
3475
|
+
recommendationPercentage: import_zod8.z.number().min(0).max(100)
|
|
3476
|
+
});
|
|
3477
|
+
var practitionerReviewInfoSchema = import_zod8.z.object({
|
|
3478
|
+
totalReviews: import_zod8.z.number().min(0),
|
|
3479
|
+
averageRating: import_zod8.z.number().min(0).max(5),
|
|
3480
|
+
knowledgeAndExpertise: import_zod8.z.number().min(0).max(5),
|
|
3481
|
+
communicationSkills: import_zod8.z.number().min(0).max(5),
|
|
3482
|
+
bedSideManner: import_zod8.z.number().min(0).max(5),
|
|
3483
|
+
thoroughness: import_zod8.z.number().min(0).max(5),
|
|
3484
|
+
trustworthiness: import_zod8.z.number().min(0).max(5),
|
|
3485
|
+
recommendationPercentage: import_zod8.z.number().min(0).max(100)
|
|
3486
|
+
});
|
|
3487
|
+
var procedureReviewInfoSchema = import_zod8.z.object({
|
|
3488
|
+
totalReviews: import_zod8.z.number().min(0),
|
|
3489
|
+
averageRating: import_zod8.z.number().min(0).max(5),
|
|
3490
|
+
effectivenessOfTreatment: import_zod8.z.number().min(0).max(5),
|
|
3491
|
+
outcomeExplanation: import_zod8.z.number().min(0).max(5),
|
|
3492
|
+
painManagement: import_zod8.z.number().min(0).max(5),
|
|
3493
|
+
followUpCare: import_zod8.z.number().min(0).max(5),
|
|
3494
|
+
valueForMoney: import_zod8.z.number().min(0).max(5),
|
|
3495
|
+
recommendationPercentage: import_zod8.z.number().min(0).max(100)
|
|
3496
|
+
});
|
|
3497
|
+
var reviewSchema = import_zod8.z.object({
|
|
3498
|
+
id: import_zod8.z.string().min(1),
|
|
3499
|
+
appointmentId: import_zod8.z.string().min(1),
|
|
3500
|
+
patientId: import_zod8.z.string().min(1),
|
|
3501
|
+
createdAt: import_zod8.z.date(),
|
|
3502
|
+
updatedAt: import_zod8.z.date(),
|
|
3503
|
+
clinicReview: clinicReviewSchema.optional(),
|
|
3504
|
+
practitionerReview: practitionerReviewSchema.optional(),
|
|
3505
|
+
procedureReview: procedureReviewSchema.optional(),
|
|
3506
|
+
overallComment: import_zod8.z.string().min(1).max(2e3),
|
|
3507
|
+
overallRating: import_zod8.z.number().min(1).max(5)
|
|
3508
|
+
});
|
|
3509
|
+
var createReviewSchema = import_zod8.z.object({
|
|
3510
|
+
patientId: import_zod8.z.string().min(1),
|
|
3511
|
+
clinicReview: createClinicReviewSchema.optional(),
|
|
3512
|
+
practitionerReview: createPractitionerReviewSchema.optional(),
|
|
3513
|
+
procedureReview: createProcedureReviewSchema.optional(),
|
|
3514
|
+
overallComment: import_zod8.z.string().min(1).max(2e3)
|
|
3515
|
+
}).refine(
|
|
3516
|
+
(data) => {
|
|
3517
|
+
return data.clinicReview || data.practitionerReview || data.procedureReview;
|
|
3518
|
+
},
|
|
3519
|
+
{
|
|
3520
|
+
message: "At least one review type (clinic, practitioner, or procedure) must be provided",
|
|
3521
|
+
path: ["reviewType"]
|
|
3522
|
+
}
|
|
3523
|
+
);
|
|
3888
3524
|
|
|
3889
|
-
// src/
|
|
3890
|
-
var
|
|
3525
|
+
// src/validations/shared.schema.ts
|
|
3526
|
+
var import_zod9 = require("zod");
|
|
3527
|
+
|
|
3528
|
+
// src/backoffice/types/static/procedure-family.types.ts
|
|
3529
|
+
var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
|
|
3530
|
+
ProcedureFamily2["AESTHETICS"] = "aesthetics";
|
|
3531
|
+
ProcedureFamily2["SURGERY"] = "surgery";
|
|
3532
|
+
return ProcedureFamily2;
|
|
3533
|
+
})(ProcedureFamily || {});
|
|
3534
|
+
|
|
3535
|
+
// src/validations/shared.schema.ts
|
|
3536
|
+
var sharedClinicContactInfoSchema = import_zod9.z.object({
|
|
3537
|
+
email: import_zod9.z.string().email(),
|
|
3538
|
+
phoneNumber: import_zod9.z.string(),
|
|
3539
|
+
alternativePhoneNumber: import_zod9.z.string().nullable().optional(),
|
|
3540
|
+
website: import_zod9.z.string().nullable().optional()
|
|
3541
|
+
});
|
|
3542
|
+
var sharedClinicLocationSchema = import_zod9.z.object({
|
|
3543
|
+
address: import_zod9.z.string(),
|
|
3544
|
+
city: import_zod9.z.string(),
|
|
3545
|
+
country: import_zod9.z.string(),
|
|
3546
|
+
postalCode: import_zod9.z.string(),
|
|
3547
|
+
latitude: import_zod9.z.number().min(-90).max(90),
|
|
3548
|
+
longitude: import_zod9.z.number().min(-180).max(180),
|
|
3549
|
+
geohash: import_zod9.z.string().nullable().optional()
|
|
3550
|
+
});
|
|
3551
|
+
var procedureSummaryInfoSchema = import_zod9.z.object({
|
|
3552
|
+
id: import_zod9.z.string().min(1),
|
|
3553
|
+
name: import_zod9.z.string().min(1),
|
|
3554
|
+
description: import_zod9.z.string().optional(),
|
|
3555
|
+
photo: import_zod9.z.string().optional(),
|
|
3556
|
+
family: import_zod9.z.nativeEnum(ProcedureFamily),
|
|
3557
|
+
categoryName: import_zod9.z.string(),
|
|
3558
|
+
subcategoryName: import_zod9.z.string(),
|
|
3559
|
+
technologyName: import_zod9.z.string(),
|
|
3560
|
+
price: import_zod9.z.number().nonnegative(),
|
|
3561
|
+
pricingMeasure: import_zod9.z.nativeEnum(PricingMeasure),
|
|
3562
|
+
currency: import_zod9.z.nativeEnum(Currency),
|
|
3563
|
+
duration: import_zod9.z.number().int().positive(),
|
|
3564
|
+
clinicId: import_zod9.z.string().min(1),
|
|
3565
|
+
clinicName: import_zod9.z.string().min(1),
|
|
3566
|
+
practitionerId: import_zod9.z.string().min(1),
|
|
3567
|
+
practitionerName: import_zod9.z.string().min(1)
|
|
3568
|
+
});
|
|
3569
|
+
var clinicInfoSchema = import_zod9.z.object({
|
|
3570
|
+
id: import_zod9.z.string(),
|
|
3571
|
+
featuredPhoto: import_zod9.z.string(),
|
|
3572
|
+
name: import_zod9.z.string(),
|
|
3573
|
+
description: import_zod9.z.string().nullable().optional(),
|
|
3574
|
+
location: sharedClinicLocationSchema,
|
|
3575
|
+
contactInfo: sharedClinicContactInfoSchema
|
|
3576
|
+
});
|
|
3577
|
+
var doctorInfoSchema = import_zod9.z.object({
|
|
3578
|
+
id: import_zod9.z.string(),
|
|
3579
|
+
name: import_zod9.z.string(),
|
|
3580
|
+
description: import_zod9.z.string().nullable().optional(),
|
|
3581
|
+
photo: import_zod9.z.string(),
|
|
3582
|
+
rating: import_zod9.z.number().min(0).max(5),
|
|
3583
|
+
services: import_zod9.z.array(import_zod9.z.string())
|
|
3584
|
+
// List of procedure IDs practitioner offers
|
|
3585
|
+
});
|
|
3891
3586
|
|
|
3892
3587
|
// src/validations/clinic.schema.ts
|
|
3893
|
-
var
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
alternativePhoneNumber: import_zod13.z.string().nullable().optional(),
|
|
3899
|
-
website: import_zod13.z.string().nullable().optional()
|
|
3588
|
+
var clinicContactInfoSchema = import_zod10.z.object({
|
|
3589
|
+
email: import_zod10.z.string().email(),
|
|
3590
|
+
phoneNumber: import_zod10.z.string(),
|
|
3591
|
+
alternativePhoneNumber: import_zod10.z.string().nullable().optional(),
|
|
3592
|
+
website: import_zod10.z.string().nullable().optional()
|
|
3900
3593
|
});
|
|
3901
|
-
var clinicLocationSchema =
|
|
3902
|
-
address:
|
|
3903
|
-
city:
|
|
3904
|
-
country:
|
|
3905
|
-
postalCode:
|
|
3906
|
-
latitude:
|
|
3907
|
-
longitude:
|
|
3908
|
-
geohash:
|
|
3594
|
+
var clinicLocationSchema = import_zod10.z.object({
|
|
3595
|
+
address: import_zod10.z.string(),
|
|
3596
|
+
city: import_zod10.z.string(),
|
|
3597
|
+
country: import_zod10.z.string(),
|
|
3598
|
+
postalCode: import_zod10.z.string(),
|
|
3599
|
+
latitude: import_zod10.z.number().min(-90).max(90),
|
|
3600
|
+
longitude: import_zod10.z.number().min(-180).max(180),
|
|
3601
|
+
geohash: import_zod10.z.string().nullable().optional()
|
|
3909
3602
|
});
|
|
3910
|
-
var workingHoursTimeSchema =
|
|
3911
|
-
open:
|
|
3912
|
-
close:
|
|
3913
|
-
breaks:
|
|
3914
|
-
|
|
3915
|
-
start:
|
|
3916
|
-
end:
|
|
3603
|
+
var workingHoursTimeSchema = import_zod10.z.object({
|
|
3604
|
+
open: import_zod10.z.string(),
|
|
3605
|
+
close: import_zod10.z.string(),
|
|
3606
|
+
breaks: import_zod10.z.array(
|
|
3607
|
+
import_zod10.z.object({
|
|
3608
|
+
start: import_zod10.z.string(),
|
|
3609
|
+
end: import_zod10.z.string()
|
|
3917
3610
|
})
|
|
3918
3611
|
).optional()
|
|
3919
3612
|
});
|
|
3920
|
-
var workingHoursSchema =
|
|
3613
|
+
var workingHoursSchema = import_zod10.z.object({
|
|
3921
3614
|
monday: workingHoursTimeSchema.nullable(),
|
|
3922
3615
|
tuesday: workingHoursTimeSchema.nullable(),
|
|
3923
3616
|
wednesday: workingHoursTimeSchema.nullable(),
|
|
@@ -3926,255 +3619,255 @@ var workingHoursSchema = import_zod13.z.object({
|
|
|
3926
3619
|
saturday: workingHoursTimeSchema.nullable(),
|
|
3927
3620
|
sunday: workingHoursTimeSchema.nullable()
|
|
3928
3621
|
});
|
|
3929
|
-
var clinicTagsSchema =
|
|
3930
|
-
tags:
|
|
3622
|
+
var clinicTagsSchema = import_zod10.z.object({
|
|
3623
|
+
tags: import_zod10.z.array(import_zod10.z.nativeEnum(ClinicTag))
|
|
3931
3624
|
});
|
|
3932
|
-
var contactPersonSchema =
|
|
3933
|
-
firstName:
|
|
3934
|
-
lastName:
|
|
3935
|
-
title:
|
|
3936
|
-
email:
|
|
3937
|
-
phoneNumber:
|
|
3625
|
+
var contactPersonSchema = import_zod10.z.object({
|
|
3626
|
+
firstName: import_zod10.z.string(),
|
|
3627
|
+
lastName: import_zod10.z.string(),
|
|
3628
|
+
title: import_zod10.z.string().nullable().optional(),
|
|
3629
|
+
email: import_zod10.z.string().email(),
|
|
3630
|
+
phoneNumber: import_zod10.z.string().nullable().optional()
|
|
3938
3631
|
});
|
|
3939
|
-
var adminInfoSchema =
|
|
3940
|
-
id:
|
|
3941
|
-
name:
|
|
3942
|
-
email:
|
|
3632
|
+
var adminInfoSchema = import_zod10.z.object({
|
|
3633
|
+
id: import_zod10.z.string(),
|
|
3634
|
+
name: import_zod10.z.string(),
|
|
3635
|
+
email: import_zod10.z.string().email()
|
|
3943
3636
|
});
|
|
3944
|
-
var clinicAdminSchema =
|
|
3945
|
-
id:
|
|
3946
|
-
userRef:
|
|
3947
|
-
clinicGroupId:
|
|
3948
|
-
isGroupOwner:
|
|
3949
|
-
clinicsManaged:
|
|
3950
|
-
clinicsManagedInfo:
|
|
3637
|
+
var clinicAdminSchema = import_zod10.z.object({
|
|
3638
|
+
id: import_zod10.z.string(),
|
|
3639
|
+
userRef: import_zod10.z.string(),
|
|
3640
|
+
clinicGroupId: import_zod10.z.string(),
|
|
3641
|
+
isGroupOwner: import_zod10.z.boolean(),
|
|
3642
|
+
clinicsManaged: import_zod10.z.array(import_zod10.z.string()),
|
|
3643
|
+
clinicsManagedInfo: import_zod10.z.array(clinicInfoSchema),
|
|
3951
3644
|
contactInfo: contactPersonSchema,
|
|
3952
|
-
roleTitle:
|
|
3953
|
-
createdAt:
|
|
3954
|
-
updatedAt:
|
|
3955
|
-
isActive:
|
|
3645
|
+
roleTitle: import_zod10.z.string(),
|
|
3646
|
+
createdAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)),
|
|
3647
|
+
updatedAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)),
|
|
3648
|
+
isActive: import_zod10.z.boolean()
|
|
3956
3649
|
});
|
|
3957
|
-
var adminTokenSchema =
|
|
3958
|
-
id:
|
|
3959
|
-
token:
|
|
3960
|
-
email:
|
|
3961
|
-
status:
|
|
3962
|
-
usedByUserRef:
|
|
3963
|
-
createdAt:
|
|
3650
|
+
var adminTokenSchema = import_zod10.z.object({
|
|
3651
|
+
id: import_zod10.z.string(),
|
|
3652
|
+
token: import_zod10.z.string(),
|
|
3653
|
+
email: import_zod10.z.string().email().optional().nullable(),
|
|
3654
|
+
status: import_zod10.z.nativeEnum(AdminTokenStatus),
|
|
3655
|
+
usedByUserRef: import_zod10.z.string().optional(),
|
|
3656
|
+
createdAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)),
|
|
3964
3657
|
// Timestamp
|
|
3965
|
-
expiresAt:
|
|
3658
|
+
expiresAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp))
|
|
3966
3659
|
// Timestamp
|
|
3967
3660
|
});
|
|
3968
|
-
var createAdminTokenSchema =
|
|
3969
|
-
expiresInDays:
|
|
3970
|
-
email:
|
|
3661
|
+
var createAdminTokenSchema = import_zod10.z.object({
|
|
3662
|
+
expiresInDays: import_zod10.z.number().min(1).max(30).optional(),
|
|
3663
|
+
email: import_zod10.z.string().email().optional().nullable()
|
|
3971
3664
|
});
|
|
3972
|
-
var clinicGroupSchema =
|
|
3973
|
-
id:
|
|
3974
|
-
name:
|
|
3975
|
-
description:
|
|
3665
|
+
var clinicGroupSchema = import_zod10.z.object({
|
|
3666
|
+
id: import_zod10.z.string(),
|
|
3667
|
+
name: import_zod10.z.string(),
|
|
3668
|
+
description: import_zod10.z.string().nullable().optional(),
|
|
3976
3669
|
hqLocation: clinicLocationSchema,
|
|
3977
3670
|
contactInfo: clinicContactInfoSchema,
|
|
3978
3671
|
contactPerson: contactPersonSchema,
|
|
3979
|
-
clinics:
|
|
3980
|
-
clinicsInfo:
|
|
3981
|
-
admins:
|
|
3982
|
-
adminsInfo:
|
|
3983
|
-
adminTokens:
|
|
3984
|
-
ownerId:
|
|
3985
|
-
createdAt:
|
|
3672
|
+
clinics: import_zod10.z.array(import_zod10.z.string()),
|
|
3673
|
+
clinicsInfo: import_zod10.z.array(clinicInfoSchema),
|
|
3674
|
+
admins: import_zod10.z.array(import_zod10.z.string()),
|
|
3675
|
+
adminsInfo: import_zod10.z.array(adminInfoSchema),
|
|
3676
|
+
adminTokens: import_zod10.z.array(adminTokenSchema),
|
|
3677
|
+
ownerId: import_zod10.z.string().nullable(),
|
|
3678
|
+
createdAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)),
|
|
3986
3679
|
// Timestamp
|
|
3987
|
-
updatedAt:
|
|
3680
|
+
updatedAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)),
|
|
3988
3681
|
// Timestamp
|
|
3989
|
-
isActive:
|
|
3682
|
+
isActive: import_zod10.z.boolean(),
|
|
3990
3683
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3991
|
-
practiceType:
|
|
3992
|
-
languages:
|
|
3993
|
-
subscriptionModel:
|
|
3994
|
-
calendarSyncEnabled:
|
|
3995
|
-
autoConfirmAppointments:
|
|
3996
|
-
businessIdentificationNumber:
|
|
3997
|
-
onboarding:
|
|
3998
|
-
completed:
|
|
3999
|
-
step:
|
|
3684
|
+
practiceType: import_zod10.z.nativeEnum(PracticeType).optional(),
|
|
3685
|
+
languages: import_zod10.z.array(import_zod10.z.nativeEnum(Language)).optional(),
|
|
3686
|
+
subscriptionModel: import_zod10.z.nativeEnum(SubscriptionModel),
|
|
3687
|
+
calendarSyncEnabled: import_zod10.z.boolean().optional(),
|
|
3688
|
+
autoConfirmAppointments: import_zod10.z.boolean().optional(),
|
|
3689
|
+
businessIdentificationNumber: import_zod10.z.string().optional().nullable(),
|
|
3690
|
+
onboarding: import_zod10.z.object({
|
|
3691
|
+
completed: import_zod10.z.boolean().optional().default(false),
|
|
3692
|
+
step: import_zod10.z.number().optional().default(1)
|
|
4000
3693
|
}).optional()
|
|
4001
3694
|
});
|
|
4002
|
-
var clinicSchema =
|
|
4003
|
-
id:
|
|
4004
|
-
clinicGroupId:
|
|
4005
|
-
name:
|
|
4006
|
-
description:
|
|
3695
|
+
var clinicSchema = import_zod10.z.object({
|
|
3696
|
+
id: import_zod10.z.string(),
|
|
3697
|
+
clinicGroupId: import_zod10.z.string(),
|
|
3698
|
+
name: import_zod10.z.string(),
|
|
3699
|
+
description: import_zod10.z.string().nullable().optional(),
|
|
4007
3700
|
location: clinicLocationSchema,
|
|
4008
3701
|
contactInfo: clinicContactInfoSchema,
|
|
4009
3702
|
workingHours: workingHoursSchema,
|
|
4010
|
-
tags:
|
|
4011
|
-
featuredPhotos:
|
|
3703
|
+
tags: import_zod10.z.array(import_zod10.z.nativeEnum(ClinicTag)),
|
|
3704
|
+
featuredPhotos: import_zod10.z.array(mediaResourceSchema),
|
|
4012
3705
|
coverPhoto: mediaResourceSchema.nullable(),
|
|
4013
|
-
photosWithTags:
|
|
4014
|
-
|
|
3706
|
+
photosWithTags: import_zod10.z.array(
|
|
3707
|
+
import_zod10.z.object({
|
|
4015
3708
|
url: mediaResourceSchema,
|
|
4016
|
-
tag:
|
|
3709
|
+
tag: import_zod10.z.string()
|
|
4017
3710
|
})
|
|
4018
3711
|
).optional(),
|
|
4019
|
-
doctors:
|
|
3712
|
+
doctors: import_zod10.z.array(import_zod10.z.string()),
|
|
4020
3713
|
// List of practitioner IDs
|
|
4021
|
-
doctorsInfo:
|
|
3714
|
+
doctorsInfo: import_zod10.z.array(doctorInfoSchema),
|
|
4022
3715
|
// Aggregated doctor info
|
|
4023
|
-
procedures:
|
|
3716
|
+
procedures: import_zod10.z.array(import_zod10.z.string()),
|
|
4024
3717
|
// List of procedure IDs offered by clinic
|
|
4025
|
-
proceduresInfo:
|
|
3718
|
+
proceduresInfo: import_zod10.z.array(procedureSummaryInfoSchema),
|
|
4026
3719
|
// Use the correct schema for aggregated procedure info
|
|
4027
3720
|
reviewInfo: clinicReviewInfoSchema,
|
|
4028
|
-
admins:
|
|
4029
|
-
createdAt:
|
|
3721
|
+
admins: import_zod10.z.array(import_zod10.z.string()),
|
|
3722
|
+
createdAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)),
|
|
4030
3723
|
// Timestamp
|
|
4031
|
-
updatedAt:
|
|
3724
|
+
updatedAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)),
|
|
4032
3725
|
// Timestamp
|
|
4033
|
-
isActive:
|
|
4034
|
-
isVerified:
|
|
3726
|
+
isActive: import_zod10.z.boolean(),
|
|
3727
|
+
isVerified: import_zod10.z.boolean(),
|
|
4035
3728
|
logo: mediaResourceSchema.optional().nullable()
|
|
4036
3729
|
});
|
|
4037
|
-
var createClinicAdminSchema =
|
|
4038
|
-
userRef:
|
|
4039
|
-
clinicGroupId:
|
|
4040
|
-
isGroupOwner:
|
|
4041
|
-
clinicsManaged:
|
|
3730
|
+
var createClinicAdminSchema = import_zod10.z.object({
|
|
3731
|
+
userRef: import_zod10.z.string(),
|
|
3732
|
+
clinicGroupId: import_zod10.z.string().optional(),
|
|
3733
|
+
isGroupOwner: import_zod10.z.boolean(),
|
|
3734
|
+
clinicsManaged: import_zod10.z.array(import_zod10.z.string()),
|
|
4042
3735
|
contactInfo: contactPersonSchema,
|
|
4043
|
-
roleTitle:
|
|
4044
|
-
isActive:
|
|
3736
|
+
roleTitle: import_zod10.z.string(),
|
|
3737
|
+
isActive: import_zod10.z.boolean()
|
|
4045
3738
|
// clinicsManagedInfo is aggregated, not provided on creation
|
|
4046
3739
|
});
|
|
4047
|
-
var createClinicGroupSchema =
|
|
4048
|
-
name:
|
|
4049
|
-
description:
|
|
3740
|
+
var createClinicGroupSchema = import_zod10.z.object({
|
|
3741
|
+
name: import_zod10.z.string(),
|
|
3742
|
+
description: import_zod10.z.string().optional(),
|
|
4050
3743
|
hqLocation: clinicLocationSchema,
|
|
4051
3744
|
contactInfo: clinicContactInfoSchema,
|
|
4052
3745
|
contactPerson: contactPersonSchema,
|
|
4053
|
-
ownerId:
|
|
4054
|
-
isActive:
|
|
3746
|
+
ownerId: import_zod10.z.string().nullable(),
|
|
3747
|
+
isActive: import_zod10.z.boolean(),
|
|
4055
3748
|
logo: mediaResourceSchema.optional().nullable(),
|
|
4056
|
-
practiceType:
|
|
4057
|
-
languages:
|
|
4058
|
-
subscriptionModel:
|
|
4059
|
-
calendarSyncEnabled:
|
|
4060
|
-
autoConfirmAppointments:
|
|
4061
|
-
businessIdentificationNumber:
|
|
4062
|
-
onboarding:
|
|
4063
|
-
completed:
|
|
4064
|
-
step:
|
|
3749
|
+
practiceType: import_zod10.z.nativeEnum(PracticeType).optional(),
|
|
3750
|
+
languages: import_zod10.z.array(import_zod10.z.nativeEnum(Language)).optional(),
|
|
3751
|
+
subscriptionModel: import_zod10.z.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
|
|
3752
|
+
calendarSyncEnabled: import_zod10.z.boolean().optional(),
|
|
3753
|
+
autoConfirmAppointments: import_zod10.z.boolean().optional(),
|
|
3754
|
+
businessIdentificationNumber: import_zod10.z.string().optional().nullable(),
|
|
3755
|
+
onboarding: import_zod10.z.object({
|
|
3756
|
+
completed: import_zod10.z.boolean().optional().default(false),
|
|
3757
|
+
step: import_zod10.z.number().optional().default(1)
|
|
4065
3758
|
}).optional()
|
|
4066
3759
|
// clinics, clinicsInfo, admins, adminsInfo, adminTokens are managed internally
|
|
4067
3760
|
});
|
|
4068
|
-
var createClinicSchema =
|
|
4069
|
-
clinicGroupId:
|
|
4070
|
-
name:
|
|
4071
|
-
description:
|
|
3761
|
+
var createClinicSchema = import_zod10.z.object({
|
|
3762
|
+
clinicGroupId: import_zod10.z.string(),
|
|
3763
|
+
name: import_zod10.z.string(),
|
|
3764
|
+
description: import_zod10.z.string().optional(),
|
|
4072
3765
|
location: clinicLocationSchema,
|
|
4073
3766
|
contactInfo: clinicContactInfoSchema,
|
|
4074
3767
|
workingHours: workingHoursSchema,
|
|
4075
|
-
tags:
|
|
3768
|
+
tags: import_zod10.z.array(import_zod10.z.nativeEnum(ClinicTag)),
|
|
4076
3769
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
4077
|
-
photosWithTags:
|
|
4078
|
-
|
|
3770
|
+
photosWithTags: import_zod10.z.array(
|
|
3771
|
+
import_zod10.z.object({
|
|
4079
3772
|
url: mediaResourceSchema,
|
|
4080
|
-
tag:
|
|
3773
|
+
tag: import_zod10.z.string()
|
|
4081
3774
|
})
|
|
4082
3775
|
).optional(),
|
|
4083
|
-
doctors:
|
|
4084
|
-
procedures:
|
|
4085
|
-
proceduresInfo:
|
|
4086
|
-
admins:
|
|
4087
|
-
isActive:
|
|
4088
|
-
isVerified:
|
|
3776
|
+
doctors: import_zod10.z.array(import_zod10.z.string()).optional().default([]),
|
|
3777
|
+
procedures: import_zod10.z.array(import_zod10.z.string()).optional().default([]),
|
|
3778
|
+
proceduresInfo: import_zod10.z.array(procedureSummaryInfoSchema).optional(),
|
|
3779
|
+
admins: import_zod10.z.array(import_zod10.z.string()),
|
|
3780
|
+
isActive: import_zod10.z.boolean().optional().default(true),
|
|
3781
|
+
isVerified: import_zod10.z.boolean().optional().default(false),
|
|
4089
3782
|
logo: mediaResourceSchema.optional().nullable(),
|
|
4090
|
-
featuredPhotos:
|
|
3783
|
+
featuredPhotos: import_zod10.z.array(mediaResourceSchema).optional().default([])
|
|
4091
3784
|
});
|
|
4092
|
-
var createDefaultClinicGroupSchema =
|
|
4093
|
-
name:
|
|
4094
|
-
ownerId:
|
|
3785
|
+
var createDefaultClinicGroupSchema = import_zod10.z.object({
|
|
3786
|
+
name: import_zod10.z.string(),
|
|
3787
|
+
ownerId: import_zod10.z.string().nullable(),
|
|
4095
3788
|
contactPerson: contactPersonSchema,
|
|
4096
3789
|
contactInfo: clinicContactInfoSchema,
|
|
4097
3790
|
hqLocation: clinicLocationSchema,
|
|
4098
|
-
isActive:
|
|
3791
|
+
isActive: import_zod10.z.boolean(),
|
|
4099
3792
|
logo: mediaResourceSchema.optional().nullable(),
|
|
4100
|
-
practiceType:
|
|
4101
|
-
languages:
|
|
4102
|
-
subscriptionModel:
|
|
4103
|
-
onboarding:
|
|
4104
|
-
completed:
|
|
4105
|
-
step:
|
|
3793
|
+
practiceType: import_zod10.z.nativeEnum(PracticeType).optional(),
|
|
3794
|
+
languages: import_zod10.z.array(import_zod10.z.nativeEnum(Language)).optional(),
|
|
3795
|
+
subscriptionModel: import_zod10.z.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
|
|
3796
|
+
onboarding: import_zod10.z.object({
|
|
3797
|
+
completed: import_zod10.z.boolean().optional().default(false),
|
|
3798
|
+
step: import_zod10.z.number().optional().default(1)
|
|
4106
3799
|
}).optional()
|
|
4107
3800
|
});
|
|
4108
|
-
var clinicAdminSignupSchema =
|
|
4109
|
-
email:
|
|
4110
|
-
password:
|
|
4111
|
-
firstName:
|
|
4112
|
-
lastName:
|
|
4113
|
-
title:
|
|
4114
|
-
phoneNumber:
|
|
4115
|
-
isCreatingNewGroup:
|
|
4116
|
-
inviteToken:
|
|
4117
|
-
clinicGroupData:
|
|
4118
|
-
name:
|
|
3801
|
+
var clinicAdminSignupSchema = import_zod10.z.object({
|
|
3802
|
+
email: import_zod10.z.string().email(),
|
|
3803
|
+
password: import_zod10.z.string().min(8),
|
|
3804
|
+
firstName: import_zod10.z.string(),
|
|
3805
|
+
lastName: import_zod10.z.string(),
|
|
3806
|
+
title: import_zod10.z.string(),
|
|
3807
|
+
phoneNumber: import_zod10.z.string(),
|
|
3808
|
+
isCreatingNewGroup: import_zod10.z.boolean(),
|
|
3809
|
+
inviteToken: import_zod10.z.string().optional(),
|
|
3810
|
+
clinicGroupData: import_zod10.z.object({
|
|
3811
|
+
name: import_zod10.z.string(),
|
|
4119
3812
|
hqLocation: clinicLocationSchema,
|
|
4120
3813
|
logo: mediaResourceSchema.optional(),
|
|
4121
3814
|
contactInfo: clinicContactInfoSchema,
|
|
4122
|
-
subscriptionModel:
|
|
3815
|
+
subscriptionModel: import_zod10.z.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */)
|
|
4123
3816
|
}).optional()
|
|
4124
3817
|
});
|
|
4125
|
-
var clinicGroupSetupSchema =
|
|
4126
|
-
languages:
|
|
4127
|
-
practiceType:
|
|
4128
|
-
description:
|
|
3818
|
+
var clinicGroupSetupSchema = import_zod10.z.object({
|
|
3819
|
+
languages: import_zod10.z.array(import_zod10.z.nativeEnum(Language)),
|
|
3820
|
+
practiceType: import_zod10.z.nativeEnum(PracticeType),
|
|
3821
|
+
description: import_zod10.z.string(),
|
|
4129
3822
|
logo: mediaResourceSchema,
|
|
4130
|
-
calendarSyncEnabled:
|
|
4131
|
-
autoConfirmAppointments:
|
|
4132
|
-
businessIdentificationNumber:
|
|
4133
|
-
onboarding:
|
|
4134
|
-
completed:
|
|
4135
|
-
step:
|
|
3823
|
+
calendarSyncEnabled: import_zod10.z.boolean(),
|
|
3824
|
+
autoConfirmAppointments: import_zod10.z.boolean(),
|
|
3825
|
+
businessIdentificationNumber: import_zod10.z.string().optional().nullable(),
|
|
3826
|
+
onboarding: import_zod10.z.object({
|
|
3827
|
+
completed: import_zod10.z.boolean().optional().default(false),
|
|
3828
|
+
step: import_zod10.z.number().optional().default(1)
|
|
4136
3829
|
}).optional()
|
|
4137
3830
|
});
|
|
4138
|
-
var clinicBranchSetupSchema =
|
|
4139
|
-
name:
|
|
3831
|
+
var clinicBranchSetupSchema = import_zod10.z.object({
|
|
3832
|
+
name: import_zod10.z.string(),
|
|
4140
3833
|
location: clinicLocationSchema,
|
|
4141
|
-
description:
|
|
3834
|
+
description: import_zod10.z.string().optional(),
|
|
4142
3835
|
contactInfo: clinicContactInfoSchema,
|
|
4143
3836
|
workingHours: workingHoursSchema,
|
|
4144
|
-
tags:
|
|
3837
|
+
tags: import_zod10.z.array(import_zod10.z.nativeEnum(ClinicTag)),
|
|
4145
3838
|
logo: mediaResourceSchema.optional(),
|
|
4146
3839
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
4147
|
-
photosWithTags:
|
|
4148
|
-
|
|
3840
|
+
photosWithTags: import_zod10.z.array(
|
|
3841
|
+
import_zod10.z.object({
|
|
4149
3842
|
url: mediaResourceSchema,
|
|
4150
|
-
tag:
|
|
3843
|
+
tag: import_zod10.z.string()
|
|
4151
3844
|
})
|
|
4152
3845
|
).optional(),
|
|
4153
|
-
featuredPhotos:
|
|
3846
|
+
featuredPhotos: import_zod10.z.array(mediaResourceSchema).optional()
|
|
4154
3847
|
});
|
|
4155
3848
|
var updateClinicAdminSchema = createClinicAdminSchema.partial();
|
|
4156
3849
|
var updateClinicGroupSchema = createClinicGroupSchema.partial();
|
|
4157
|
-
var updateClinicSchema =
|
|
4158
|
-
name:
|
|
4159
|
-
description:
|
|
3850
|
+
var updateClinicSchema = import_zod10.z.object({
|
|
3851
|
+
name: import_zod10.z.string().optional(),
|
|
3852
|
+
description: import_zod10.z.string().optional(),
|
|
4160
3853
|
location: clinicLocationSchema.optional(),
|
|
4161
3854
|
contactInfo: clinicContactInfoSchema.optional(),
|
|
4162
3855
|
workingHours: workingHoursSchema.optional(),
|
|
4163
|
-
tags:
|
|
3856
|
+
tags: import_zod10.z.array(import_zod10.z.nativeEnum(ClinicTag)).optional(),
|
|
4164
3857
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
4165
|
-
photosWithTags:
|
|
4166
|
-
|
|
3858
|
+
photosWithTags: import_zod10.z.array(
|
|
3859
|
+
import_zod10.z.object({
|
|
4167
3860
|
url: mediaResourceSchema,
|
|
4168
|
-
tag:
|
|
3861
|
+
tag: import_zod10.z.string()
|
|
4169
3862
|
})
|
|
4170
3863
|
).optional(),
|
|
4171
|
-
doctors:
|
|
4172
|
-
procedures:
|
|
4173
|
-
proceduresInfo:
|
|
4174
|
-
isActive:
|
|
4175
|
-
isVerified:
|
|
3864
|
+
doctors: import_zod10.z.array(import_zod10.z.string()).optional(),
|
|
3865
|
+
procedures: import_zod10.z.array(import_zod10.z.string()).optional(),
|
|
3866
|
+
proceduresInfo: import_zod10.z.array(procedureSummaryInfoSchema).optional(),
|
|
3867
|
+
isActive: import_zod10.z.boolean().optional(),
|
|
3868
|
+
isVerified: import_zod10.z.boolean().optional(),
|
|
4176
3869
|
logo: mediaResourceSchema.optional().nullable(),
|
|
4177
|
-
featuredPhotos:
|
|
3870
|
+
featuredPhotos: import_zod10.z.array(mediaResourceSchema).optional()
|
|
4178
3871
|
});
|
|
4179
3872
|
|
|
4180
3873
|
// src/services/clinic/utils/admin.utils.ts
|
|
@@ -4250,7 +3943,7 @@ async function createClinicAdmin(db, data, clinicGroupService) {
|
|
|
4250
3943
|
}
|
|
4251
3944
|
console.log("[CLINIC_ADMIN] Preparing admin data object");
|
|
4252
3945
|
const adminData = {
|
|
4253
|
-
id: (0,
|
|
3946
|
+
id: (0, import_firestore10.doc)((0, import_firestore10.collection)(db, CLINIC_ADMINS_COLLECTION)).id,
|
|
4254
3947
|
// Generate a new ID for the admin document
|
|
4255
3948
|
userRef: validatedData.userRef,
|
|
4256
3949
|
clinicGroupId: clinicGroupId || "",
|
|
@@ -4263,15 +3956,15 @@ async function createClinicAdmin(db, data, clinicGroupService) {
|
|
|
4263
3956
|
contactInfo: validatedData.contactInfo,
|
|
4264
3957
|
roleTitle: validatedData.roleTitle,
|
|
4265
3958
|
isActive: validatedData.isActive,
|
|
4266
|
-
createdAt: (0,
|
|
4267
|
-
updatedAt: (0,
|
|
3959
|
+
createdAt: (0, import_firestore10.serverTimestamp)(),
|
|
3960
|
+
updatedAt: (0, import_firestore10.serverTimestamp)()
|
|
4268
3961
|
};
|
|
4269
3962
|
console.log("[CLINIC_ADMIN] Validating complete admin object");
|
|
4270
3963
|
try {
|
|
4271
3964
|
clinicAdminSchema.parse({
|
|
4272
3965
|
...adminData,
|
|
4273
|
-
createdAt:
|
|
4274
|
-
updatedAt:
|
|
3966
|
+
createdAt: import_firestore10.Timestamp.now(),
|
|
3967
|
+
updatedAt: import_firestore10.Timestamp.now()
|
|
4275
3968
|
});
|
|
4276
3969
|
console.log("[CLINIC_ADMIN] Admin object validation passed");
|
|
4277
3970
|
} catch (schemaError) {
|
|
@@ -4285,7 +3978,7 @@ async function createClinicAdmin(db, data, clinicGroupService) {
|
|
|
4285
3978
|
adminId: adminData.id
|
|
4286
3979
|
});
|
|
4287
3980
|
try {
|
|
4288
|
-
await (0,
|
|
3981
|
+
await (0, import_firestore10.setDoc)((0, import_firestore10.doc)(db, CLINIC_ADMINS_COLLECTION, adminData.id), adminData);
|
|
4289
3982
|
console.log("[CLINIC_ADMIN] Admin saved successfully");
|
|
4290
3983
|
} catch (firestoreError) {
|
|
4291
3984
|
console.error(
|
|
@@ -4334,30 +4027,30 @@ async function checkClinicGroupExists(db, groupId, clinicGroupService) {
|
|
|
4334
4027
|
return !!group;
|
|
4335
4028
|
}
|
|
4336
4029
|
async function getClinicAdmin(db, adminId) {
|
|
4337
|
-
const docRef = (0,
|
|
4338
|
-
const docSnap = await (0,
|
|
4030
|
+
const docRef = (0, import_firestore10.doc)(db, CLINIC_ADMINS_COLLECTION, adminId);
|
|
4031
|
+
const docSnap = await (0, import_firestore10.getDoc)(docRef);
|
|
4339
4032
|
if (docSnap.exists()) {
|
|
4340
4033
|
return docSnap.data();
|
|
4341
4034
|
}
|
|
4342
4035
|
return null;
|
|
4343
4036
|
}
|
|
4344
4037
|
async function getClinicAdminByUserRef(db, userRef) {
|
|
4345
|
-
const q = (0,
|
|
4346
|
-
(0,
|
|
4347
|
-
(0,
|
|
4038
|
+
const q = (0, import_firestore10.query)(
|
|
4039
|
+
(0, import_firestore10.collection)(db, CLINIC_ADMINS_COLLECTION),
|
|
4040
|
+
(0, import_firestore10.where)("userRef", "==", userRef)
|
|
4348
4041
|
);
|
|
4349
|
-
const querySnapshot = await (0,
|
|
4042
|
+
const querySnapshot = await (0, import_firestore10.getDocs)(q);
|
|
4350
4043
|
if (querySnapshot.empty) {
|
|
4351
4044
|
return null;
|
|
4352
4045
|
}
|
|
4353
4046
|
return querySnapshot.docs[0].data();
|
|
4354
4047
|
}
|
|
4355
4048
|
async function getClinicAdminsByGroup(db, clinicGroupId) {
|
|
4356
|
-
const q = (0,
|
|
4357
|
-
(0,
|
|
4358
|
-
(0,
|
|
4049
|
+
const q = (0, import_firestore10.query)(
|
|
4050
|
+
(0, import_firestore10.collection)(db, CLINIC_ADMINS_COLLECTION),
|
|
4051
|
+
(0, import_firestore10.where)("clinicGroupId", "==", clinicGroupId)
|
|
4359
4052
|
);
|
|
4360
|
-
const querySnapshot = await (0,
|
|
4053
|
+
const querySnapshot = await (0, import_firestore10.getDocs)(q);
|
|
4361
4054
|
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
4362
4055
|
}
|
|
4363
4056
|
async function updateClinicAdmin(db, adminId, data) {
|
|
@@ -4367,9 +4060,9 @@ async function updateClinicAdmin(db, adminId, data) {
|
|
|
4367
4060
|
}
|
|
4368
4061
|
const updatedData = {
|
|
4369
4062
|
...data,
|
|
4370
|
-
updatedAt: (0,
|
|
4063
|
+
updatedAt: (0, import_firestore10.serverTimestamp)()
|
|
4371
4064
|
};
|
|
4372
|
-
await (0,
|
|
4065
|
+
await (0, import_firestore10.updateDoc)((0, import_firestore10.doc)(db, CLINIC_ADMINS_COLLECTION, adminId), updatedData);
|
|
4373
4066
|
const updatedAdmin = await getClinicAdmin(db, adminId);
|
|
4374
4067
|
if (!updatedAdmin) {
|
|
4375
4068
|
throw new Error("Failed to retrieve updated admin");
|
|
@@ -4381,7 +4074,7 @@ async function deleteClinicAdmin(db, adminId) {
|
|
|
4381
4074
|
if (!admin2) {
|
|
4382
4075
|
throw new Error("Clinic admin not found");
|
|
4383
4076
|
}
|
|
4384
|
-
await (0,
|
|
4077
|
+
await (0, import_firestore10.deleteDoc)((0, import_firestore10.doc)(db, CLINIC_ADMINS_COLLECTION, adminId));
|
|
4385
4078
|
}
|
|
4386
4079
|
async function addClinicToManaged(db, adminId, clinicId, requesterId, clinicService) {
|
|
4387
4080
|
const admin2 = await getClinicAdmin(db, adminId);
|
|
@@ -4495,7 +4188,7 @@ async function syncOwnerClinics(db, adminId, clinicService, clinicGroupService)
|
|
|
4495
4188
|
// src/services/patient/utils/sensitive.utils.ts
|
|
4496
4189
|
var checkSensitiveAccessUtil = async (db, patientId, requesterId, requesterRoles) => {
|
|
4497
4190
|
var _a;
|
|
4498
|
-
const patientDoc = await (0,
|
|
4191
|
+
const patientDoc = await (0, import_firestore11.getDoc)(getPatientDocRef(db, patientId));
|
|
4499
4192
|
if (!patientDoc.exists()) {
|
|
4500
4193
|
throw new Error("Patient profile not found");
|
|
4501
4194
|
}
|
|
@@ -4562,7 +4255,7 @@ var createSensitiveInfoUtil = async (db, data, requesterId, requesterRoles, medi
|
|
|
4562
4255
|
requesterRoles
|
|
4563
4256
|
);
|
|
4564
4257
|
const validatedData = createPatientSensitiveInfoSchema.parse(data);
|
|
4565
|
-
const sensitiveDoc = await (0,
|
|
4258
|
+
const sensitiveDoc = await (0, import_firestore11.getDoc)(
|
|
4566
4259
|
getSensitiveInfoDocRef(db, data.patientId)
|
|
4567
4260
|
);
|
|
4568
4261
|
if (sensitiveDoc.exists()) {
|
|
@@ -4581,17 +4274,17 @@ var createSensitiveInfoUtil = async (db, data, requesterId, requesterRoles, medi
|
|
|
4581
4274
|
const sensitiveInfoData = {
|
|
4582
4275
|
...validatedData,
|
|
4583
4276
|
photoUrl: processedPhotoUrl,
|
|
4584
|
-
createdAt: (0,
|
|
4585
|
-
updatedAt: (0,
|
|
4277
|
+
createdAt: (0, import_firestore11.serverTimestamp)(),
|
|
4278
|
+
updatedAt: (0, import_firestore11.serverTimestamp)()
|
|
4586
4279
|
};
|
|
4587
|
-
await (0,
|
|
4588
|
-
const createdDoc = await (0,
|
|
4280
|
+
await (0, import_firestore11.setDoc)(getSensitiveInfoDocRef(db, data.patientId), sensitiveInfoData);
|
|
4281
|
+
const createdDoc = await (0, import_firestore11.getDoc)(getSensitiveInfoDocRef(db, data.patientId));
|
|
4589
4282
|
if (!createdDoc.exists()) {
|
|
4590
4283
|
throw new Error("Failed to create sensitive information");
|
|
4591
4284
|
}
|
|
4592
4285
|
return createdDoc.data();
|
|
4593
4286
|
} catch (error) {
|
|
4594
|
-
if (error instanceof
|
|
4287
|
+
if (error instanceof import_zod11.z.ZodError) {
|
|
4595
4288
|
throw new Error("Invalid sensitive info data: " + error.message);
|
|
4596
4289
|
}
|
|
4597
4290
|
throw error;
|
|
@@ -4600,7 +4293,7 @@ var createSensitiveInfoUtil = async (db, data, requesterId, requesterRoles, medi
|
|
|
4600
4293
|
var getSensitiveInfoUtil = async (db, patientId, requesterId, requesterRoles) => {
|
|
4601
4294
|
await checkSensitiveAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4602
4295
|
await initSensitiveInfoDocIfNotExists(db, patientId, requesterId);
|
|
4603
|
-
const sensitiveDoc = await (0,
|
|
4296
|
+
const sensitiveDoc = await (0, import_firestore11.getDoc)(getSensitiveInfoDocRef(db, patientId));
|
|
4604
4297
|
return sensitiveDoc.exists() ? sensitiveDoc.data() : null;
|
|
4605
4298
|
};
|
|
4606
4299
|
var updateSensitiveInfoUtil = async (db, patientId, data, requesterId, requesterRoles, mediaService) => {
|
|
@@ -4623,10 +4316,10 @@ var updateSensitiveInfoUtil = async (db, patientId, data, requesterId, requester
|
|
|
4623
4316
|
const updateData = {
|
|
4624
4317
|
...data,
|
|
4625
4318
|
photoUrl: processedPhotoUrl,
|
|
4626
|
-
updatedAt: (0,
|
|
4319
|
+
updatedAt: (0, import_firestore11.serverTimestamp)()
|
|
4627
4320
|
};
|
|
4628
|
-
await (0,
|
|
4629
|
-
const updatedDoc = await (0,
|
|
4321
|
+
await (0, import_firestore11.updateDoc)(getSensitiveInfoDocRef(db, patientId), updateData);
|
|
4322
|
+
const updatedDoc = await (0, import_firestore11.getDoc)(getSensitiveInfoDocRef(db, patientId));
|
|
4630
4323
|
if (!updatedDoc.exists()) {
|
|
4631
4324
|
throw new Error("Failed to retrieve updated sensitive information");
|
|
4632
4325
|
}
|
|
@@ -4635,21 +4328,21 @@ var updateSensitiveInfoUtil = async (db, patientId, data, requesterId, requester
|
|
|
4635
4328
|
|
|
4636
4329
|
// src/services/patient/utils/docs.utils.ts
|
|
4637
4330
|
var getPatientDocRef = (db, patientId) => {
|
|
4638
|
-
return (0,
|
|
4331
|
+
return (0, import_firestore12.doc)(db, PATIENTS_COLLECTION, patientId);
|
|
4639
4332
|
};
|
|
4640
4333
|
var getPatientDocRefByUserRef = async (db, userRef) => {
|
|
4641
|
-
const patientsRef = (0,
|
|
4642
|
-
const q = (0,
|
|
4643
|
-
const querySnapshot = await (0,
|
|
4334
|
+
const patientsRef = (0, import_firestore12.collection)(db, PATIENTS_COLLECTION);
|
|
4335
|
+
const q = (0, import_firestore12.query)(patientsRef, (0, import_firestore12.where)("userRef", "==", userRef));
|
|
4336
|
+
const querySnapshot = await (0, import_firestore12.getDocs)(q);
|
|
4644
4337
|
if (querySnapshot.empty) {
|
|
4645
4338
|
throw new Error("Patient profile not found");
|
|
4646
4339
|
}
|
|
4647
|
-
return (0,
|
|
4340
|
+
return (0, import_firestore12.doc)(db, PATIENTS_COLLECTION, querySnapshot.docs[0].id);
|
|
4648
4341
|
};
|
|
4649
4342
|
var getSensitiveInfoDocRef = (db, patientId) => {
|
|
4650
4343
|
const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_SENSITIVE_INFO_COLLECTION}/${patientId}`;
|
|
4651
4344
|
console.log(`[getSensitiveInfoDocRef] Creating reference with path: ${path}`);
|
|
4652
|
-
return (0,
|
|
4345
|
+
return (0, import_firestore12.doc)(
|
|
4653
4346
|
db,
|
|
4654
4347
|
PATIENTS_COLLECTION,
|
|
4655
4348
|
patientId,
|
|
@@ -4660,7 +4353,7 @@ var getSensitiveInfoDocRef = (db, patientId) => {
|
|
|
4660
4353
|
var getLocationInfoDocRef = (db, patientId) => {
|
|
4661
4354
|
const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_LOCATION_INFO_COLLECTION}/${patientId}`;
|
|
4662
4355
|
console.log(`[getLocationInfoDocRef] Creating reference with path: ${path}`);
|
|
4663
|
-
return (0,
|
|
4356
|
+
return (0, import_firestore12.doc)(
|
|
4664
4357
|
db,
|
|
4665
4358
|
PATIENTS_COLLECTION,
|
|
4666
4359
|
patientId,
|
|
@@ -4671,7 +4364,7 @@ var getLocationInfoDocRef = (db, patientId) => {
|
|
|
4671
4364
|
var getMedicalInfoDocRef = (db, patientId) => {
|
|
4672
4365
|
const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_MEDICAL_INFO_COLLECTION}/${patientId}`;
|
|
4673
4366
|
console.log(`[getMedicalInfoDocRef] Creating reference with path: ${path}`);
|
|
4674
|
-
return (0,
|
|
4367
|
+
return (0, import_firestore12.doc)(
|
|
4675
4368
|
db,
|
|
4676
4369
|
PATIENTS_COLLECTION,
|
|
4677
4370
|
patientId,
|
|
@@ -4688,7 +4381,7 @@ var initSensitiveInfoDocIfNotExists = async (db, patientId, userRef) => {
|
|
|
4688
4381
|
console.log(
|
|
4689
4382
|
`[initSensitiveInfoDocIfNotExists] Got document reference: ${sensitiveInfoRef.path}`
|
|
4690
4383
|
);
|
|
4691
|
-
const sensitiveDoc = await (0,
|
|
4384
|
+
const sensitiveDoc = await (0, import_firestore12.getDoc)(sensitiveInfoRef);
|
|
4692
4385
|
console.log(
|
|
4693
4386
|
`[initSensitiveInfoDocIfNotExists] Document exists: ${sensitiveDoc.exists()}`
|
|
4694
4387
|
);
|
|
@@ -4712,7 +4405,7 @@ var initSensitiveInfoDocIfNotExists = async (db, patientId, userRef) => {
|
|
|
4712
4405
|
)
|
|
4713
4406
|
);
|
|
4714
4407
|
await createSensitiveInfoUtil(db, defaultSensitiveInfo, userRef);
|
|
4715
|
-
const verifyDoc = await (0,
|
|
4408
|
+
const verifyDoc = await (0, import_firestore12.getDoc)(sensitiveInfoRef);
|
|
4716
4409
|
console.log(
|
|
4717
4410
|
`[initSensitiveInfoDocIfNotExists] Verification - document exists: ${verifyDoc.exists()}`
|
|
4718
4411
|
);
|
|
@@ -4729,8 +4422,8 @@ var initSensitiveInfoDocIfNotExists = async (db, patientId, userRef) => {
|
|
|
4729
4422
|
};
|
|
4730
4423
|
|
|
4731
4424
|
// src/services/patient/utils/location.utils.ts
|
|
4732
|
-
var
|
|
4733
|
-
var
|
|
4425
|
+
var import_firestore13 = require("firebase/firestore");
|
|
4426
|
+
var import_zod12 = require("zod");
|
|
4734
4427
|
var import_geofire_common = require("geofire-common");
|
|
4735
4428
|
var updatePatientLocationUtil = async (db, patientId, latitude, longitude) => {
|
|
4736
4429
|
const locationData = {
|
|
@@ -4740,9 +4433,9 @@ var updatePatientLocationUtil = async (db, patientId, latitude, longitude) => {
|
|
|
4740
4433
|
};
|
|
4741
4434
|
const updateData = {
|
|
4742
4435
|
locationData,
|
|
4743
|
-
updatedAt: (0,
|
|
4436
|
+
updatedAt: (0, import_firestore13.serverTimestamp)()
|
|
4744
4437
|
};
|
|
4745
|
-
await (0,
|
|
4438
|
+
await (0, import_firestore13.updateDoc)(getLocationInfoDocRef(db, patientId), updateData);
|
|
4746
4439
|
};
|
|
4747
4440
|
var createLocationInfoUtil = async (db, data, requesterId) => {
|
|
4748
4441
|
try {
|
|
@@ -4759,17 +4452,17 @@ var createLocationInfoUtil = async (db, data, requesterId) => {
|
|
|
4759
4452
|
validatedData.locationData.longitude
|
|
4760
4453
|
])
|
|
4761
4454
|
},
|
|
4762
|
-
createdAt: (0,
|
|
4763
|
-
updatedAt: (0,
|
|
4455
|
+
createdAt: (0, import_firestore13.serverTimestamp)(),
|
|
4456
|
+
updatedAt: (0, import_firestore13.serverTimestamp)()
|
|
4764
4457
|
};
|
|
4765
|
-
await (0,
|
|
4766
|
-
const locationDoc = await (0,
|
|
4458
|
+
await (0, import_firestore13.setDoc)(getLocationInfoDocRef(db, data.patientId), locationData);
|
|
4459
|
+
const locationDoc = await (0, import_firestore13.getDoc)(getLocationInfoDocRef(db, data.patientId));
|
|
4767
4460
|
if (!locationDoc.exists()) {
|
|
4768
4461
|
throw new Error("Failed to create location information");
|
|
4769
4462
|
}
|
|
4770
4463
|
return locationDoc.data();
|
|
4771
4464
|
} catch (error) {
|
|
4772
|
-
if (error instanceof
|
|
4465
|
+
if (error instanceof import_zod12.z.ZodError) {
|
|
4773
4466
|
throw new Error("Invalid location data: " + error.message);
|
|
4774
4467
|
}
|
|
4775
4468
|
throw error;
|
|
@@ -4779,7 +4472,7 @@ var getLocationInfoUtil = async (db, patientId, requesterId) => {
|
|
|
4779
4472
|
if (patientId !== requesterId) {
|
|
4780
4473
|
throw new Error("Unauthorized access to location information");
|
|
4781
4474
|
}
|
|
4782
|
-
const locationDoc = await (0,
|
|
4475
|
+
const locationDoc = await (0, import_firestore13.getDoc)(getLocationInfoDocRef(db, patientId));
|
|
4783
4476
|
return locationDoc.exists() ? locationDoc.data() : null;
|
|
4784
4477
|
};
|
|
4785
4478
|
var updateLocationInfoUtil = async (db, patientId, data, requesterId) => {
|
|
@@ -4796,8 +4489,8 @@ var updateLocationInfoUtil = async (db, patientId, data, requesterId) => {
|
|
|
4796
4489
|
])
|
|
4797
4490
|
};
|
|
4798
4491
|
}
|
|
4799
|
-
updateData.updatedAt = (0,
|
|
4800
|
-
await (0,
|
|
4492
|
+
updateData.updatedAt = (0, import_firestore13.serverTimestamp)();
|
|
4493
|
+
await (0, import_firestore13.updateDoc)(getLocationInfoDocRef(db, patientId), updateData);
|
|
4801
4494
|
const updatedInfo = await getLocationInfoUtil(db, patientId, requesterId);
|
|
4802
4495
|
if (!updatedInfo) {
|
|
4803
4496
|
throw new Error("Failed to retrieve updated location information");
|
|
@@ -4806,121 +4499,121 @@ var updateLocationInfoUtil = async (db, patientId, data, requesterId) => {
|
|
|
4806
4499
|
};
|
|
4807
4500
|
|
|
4808
4501
|
// src/services/patient/utils/medical-stuff.utils.ts
|
|
4809
|
-
var
|
|
4502
|
+
var import_firestore14 = require("firebase/firestore");
|
|
4810
4503
|
var addDoctorUtil = async (db, patientId, doctorRef, assignedBy) => {
|
|
4811
4504
|
var _a;
|
|
4812
4505
|
const newDoctor = {
|
|
4813
4506
|
userRef: doctorRef,
|
|
4814
|
-
assignedAt:
|
|
4507
|
+
assignedAt: import_firestore14.Timestamp.now(),
|
|
4815
4508
|
assignedBy,
|
|
4816
4509
|
isActive: true
|
|
4817
4510
|
};
|
|
4818
|
-
const patientDoc = await (0,
|
|
4511
|
+
const patientDoc = await (0, import_firestore14.getDoc)(getPatientDocRef(db, patientId));
|
|
4819
4512
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
4820
4513
|
const patientData = patientDoc.data();
|
|
4821
4514
|
const existingDoctorIndex = (_a = patientData.doctors) == null ? void 0 : _a.findIndex(
|
|
4822
4515
|
(d) => d.userRef === doctorRef
|
|
4823
4516
|
);
|
|
4824
4517
|
const updates = {
|
|
4825
|
-
updatedAt: (0,
|
|
4826
|
-
doctorIds: (0,
|
|
4518
|
+
updatedAt: (0, import_firestore14.serverTimestamp)(),
|
|
4519
|
+
doctorIds: (0, import_firestore14.arrayUnion)(doctorRef)
|
|
4827
4520
|
};
|
|
4828
4521
|
if (existingDoctorIndex !== void 0 && existingDoctorIndex > -1) {
|
|
4829
4522
|
const updatedDoctors = [...patientData.doctors];
|
|
4830
4523
|
updatedDoctors[existingDoctorIndex] = {
|
|
4831
4524
|
...updatedDoctors[existingDoctorIndex],
|
|
4832
4525
|
isActive: true,
|
|
4833
|
-
assignedAt:
|
|
4526
|
+
assignedAt: import_firestore14.Timestamp.now(),
|
|
4834
4527
|
assignedBy
|
|
4835
4528
|
};
|
|
4836
4529
|
updates.doctors = updatedDoctors;
|
|
4837
4530
|
} else {
|
|
4838
|
-
updates.doctors = (0,
|
|
4531
|
+
updates.doctors = (0, import_firestore14.arrayUnion)(newDoctor);
|
|
4839
4532
|
}
|
|
4840
|
-
await (0,
|
|
4533
|
+
await (0, import_firestore14.updateDoc)(getPatientDocRef(db, patientId), updates);
|
|
4841
4534
|
};
|
|
4842
4535
|
var removeDoctorUtil = async (db, patientId, doctorRef) => {
|
|
4843
4536
|
var _a;
|
|
4844
4537
|
const patientDocRef = getPatientDocRef(db, patientId);
|
|
4845
|
-
const patientDoc = await (0,
|
|
4538
|
+
const patientDoc = await (0, import_firestore14.getDoc)(patientDocRef);
|
|
4846
4539
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
4847
4540
|
const patientData = patientDoc.data();
|
|
4848
4541
|
const updatedDoctors = ((_a = patientData.doctors) == null ? void 0 : _a.filter((doctor) => doctor.userRef !== doctorRef)) || [];
|
|
4849
|
-
await (0,
|
|
4542
|
+
await (0, import_firestore14.updateDoc)(patientDocRef, {
|
|
4850
4543
|
doctors: updatedDoctors,
|
|
4851
4544
|
// Set the filtered array
|
|
4852
|
-
doctorIds: (0,
|
|
4545
|
+
doctorIds: (0, import_firestore14.arrayRemove)(doctorRef),
|
|
4853
4546
|
// Remove ID from the denormalized list
|
|
4854
|
-
updatedAt: (0,
|
|
4547
|
+
updatedAt: (0, import_firestore14.serverTimestamp)()
|
|
4855
4548
|
});
|
|
4856
4549
|
};
|
|
4857
4550
|
var addClinicUtil = async (db, patientId, clinicId, assignedBy) => {
|
|
4858
4551
|
var _a;
|
|
4859
4552
|
const newClinic = {
|
|
4860
4553
|
clinicId,
|
|
4861
|
-
assignedAt:
|
|
4554
|
+
assignedAt: import_firestore14.Timestamp.now(),
|
|
4862
4555
|
assignedBy,
|
|
4863
4556
|
isActive: true
|
|
4864
4557
|
};
|
|
4865
|
-
const patientDoc = await (0,
|
|
4558
|
+
const patientDoc = await (0, import_firestore14.getDoc)(getPatientDocRef(db, patientId));
|
|
4866
4559
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
4867
4560
|
const patientData = patientDoc.data();
|
|
4868
4561
|
const existingClinicIndex = (_a = patientData.clinics) == null ? void 0 : _a.findIndex(
|
|
4869
4562
|
(c) => c.clinicId === clinicId
|
|
4870
4563
|
);
|
|
4871
4564
|
const updates = {
|
|
4872
|
-
updatedAt: (0,
|
|
4873
|
-
clinicIds: (0,
|
|
4565
|
+
updatedAt: (0, import_firestore14.serverTimestamp)(),
|
|
4566
|
+
clinicIds: (0, import_firestore14.arrayUnion)(clinicId)
|
|
4874
4567
|
};
|
|
4875
4568
|
if (existingClinicIndex !== void 0 && existingClinicIndex > -1) {
|
|
4876
4569
|
const updatedClinics = [...patientData.clinics];
|
|
4877
4570
|
updatedClinics[existingClinicIndex] = {
|
|
4878
4571
|
...updatedClinics[existingClinicIndex],
|
|
4879
4572
|
isActive: true,
|
|
4880
|
-
assignedAt:
|
|
4573
|
+
assignedAt: import_firestore14.Timestamp.now(),
|
|
4881
4574
|
assignedBy
|
|
4882
4575
|
};
|
|
4883
4576
|
updates.clinics = updatedClinics;
|
|
4884
4577
|
} else {
|
|
4885
|
-
updates.clinics = (0,
|
|
4578
|
+
updates.clinics = (0, import_firestore14.arrayUnion)(newClinic);
|
|
4886
4579
|
}
|
|
4887
|
-
await (0,
|
|
4580
|
+
await (0, import_firestore14.updateDoc)(getPatientDocRef(db, patientId), updates);
|
|
4888
4581
|
};
|
|
4889
4582
|
var removeClinicUtil = async (db, patientId, clinicId) => {
|
|
4890
4583
|
var _a;
|
|
4891
4584
|
const patientDocRef = getPatientDocRef(db, patientId);
|
|
4892
|
-
const patientDoc = await (0,
|
|
4585
|
+
const patientDoc = await (0, import_firestore14.getDoc)(patientDocRef);
|
|
4893
4586
|
if (!patientDoc.exists()) throw new Error("Patient profile not found");
|
|
4894
4587
|
const patientData = patientDoc.data();
|
|
4895
4588
|
const updatedClinics = ((_a = patientData.clinics) == null ? void 0 : _a.filter((clinic) => clinic.clinicId !== clinicId)) || [];
|
|
4896
|
-
await (0,
|
|
4589
|
+
await (0, import_firestore14.updateDoc)(patientDocRef, {
|
|
4897
4590
|
clinics: updatedClinics,
|
|
4898
4591
|
// Set the filtered array
|
|
4899
|
-
clinicIds: (0,
|
|
4592
|
+
clinicIds: (0, import_firestore14.arrayRemove)(clinicId),
|
|
4900
4593
|
// Remove ID from the denormalized list
|
|
4901
|
-
updatedAt: (0,
|
|
4594
|
+
updatedAt: (0, import_firestore14.serverTimestamp)()
|
|
4902
4595
|
});
|
|
4903
4596
|
};
|
|
4904
4597
|
|
|
4905
4598
|
// src/services/patient/utils/medical.utils.ts
|
|
4906
|
-
var
|
|
4599
|
+
var import_firestore15 = require("firebase/firestore");
|
|
4907
4600
|
var ensureMedicalInfoExists = async (db, patientId, requesterId) => {
|
|
4908
4601
|
const medicalInfoRef = getMedicalInfoDocRef(db, patientId);
|
|
4909
|
-
const medicalInfoDoc = await (0,
|
|
4602
|
+
const medicalInfoDoc = await (0, import_firestore15.getDoc)(medicalInfoRef);
|
|
4910
4603
|
if (!medicalInfoDoc.exists()) {
|
|
4911
4604
|
const defaultData = {
|
|
4912
4605
|
...DEFAULT_MEDICAL_INFO,
|
|
4913
4606
|
patientId,
|
|
4914
|
-
lastUpdated: (0,
|
|
4607
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
4915
4608
|
updatedBy: requesterId
|
|
4916
4609
|
// Koristimo ID onoga ko zahteva akciju
|
|
4917
4610
|
};
|
|
4918
|
-
await (0,
|
|
4611
|
+
await (0, import_firestore15.setDoc)(medicalInfoRef, defaultData);
|
|
4919
4612
|
}
|
|
4920
4613
|
};
|
|
4921
4614
|
var checkMedicalAccessUtil = async (db, patientId, requesterId, requesterRoles) => {
|
|
4922
4615
|
var _a;
|
|
4923
|
-
const patientDoc = await (0,
|
|
4616
|
+
const patientDoc = await (0, import_firestore15.getDoc)(getPatientDocRef(db, patientId));
|
|
4924
4617
|
if (!patientDoc.exists()) {
|
|
4925
4618
|
throw new Error("Patient profile not found");
|
|
4926
4619
|
}
|
|
@@ -4960,20 +4653,20 @@ var checkMedicalAccessUtil = async (db, patientId, requesterId, requesterRoles)
|
|
|
4960
4653
|
var createMedicalInfoUtil = async (db, patientId, data, requesterId, requesterRoles) => {
|
|
4961
4654
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4962
4655
|
const validatedData = createPatientMedicalInfoSchema.parse(data);
|
|
4963
|
-
await (0,
|
|
4656
|
+
await (0, import_firestore15.setDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
4964
4657
|
...validatedData,
|
|
4965
4658
|
patientId,
|
|
4966
|
-
lastUpdated: (0,
|
|
4659
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
4967
4660
|
updatedBy: requesterId
|
|
4968
4661
|
});
|
|
4969
4662
|
};
|
|
4970
4663
|
var getMedicalInfoUtil = async (db, patientId, requesterId, requesterRoles) => {
|
|
4971
4664
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4972
4665
|
const docRef = getMedicalInfoDocRef(db, patientId);
|
|
4973
|
-
const snapshot = await (0,
|
|
4666
|
+
const snapshot = await (0, import_firestore15.getDoc)(docRef);
|
|
4974
4667
|
if (!snapshot.exists()) {
|
|
4975
4668
|
await ensureMedicalInfoExists(db, patientId, requesterId);
|
|
4976
|
-
const newSnapshot = await (0,
|
|
4669
|
+
const newSnapshot = await (0, import_firestore15.getDoc)(docRef);
|
|
4977
4670
|
return patientMedicalInfoSchema.parse(newSnapshot.data());
|
|
4978
4671
|
}
|
|
4979
4672
|
return patientMedicalInfoSchema.parse(snapshot.data());
|
|
@@ -4982,9 +4675,9 @@ var updateVitalStatsUtil = async (db, patientId, data, requesterId, requesterRol
|
|
|
4982
4675
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4983
4676
|
await ensureMedicalInfoExists(db, patientId, requesterId);
|
|
4984
4677
|
const validatedData = updateVitalStatsSchema.parse(data);
|
|
4985
|
-
await (0,
|
|
4678
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
4986
4679
|
vitalStats: validatedData,
|
|
4987
|
-
lastUpdated: (0,
|
|
4680
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
4988
4681
|
updatedBy: requesterId
|
|
4989
4682
|
});
|
|
4990
4683
|
};
|
|
@@ -4992,9 +4685,9 @@ var addAllergyUtil = async (db, patientId, data, requesterId, requesterRoles) =>
|
|
|
4992
4685
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
4993
4686
|
await ensureMedicalInfoExists(db, patientId, requesterId);
|
|
4994
4687
|
const validatedData = addAllergySchema.parse(data);
|
|
4995
|
-
await (0,
|
|
4996
|
-
allergies: (0,
|
|
4997
|
-
lastUpdated: (0,
|
|
4688
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
4689
|
+
allergies: (0, import_firestore15.arrayUnion)(validatedData),
|
|
4690
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
4998
4691
|
updatedBy: requesterId
|
|
4999
4692
|
});
|
|
5000
4693
|
};
|
|
@@ -5002,7 +4695,7 @@ var updateAllergyUtil = async (db, patientId, data, requesterId, requesterRoles)
|
|
|
5002
4695
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5003
4696
|
const validatedData = updateAllergySchema.parse(data);
|
|
5004
4697
|
const { allergyIndex, ...updateData } = validatedData;
|
|
5005
|
-
const docSnapshot = await (0,
|
|
4698
|
+
const docSnapshot = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
5006
4699
|
if (!docSnapshot.exists()) throw new Error("Medical info not found");
|
|
5007
4700
|
const medicalInfo = patientMedicalInfoSchema.parse(docSnapshot.data());
|
|
5008
4701
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
@@ -5013,15 +4706,15 @@ var updateAllergyUtil = async (db, patientId, data, requesterId, requesterRoles)
|
|
|
5013
4706
|
...updatedAllergies[allergyIndex],
|
|
5014
4707
|
...updateData
|
|
5015
4708
|
};
|
|
5016
|
-
await (0,
|
|
4709
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
5017
4710
|
allergies: updatedAllergies,
|
|
5018
|
-
lastUpdated: (0,
|
|
4711
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5019
4712
|
updatedBy: requesterId
|
|
5020
4713
|
});
|
|
5021
4714
|
};
|
|
5022
4715
|
var removeAllergyUtil = async (db, patientId, allergyIndex, requesterId, requesterRoles) => {
|
|
5023
4716
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5024
|
-
const doc37 = await (0,
|
|
4717
|
+
const doc37 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
5025
4718
|
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
5026
4719
|
const medicalInfo = doc37.data();
|
|
5027
4720
|
if (allergyIndex >= medicalInfo.allergies.length) {
|
|
@@ -5030,9 +4723,9 @@ var removeAllergyUtil = async (db, patientId, allergyIndex, requesterId, request
|
|
|
5030
4723
|
const updatedAllergies = medicalInfo.allergies.filter(
|
|
5031
4724
|
(_, index) => index !== allergyIndex
|
|
5032
4725
|
);
|
|
5033
|
-
await (0,
|
|
4726
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
5034
4727
|
allergies: updatedAllergies,
|
|
5035
|
-
lastUpdated: (0,
|
|
4728
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5036
4729
|
updatedBy: requesterId
|
|
5037
4730
|
});
|
|
5038
4731
|
};
|
|
@@ -5040,9 +4733,9 @@ var addBlockingConditionUtil = async (db, patientId, data, requesterId, requeste
|
|
|
5040
4733
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5041
4734
|
await ensureMedicalInfoExists(db, patientId, requesterId);
|
|
5042
4735
|
const validatedData = addBlockingConditionSchema.parse(data);
|
|
5043
|
-
await (0,
|
|
5044
|
-
blockingConditions: (0,
|
|
5045
|
-
lastUpdated: (0,
|
|
4736
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
4737
|
+
blockingConditions: (0, import_firestore15.arrayUnion)(validatedData),
|
|
4738
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5046
4739
|
updatedBy: requesterId
|
|
5047
4740
|
});
|
|
5048
4741
|
};
|
|
@@ -5050,7 +4743,7 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
|
|
|
5050
4743
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5051
4744
|
const validatedData = updateBlockingConditionSchema.parse(data);
|
|
5052
4745
|
const { conditionIndex, ...updateData } = validatedData;
|
|
5053
|
-
const doc37 = await (0,
|
|
4746
|
+
const doc37 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
5054
4747
|
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
5055
4748
|
const medicalInfo = doc37.data();
|
|
5056
4749
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
@@ -5061,15 +4754,15 @@ var updateBlockingConditionUtil = async (db, patientId, data, requesterId, reque
|
|
|
5061
4754
|
...updatedConditions[conditionIndex],
|
|
5062
4755
|
...updateData
|
|
5063
4756
|
};
|
|
5064
|
-
await (0,
|
|
4757
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
5065
4758
|
blockingConditions: updatedConditions,
|
|
5066
|
-
lastUpdated: (0,
|
|
4759
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5067
4760
|
updatedBy: requesterId
|
|
5068
4761
|
});
|
|
5069
4762
|
};
|
|
5070
4763
|
var removeBlockingConditionUtil = async (db, patientId, conditionIndex, requesterId, requesterRoles) => {
|
|
5071
4764
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5072
|
-
const doc37 = await (0,
|
|
4765
|
+
const doc37 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
5073
4766
|
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
5074
4767
|
const medicalInfo = doc37.data();
|
|
5075
4768
|
if (conditionIndex >= medicalInfo.blockingConditions.length) {
|
|
@@ -5078,9 +4771,9 @@ var removeBlockingConditionUtil = async (db, patientId, conditionIndex, requeste
|
|
|
5078
4771
|
const updatedConditions = medicalInfo.blockingConditions.filter(
|
|
5079
4772
|
(_, index) => index !== conditionIndex
|
|
5080
4773
|
);
|
|
5081
|
-
await (0,
|
|
4774
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
5082
4775
|
blockingConditions: updatedConditions,
|
|
5083
|
-
lastUpdated: (0,
|
|
4776
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5084
4777
|
updatedBy: requesterId
|
|
5085
4778
|
});
|
|
5086
4779
|
};
|
|
@@ -5088,9 +4781,9 @@ var addContraindicationUtil = async (db, patientId, data, requesterId, requester
|
|
|
5088
4781
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5089
4782
|
await ensureMedicalInfoExists(db, patientId, requesterId);
|
|
5090
4783
|
const validatedData = addContraindicationSchema.parse(data);
|
|
5091
|
-
await (0,
|
|
5092
|
-
contraindications: (0,
|
|
5093
|
-
lastUpdated: (0,
|
|
4784
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
4785
|
+
contraindications: (0, import_firestore15.arrayUnion)(validatedData),
|
|
4786
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5094
4787
|
updatedBy: requesterId
|
|
5095
4788
|
});
|
|
5096
4789
|
};
|
|
@@ -5098,7 +4791,7 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
|
|
|
5098
4791
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5099
4792
|
const validatedData = updateContraindicationSchema.parse(data);
|
|
5100
4793
|
const { contraindicationIndex, ...updateData } = validatedData;
|
|
5101
|
-
const doc37 = await (0,
|
|
4794
|
+
const doc37 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
5102
4795
|
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
5103
4796
|
const medicalInfo = doc37.data();
|
|
5104
4797
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
@@ -5109,15 +4802,15 @@ var updateContraindicationUtil = async (db, patientId, data, requesterId, reques
|
|
|
5109
4802
|
...updatedContraindications[contraindicationIndex],
|
|
5110
4803
|
...updateData
|
|
5111
4804
|
};
|
|
5112
|
-
await (0,
|
|
4805
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
5113
4806
|
contraindications: updatedContraindications,
|
|
5114
|
-
lastUpdated: (0,
|
|
4807
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5115
4808
|
updatedBy: requesterId
|
|
5116
4809
|
});
|
|
5117
4810
|
};
|
|
5118
4811
|
var removeContraindicationUtil = async (db, patientId, contraindicationIndex, requesterId, requesterRoles) => {
|
|
5119
4812
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5120
|
-
const doc37 = await (0,
|
|
4813
|
+
const doc37 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
5121
4814
|
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
5122
4815
|
const medicalInfo = doc37.data();
|
|
5123
4816
|
if (contraindicationIndex >= medicalInfo.contraindications.length) {
|
|
@@ -5126,9 +4819,9 @@ var removeContraindicationUtil = async (db, patientId, contraindicationIndex, re
|
|
|
5126
4819
|
const updatedContraindications = medicalInfo.contraindications.filter(
|
|
5127
4820
|
(_, index) => index !== contraindicationIndex
|
|
5128
4821
|
);
|
|
5129
|
-
await (0,
|
|
4822
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
5130
4823
|
contraindications: updatedContraindications,
|
|
5131
|
-
lastUpdated: (0,
|
|
4824
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5132
4825
|
updatedBy: requesterId
|
|
5133
4826
|
});
|
|
5134
4827
|
};
|
|
@@ -5136,9 +4829,9 @@ var addMedicationUtil = async (db, patientId, data, requesterId, requesterRoles)
|
|
|
5136
4829
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5137
4830
|
await ensureMedicalInfoExists(db, patientId, requesterId);
|
|
5138
4831
|
const validatedData = addMedicationSchema.parse(data);
|
|
5139
|
-
await (0,
|
|
5140
|
-
currentMedications: (0,
|
|
5141
|
-
lastUpdated: (0,
|
|
4832
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
4833
|
+
currentMedications: (0, import_firestore15.arrayUnion)(validatedData),
|
|
4834
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5142
4835
|
updatedBy: requesterId
|
|
5143
4836
|
});
|
|
5144
4837
|
};
|
|
@@ -5146,7 +4839,7 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
|
|
|
5146
4839
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5147
4840
|
const validatedData = updateMedicationSchema.parse(data);
|
|
5148
4841
|
const { medicationIndex, ...updateData } = validatedData;
|
|
5149
|
-
const doc37 = await (0,
|
|
4842
|
+
const doc37 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
5150
4843
|
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
5151
4844
|
const medicalInfo = doc37.data();
|
|
5152
4845
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
@@ -5157,15 +4850,15 @@ var updateMedicationUtil = async (db, patientId, data, requesterId, requesterRol
|
|
|
5157
4850
|
...updatedMedications[medicationIndex],
|
|
5158
4851
|
...updateData
|
|
5159
4852
|
};
|
|
5160
|
-
await (0,
|
|
4853
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
5161
4854
|
currentMedications: updatedMedications,
|
|
5162
|
-
lastUpdated: (0,
|
|
4855
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5163
4856
|
updatedBy: requesterId
|
|
5164
4857
|
});
|
|
5165
4858
|
};
|
|
5166
4859
|
var removeMedicationUtil = async (db, patientId, medicationIndex, requesterId, requesterRoles) => {
|
|
5167
4860
|
await checkMedicalAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
5168
|
-
const doc37 = await (0,
|
|
4861
|
+
const doc37 = await (0, import_firestore15.getDoc)(getMedicalInfoDocRef(db, patientId));
|
|
5169
4862
|
if (!doc37.exists()) throw new Error("Medical info not found");
|
|
5170
4863
|
const medicalInfo = doc37.data();
|
|
5171
4864
|
if (medicationIndex >= medicalInfo.currentMedications.length) {
|
|
@@ -5174,16 +4867,16 @@ var removeMedicationUtil = async (db, patientId, medicationIndex, requesterId, r
|
|
|
5174
4867
|
const updatedMedications = medicalInfo.currentMedications.filter(
|
|
5175
4868
|
(_, index) => index !== medicationIndex
|
|
5176
4869
|
);
|
|
5177
|
-
await (0,
|
|
4870
|
+
await (0, import_firestore15.updateDoc)(getMedicalInfoDocRef(db, patientId), {
|
|
5178
4871
|
currentMedications: updatedMedications,
|
|
5179
|
-
lastUpdated: (0,
|
|
4872
|
+
lastUpdated: (0, import_firestore15.serverTimestamp)(),
|
|
5180
4873
|
updatedBy: requesterId
|
|
5181
4874
|
});
|
|
5182
4875
|
};
|
|
5183
4876
|
|
|
5184
4877
|
// src/services/patient/utils/profile.utils.ts
|
|
5185
|
-
var
|
|
5186
|
-
var
|
|
4878
|
+
var import_firestore16 = require("firebase/firestore");
|
|
4879
|
+
var import_zod13 = require("zod");
|
|
5187
4880
|
var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
5188
4881
|
var _a, _b;
|
|
5189
4882
|
try {
|
|
@@ -5212,15 +4905,15 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
|
5212
4905
|
clinics: validatedData.clinics || [],
|
|
5213
4906
|
doctorIds: ((_a = validatedData.doctors) == null ? void 0 : _a.map((d) => d.userRef)) || [],
|
|
5214
4907
|
clinicIds: ((_b = validatedData.clinics) == null ? void 0 : _b.map((c) => c.clinicId)) || [],
|
|
5215
|
-
createdAt: (0,
|
|
5216
|
-
updatedAt: (0,
|
|
4908
|
+
createdAt: (0, import_firestore16.serverTimestamp)(),
|
|
4909
|
+
updatedAt: (0, import_firestore16.serverTimestamp)()
|
|
5217
4910
|
};
|
|
5218
4911
|
patientProfileSchema.parse({
|
|
5219
4912
|
...patientData,
|
|
5220
|
-
createdAt:
|
|
5221
|
-
updatedAt:
|
|
4913
|
+
createdAt: import_firestore16.Timestamp.now(),
|
|
4914
|
+
updatedAt: import_firestore16.Timestamp.now()
|
|
5222
4915
|
});
|
|
5223
|
-
await (0,
|
|
4916
|
+
await (0, import_firestore16.setDoc)(getPatientDocRef(db, patientId), patientData);
|
|
5224
4917
|
console.log(`[createPatientProfileUtil] Creating sensitive info document`);
|
|
5225
4918
|
let sensitiveInfoSuccess = false;
|
|
5226
4919
|
try {
|
|
@@ -5270,7 +4963,7 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
|
5270
4963
|
}
|
|
5271
4964
|
}
|
|
5272
4965
|
console.log(`[createPatientProfileUtil] Verifying patient document exists`);
|
|
5273
|
-
const patientDoc = await (0,
|
|
4966
|
+
const patientDoc = await (0, import_firestore16.getDoc)(getPatientDocRef(db, patientId));
|
|
5274
4967
|
if (!patientDoc.exists()) {
|
|
5275
4968
|
console.error(
|
|
5276
4969
|
`[createPatientProfileUtil] Patient document not found after creation`
|
|
@@ -5286,51 +4979,51 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
|
|
|
5286
4979
|
`[createPatientProfileUtil] Error in patient profile creation:`,
|
|
5287
4980
|
error
|
|
5288
4981
|
);
|
|
5289
|
-
if (error instanceof
|
|
4982
|
+
if (error instanceof import_zod13.z.ZodError) {
|
|
5290
4983
|
throw new Error("Invalid patient data: " + error.message);
|
|
5291
4984
|
}
|
|
5292
4985
|
throw error;
|
|
5293
4986
|
}
|
|
5294
4987
|
};
|
|
5295
4988
|
var getPatientProfileUtil = async (db, patientId) => {
|
|
5296
|
-
const patientDoc = await (0,
|
|
4989
|
+
const patientDoc = await (0, import_firestore16.getDoc)(getPatientDocRef(db, patientId));
|
|
5297
4990
|
return patientDoc.exists() ? patientDoc.data() : null;
|
|
5298
4991
|
};
|
|
5299
4992
|
var getPatientProfileByUserRefUtil = async (db, userRef) => {
|
|
5300
4993
|
try {
|
|
5301
4994
|
const docRef = await getPatientDocRefByUserRef(db, userRef);
|
|
5302
|
-
const patientDoc = await (0,
|
|
4995
|
+
const patientDoc = await (0, import_firestore16.getDoc)(docRef);
|
|
5303
4996
|
return patientDoc.exists() ? patientDoc.data() : null;
|
|
5304
4997
|
} catch (error) {
|
|
5305
4998
|
return null;
|
|
5306
4999
|
}
|
|
5307
5000
|
};
|
|
5308
5001
|
var addExpoTokenUtil = async (db, patientId, token) => {
|
|
5309
|
-
await (0,
|
|
5310
|
-
expoTokens: (0,
|
|
5311
|
-
updatedAt: (0,
|
|
5002
|
+
await (0, import_firestore16.updateDoc)(getPatientDocRef(db, patientId), {
|
|
5003
|
+
expoTokens: (0, import_firestore16.arrayUnion)(token),
|
|
5004
|
+
updatedAt: (0, import_firestore16.serverTimestamp)()
|
|
5312
5005
|
});
|
|
5313
5006
|
};
|
|
5314
5007
|
var removeExpoTokenUtil = async (db, patientId, token) => {
|
|
5315
|
-
await (0,
|
|
5316
|
-
expoTokens: (0,
|
|
5317
|
-
updatedAt: (0,
|
|
5008
|
+
await (0, import_firestore16.updateDoc)(getPatientDocRef(db, patientId), {
|
|
5009
|
+
expoTokens: (0, import_firestore16.arrayRemove)(token),
|
|
5010
|
+
updatedAt: (0, import_firestore16.serverTimestamp)()
|
|
5318
5011
|
});
|
|
5319
5012
|
};
|
|
5320
5013
|
var addPointsUtil = async (db, patientId, points) => {
|
|
5321
|
-
await (0,
|
|
5322
|
-
"gamification.points": (0,
|
|
5323
|
-
updatedAt: (0,
|
|
5014
|
+
await (0, import_firestore16.updateDoc)(getPatientDocRef(db, patientId), {
|
|
5015
|
+
"gamification.points": (0, import_firestore16.increment)(points),
|
|
5016
|
+
updatedAt: (0, import_firestore16.serverTimestamp)()
|
|
5324
5017
|
});
|
|
5325
5018
|
};
|
|
5326
5019
|
var updatePatientProfileUtil = async (db, patientId, data) => {
|
|
5327
5020
|
try {
|
|
5328
5021
|
const updateData = {
|
|
5329
5022
|
...data,
|
|
5330
|
-
updatedAt: (0,
|
|
5023
|
+
updatedAt: (0, import_firestore16.serverTimestamp)()
|
|
5331
5024
|
};
|
|
5332
|
-
await (0,
|
|
5333
|
-
const updatedDoc = await (0,
|
|
5025
|
+
await (0, import_firestore16.updateDoc)(getPatientDocRef(db, patientId), updateData);
|
|
5026
|
+
const updatedDoc = await (0, import_firestore16.getDoc)(getPatientDocRef(db, patientId));
|
|
5334
5027
|
if (!updatedDoc.exists()) {
|
|
5335
5028
|
throw new Error("Patient profile not found after update");
|
|
5336
5029
|
}
|
|
@@ -5343,7 +5036,7 @@ var updatePatientProfileUtil = async (db, patientId, data) => {
|
|
|
5343
5036
|
var updatePatientProfileByUserRefUtil = async (db, userRef, data) => {
|
|
5344
5037
|
try {
|
|
5345
5038
|
const docRef = await getPatientDocRefByUserRef(db, userRef);
|
|
5346
|
-
const patientDoc = await (0,
|
|
5039
|
+
const patientDoc = await (0, import_firestore16.getDoc)(docRef);
|
|
5347
5040
|
if (!patientDoc.exists()) {
|
|
5348
5041
|
throw new Error("Patient profile not found");
|
|
5349
5042
|
}
|
|
@@ -5372,14 +5065,14 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
|
|
|
5372
5065
|
photoUrl: "",
|
|
5373
5066
|
firstName: "Name",
|
|
5374
5067
|
lastName: "Surname",
|
|
5375
|
-
dateOfBirth:
|
|
5068
|
+
dateOfBirth: import_firestore16.Timestamp.now(),
|
|
5376
5069
|
gender: "prefer_not_to_say" /* PREFER_NOT_TO_SAY */,
|
|
5377
5070
|
email: "test@example.com",
|
|
5378
5071
|
phoneNumber: "",
|
|
5379
|
-
createdAt:
|
|
5380
|
-
updatedAt:
|
|
5072
|
+
createdAt: import_firestore16.Timestamp.now(),
|
|
5073
|
+
updatedAt: import_firestore16.Timestamp.now()
|
|
5381
5074
|
};
|
|
5382
|
-
await (0,
|
|
5075
|
+
await (0, import_firestore16.setDoc)(sensitiveInfoRef, defaultSensitiveInfo);
|
|
5383
5076
|
console.log(
|
|
5384
5077
|
`[testCreateSubDocuments] Sensitive info document created directly`
|
|
5385
5078
|
);
|
|
@@ -5391,10 +5084,10 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
|
|
|
5391
5084
|
const defaultMedicalInfo = {
|
|
5392
5085
|
...DEFAULT_MEDICAL_INFO,
|
|
5393
5086
|
patientId,
|
|
5394
|
-
lastUpdated:
|
|
5087
|
+
lastUpdated: import_firestore16.Timestamp.now(),
|
|
5395
5088
|
updatedBy: userRef
|
|
5396
5089
|
};
|
|
5397
|
-
await (0,
|
|
5090
|
+
await (0, import_firestore16.setDoc)(medicalInfoRef, defaultMedicalInfo);
|
|
5398
5091
|
console.log(
|
|
5399
5092
|
`[testCreateSubDocuments] Medical info document created directly`
|
|
5400
5093
|
);
|
|
@@ -5408,7 +5101,7 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
5408
5101
|
searchPatientsSchema.parse(params);
|
|
5409
5102
|
requesterInfoSchema.parse(requester);
|
|
5410
5103
|
const constraints = [];
|
|
5411
|
-
const patientsCollectionRef = (0,
|
|
5104
|
+
const patientsCollectionRef = (0, import_firestore16.collection)(db, PATIENTS_COLLECTION);
|
|
5412
5105
|
if (requester.role === "clinic_admin") {
|
|
5413
5106
|
if (!requester.associatedClinicId) {
|
|
5414
5107
|
throw new Error(
|
|
@@ -5422,11 +5115,11 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
5422
5115
|
return [];
|
|
5423
5116
|
}
|
|
5424
5117
|
constraints.push(
|
|
5425
|
-
(0,
|
|
5118
|
+
(0, import_firestore16.where)("clinicIds", "array-contains", requester.associatedClinicId)
|
|
5426
5119
|
);
|
|
5427
5120
|
if (params.practitionerId) {
|
|
5428
5121
|
constraints.push(
|
|
5429
|
-
(0,
|
|
5122
|
+
(0, import_firestore16.where)("doctorIds", "array-contains", params.practitionerId)
|
|
5430
5123
|
);
|
|
5431
5124
|
}
|
|
5432
5125
|
} else if (requester.role === "practitioner") {
|
|
@@ -5442,17 +5135,17 @@ var searchPatientsUtil = async (db, params, requester) => {
|
|
|
5442
5135
|
return [];
|
|
5443
5136
|
}
|
|
5444
5137
|
constraints.push(
|
|
5445
|
-
(0,
|
|
5138
|
+
(0, import_firestore16.where)("doctorIds", "array-contains", requester.associatedPractitionerId)
|
|
5446
5139
|
);
|
|
5447
5140
|
if (params.clinicId) {
|
|
5448
|
-
constraints.push((0,
|
|
5141
|
+
constraints.push((0, import_firestore16.where)("clinicIds", "array-contains", params.clinicId));
|
|
5449
5142
|
}
|
|
5450
5143
|
} else {
|
|
5451
5144
|
throw new Error("Invalid requester role.");
|
|
5452
5145
|
}
|
|
5453
5146
|
try {
|
|
5454
|
-
const finalQuery = (0,
|
|
5455
|
-
const querySnapshot = await (0,
|
|
5147
|
+
const finalQuery = (0, import_firestore16.query)(patientsCollectionRef, ...constraints);
|
|
5148
|
+
const querySnapshot = await (0, import_firestore16.getDocs)(finalQuery);
|
|
5456
5149
|
const patients = querySnapshot.docs.map(
|
|
5457
5150
|
(doc37) => doc37.data()
|
|
5458
5151
|
);
|
|
@@ -5471,20 +5164,20 @@ var getAllPatientsUtil = async (db, options) => {
|
|
|
5471
5164
|
`[getAllPatientsUtil] Fetching patients with options:`,
|
|
5472
5165
|
options
|
|
5473
5166
|
);
|
|
5474
|
-
const patientsCollection = (0,
|
|
5475
|
-
let q = (0,
|
|
5167
|
+
const patientsCollection = (0, import_firestore16.collection)(db, PATIENTS_COLLECTION);
|
|
5168
|
+
let q = (0, import_firestore16.query)(patientsCollection);
|
|
5476
5169
|
if (options == null ? void 0 : options.limit) {
|
|
5477
|
-
q = (0,
|
|
5170
|
+
q = (0, import_firestore16.query)(q, (0, import_firestore16.limit)(options.limit));
|
|
5478
5171
|
}
|
|
5479
5172
|
if (options == null ? void 0 : options.startAfter) {
|
|
5480
|
-
const startAfterDoc = await (0,
|
|
5481
|
-
(0,
|
|
5173
|
+
const startAfterDoc = await (0, import_firestore16.getDoc)(
|
|
5174
|
+
(0, import_firestore16.doc)(db, PATIENTS_COLLECTION, options.startAfter)
|
|
5482
5175
|
);
|
|
5483
5176
|
if (startAfterDoc.exists()) {
|
|
5484
|
-
q = (0,
|
|
5177
|
+
q = (0, import_firestore16.query)(q, (0, import_firestore16.startAfter)(startAfterDoc));
|
|
5485
5178
|
}
|
|
5486
5179
|
}
|
|
5487
|
-
const patientsSnapshot = await (0,
|
|
5180
|
+
const patientsSnapshot = await (0, import_firestore16.getDocs)(q);
|
|
5488
5181
|
const patients = [];
|
|
5489
5182
|
patientsSnapshot.forEach((doc37) => {
|
|
5490
5183
|
patients.push(doc37.data());
|
|
@@ -5500,31 +5193,31 @@ var getAllPatientsUtil = async (db, options) => {
|
|
|
5500
5193
|
};
|
|
5501
5194
|
|
|
5502
5195
|
// src/services/patient/utils/token.utils.ts
|
|
5503
|
-
var
|
|
5196
|
+
var import_firestore17 = require("firebase/firestore");
|
|
5504
5197
|
|
|
5505
5198
|
// src/validations/patient/token.schema.ts
|
|
5506
|
-
var
|
|
5507
|
-
var patientTokenSchema =
|
|
5508
|
-
id:
|
|
5509
|
-
token:
|
|
5510
|
-
patientId:
|
|
5511
|
-
email:
|
|
5512
|
-
clinicId:
|
|
5513
|
-
status:
|
|
5514
|
-
createdBy:
|
|
5515
|
-
createdAt:
|
|
5199
|
+
var import_zod14 = require("zod");
|
|
5200
|
+
var patientTokenSchema = import_zod14.z.object({
|
|
5201
|
+
id: import_zod14.z.string().min(1, "Token ID is required"),
|
|
5202
|
+
token: import_zod14.z.string().min(1, "Token string is required"),
|
|
5203
|
+
patientId: import_zod14.z.string().min(1, "Patient ID is required"),
|
|
5204
|
+
email: import_zod14.z.string().email("Invalid email format"),
|
|
5205
|
+
clinicId: import_zod14.z.string().min(1, "Clinic ID is required"),
|
|
5206
|
+
status: import_zod14.z.nativeEnum(PatientTokenStatus),
|
|
5207
|
+
createdBy: import_zod14.z.string().min(1, "Creator ID is required"),
|
|
5208
|
+
createdAt: import_zod14.z.any(),
|
|
5516
5209
|
// Assuming Timestamp validated elsewhere
|
|
5517
|
-
expiresAt:
|
|
5210
|
+
expiresAt: import_zod14.z.any(),
|
|
5518
5211
|
// Assuming Timestamp validated elsewhere
|
|
5519
|
-
usedBy:
|
|
5520
|
-
usedAt:
|
|
5212
|
+
usedBy: import_zod14.z.string().optional(),
|
|
5213
|
+
usedAt: import_zod14.z.any().optional()
|
|
5521
5214
|
// Assuming Timestamp validated elsewhere
|
|
5522
5215
|
});
|
|
5523
|
-
var createPatientTokenSchema =
|
|
5524
|
-
patientId:
|
|
5525
|
-
clinicId:
|
|
5526
|
-
email:
|
|
5527
|
-
expiresAt:
|
|
5216
|
+
var createPatientTokenSchema = import_zod14.z.object({
|
|
5217
|
+
patientId: import_zod14.z.string().min(1, "Patient ID is required"),
|
|
5218
|
+
clinicId: import_zod14.z.string().min(1, "Clinic ID is required"),
|
|
5219
|
+
email: import_zod14.z.string().email("Invalid email format"),
|
|
5220
|
+
expiresAt: import_zod14.z.date().optional()
|
|
5528
5221
|
});
|
|
5529
5222
|
|
|
5530
5223
|
// src/services/patient/utils/token.utils.ts
|
|
@@ -5532,7 +5225,7 @@ var createPatientTokenUtil = async (db, data, createdBy, generateId2) => {
|
|
|
5532
5225
|
var _a;
|
|
5533
5226
|
const validatedData = createPatientTokenSchema.parse(data);
|
|
5534
5227
|
const patientRef = getPatientDocRef(db, validatedData.patientId);
|
|
5535
|
-
const patientDoc = await (0,
|
|
5228
|
+
const patientDoc = await (0, import_firestore17.getDoc)(patientRef);
|
|
5536
5229
|
if (!patientDoc.exists() || !((_a = patientDoc.data()) == null ? void 0 : _a.isManual)) {
|
|
5537
5230
|
throw new Error(
|
|
5538
5231
|
"Patient profile not found or is not a manually created profile."
|
|
@@ -5548,36 +5241,36 @@ var createPatientTokenUtil = async (db, data, createdBy, generateId2) => {
|
|
|
5548
5241
|
clinicId: validatedData.clinicId,
|
|
5549
5242
|
status: "active" /* ACTIVE */,
|
|
5550
5243
|
createdBy,
|
|
5551
|
-
createdAt:
|
|
5552
|
-
expiresAt:
|
|
5244
|
+
createdAt: import_firestore17.Timestamp.now(),
|
|
5245
|
+
expiresAt: import_firestore17.Timestamp.fromDate(expiration)
|
|
5553
5246
|
};
|
|
5554
5247
|
patientTokenSchema.parse(token);
|
|
5555
|
-
const tokenRef = (0,
|
|
5248
|
+
const tokenRef = (0, import_firestore17.doc)(
|
|
5556
5249
|
db,
|
|
5557
5250
|
PATIENTS_COLLECTION,
|
|
5558
5251
|
validatedData.patientId,
|
|
5559
5252
|
INVITE_TOKENS_COLLECTION,
|
|
5560
5253
|
token.id
|
|
5561
5254
|
);
|
|
5562
|
-
await (0,
|
|
5255
|
+
await (0, import_firestore17.setDoc)(tokenRef, token);
|
|
5563
5256
|
return token;
|
|
5564
5257
|
};
|
|
5565
5258
|
var validatePatientTokenUtil = async (db, tokenString) => {
|
|
5566
|
-
const patientsRef = (0,
|
|
5567
|
-
const patientsSnapshot = await (0,
|
|
5259
|
+
const patientsRef = (0, import_firestore17.collection)(db, PATIENTS_COLLECTION);
|
|
5260
|
+
const patientsSnapshot = await (0, import_firestore17.getDocs)(patientsRef);
|
|
5568
5261
|
for (const patientDoc of patientsSnapshot.docs) {
|
|
5569
|
-
const tokensRef = (0,
|
|
5262
|
+
const tokensRef = (0, import_firestore17.collection)(
|
|
5570
5263
|
db,
|
|
5571
5264
|
patientDoc.ref.path,
|
|
5572
5265
|
INVITE_TOKENS_COLLECTION
|
|
5573
5266
|
);
|
|
5574
|
-
const q = (0,
|
|
5267
|
+
const q = (0, import_firestore17.query)(
|
|
5575
5268
|
tokensRef,
|
|
5576
|
-
(0,
|
|
5577
|
-
(0,
|
|
5578
|
-
(0,
|
|
5269
|
+
(0, import_firestore17.where)("token", "==", tokenString),
|
|
5270
|
+
(0, import_firestore17.where)("status", "==", "active" /* ACTIVE */),
|
|
5271
|
+
(0, import_firestore17.where)("expiresAt", ">", import_firestore17.Timestamp.now())
|
|
5579
5272
|
);
|
|
5580
|
-
const tokenSnapshot = await (0,
|
|
5273
|
+
const tokenSnapshot = await (0, import_firestore17.getDocs)(q);
|
|
5581
5274
|
if (!tokenSnapshot.empty) {
|
|
5582
5275
|
return tokenSnapshot.docs[0].data();
|
|
5583
5276
|
}
|
|
@@ -5585,45 +5278,45 @@ var validatePatientTokenUtil = async (db, tokenString) => {
|
|
|
5585
5278
|
return null;
|
|
5586
5279
|
};
|
|
5587
5280
|
var markPatientTokenAsUsedUtil = async (db, tokenId, patientId, userId) => {
|
|
5588
|
-
const tokenRef = (0,
|
|
5281
|
+
const tokenRef = (0, import_firestore17.doc)(
|
|
5589
5282
|
db,
|
|
5590
5283
|
PATIENTS_COLLECTION,
|
|
5591
5284
|
patientId,
|
|
5592
5285
|
INVITE_TOKENS_COLLECTION,
|
|
5593
5286
|
tokenId
|
|
5594
5287
|
);
|
|
5595
|
-
await (0,
|
|
5288
|
+
await (0, import_firestore17.updateDoc)(tokenRef, {
|
|
5596
5289
|
status: "used" /* USED */,
|
|
5597
5290
|
usedBy: userId,
|
|
5598
|
-
usedAt:
|
|
5291
|
+
usedAt: import_firestore17.Timestamp.now()
|
|
5599
5292
|
});
|
|
5600
5293
|
};
|
|
5601
5294
|
var getActiveInviteTokensByClinicUtil = async (db, clinicId) => {
|
|
5602
|
-
const tokensQuery = (0,
|
|
5603
|
-
(0,
|
|
5604
|
-
(0,
|
|
5605
|
-
(0,
|
|
5606
|
-
(0,
|
|
5295
|
+
const tokensQuery = (0, import_firestore17.query)(
|
|
5296
|
+
(0, import_firestore17.collectionGroup)(db, INVITE_TOKENS_COLLECTION),
|
|
5297
|
+
(0, import_firestore17.where)("clinicId", "==", clinicId),
|
|
5298
|
+
(0, import_firestore17.where)("status", "==", "active" /* ACTIVE */),
|
|
5299
|
+
(0, import_firestore17.where)("expiresAt", ">", import_firestore17.Timestamp.now())
|
|
5607
5300
|
);
|
|
5608
|
-
const querySnapshot = await (0,
|
|
5301
|
+
const querySnapshot = await (0, import_firestore17.getDocs)(tokensQuery);
|
|
5609
5302
|
if (querySnapshot.empty) {
|
|
5610
5303
|
return [];
|
|
5611
5304
|
}
|
|
5612
5305
|
return querySnapshot.docs.map((doc37) => doc37.data());
|
|
5613
5306
|
};
|
|
5614
5307
|
var getActiveInviteTokensByPatientUtil = async (db, patientId) => {
|
|
5615
|
-
const tokensRef = (0,
|
|
5308
|
+
const tokensRef = (0, import_firestore17.collection)(
|
|
5616
5309
|
db,
|
|
5617
5310
|
PATIENTS_COLLECTION,
|
|
5618
5311
|
patientId,
|
|
5619
5312
|
INVITE_TOKENS_COLLECTION
|
|
5620
5313
|
);
|
|
5621
|
-
const q = (0,
|
|
5314
|
+
const q = (0, import_firestore17.query)(
|
|
5622
5315
|
tokensRef,
|
|
5623
|
-
(0,
|
|
5624
|
-
(0,
|
|
5316
|
+
(0, import_firestore17.where)("status", "==", "active" /* ACTIVE */),
|
|
5317
|
+
(0, import_firestore17.where)("expiresAt", ">", import_firestore17.Timestamp.now())
|
|
5625
5318
|
);
|
|
5626
|
-
const querySnapshot = await (0,
|
|
5319
|
+
const querySnapshot = await (0, import_firestore17.getDocs)(q);
|
|
5627
5320
|
if (querySnapshot.empty) {
|
|
5628
5321
|
return [];
|
|
5629
5322
|
}
|
|
@@ -5663,8 +5356,8 @@ var PatientService = class extends BaseService {
|
|
|
5663
5356
|
);
|
|
5664
5357
|
}
|
|
5665
5358
|
const patientId = this.generateId();
|
|
5666
|
-
const batch = (0,
|
|
5667
|
-
const now =
|
|
5359
|
+
const batch = (0, import_firestore18.writeBatch)(this.db);
|
|
5360
|
+
const now = import_firestore19.Timestamp.now();
|
|
5668
5361
|
const patientProfileRef = getPatientDocRef(this.db, patientId);
|
|
5669
5362
|
const newProfile = {
|
|
5670
5363
|
id: patientId,
|
|
@@ -5989,8 +5682,8 @@ var PatientService = class extends BaseService {
|
|
|
5989
5682
|
if (!this.auth.currentUser) {
|
|
5990
5683
|
throw new Error("No authenticated user");
|
|
5991
5684
|
}
|
|
5992
|
-
const userDoc = await (0,
|
|
5993
|
-
(0,
|
|
5685
|
+
const userDoc = await (0, import_firestore18.getDoc)(
|
|
5686
|
+
(0, import_firestore18.doc)(this.db, "users", this.auth.currentUser.uid)
|
|
5994
5687
|
);
|
|
5995
5688
|
if (!userDoc.exists()) {
|
|
5996
5689
|
throw new Error("User not found");
|
|
@@ -6001,7 +5694,7 @@ var PatientService = class extends BaseService {
|
|
|
6001
5694
|
* Briše profil pacijenta i sve povezane subkolekcije
|
|
6002
5695
|
*/
|
|
6003
5696
|
async deletePatientProfile(patientId) {
|
|
6004
|
-
const batch = (0,
|
|
5697
|
+
const batch = (0, import_firestore18.writeBatch)(this.db);
|
|
6005
5698
|
batch.delete(getSensitiveInfoDocRef(this.db, patientId));
|
|
6006
5699
|
batch.delete(getLocationInfoDocRef(this.db, patientId));
|
|
6007
5700
|
batch.delete(getMedicalInfoDocRef(this.db, patientId));
|
|
@@ -6044,9 +5737,9 @@ var PatientService = class extends BaseService {
|
|
|
6044
5737
|
"patient_profile_photos",
|
|
6045
5738
|
file instanceof File ? file.name : `profile_photo_${patientId}`
|
|
6046
5739
|
);
|
|
6047
|
-
await (0,
|
|
5740
|
+
await (0, import_firestore18.updateDoc)(getSensitiveInfoDocRef(this.db, patientId), {
|
|
6048
5741
|
photoUrl: mediaMetadata.url,
|
|
6049
|
-
updatedAt: (0,
|
|
5742
|
+
updatedAt: (0, import_firestore18.serverTimestamp)()
|
|
6050
5743
|
});
|
|
6051
5744
|
return mediaMetadata.url;
|
|
6052
5745
|
}
|
|
@@ -6109,9 +5802,9 @@ var PatientService = class extends BaseService {
|
|
|
6109
5802
|
error
|
|
6110
5803
|
);
|
|
6111
5804
|
}
|
|
6112
|
-
await (0,
|
|
5805
|
+
await (0, import_firestore18.updateDoc)(getSensitiveInfoDocRef(this.db, patientId), {
|
|
6113
5806
|
photoUrl: null,
|
|
6114
|
-
updatedAt: (0,
|
|
5807
|
+
updatedAt: (0, import_firestore18.serverTimestamp)()
|
|
6115
5808
|
});
|
|
6116
5809
|
}
|
|
6117
5810
|
}
|
|
@@ -6412,7 +6105,169 @@ var ClinicAdminService = class extends BaseService {
|
|
|
6412
6105
|
|
|
6413
6106
|
// src/services/practitioner/practitioner.service.ts
|
|
6414
6107
|
var import_firestore21 = require("firebase/firestore");
|
|
6415
|
-
|
|
6108
|
+
|
|
6109
|
+
// src/validations/practitioner.schema.ts
|
|
6110
|
+
var import_zod15 = require("zod");
|
|
6111
|
+
var import_firestore20 = require("firebase/firestore");
|
|
6112
|
+
|
|
6113
|
+
// src/backoffice/types/static/certification.types.ts
|
|
6114
|
+
var CertificationLevel = /* @__PURE__ */ ((CertificationLevel2) => {
|
|
6115
|
+
CertificationLevel2["AESTHETICIAN"] = "aesthetician";
|
|
6116
|
+
CertificationLevel2["NURSE_ASSISTANT"] = "nurse_assistant";
|
|
6117
|
+
CertificationLevel2["NURSE"] = "nurse";
|
|
6118
|
+
CertificationLevel2["NURSE_PRACTITIONER"] = "nurse_practitioner";
|
|
6119
|
+
CertificationLevel2["PHYSICIAN_ASSISTANT"] = "physician_assistant";
|
|
6120
|
+
CertificationLevel2["DOCTOR"] = "doctor";
|
|
6121
|
+
CertificationLevel2["SPECIALIST"] = "specialist";
|
|
6122
|
+
CertificationLevel2["PLASTIC_SURGEON"] = "plastic_surgeon";
|
|
6123
|
+
return CertificationLevel2;
|
|
6124
|
+
})(CertificationLevel || {});
|
|
6125
|
+
var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
|
|
6126
|
+
CertificationSpecialty3["LASER"] = "laser";
|
|
6127
|
+
CertificationSpecialty3["INJECTABLES"] = "injectables";
|
|
6128
|
+
CertificationSpecialty3["CHEMICAL_PEELS"] = "chemical_peels";
|
|
6129
|
+
CertificationSpecialty3["MICRODERMABRASION"] = "microdermabrasion";
|
|
6130
|
+
CertificationSpecialty3["BODY_CONTOURING"] = "body_contouring";
|
|
6131
|
+
CertificationSpecialty3["SKIN_CARE"] = "skin_care";
|
|
6132
|
+
CertificationSpecialty3["WOUND_CARE"] = "wound_care";
|
|
6133
|
+
CertificationSpecialty3["ANESTHESIA"] = "anesthesia";
|
|
6134
|
+
return CertificationSpecialty3;
|
|
6135
|
+
})(CertificationSpecialty || {});
|
|
6136
|
+
|
|
6137
|
+
// src/validations/practitioner.schema.ts
|
|
6138
|
+
var practitionerBasicInfoSchema = import_zod15.z.object({
|
|
6139
|
+
firstName: import_zod15.z.string().min(2).max(50),
|
|
6140
|
+
lastName: import_zod15.z.string().min(2).max(50),
|
|
6141
|
+
title: import_zod15.z.string().min(2).max(100),
|
|
6142
|
+
email: import_zod15.z.string().email(),
|
|
6143
|
+
phoneNumber: import_zod15.z.string().regex(/^\+?[1-9]\d{1,14}$/, "Invalid phone number").nullable(),
|
|
6144
|
+
dateOfBirth: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date()).nullable(),
|
|
6145
|
+
gender: import_zod15.z.enum(["male", "female", "other"]),
|
|
6146
|
+
profileImageUrl: mediaResourceSchema.optional().nullable(),
|
|
6147
|
+
bio: import_zod15.z.string().max(1e3).optional(),
|
|
6148
|
+
languages: import_zod15.z.array(import_zod15.z.string()).min(1)
|
|
6149
|
+
});
|
|
6150
|
+
var practitionerCertificationSchema = import_zod15.z.object({
|
|
6151
|
+
level: import_zod15.z.nativeEnum(CertificationLevel),
|
|
6152
|
+
specialties: import_zod15.z.array(import_zod15.z.nativeEnum(CertificationSpecialty)),
|
|
6153
|
+
licenseNumber: import_zod15.z.string().min(3).max(50),
|
|
6154
|
+
issuingAuthority: import_zod15.z.string().min(2).max(100),
|
|
6155
|
+
issueDate: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date()),
|
|
6156
|
+
expiryDate: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date()).optional().nullable(),
|
|
6157
|
+
verificationStatus: import_zod15.z.enum(["pending", "verified", "rejected"])
|
|
6158
|
+
});
|
|
6159
|
+
var timeSlotSchema = import_zod15.z.object({
|
|
6160
|
+
start: import_zod15.z.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format"),
|
|
6161
|
+
end: import_zod15.z.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format")
|
|
6162
|
+
}).nullable();
|
|
6163
|
+
var practitionerWorkingHoursSchema = import_zod15.z.object({
|
|
6164
|
+
practitionerId: import_zod15.z.string().min(1),
|
|
6165
|
+
clinicId: import_zod15.z.string().min(1),
|
|
6166
|
+
monday: timeSlotSchema,
|
|
6167
|
+
tuesday: timeSlotSchema,
|
|
6168
|
+
wednesday: timeSlotSchema,
|
|
6169
|
+
thursday: timeSlotSchema,
|
|
6170
|
+
friday: timeSlotSchema,
|
|
6171
|
+
saturday: timeSlotSchema,
|
|
6172
|
+
sunday: timeSlotSchema,
|
|
6173
|
+
createdAt: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date()),
|
|
6174
|
+
updatedAt: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date())
|
|
6175
|
+
});
|
|
6176
|
+
var practitionerClinicWorkingHoursSchema = import_zod15.z.object({
|
|
6177
|
+
clinicId: import_zod15.z.string().min(1),
|
|
6178
|
+
workingHours: import_zod15.z.object({
|
|
6179
|
+
monday: timeSlotSchema,
|
|
6180
|
+
tuesday: timeSlotSchema,
|
|
6181
|
+
wednesday: timeSlotSchema,
|
|
6182
|
+
thursday: timeSlotSchema,
|
|
6183
|
+
friday: timeSlotSchema,
|
|
6184
|
+
saturday: timeSlotSchema,
|
|
6185
|
+
sunday: timeSlotSchema
|
|
6186
|
+
}),
|
|
6187
|
+
isActive: import_zod15.z.boolean(),
|
|
6188
|
+
createdAt: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date()),
|
|
6189
|
+
updatedAt: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date())
|
|
6190
|
+
});
|
|
6191
|
+
var practitionerSchema = import_zod15.z.object({
|
|
6192
|
+
id: import_zod15.z.string().min(1),
|
|
6193
|
+
userRef: import_zod15.z.string().min(1),
|
|
6194
|
+
basicInfo: practitionerBasicInfoSchema,
|
|
6195
|
+
certification: practitionerCertificationSchema,
|
|
6196
|
+
clinics: import_zod15.z.array(import_zod15.z.string()),
|
|
6197
|
+
clinicWorkingHours: import_zod15.z.array(practitionerClinicWorkingHoursSchema),
|
|
6198
|
+
clinicsInfo: import_zod15.z.array(clinicInfoSchema),
|
|
6199
|
+
procedures: import_zod15.z.array(import_zod15.z.string()),
|
|
6200
|
+
freeConsultations: import_zod15.z.record(import_zod15.z.string(), import_zod15.z.string()).optional().nullable(),
|
|
6201
|
+
proceduresInfo: import_zod15.z.array(procedureSummaryInfoSchema),
|
|
6202
|
+
reviewInfo: practitionerReviewInfoSchema,
|
|
6203
|
+
isActive: import_zod15.z.boolean(),
|
|
6204
|
+
isVerified: import_zod15.z.boolean(),
|
|
6205
|
+
status: import_zod15.z.nativeEnum(PractitionerStatus),
|
|
6206
|
+
createdAt: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date()),
|
|
6207
|
+
updatedAt: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date())
|
|
6208
|
+
});
|
|
6209
|
+
var createPractitionerSchema = import_zod15.z.object({
|
|
6210
|
+
userRef: import_zod15.z.string().min(1),
|
|
6211
|
+
basicInfo: practitionerBasicInfoSchema,
|
|
6212
|
+
certification: practitionerCertificationSchema,
|
|
6213
|
+
clinics: import_zod15.z.array(import_zod15.z.string()).optional(),
|
|
6214
|
+
clinicWorkingHours: import_zod15.z.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
6215
|
+
clinicsInfo: import_zod15.z.array(clinicInfoSchema).optional(),
|
|
6216
|
+
freeConsultations: import_zod15.z.record(import_zod15.z.string(), import_zod15.z.string()).optional().nullable(),
|
|
6217
|
+
proceduresInfo: import_zod15.z.array(procedureSummaryInfoSchema).optional(),
|
|
6218
|
+
isActive: import_zod15.z.boolean(),
|
|
6219
|
+
isVerified: import_zod15.z.boolean(),
|
|
6220
|
+
status: import_zod15.z.nativeEnum(PractitionerStatus).optional()
|
|
6221
|
+
});
|
|
6222
|
+
var createDraftPractitionerSchema = import_zod15.z.object({
|
|
6223
|
+
basicInfo: practitionerBasicInfoSchema,
|
|
6224
|
+
certification: practitionerCertificationSchema,
|
|
6225
|
+
clinics: import_zod15.z.array(import_zod15.z.string()).optional(),
|
|
6226
|
+
clinicWorkingHours: import_zod15.z.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
6227
|
+
clinicsInfo: import_zod15.z.array(clinicInfoSchema).optional(),
|
|
6228
|
+
freeConsultations: import_zod15.z.record(import_zod15.z.string(), import_zod15.z.string()).optional().nullable(),
|
|
6229
|
+
proceduresInfo: import_zod15.z.array(procedureSummaryInfoSchema).optional(),
|
|
6230
|
+
isActive: import_zod15.z.boolean().optional().default(false),
|
|
6231
|
+
isVerified: import_zod15.z.boolean().optional().default(false)
|
|
6232
|
+
});
|
|
6233
|
+
var practitionerTokenSchema = import_zod15.z.object({
|
|
6234
|
+
id: import_zod15.z.string().min(1),
|
|
6235
|
+
token: import_zod15.z.string().min(6),
|
|
6236
|
+
practitionerId: import_zod15.z.string().min(1),
|
|
6237
|
+
email: import_zod15.z.string().email(),
|
|
6238
|
+
clinicId: import_zod15.z.string().min(1),
|
|
6239
|
+
status: import_zod15.z.nativeEnum(PractitionerTokenStatus),
|
|
6240
|
+
createdBy: import_zod15.z.string().min(1),
|
|
6241
|
+
createdAt: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date()),
|
|
6242
|
+
expiresAt: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date()),
|
|
6243
|
+
usedBy: import_zod15.z.string().optional(),
|
|
6244
|
+
usedAt: import_zod15.z.instanceof(import_firestore20.Timestamp).or(import_zod15.z.date()).optional()
|
|
6245
|
+
});
|
|
6246
|
+
var createPractitionerTokenSchema = import_zod15.z.object({
|
|
6247
|
+
practitionerId: import_zod15.z.string().min(1),
|
|
6248
|
+
email: import_zod15.z.string().email(),
|
|
6249
|
+
clinicId: import_zod15.z.string().min(1),
|
|
6250
|
+
expiresAt: import_zod15.z.date().optional()
|
|
6251
|
+
});
|
|
6252
|
+
var practitionerSignupSchema = import_zod15.z.object({
|
|
6253
|
+
email: import_zod15.z.string().email(),
|
|
6254
|
+
password: import_zod15.z.string().min(8),
|
|
6255
|
+
firstName: import_zod15.z.string().min(2).max(50).optional(),
|
|
6256
|
+
lastName: import_zod15.z.string().min(2).max(50).optional(),
|
|
6257
|
+
token: import_zod15.z.string().optional(),
|
|
6258
|
+
profileData: import_zod15.z.object({
|
|
6259
|
+
basicInfo: import_zod15.z.object({
|
|
6260
|
+
phoneNumber: import_zod15.z.string().optional(),
|
|
6261
|
+
profileImageUrl: mediaResourceSchema.optional(),
|
|
6262
|
+
gender: import_zod15.z.enum(["male", "female", "other"]).optional(),
|
|
6263
|
+
bio: import_zod15.z.string().optional()
|
|
6264
|
+
}).optional(),
|
|
6265
|
+
certification: import_zod15.z.any().optional()
|
|
6266
|
+
}).optional()
|
|
6267
|
+
});
|
|
6268
|
+
|
|
6269
|
+
// src/services/practitioner/practitioner.service.ts
|
|
6270
|
+
var import_zod16 = require("zod");
|
|
6416
6271
|
var import_geofire_common2 = require("geofire-common");
|
|
6417
6272
|
var PractitionerService = class extends BaseService {
|
|
6418
6273
|
constructor(db, auth, app, clinicService, procedureService) {
|
|
@@ -6542,7 +6397,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6542
6397
|
}
|
|
6543
6398
|
return createdPractitioner;
|
|
6544
6399
|
} catch (error) {
|
|
6545
|
-
if (error instanceof
|
|
6400
|
+
if (error instanceof import_zod16.z.ZodError) {
|
|
6546
6401
|
throw new Error(`Invalid practitioner data: ${error.message}`);
|
|
6547
6402
|
}
|
|
6548
6403
|
console.error("Error creating practitioner:", error);
|
|
@@ -6658,7 +6513,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6658
6513
|
await (0, import_firestore21.setDoc)((0, import_firestore21.doc)(this.db, tokenPath), token);
|
|
6659
6514
|
return { practitioner: savedPractitioner, token };
|
|
6660
6515
|
} catch (error) {
|
|
6661
|
-
if (error instanceof
|
|
6516
|
+
if (error instanceof import_zod16.z.ZodError) {
|
|
6662
6517
|
throw new Error("Invalid practitioner data: " + error.message);
|
|
6663
6518
|
}
|
|
6664
6519
|
throw error;
|
|
@@ -6711,7 +6566,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6711
6566
|
await (0, import_firestore21.setDoc)((0, import_firestore21.doc)(this.db, tokenPath), token);
|
|
6712
6567
|
return token;
|
|
6713
6568
|
} catch (error) {
|
|
6714
|
-
if (error instanceof
|
|
6569
|
+
if (error instanceof import_zod16.z.ZodError) {
|
|
6715
6570
|
throw new Error("Invalid token data: " + error.message);
|
|
6716
6571
|
}
|
|
6717
6572
|
throw error;
|
|
@@ -6905,7 +6760,7 @@ var PractitionerService = class extends BaseService {
|
|
|
6905
6760
|
}
|
|
6906
6761
|
return updatedPractitioner;
|
|
6907
6762
|
} catch (error) {
|
|
6908
|
-
if (error instanceof
|
|
6763
|
+
if (error instanceof import_zod16.z.ZodError) {
|
|
6909
6764
|
throw new Error(`Invalid practitioner update data: ${error.message}`);
|
|
6910
6765
|
}
|
|
6911
6766
|
console.error(`Error updating practitioner ${practitionerId}:`, error);
|
|
@@ -7688,7 +7543,7 @@ var UserService = class extends BaseService {
|
|
|
7688
7543
|
});
|
|
7689
7544
|
return this.getUserById(uid);
|
|
7690
7545
|
} catch (error) {
|
|
7691
|
-
if (error instanceof
|
|
7546
|
+
if (error instanceof import_zod17.z.ZodError) {
|
|
7692
7547
|
throw USER_ERRORS.VALIDATION_ERROR;
|
|
7693
7548
|
}
|
|
7694
7549
|
throw error;
|
|
@@ -7775,7 +7630,7 @@ var UserService = class extends BaseService {
|
|
|
7775
7630
|
// src/services/clinic/utils/clinic-group.utils.ts
|
|
7776
7631
|
var import_firestore23 = require("firebase/firestore");
|
|
7777
7632
|
var import_geofire_common3 = require("geofire-common");
|
|
7778
|
-
var
|
|
7633
|
+
var import_zod18 = require("zod");
|
|
7779
7634
|
|
|
7780
7635
|
// src/services/clinic/utils/photos.utils.ts
|
|
7781
7636
|
var import_storage3 = require("firebase/storage");
|
|
@@ -7973,7 +7828,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
7973
7828
|
});
|
|
7974
7829
|
return groupData;
|
|
7975
7830
|
} catch (error) {
|
|
7976
|
-
if (error instanceof
|
|
7831
|
+
if (error instanceof import_zod18.z.ZodError) {
|
|
7977
7832
|
console.error(
|
|
7978
7833
|
"[CLINIC_GROUP] Zod validation error:",
|
|
7979
7834
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -8420,12 +8275,12 @@ var ClinicGroupService = class extends BaseService {
|
|
|
8420
8275
|
// src/services/clinic/clinic.service.ts
|
|
8421
8276
|
var import_firestore27 = require("firebase/firestore");
|
|
8422
8277
|
var import_geofire_common7 = require("geofire-common");
|
|
8423
|
-
var
|
|
8278
|
+
var import_zod20 = require("zod");
|
|
8424
8279
|
|
|
8425
8280
|
// src/services/clinic/utils/clinic.utils.ts
|
|
8426
8281
|
var import_firestore24 = require("firebase/firestore");
|
|
8427
8282
|
var import_geofire_common4 = require("geofire-common");
|
|
8428
|
-
var
|
|
8283
|
+
var import_zod19 = require("zod");
|
|
8429
8284
|
async function getClinic(db, clinicId) {
|
|
8430
8285
|
const docRef = (0, import_firestore24.doc)(db, CLINICS_COLLECTION, clinicId);
|
|
8431
8286
|
const docSnap = await (0, import_firestore24.getDoc)(docRef);
|
|
@@ -9189,7 +9044,7 @@ var ClinicService = class extends BaseService {
|
|
|
9189
9044
|
if (!savedClinic) throw new Error("Failed to retrieve created clinic");
|
|
9190
9045
|
return savedClinic;
|
|
9191
9046
|
} catch (error) {
|
|
9192
|
-
if (error instanceof
|
|
9047
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
9193
9048
|
throw new Error("Invalid clinic data: " + error.message);
|
|
9194
9049
|
}
|
|
9195
9050
|
console.error("Error creating clinic:", error);
|
|
@@ -9269,7 +9124,7 @@ var ClinicService = class extends BaseService {
|
|
|
9269
9124
|
if (!updatedClinic) throw new Error("Failed to retrieve updated clinic");
|
|
9270
9125
|
return updatedClinic;
|
|
9271
9126
|
} catch (error) {
|
|
9272
|
-
if (error instanceof
|
|
9127
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
9273
9128
|
throw new Error("Invalid clinic update data: " + error.message);
|
|
9274
9129
|
}
|
|
9275
9130
|
console.error(`Error updating clinic ${clinicId}:`, error);
|
|
@@ -9432,6 +9287,125 @@ var ClinicService = class extends BaseService {
|
|
|
9432
9287
|
}
|
|
9433
9288
|
};
|
|
9434
9289
|
|
|
9290
|
+
// src/services/auth/utils/firebase.utils.ts
|
|
9291
|
+
var import_auth5 = require("firebase/auth");
|
|
9292
|
+
var checkEmailExists = async (auth, email) => {
|
|
9293
|
+
try {
|
|
9294
|
+
const methods = await (0, import_auth5.fetchSignInMethodsForEmail)(auth, email);
|
|
9295
|
+
return methods.length > 0;
|
|
9296
|
+
} catch (error) {
|
|
9297
|
+
console.warn(
|
|
9298
|
+
"[FIREBASE] Could not check email existence, allowing signup to proceed:",
|
|
9299
|
+
error
|
|
9300
|
+
);
|
|
9301
|
+
return false;
|
|
9302
|
+
}
|
|
9303
|
+
};
|
|
9304
|
+
var cleanupFirebaseUser = async (firebaseUser) => {
|
|
9305
|
+
try {
|
|
9306
|
+
console.log("[FIREBASE] Cleaning up Firebase user", {
|
|
9307
|
+
uid: firebaseUser.uid
|
|
9308
|
+
});
|
|
9309
|
+
await firebaseUser.delete();
|
|
9310
|
+
console.log("[FIREBASE] Firebase user cleanup successful");
|
|
9311
|
+
} catch (cleanupError) {
|
|
9312
|
+
console.error("[FIREBASE] Failed to cleanup Firebase user:", cleanupError);
|
|
9313
|
+
}
|
|
9314
|
+
};
|
|
9315
|
+
|
|
9316
|
+
// src/services/auth/utils/error.utils.ts
|
|
9317
|
+
var import_zod21 = require("zod");
|
|
9318
|
+
var handleFirebaseError = (error) => {
|
|
9319
|
+
const firebaseError = error;
|
|
9320
|
+
switch (firebaseError.code) {
|
|
9321
|
+
case "auth/email-already-in-use" /* EMAIL_ALREADY_IN_USE */:
|
|
9322
|
+
return AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
|
|
9323
|
+
case "auth/weak-password":
|
|
9324
|
+
return new Error(
|
|
9325
|
+
"Password is too weak. Please choose a stronger password."
|
|
9326
|
+
);
|
|
9327
|
+
case "auth/invalid-email":
|
|
9328
|
+
return new Error("Please enter a valid email address.");
|
|
9329
|
+
case "auth/network-request-failed":
|
|
9330
|
+
return new Error(
|
|
9331
|
+
"Network error. Please check your internet connection and try again."
|
|
9332
|
+
);
|
|
9333
|
+
default:
|
|
9334
|
+
return new Error(
|
|
9335
|
+
`Account creation failed: ${firebaseError.message || "Unknown error"}`
|
|
9336
|
+
);
|
|
9337
|
+
}
|
|
9338
|
+
};
|
|
9339
|
+
var handleSignupError = (error) => {
|
|
9340
|
+
if (error instanceof import_zod21.z.ZodError) {
|
|
9341
|
+
const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
|
|
9342
|
+
return new Error(`Validation failed: ${errorMessages}`);
|
|
9343
|
+
}
|
|
9344
|
+
if (error.code && error.code.startsWith("auth/")) {
|
|
9345
|
+
return handleFirebaseError(error);
|
|
9346
|
+
}
|
|
9347
|
+
if (error.message && error.message.includes("token")) {
|
|
9348
|
+
return new Error("Invalid or expired invitation token");
|
|
9349
|
+
}
|
|
9350
|
+
if (error.message && error.message.includes("validation")) {
|
|
9351
|
+
return new Error(`Invalid practitioner data: ${error.message}`);
|
|
9352
|
+
}
|
|
9353
|
+
return new Error(
|
|
9354
|
+
`Registration failed: ${error.message || "Unknown error occurred"}`
|
|
9355
|
+
);
|
|
9356
|
+
};
|
|
9357
|
+
|
|
9358
|
+
// src/services/auth/utils/practitioner.utils.ts
|
|
9359
|
+
var import_zod22 = require("zod");
|
|
9360
|
+
var profileDataSchema = import_zod22.z.object({
|
|
9361
|
+
basicInfo: practitionerBasicInfoSchema.partial().optional(),
|
|
9362
|
+
certification: practitionerCertificationSchema.partial().optional()
|
|
9363
|
+
}).partial();
|
|
9364
|
+
var buildPractitionerData = (data, userRef) => {
|
|
9365
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
9366
|
+
const basicInfo = {
|
|
9367
|
+
firstName: data.firstName || "Name",
|
|
9368
|
+
lastName: data.lastName || "Surname",
|
|
9369
|
+
email: data.email,
|
|
9370
|
+
phoneNumber: ((_b = (_a = data.profileData) == null ? void 0 : _a.basicInfo) == null ? void 0 : _b.phoneNumber) || null,
|
|
9371
|
+
profileImageUrl: ((_d = (_c = data.profileData) == null ? void 0 : _c.basicInfo) == null ? void 0 : _d.profileImageUrl) || "",
|
|
9372
|
+
gender: ((_f = (_e = data.profileData) == null ? void 0 : _e.basicInfo) == null ? void 0 : _f.gender) || "other",
|
|
9373
|
+
bio: ((_h = (_g = data.profileData) == null ? void 0 : _g.basicInfo) == null ? void 0 : _h.bio) || "",
|
|
9374
|
+
title: "Practitioner",
|
|
9375
|
+
dateOfBirth: ((_j = (_i = data.profileData) == null ? void 0 : _i.basicInfo) == null ? void 0 : _j.dateOfBirth) || /* @__PURE__ */ new Date(),
|
|
9376
|
+
languages: ((_l = (_k = data.profileData) == null ? void 0 : _k.basicInfo) == null ? void 0 : _l.languages) || ["English"]
|
|
9377
|
+
};
|
|
9378
|
+
const certification = ((_m = data.profileData) == null ? void 0 : _m.certification) || {
|
|
9379
|
+
level: "aesthetician" /* AESTHETICIAN */,
|
|
9380
|
+
specialties: [],
|
|
9381
|
+
licenseNumber: "Pending",
|
|
9382
|
+
issuingAuthority: "Pending",
|
|
9383
|
+
issueDate: /* @__PURE__ */ new Date(),
|
|
9384
|
+
verificationStatus: "pending"
|
|
9385
|
+
};
|
|
9386
|
+
return {
|
|
9387
|
+
userRef,
|
|
9388
|
+
basicInfo,
|
|
9389
|
+
certification,
|
|
9390
|
+
status: "active" /* ACTIVE */,
|
|
9391
|
+
isActive: true,
|
|
9392
|
+
isVerified: false
|
|
9393
|
+
};
|
|
9394
|
+
};
|
|
9395
|
+
var validatePractitionerProfileData = async (profileData) => {
|
|
9396
|
+
try {
|
|
9397
|
+
await profileDataSchema.parseAsync(profileData);
|
|
9398
|
+
} catch (error) {
|
|
9399
|
+
if (error instanceof import_zod22.z.ZodError) {
|
|
9400
|
+
const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
|
|
9401
|
+
throw new Error(
|
|
9402
|
+
`Practitioner profile validation failed: ${errorMessages}`
|
|
9403
|
+
);
|
|
9404
|
+
}
|
|
9405
|
+
throw error;
|
|
9406
|
+
}
|
|
9407
|
+
};
|
|
9408
|
+
|
|
9435
9409
|
// src/services/auth/auth.service.ts
|
|
9436
9410
|
var AuthService = class extends BaseService {
|
|
9437
9411
|
constructor(db, auth, app, userService) {
|
|
@@ -17246,11 +17220,8 @@ var ProductService = class extends BaseService {
|
|
|
17246
17220
|
beforeAfterPerZoneSchema,
|
|
17247
17221
|
billingPerZoneSchema,
|
|
17248
17222
|
blockingConditionSchema,
|
|
17249
|
-
buildPractitionerData,
|
|
17250
17223
|
calendarEventSchema,
|
|
17251
17224
|
calendarEventTimeSchema,
|
|
17252
|
-
checkEmailExists,
|
|
17253
|
-
cleanupFirebaseUser,
|
|
17254
17225
|
clinicAdminOptionsSchema,
|
|
17255
17226
|
clinicAdminSchema,
|
|
17256
17227
|
clinicAdminSignupSchema,
|
|
@@ -17298,7 +17269,6 @@ var ProductService = class extends BaseService {
|
|
|
17298
17269
|
documentTemplateSchema,
|
|
17299
17270
|
emailSchema,
|
|
17300
17271
|
emergencyContactSchema,
|
|
17301
|
-
extractErrorMessage,
|
|
17302
17272
|
filledDocumentSchema,
|
|
17303
17273
|
filledDocumentStatusSchema,
|
|
17304
17274
|
finalBillingSchema,
|
|
@@ -17310,10 +17280,7 @@ var ProductService = class extends BaseService {
|
|
|
17310
17280
|
getFirebaseFunctions,
|
|
17311
17281
|
getFirebaseInstance,
|
|
17312
17282
|
getFirebaseStorage,
|
|
17313
|
-
handleFirebaseError,
|
|
17314
|
-
handleSignupError,
|
|
17315
17283
|
initializeFirebase,
|
|
17316
|
-
isPractitionerDataComplete,
|
|
17317
17284
|
linkedFormInfoSchema,
|
|
17318
17285
|
locationDataSchema,
|
|
17319
17286
|
mediaResourceSchema,
|
|
@@ -17385,7 +17352,6 @@ var ProductService = class extends BaseService {
|
|
|
17385
17352
|
userRoleSchema,
|
|
17386
17353
|
userRolesSchema,
|
|
17387
17354
|
userSchema,
|
|
17388
|
-
validatePractitionerProfileData,
|
|
17389
17355
|
vitalStatsSchema,
|
|
17390
17356
|
workingHoursSchema
|
|
17391
17357
|
});
|