@blackcode_sa/metaestetics-api 1.5.52 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +106 -1
- package/dist/index.d.ts +106 -1
- package/dist/index.js +266 -4
- package/dist/index.mjs +265 -4
- package/package.json +1 -1
- package/src/services/auth.service.ts +295 -0
- package/src/services/practitioner/practitioner.service.ts +36 -6
- package/src/validations/practitioner.schema.ts +24 -0
package/dist/index.d.mts
CHANGED
|
@@ -5326,6 +5326,36 @@ declare class AuthService extends BaseService {
|
|
|
5326
5326
|
* @returns Promise koji se razrešava kada je lozinka promenjena
|
|
5327
5327
|
*/
|
|
5328
5328
|
confirmPasswordReset(oobCode: string, newPassword: string): Promise<void>;
|
|
5329
|
+
/**
|
|
5330
|
+
* Registers a new practitioner user with email and password
|
|
5331
|
+
* Can either create a new practitioner profile or claim an existing draft profile with a token
|
|
5332
|
+
*
|
|
5333
|
+
* @param data - Practitioner signup data containing either new profile details or token for claiming draft profile
|
|
5334
|
+
* @returns Object containing the created user and practitioner profile
|
|
5335
|
+
*/
|
|
5336
|
+
signUpPractitioner(data: {
|
|
5337
|
+
email: string;
|
|
5338
|
+
password: string;
|
|
5339
|
+
firstName: string;
|
|
5340
|
+
lastName: string;
|
|
5341
|
+
token?: string;
|
|
5342
|
+
profileData?: Partial<CreatePractitionerData>;
|
|
5343
|
+
}): Promise<{
|
|
5344
|
+
user: User;
|
|
5345
|
+
practitioner: Practitioner;
|
|
5346
|
+
}>;
|
|
5347
|
+
/**
|
|
5348
|
+
* Signs in a user with email and password specifically for practitioner role
|
|
5349
|
+
* @param email - User's email
|
|
5350
|
+
* @param password - User's password
|
|
5351
|
+
* @returns Object containing the user and practitioner profile
|
|
5352
|
+
* @throws {AUTH_ERRORS.INVALID_ROLE} If user doesn't have practitioner role
|
|
5353
|
+
* @throws {AUTH_ERRORS.NOT_FOUND} If practitioner profile is not found
|
|
5354
|
+
*/
|
|
5355
|
+
signInPractitioner(email: string, password: string): Promise<{
|
|
5356
|
+
user: User;
|
|
5357
|
+
practitioner: Practitioner;
|
|
5358
|
+
}>;
|
|
5329
5359
|
}
|
|
5330
5360
|
|
|
5331
5361
|
/**
|
|
@@ -12052,6 +12082,81 @@ declare const createPractitionerTokenSchema: z.ZodObject<{
|
|
|
12052
12082
|
clinicId: string;
|
|
12053
12083
|
expiresAt?: Date | undefined;
|
|
12054
12084
|
}>;
|
|
12085
|
+
/**
|
|
12086
|
+
* Simplified schema for practitioner signup
|
|
12087
|
+
*/
|
|
12088
|
+
declare const practitionerSignupSchema: z.ZodObject<{
|
|
12089
|
+
email: z.ZodString;
|
|
12090
|
+
password: z.ZodString;
|
|
12091
|
+
firstName: z.ZodString;
|
|
12092
|
+
lastName: z.ZodString;
|
|
12093
|
+
token: z.ZodOptional<z.ZodString>;
|
|
12094
|
+
profileData: z.ZodOptional<z.ZodObject<{
|
|
12095
|
+
basicInfo: z.ZodOptional<z.ZodObject<{
|
|
12096
|
+
phoneNumber: z.ZodOptional<z.ZodString>;
|
|
12097
|
+
profileImageUrl: z.ZodOptional<z.ZodString>;
|
|
12098
|
+
gender: z.ZodOptional<z.ZodEnum<["male", "female", "other"]>>;
|
|
12099
|
+
bio: z.ZodOptional<z.ZodString>;
|
|
12100
|
+
}, "strip", z.ZodTypeAny, {
|
|
12101
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12102
|
+
phoneNumber?: string | undefined;
|
|
12103
|
+
profileImageUrl?: string | undefined;
|
|
12104
|
+
bio?: string | undefined;
|
|
12105
|
+
}, {
|
|
12106
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12107
|
+
phoneNumber?: string | undefined;
|
|
12108
|
+
profileImageUrl?: string | undefined;
|
|
12109
|
+
bio?: string | undefined;
|
|
12110
|
+
}>>;
|
|
12111
|
+
certification: z.ZodOptional<z.ZodAny>;
|
|
12112
|
+
}, "strip", z.ZodTypeAny, {
|
|
12113
|
+
basicInfo?: {
|
|
12114
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12115
|
+
phoneNumber?: string | undefined;
|
|
12116
|
+
profileImageUrl?: string | undefined;
|
|
12117
|
+
bio?: string | undefined;
|
|
12118
|
+
} | undefined;
|
|
12119
|
+
certification?: any;
|
|
12120
|
+
}, {
|
|
12121
|
+
basicInfo?: {
|
|
12122
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12123
|
+
phoneNumber?: string | undefined;
|
|
12124
|
+
profileImageUrl?: string | undefined;
|
|
12125
|
+
bio?: string | undefined;
|
|
12126
|
+
} | undefined;
|
|
12127
|
+
certification?: any;
|
|
12128
|
+
}>>;
|
|
12129
|
+
}, "strip", z.ZodTypeAny, {
|
|
12130
|
+
firstName: string;
|
|
12131
|
+
lastName: string;
|
|
12132
|
+
email: string;
|
|
12133
|
+
password: string;
|
|
12134
|
+
token?: string | undefined;
|
|
12135
|
+
profileData?: {
|
|
12136
|
+
basicInfo?: {
|
|
12137
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12138
|
+
phoneNumber?: string | undefined;
|
|
12139
|
+
profileImageUrl?: string | undefined;
|
|
12140
|
+
bio?: string | undefined;
|
|
12141
|
+
} | undefined;
|
|
12142
|
+
certification?: any;
|
|
12143
|
+
} | undefined;
|
|
12144
|
+
}, {
|
|
12145
|
+
firstName: string;
|
|
12146
|
+
lastName: string;
|
|
12147
|
+
email: string;
|
|
12148
|
+
password: string;
|
|
12149
|
+
token?: string | undefined;
|
|
12150
|
+
profileData?: {
|
|
12151
|
+
basicInfo?: {
|
|
12152
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12153
|
+
phoneNumber?: string | undefined;
|
|
12154
|
+
profileImageUrl?: string | undefined;
|
|
12155
|
+
bio?: string | undefined;
|
|
12156
|
+
} | undefined;
|
|
12157
|
+
certification?: any;
|
|
12158
|
+
} | undefined;
|
|
12159
|
+
}>;
|
|
12055
12160
|
|
|
12056
12161
|
/**
|
|
12057
12162
|
* Validaciona šema za kontakt informacije
|
|
@@ -18192,4 +18297,4 @@ declare const createReviewSchema: z.ZodEffects<z.ZodObject<{
|
|
|
18192
18297
|
} | undefined;
|
|
18193
18298
|
}>;
|
|
18194
18299
|
|
|
18195
|
-
export { APPOINTMENTS_COLLECTION, AUTH_ERRORS, type AddAllergyData, type AddBlockingConditionData, type AddContraindicationData, type AddMedicationData, type AddressData, type AdminInfo, type AdminToken, AdminTokenStatus, type Allergy, type AllergySubtype, AllergyType, type AllergyTypeWithSubtype, type Appointment, type AppointmentNotification, type AppointmentReminderNotification, AppointmentService, AppointmentStatus, AuthError, AuthService, type BaseNotification, BlockingCondition, type Brand, BrandService, CALENDAR_COLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_GROUPS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarSyncStatus, type Category, CategoryService, CertificationLevel, CertificationSpecialty, type Clinic, type ClinicAdmin, ClinicAdminService, type ClinicAdminSignupData, type ClinicBranchSetupData, type ClinicContactInfo, type ClinicGroup, ClinicGroupService, type ClinicGroupSetupData, type ClinicInfo, type ClinicLocation, ClinicPhotoTag, type ClinicReview, type ClinicReviewInfo, ClinicService, ClinicTag, type ClinicTags, type ContactPerson, Contraindication, CosmeticAllergySubtype, type CreateAdminTokenData, type CreateAppointmentData, type CreateAppointmentParams, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePractitionerData, type CreatePractitionerTokenData, type CreateProcedureData, type CreateSyncedCalendarData, type CreateUserData, Currency, DOCUMENTATION_TEMPLATES_COLLECTION, type DateRange, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, DynamicVariable, type EmergencyContact, EnvironmentalAllergySubtype, FILLED_DOCUMENTS_COLLECTION, type FilledDocument, FilledDocumentService, FilledDocumentStatus, FirebaseErrorCode, type FirebaseUser, FoodAllergySubtype, type GamificationInfo, Gender, HeadingLevel, Language, ListType, type LocationData, MedicationAllergySubtype, type Notification, NotificationService, NotificationStatus, NotificationType, PATIENTS_COLLECTION, PATIENT_APPOINTMENTS_COLLECTION, PATIENT_LOCATION_INFO_COLLECTION, PATIENT_MEDICAL_HISTORY_COLLECTION, PATIENT_MEDICAL_INFO_COLLECTION, PATIENT_SENSITIVE_INFO_COLLECTION, PRACTITIONERS_COLLECTION, PROCEDURES_COLLECTION, type PatientClinic, type PatientDoctor, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileInfo, type PatientSensitiveInfo, PatientService, PaymentStatus, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerBasicInfo, type PractitionerCertification, type PractitionerClinicProcedures, type PractitionerClinicWorkingHours, type PractitionerProfileInfo, type PractitionerReview, type PractitionerReviewInfo, PractitionerService, PractitionerStatus, type PractitionerToken, PractitionerTokenStatus, type PractitionerWorkingHours, type PreRequirementNotification, PricingMeasure, type Procedure, type ProcedureCategorization, ProcedureFamily, type ProcedureInfo, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type Product, ProductService, REGISTER_TOKENS_COLLECTION, REVIEWS_COLLECTION, type RequesterInfo, type Requirement, RequirementType, type Review, ReviewService, SYNCED_CALENDARS_COLLECTION, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type Subcategory, SubcategoryService, SubscriptionModel, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, type Technology, TechnologyService, type TimeSlot, TimeUnit, TreatmentBenefit, USER_ERRORS, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateCalendarEventData, type UpdateClinicAdminData, type UpdateClinicData, type UpdateClinicGroupData, type UpdateContraindicationData, type UpdateDocumentTemplateData, type UpdateMedicationData, type UpdatePatientLocationInfoData, type UpdatePatientMedicalInfoData, type UpdatePatientProfileData, type UpdatePatientSensitiveInfoData, type UpdatePractitionerData, type UpdateProcedureData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type ValidationSchema, type VitalStats, type WorkingHours, addAllergySchema, addBlockingConditionSchema, addContraindicationSchema, addMedicationSchema, addressDataSchema, adminInfoSchema, adminTokenSchema, allergySchema, allergySubtypeSchema, appointmentNotificationSchema, appointmentReminderNotificationSchema, baseNotificationSchema, blockingConditionSchema, calendarEventSchema, calendarEventTimeSchema, clinicAdminOptionsSchema, clinicAdminSchema, clinicAdminSignupSchema, clinicBranchSetupSchema, clinicContactInfoSchema, clinicGroupSchema, clinicGroupSetupSchema, clinicInfoSchema, clinicLocationSchema, clinicReviewInfoSchema, clinicReviewSchema, clinicSchema, clinicTagsSchema, contactPersonSchema, contraindicationSchema, createAdminTokenSchema, createAppointmentSchema, createCalendarEventSchema, createClinicAdminSchema, createClinicGroupSchema, createClinicReviewSchema, createClinicSchema, createDefaultClinicGroupSchema, createDocumentTemplateSchema, createDraftPractitionerSchema, createPatientLocationInfoSchema, createPatientMedicalInfoSchema, createPatientProfileSchema, createPatientSensitiveInfoSchema, createPractitionerReviewSchema, createPractitionerSchema, createPractitionerTokenSchema, createProcedureReviewSchema, createReviewSchema, createUserOptionsSchema, doctorInfoSchema, documentElementSchema, documentElementWithoutIdSchema, documentTemplateSchema, emailSchema, emergencyContactSchema, gamificationSchema, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseInstance, initializeFirebase, locationDataSchema, medicationSchema, notificationSchema, passwordSchema, patientClinicSchema, patientDoctorSchema, patientLocationInfoSchema, patientMedicalInfoSchema, patientProfileInfoSchema, patientProfileSchema, patientSensitiveInfoSchema, postRequirementNotificationSchema, practitionerBasicInfoSchema, practitionerCertificationSchema, practitionerClinicWorkingHoursSchema, practitionerProfileInfoSchema, practitionerReviewInfoSchema, practitionerReviewSchema, practitionerSchema, practitionerTokenSchema, practitionerWorkingHoursSchema, preRequirementNotificationSchema, procedureCategorizationSchema, procedureInfoSchema, procedureReviewInfoSchema, procedureReviewSchema, procedureSummaryInfoSchema, requesterInfoSchema, reviewSchema, searchAppointmentsSchema, searchPatientsSchema, syncedCalendarEventSchema, timeSlotSchema, timestampSchema, updateAllergySchema, updateAppointmentSchema, updateBlockingConditionSchema, updateCalendarEventSchema, updateClinicAdminSchema, updateClinicGroupSchema, updateClinicSchema, updateContraindicationSchema, updateDocumentTemplateSchema, updateMedicationSchema, updatePatientMedicalInfoSchema, updateVitalStatsSchema, userRoleSchema, userRolesSchema, userSchema, vitalStatsSchema, workingHoursSchema };
|
|
18300
|
+
export { APPOINTMENTS_COLLECTION, AUTH_ERRORS, type AddAllergyData, type AddBlockingConditionData, type AddContraindicationData, type AddMedicationData, type AddressData, type AdminInfo, type AdminToken, AdminTokenStatus, type Allergy, type AllergySubtype, AllergyType, type AllergyTypeWithSubtype, type Appointment, type AppointmentNotification, type AppointmentReminderNotification, AppointmentService, AppointmentStatus, AuthError, AuthService, type BaseNotification, BlockingCondition, type Brand, BrandService, CALENDAR_COLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_GROUPS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarSyncStatus, type Category, CategoryService, CertificationLevel, CertificationSpecialty, type Clinic, type ClinicAdmin, ClinicAdminService, type ClinicAdminSignupData, type ClinicBranchSetupData, type ClinicContactInfo, type ClinicGroup, ClinicGroupService, type ClinicGroupSetupData, type ClinicInfo, type ClinicLocation, ClinicPhotoTag, type ClinicReview, type ClinicReviewInfo, ClinicService, ClinicTag, type ClinicTags, type ContactPerson, Contraindication, CosmeticAllergySubtype, type CreateAdminTokenData, type CreateAppointmentData, type CreateAppointmentParams, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePractitionerData, type CreatePractitionerTokenData, type CreateProcedureData, type CreateSyncedCalendarData, type CreateUserData, Currency, DOCUMENTATION_TEMPLATES_COLLECTION, type DateRange, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, DynamicVariable, type EmergencyContact, EnvironmentalAllergySubtype, FILLED_DOCUMENTS_COLLECTION, type FilledDocument, FilledDocumentService, FilledDocumentStatus, FirebaseErrorCode, type FirebaseUser, FoodAllergySubtype, type GamificationInfo, Gender, HeadingLevel, Language, ListType, type LocationData, MedicationAllergySubtype, type Notification, NotificationService, NotificationStatus, NotificationType, PATIENTS_COLLECTION, PATIENT_APPOINTMENTS_COLLECTION, PATIENT_LOCATION_INFO_COLLECTION, PATIENT_MEDICAL_HISTORY_COLLECTION, PATIENT_MEDICAL_INFO_COLLECTION, PATIENT_SENSITIVE_INFO_COLLECTION, PRACTITIONERS_COLLECTION, PROCEDURES_COLLECTION, type PatientClinic, type PatientDoctor, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileInfo, type PatientSensitiveInfo, PatientService, PaymentStatus, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerBasicInfo, type PractitionerCertification, type PractitionerClinicProcedures, type PractitionerClinicWorkingHours, type PractitionerProfileInfo, type PractitionerReview, type PractitionerReviewInfo, PractitionerService, PractitionerStatus, type PractitionerToken, PractitionerTokenStatus, type PractitionerWorkingHours, type PreRequirementNotification, PricingMeasure, type Procedure, type ProcedureCategorization, ProcedureFamily, type ProcedureInfo, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type Product, ProductService, REGISTER_TOKENS_COLLECTION, REVIEWS_COLLECTION, type RequesterInfo, type Requirement, RequirementType, type Review, ReviewService, SYNCED_CALENDARS_COLLECTION, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type Subcategory, SubcategoryService, SubscriptionModel, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, type Technology, TechnologyService, type TimeSlot, TimeUnit, TreatmentBenefit, USER_ERRORS, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateCalendarEventData, type UpdateClinicAdminData, type UpdateClinicData, type UpdateClinicGroupData, type UpdateContraindicationData, type UpdateDocumentTemplateData, type UpdateMedicationData, type UpdatePatientLocationInfoData, type UpdatePatientMedicalInfoData, type UpdatePatientProfileData, type UpdatePatientSensitiveInfoData, type UpdatePractitionerData, type UpdateProcedureData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type ValidationSchema, type VitalStats, type WorkingHours, addAllergySchema, addBlockingConditionSchema, addContraindicationSchema, addMedicationSchema, addressDataSchema, adminInfoSchema, adminTokenSchema, allergySchema, allergySubtypeSchema, appointmentNotificationSchema, appointmentReminderNotificationSchema, baseNotificationSchema, blockingConditionSchema, calendarEventSchema, calendarEventTimeSchema, clinicAdminOptionsSchema, clinicAdminSchema, clinicAdminSignupSchema, clinicBranchSetupSchema, clinicContactInfoSchema, clinicGroupSchema, clinicGroupSetupSchema, clinicInfoSchema, clinicLocationSchema, clinicReviewInfoSchema, clinicReviewSchema, clinicSchema, clinicTagsSchema, contactPersonSchema, contraindicationSchema, createAdminTokenSchema, createAppointmentSchema, createCalendarEventSchema, createClinicAdminSchema, createClinicGroupSchema, createClinicReviewSchema, createClinicSchema, createDefaultClinicGroupSchema, createDocumentTemplateSchema, createDraftPractitionerSchema, createPatientLocationInfoSchema, createPatientMedicalInfoSchema, createPatientProfileSchema, createPatientSensitiveInfoSchema, createPractitionerReviewSchema, createPractitionerSchema, createPractitionerTokenSchema, createProcedureReviewSchema, createReviewSchema, createUserOptionsSchema, doctorInfoSchema, documentElementSchema, documentElementWithoutIdSchema, documentTemplateSchema, emailSchema, emergencyContactSchema, gamificationSchema, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseInstance, initializeFirebase, locationDataSchema, medicationSchema, notificationSchema, passwordSchema, patientClinicSchema, patientDoctorSchema, patientLocationInfoSchema, patientMedicalInfoSchema, patientProfileInfoSchema, patientProfileSchema, patientSensitiveInfoSchema, postRequirementNotificationSchema, practitionerBasicInfoSchema, practitionerCertificationSchema, practitionerClinicWorkingHoursSchema, practitionerProfileInfoSchema, practitionerReviewInfoSchema, practitionerReviewSchema, practitionerSchema, practitionerSignupSchema, practitionerTokenSchema, practitionerWorkingHoursSchema, preRequirementNotificationSchema, procedureCategorizationSchema, procedureInfoSchema, procedureReviewInfoSchema, procedureReviewSchema, procedureSummaryInfoSchema, requesterInfoSchema, reviewSchema, searchAppointmentsSchema, searchPatientsSchema, syncedCalendarEventSchema, timeSlotSchema, timestampSchema, updateAllergySchema, updateAppointmentSchema, updateBlockingConditionSchema, updateCalendarEventSchema, updateClinicAdminSchema, updateClinicGroupSchema, updateClinicSchema, updateContraindicationSchema, updateDocumentTemplateSchema, updateMedicationSchema, updatePatientMedicalInfoSchema, updateVitalStatsSchema, userRoleSchema, userRolesSchema, userSchema, vitalStatsSchema, workingHoursSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -5326,6 +5326,36 @@ declare class AuthService extends BaseService {
|
|
|
5326
5326
|
* @returns Promise koji se razrešava kada je lozinka promenjena
|
|
5327
5327
|
*/
|
|
5328
5328
|
confirmPasswordReset(oobCode: string, newPassword: string): Promise<void>;
|
|
5329
|
+
/**
|
|
5330
|
+
* Registers a new practitioner user with email and password
|
|
5331
|
+
* Can either create a new practitioner profile or claim an existing draft profile with a token
|
|
5332
|
+
*
|
|
5333
|
+
* @param data - Practitioner signup data containing either new profile details or token for claiming draft profile
|
|
5334
|
+
* @returns Object containing the created user and practitioner profile
|
|
5335
|
+
*/
|
|
5336
|
+
signUpPractitioner(data: {
|
|
5337
|
+
email: string;
|
|
5338
|
+
password: string;
|
|
5339
|
+
firstName: string;
|
|
5340
|
+
lastName: string;
|
|
5341
|
+
token?: string;
|
|
5342
|
+
profileData?: Partial<CreatePractitionerData>;
|
|
5343
|
+
}): Promise<{
|
|
5344
|
+
user: User;
|
|
5345
|
+
practitioner: Practitioner;
|
|
5346
|
+
}>;
|
|
5347
|
+
/**
|
|
5348
|
+
* Signs in a user with email and password specifically for practitioner role
|
|
5349
|
+
* @param email - User's email
|
|
5350
|
+
* @param password - User's password
|
|
5351
|
+
* @returns Object containing the user and practitioner profile
|
|
5352
|
+
* @throws {AUTH_ERRORS.INVALID_ROLE} If user doesn't have practitioner role
|
|
5353
|
+
* @throws {AUTH_ERRORS.NOT_FOUND} If practitioner profile is not found
|
|
5354
|
+
*/
|
|
5355
|
+
signInPractitioner(email: string, password: string): Promise<{
|
|
5356
|
+
user: User;
|
|
5357
|
+
practitioner: Practitioner;
|
|
5358
|
+
}>;
|
|
5329
5359
|
}
|
|
5330
5360
|
|
|
5331
5361
|
/**
|
|
@@ -12052,6 +12082,81 @@ declare const createPractitionerTokenSchema: z.ZodObject<{
|
|
|
12052
12082
|
clinicId: string;
|
|
12053
12083
|
expiresAt?: Date | undefined;
|
|
12054
12084
|
}>;
|
|
12085
|
+
/**
|
|
12086
|
+
* Simplified schema for practitioner signup
|
|
12087
|
+
*/
|
|
12088
|
+
declare const practitionerSignupSchema: z.ZodObject<{
|
|
12089
|
+
email: z.ZodString;
|
|
12090
|
+
password: z.ZodString;
|
|
12091
|
+
firstName: z.ZodString;
|
|
12092
|
+
lastName: z.ZodString;
|
|
12093
|
+
token: z.ZodOptional<z.ZodString>;
|
|
12094
|
+
profileData: z.ZodOptional<z.ZodObject<{
|
|
12095
|
+
basicInfo: z.ZodOptional<z.ZodObject<{
|
|
12096
|
+
phoneNumber: z.ZodOptional<z.ZodString>;
|
|
12097
|
+
profileImageUrl: z.ZodOptional<z.ZodString>;
|
|
12098
|
+
gender: z.ZodOptional<z.ZodEnum<["male", "female", "other"]>>;
|
|
12099
|
+
bio: z.ZodOptional<z.ZodString>;
|
|
12100
|
+
}, "strip", z.ZodTypeAny, {
|
|
12101
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12102
|
+
phoneNumber?: string | undefined;
|
|
12103
|
+
profileImageUrl?: string | undefined;
|
|
12104
|
+
bio?: string | undefined;
|
|
12105
|
+
}, {
|
|
12106
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12107
|
+
phoneNumber?: string | undefined;
|
|
12108
|
+
profileImageUrl?: string | undefined;
|
|
12109
|
+
bio?: string | undefined;
|
|
12110
|
+
}>>;
|
|
12111
|
+
certification: z.ZodOptional<z.ZodAny>;
|
|
12112
|
+
}, "strip", z.ZodTypeAny, {
|
|
12113
|
+
basicInfo?: {
|
|
12114
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12115
|
+
phoneNumber?: string | undefined;
|
|
12116
|
+
profileImageUrl?: string | undefined;
|
|
12117
|
+
bio?: string | undefined;
|
|
12118
|
+
} | undefined;
|
|
12119
|
+
certification?: any;
|
|
12120
|
+
}, {
|
|
12121
|
+
basicInfo?: {
|
|
12122
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12123
|
+
phoneNumber?: string | undefined;
|
|
12124
|
+
profileImageUrl?: string | undefined;
|
|
12125
|
+
bio?: string | undefined;
|
|
12126
|
+
} | undefined;
|
|
12127
|
+
certification?: any;
|
|
12128
|
+
}>>;
|
|
12129
|
+
}, "strip", z.ZodTypeAny, {
|
|
12130
|
+
firstName: string;
|
|
12131
|
+
lastName: string;
|
|
12132
|
+
email: string;
|
|
12133
|
+
password: string;
|
|
12134
|
+
token?: string | undefined;
|
|
12135
|
+
profileData?: {
|
|
12136
|
+
basicInfo?: {
|
|
12137
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12138
|
+
phoneNumber?: string | undefined;
|
|
12139
|
+
profileImageUrl?: string | undefined;
|
|
12140
|
+
bio?: string | undefined;
|
|
12141
|
+
} | undefined;
|
|
12142
|
+
certification?: any;
|
|
12143
|
+
} | undefined;
|
|
12144
|
+
}, {
|
|
12145
|
+
firstName: string;
|
|
12146
|
+
lastName: string;
|
|
12147
|
+
email: string;
|
|
12148
|
+
password: string;
|
|
12149
|
+
token?: string | undefined;
|
|
12150
|
+
profileData?: {
|
|
12151
|
+
basicInfo?: {
|
|
12152
|
+
gender?: "male" | "female" | "other" | undefined;
|
|
12153
|
+
phoneNumber?: string | undefined;
|
|
12154
|
+
profileImageUrl?: string | undefined;
|
|
12155
|
+
bio?: string | undefined;
|
|
12156
|
+
} | undefined;
|
|
12157
|
+
certification?: any;
|
|
12158
|
+
} | undefined;
|
|
12159
|
+
}>;
|
|
12055
12160
|
|
|
12056
12161
|
/**
|
|
12057
12162
|
* Validaciona šema za kontakt informacije
|
|
@@ -18192,4 +18297,4 @@ declare const createReviewSchema: z.ZodEffects<z.ZodObject<{
|
|
|
18192
18297
|
} | undefined;
|
|
18193
18298
|
}>;
|
|
18194
18299
|
|
|
18195
|
-
export { APPOINTMENTS_COLLECTION, AUTH_ERRORS, type AddAllergyData, type AddBlockingConditionData, type AddContraindicationData, type AddMedicationData, type AddressData, type AdminInfo, type AdminToken, AdminTokenStatus, type Allergy, type AllergySubtype, AllergyType, type AllergyTypeWithSubtype, type Appointment, type AppointmentNotification, type AppointmentReminderNotification, AppointmentService, AppointmentStatus, AuthError, AuthService, type BaseNotification, BlockingCondition, type Brand, BrandService, CALENDAR_COLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_GROUPS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarSyncStatus, type Category, CategoryService, CertificationLevel, CertificationSpecialty, type Clinic, type ClinicAdmin, ClinicAdminService, type ClinicAdminSignupData, type ClinicBranchSetupData, type ClinicContactInfo, type ClinicGroup, ClinicGroupService, type ClinicGroupSetupData, type ClinicInfo, type ClinicLocation, ClinicPhotoTag, type ClinicReview, type ClinicReviewInfo, ClinicService, ClinicTag, type ClinicTags, type ContactPerson, Contraindication, CosmeticAllergySubtype, type CreateAdminTokenData, type CreateAppointmentData, type CreateAppointmentParams, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePractitionerData, type CreatePractitionerTokenData, type CreateProcedureData, type CreateSyncedCalendarData, type CreateUserData, Currency, DOCUMENTATION_TEMPLATES_COLLECTION, type DateRange, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, DynamicVariable, type EmergencyContact, EnvironmentalAllergySubtype, FILLED_DOCUMENTS_COLLECTION, type FilledDocument, FilledDocumentService, FilledDocumentStatus, FirebaseErrorCode, type FirebaseUser, FoodAllergySubtype, type GamificationInfo, Gender, HeadingLevel, Language, ListType, type LocationData, MedicationAllergySubtype, type Notification, NotificationService, NotificationStatus, NotificationType, PATIENTS_COLLECTION, PATIENT_APPOINTMENTS_COLLECTION, PATIENT_LOCATION_INFO_COLLECTION, PATIENT_MEDICAL_HISTORY_COLLECTION, PATIENT_MEDICAL_INFO_COLLECTION, PATIENT_SENSITIVE_INFO_COLLECTION, PRACTITIONERS_COLLECTION, PROCEDURES_COLLECTION, type PatientClinic, type PatientDoctor, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileInfo, type PatientSensitiveInfo, PatientService, PaymentStatus, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerBasicInfo, type PractitionerCertification, type PractitionerClinicProcedures, type PractitionerClinicWorkingHours, type PractitionerProfileInfo, type PractitionerReview, type PractitionerReviewInfo, PractitionerService, PractitionerStatus, type PractitionerToken, PractitionerTokenStatus, type PractitionerWorkingHours, type PreRequirementNotification, PricingMeasure, type Procedure, type ProcedureCategorization, ProcedureFamily, type ProcedureInfo, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type Product, ProductService, REGISTER_TOKENS_COLLECTION, REVIEWS_COLLECTION, type RequesterInfo, type Requirement, RequirementType, type Review, ReviewService, SYNCED_CALENDARS_COLLECTION, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type Subcategory, SubcategoryService, SubscriptionModel, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, type Technology, TechnologyService, type TimeSlot, TimeUnit, TreatmentBenefit, USER_ERRORS, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateCalendarEventData, type UpdateClinicAdminData, type UpdateClinicData, type UpdateClinicGroupData, type UpdateContraindicationData, type UpdateDocumentTemplateData, type UpdateMedicationData, type UpdatePatientLocationInfoData, type UpdatePatientMedicalInfoData, type UpdatePatientProfileData, type UpdatePatientSensitiveInfoData, type UpdatePractitionerData, type UpdateProcedureData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type ValidationSchema, type VitalStats, type WorkingHours, addAllergySchema, addBlockingConditionSchema, addContraindicationSchema, addMedicationSchema, addressDataSchema, adminInfoSchema, adminTokenSchema, allergySchema, allergySubtypeSchema, appointmentNotificationSchema, appointmentReminderNotificationSchema, baseNotificationSchema, blockingConditionSchema, calendarEventSchema, calendarEventTimeSchema, clinicAdminOptionsSchema, clinicAdminSchema, clinicAdminSignupSchema, clinicBranchSetupSchema, clinicContactInfoSchema, clinicGroupSchema, clinicGroupSetupSchema, clinicInfoSchema, clinicLocationSchema, clinicReviewInfoSchema, clinicReviewSchema, clinicSchema, clinicTagsSchema, contactPersonSchema, contraindicationSchema, createAdminTokenSchema, createAppointmentSchema, createCalendarEventSchema, createClinicAdminSchema, createClinicGroupSchema, createClinicReviewSchema, createClinicSchema, createDefaultClinicGroupSchema, createDocumentTemplateSchema, createDraftPractitionerSchema, createPatientLocationInfoSchema, createPatientMedicalInfoSchema, createPatientProfileSchema, createPatientSensitiveInfoSchema, createPractitionerReviewSchema, createPractitionerSchema, createPractitionerTokenSchema, createProcedureReviewSchema, createReviewSchema, createUserOptionsSchema, doctorInfoSchema, documentElementSchema, documentElementWithoutIdSchema, documentTemplateSchema, emailSchema, emergencyContactSchema, gamificationSchema, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseInstance, initializeFirebase, locationDataSchema, medicationSchema, notificationSchema, passwordSchema, patientClinicSchema, patientDoctorSchema, patientLocationInfoSchema, patientMedicalInfoSchema, patientProfileInfoSchema, patientProfileSchema, patientSensitiveInfoSchema, postRequirementNotificationSchema, practitionerBasicInfoSchema, practitionerCertificationSchema, practitionerClinicWorkingHoursSchema, practitionerProfileInfoSchema, practitionerReviewInfoSchema, practitionerReviewSchema, practitionerSchema, practitionerTokenSchema, practitionerWorkingHoursSchema, preRequirementNotificationSchema, procedureCategorizationSchema, procedureInfoSchema, procedureReviewInfoSchema, procedureReviewSchema, procedureSummaryInfoSchema, requesterInfoSchema, reviewSchema, searchAppointmentsSchema, searchPatientsSchema, syncedCalendarEventSchema, timeSlotSchema, timestampSchema, updateAllergySchema, updateAppointmentSchema, updateBlockingConditionSchema, updateCalendarEventSchema, updateClinicAdminSchema, updateClinicGroupSchema, updateClinicSchema, updateContraindicationSchema, updateDocumentTemplateSchema, updateMedicationSchema, updatePatientMedicalInfoSchema, updateVitalStatsSchema, userRoleSchema, userRolesSchema, userSchema, vitalStatsSchema, workingHoursSchema };
|
|
18300
|
+
export { APPOINTMENTS_COLLECTION, AUTH_ERRORS, type AddAllergyData, type AddBlockingConditionData, type AddContraindicationData, type AddMedicationData, type AddressData, type AdminInfo, type AdminToken, AdminTokenStatus, type Allergy, type AllergySubtype, AllergyType, type AllergyTypeWithSubtype, type Appointment, type AppointmentNotification, type AppointmentReminderNotification, AppointmentService, AppointmentStatus, AuthError, AuthService, type BaseNotification, BlockingCondition, type Brand, BrandService, CALENDAR_COLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_GROUPS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarSyncStatus, type Category, CategoryService, CertificationLevel, CertificationSpecialty, type Clinic, type ClinicAdmin, ClinicAdminService, type ClinicAdminSignupData, type ClinicBranchSetupData, type ClinicContactInfo, type ClinicGroup, ClinicGroupService, type ClinicGroupSetupData, type ClinicInfo, type ClinicLocation, ClinicPhotoTag, type ClinicReview, type ClinicReviewInfo, ClinicService, ClinicTag, type ClinicTags, type ContactPerson, Contraindication, CosmeticAllergySubtype, type CreateAdminTokenData, type CreateAppointmentData, type CreateAppointmentParams, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePractitionerData, type CreatePractitionerTokenData, type CreateProcedureData, type CreateSyncedCalendarData, type CreateUserData, Currency, DOCUMENTATION_TEMPLATES_COLLECTION, type DateRange, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, DynamicVariable, type EmergencyContact, EnvironmentalAllergySubtype, FILLED_DOCUMENTS_COLLECTION, type FilledDocument, FilledDocumentService, FilledDocumentStatus, FirebaseErrorCode, type FirebaseUser, FoodAllergySubtype, type GamificationInfo, Gender, HeadingLevel, Language, ListType, type LocationData, MedicationAllergySubtype, type Notification, NotificationService, NotificationStatus, NotificationType, PATIENTS_COLLECTION, PATIENT_APPOINTMENTS_COLLECTION, PATIENT_LOCATION_INFO_COLLECTION, PATIENT_MEDICAL_HISTORY_COLLECTION, PATIENT_MEDICAL_INFO_COLLECTION, PATIENT_SENSITIVE_INFO_COLLECTION, PRACTITIONERS_COLLECTION, PROCEDURES_COLLECTION, type PatientClinic, type PatientDoctor, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileInfo, type PatientSensitiveInfo, PatientService, PaymentStatus, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerBasicInfo, type PractitionerCertification, type PractitionerClinicProcedures, type PractitionerClinicWorkingHours, type PractitionerProfileInfo, type PractitionerReview, type PractitionerReviewInfo, PractitionerService, PractitionerStatus, type PractitionerToken, PractitionerTokenStatus, type PractitionerWorkingHours, type PreRequirementNotification, PricingMeasure, type Procedure, type ProcedureCategorization, ProcedureFamily, type ProcedureInfo, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type Product, ProductService, REGISTER_TOKENS_COLLECTION, REVIEWS_COLLECTION, type RequesterInfo, type Requirement, RequirementType, type Review, ReviewService, SYNCED_CALENDARS_COLLECTION, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type Subcategory, SubcategoryService, SubscriptionModel, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, type Technology, TechnologyService, type TimeSlot, TimeUnit, TreatmentBenefit, USER_ERRORS, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateCalendarEventData, type UpdateClinicAdminData, type UpdateClinicData, type UpdateClinicGroupData, type UpdateContraindicationData, type UpdateDocumentTemplateData, type UpdateMedicationData, type UpdatePatientLocationInfoData, type UpdatePatientMedicalInfoData, type UpdatePatientProfileData, type UpdatePatientSensitiveInfoData, type UpdatePractitionerData, type UpdateProcedureData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type ValidationSchema, type VitalStats, type WorkingHours, addAllergySchema, addBlockingConditionSchema, addContraindicationSchema, addMedicationSchema, addressDataSchema, adminInfoSchema, adminTokenSchema, allergySchema, allergySubtypeSchema, appointmentNotificationSchema, appointmentReminderNotificationSchema, baseNotificationSchema, blockingConditionSchema, calendarEventSchema, calendarEventTimeSchema, clinicAdminOptionsSchema, clinicAdminSchema, clinicAdminSignupSchema, clinicBranchSetupSchema, clinicContactInfoSchema, clinicGroupSchema, clinicGroupSetupSchema, clinicInfoSchema, clinicLocationSchema, clinicReviewInfoSchema, clinicReviewSchema, clinicSchema, clinicTagsSchema, contactPersonSchema, contraindicationSchema, createAdminTokenSchema, createAppointmentSchema, createCalendarEventSchema, createClinicAdminSchema, createClinicGroupSchema, createClinicReviewSchema, createClinicSchema, createDefaultClinicGroupSchema, createDocumentTemplateSchema, createDraftPractitionerSchema, createPatientLocationInfoSchema, createPatientMedicalInfoSchema, createPatientProfileSchema, createPatientSensitiveInfoSchema, createPractitionerReviewSchema, createPractitionerSchema, createPractitionerTokenSchema, createProcedureReviewSchema, createReviewSchema, createUserOptionsSchema, doctorInfoSchema, documentElementSchema, documentElementWithoutIdSchema, documentTemplateSchema, emailSchema, emergencyContactSchema, gamificationSchema, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseInstance, initializeFirebase, locationDataSchema, medicationSchema, notificationSchema, passwordSchema, patientClinicSchema, patientDoctorSchema, patientLocationInfoSchema, patientMedicalInfoSchema, patientProfileInfoSchema, patientProfileSchema, patientSensitiveInfoSchema, postRequirementNotificationSchema, practitionerBasicInfoSchema, practitionerCertificationSchema, practitionerClinicWorkingHoursSchema, practitionerProfileInfoSchema, practitionerReviewInfoSchema, practitionerReviewSchema, practitionerSchema, practitionerSignupSchema, practitionerTokenSchema, practitionerWorkingHoursSchema, preRequirementNotificationSchema, procedureCategorizationSchema, procedureInfoSchema, procedureReviewInfoSchema, procedureReviewSchema, procedureSummaryInfoSchema, requesterInfoSchema, reviewSchema, searchAppointmentsSchema, searchPatientsSchema, syncedCalendarEventSchema, timeSlotSchema, timestampSchema, updateAllergySchema, updateAppointmentSchema, updateBlockingConditionSchema, updateCalendarEventSchema, updateClinicAdminSchema, updateClinicGroupSchema, updateClinicSchema, updateContraindicationSchema, updateDocumentTemplateSchema, updateMedicationSchema, updatePatientMedicalInfoSchema, updateVitalStatsSchema, userRoleSchema, userRolesSchema, userSchema, vitalStatsSchema, workingHoursSchema };
|
package/dist/index.js
CHANGED
|
@@ -190,6 +190,7 @@ __export(index_exports, {
|
|
|
190
190
|
practitionerReviewInfoSchema: () => practitionerReviewInfoSchema,
|
|
191
191
|
practitionerReviewSchema: () => practitionerReviewSchema,
|
|
192
192
|
practitionerSchema: () => practitionerSchema,
|
|
193
|
+
practitionerSignupSchema: () => practitionerSignupSchema,
|
|
193
194
|
practitionerTokenSchema: () => practitionerTokenSchema,
|
|
194
195
|
practitionerWorkingHoursSchema: () => practitionerWorkingHoursSchema,
|
|
195
196
|
preRequirementNotificationSchema: () => preRequirementNotificationSchema,
|
|
@@ -3104,6 +3105,22 @@ var createPractitionerTokenSchema = import_zod11.z.object({
|
|
|
3104
3105
|
clinicId: import_zod11.z.string().min(1),
|
|
3105
3106
|
expiresAt: import_zod11.z.date().optional()
|
|
3106
3107
|
});
|
|
3108
|
+
var practitionerSignupSchema = import_zod11.z.object({
|
|
3109
|
+
email: import_zod11.z.string().email(),
|
|
3110
|
+
password: import_zod11.z.string().min(8),
|
|
3111
|
+
firstName: import_zod11.z.string().min(2).max(50),
|
|
3112
|
+
lastName: import_zod11.z.string().min(2).max(50),
|
|
3113
|
+
token: import_zod11.z.string().optional(),
|
|
3114
|
+
profileData: import_zod11.z.object({
|
|
3115
|
+
basicInfo: import_zod11.z.object({
|
|
3116
|
+
phoneNumber: import_zod11.z.string().optional(),
|
|
3117
|
+
profileImageUrl: import_zod11.z.string().optional(),
|
|
3118
|
+
gender: import_zod11.z.enum(["male", "female", "other"]).optional(),
|
|
3119
|
+
bio: import_zod11.z.string().optional()
|
|
3120
|
+
}).optional(),
|
|
3121
|
+
certification: import_zod11.z.any().optional()
|
|
3122
|
+
}).optional()
|
|
3123
|
+
});
|
|
3107
3124
|
|
|
3108
3125
|
// src/validations/clinic.schema.ts
|
|
3109
3126
|
var clinicContactInfoSchema = import_zod12.z.object({
|
|
@@ -3911,8 +3928,8 @@ var PractitionerService = class extends BaseService {
|
|
|
3911
3928
|
if (!clinic) {
|
|
3912
3929
|
throw new Error(`Clinic ${clinicId} not found`);
|
|
3913
3930
|
}
|
|
3914
|
-
const
|
|
3915
|
-
if (data.clinics) {
|
|
3931
|
+
const clinicsToAdd = /* @__PURE__ */ new Set([clinicId]);
|
|
3932
|
+
if (data.clinics && data.clinics.length > 0) {
|
|
3916
3933
|
for (const cId of data.clinics) {
|
|
3917
3934
|
if (cId !== clinicId) {
|
|
3918
3935
|
const otherClinic = await this.getClinicService().getClinic(cId);
|
|
@@ -3920,8 +3937,10 @@ var PractitionerService = class extends BaseService {
|
|
|
3920
3937
|
throw new Error(`Clinic ${cId} not found`);
|
|
3921
3938
|
}
|
|
3922
3939
|
}
|
|
3940
|
+
clinicsToAdd.add(cId);
|
|
3923
3941
|
}
|
|
3924
3942
|
}
|
|
3943
|
+
const clinics = Array.from(clinicsToAdd);
|
|
3925
3944
|
const defaultReviewInfo = {
|
|
3926
3945
|
totalReviews: 0,
|
|
3927
3946
|
averageRating: 0,
|
|
@@ -3933,7 +3952,21 @@ var PractitionerService = class extends BaseService {
|
|
|
3933
3952
|
recommendationPercentage: 0
|
|
3934
3953
|
};
|
|
3935
3954
|
const practitionerId = this.generateId();
|
|
3936
|
-
const clinicsInfo =
|
|
3955
|
+
const clinicsInfo = [];
|
|
3956
|
+
for (const cId of clinics) {
|
|
3957
|
+
const clinicData = await this.getClinicService().getClinic(cId);
|
|
3958
|
+
if (clinicData) {
|
|
3959
|
+
clinicsInfo.push({
|
|
3960
|
+
id: clinicData.id,
|
|
3961
|
+
name: clinicData.name,
|
|
3962
|
+
location: clinicData.location,
|
|
3963
|
+
contactInfo: clinicData.contactInfo,
|
|
3964
|
+
featuredPhoto: clinicData.coverPhoto || "",
|
|
3965
|
+
description: clinicData.description || null
|
|
3966
|
+
});
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
const finalClinicsInfo = validatedData.clinicsInfo && validatedData.clinicsInfo.length > 0 ? validatedData.clinicsInfo : clinicsInfo;
|
|
3937
3970
|
const proceduresInfo = [];
|
|
3938
3971
|
const practitionerData = {
|
|
3939
3972
|
id: practitionerId,
|
|
@@ -3943,7 +3976,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3943
3976
|
certification: validatedData.certification,
|
|
3944
3977
|
clinics,
|
|
3945
3978
|
clinicWorkingHours: validatedData.clinicWorkingHours || [],
|
|
3946
|
-
clinicsInfo,
|
|
3979
|
+
clinicsInfo: finalClinicsInfo,
|
|
3947
3980
|
procedures: [],
|
|
3948
3981
|
proceduresInfo,
|
|
3949
3982
|
reviewInfo: defaultReviewInfo,
|
|
@@ -6949,6 +6982,234 @@ var AuthService = class extends BaseService {
|
|
|
6949
6982
|
throw error;
|
|
6950
6983
|
}
|
|
6951
6984
|
}
|
|
6985
|
+
/**
|
|
6986
|
+
* Registers a new practitioner user with email and password
|
|
6987
|
+
* Can either create a new practitioner profile or claim an existing draft profile with a token
|
|
6988
|
+
*
|
|
6989
|
+
* @param data - Practitioner signup data containing either new profile details or token for claiming draft profile
|
|
6990
|
+
* @returns Object containing the created user and practitioner profile
|
|
6991
|
+
*/
|
|
6992
|
+
async signUpPractitioner(data) {
|
|
6993
|
+
var _a, _b, _c, _d;
|
|
6994
|
+
try {
|
|
6995
|
+
console.log("[AUTH] Starting practitioner signup process", {
|
|
6996
|
+
email: data.email,
|
|
6997
|
+
hasToken: !!data.token
|
|
6998
|
+
});
|
|
6999
|
+
try {
|
|
7000
|
+
await practitionerSignupSchema.parseAsync(data);
|
|
7001
|
+
console.log("[AUTH] Practitioner signup data validation passed");
|
|
7002
|
+
} catch (validationError) {
|
|
7003
|
+
console.error(
|
|
7004
|
+
"[AUTH] Validation error in signUpPractitioner:",
|
|
7005
|
+
validationError
|
|
7006
|
+
);
|
|
7007
|
+
throw validationError;
|
|
7008
|
+
}
|
|
7009
|
+
console.log("[AUTH] Creating Firebase user");
|
|
7010
|
+
let firebaseUser;
|
|
7011
|
+
try {
|
|
7012
|
+
const result = await (0, import_auth5.createUserWithEmailAndPassword)(
|
|
7013
|
+
this.auth,
|
|
7014
|
+
data.email,
|
|
7015
|
+
data.password
|
|
7016
|
+
);
|
|
7017
|
+
firebaseUser = result.user;
|
|
7018
|
+
console.log("[AUTH] Firebase user created successfully", {
|
|
7019
|
+
uid: firebaseUser.uid
|
|
7020
|
+
});
|
|
7021
|
+
} catch (firebaseError) {
|
|
7022
|
+
console.error("[AUTH] Firebase user creation failed:", firebaseError);
|
|
7023
|
+
throw firebaseError;
|
|
7024
|
+
}
|
|
7025
|
+
console.log("[AUTH] Creating user with PRACTITIONER role");
|
|
7026
|
+
let user;
|
|
7027
|
+
try {
|
|
7028
|
+
user = await this.userService.createUser(
|
|
7029
|
+
firebaseUser,
|
|
7030
|
+
["practitioner" /* PRACTITIONER */],
|
|
7031
|
+
{
|
|
7032
|
+
skipProfileCreation: true
|
|
7033
|
+
// We'll create the profile separately
|
|
7034
|
+
}
|
|
7035
|
+
);
|
|
7036
|
+
console.log("[AUTH] User with PRACTITIONER role created successfully", {
|
|
7037
|
+
userId: user.uid
|
|
7038
|
+
});
|
|
7039
|
+
} catch (userCreationError) {
|
|
7040
|
+
console.error("[AUTH] User creation failed:", userCreationError);
|
|
7041
|
+
throw userCreationError;
|
|
7042
|
+
}
|
|
7043
|
+
console.log("[AUTH] Initializing practitioner service");
|
|
7044
|
+
const practitionerService = new PractitionerService(
|
|
7045
|
+
this.db,
|
|
7046
|
+
this.auth,
|
|
7047
|
+
this.app
|
|
7048
|
+
);
|
|
7049
|
+
let practitioner = null;
|
|
7050
|
+
if (data.token) {
|
|
7051
|
+
console.log("[AUTH] Token provided, attempting to claim draft profile");
|
|
7052
|
+
try {
|
|
7053
|
+
practitioner = await practitionerService.validateTokenAndClaimProfile(
|
|
7054
|
+
data.token,
|
|
7055
|
+
firebaseUser.uid
|
|
7056
|
+
);
|
|
7057
|
+
if (!practitioner) {
|
|
7058
|
+
throw new Error("Invalid or expired invitation token");
|
|
7059
|
+
}
|
|
7060
|
+
console.log("[AUTH] Successfully claimed draft profile", {
|
|
7061
|
+
practitionerId: practitioner.id
|
|
7062
|
+
});
|
|
7063
|
+
await this.userService.updateUser(firebaseUser.uid, {
|
|
7064
|
+
practitionerProfile: practitioner.id
|
|
7065
|
+
});
|
|
7066
|
+
console.log(
|
|
7067
|
+
"[AUTH] User updated with practitioner profile reference"
|
|
7068
|
+
);
|
|
7069
|
+
} catch (tokenError) {
|
|
7070
|
+
console.error("[AUTH] Failed to claim draft profile:", tokenError);
|
|
7071
|
+
throw tokenError;
|
|
7072
|
+
}
|
|
7073
|
+
} else {
|
|
7074
|
+
console.log("[AUTH] Creating new practitioner profile");
|
|
7075
|
+
if (!data.profileData) {
|
|
7076
|
+
data.profileData = {};
|
|
7077
|
+
}
|
|
7078
|
+
const basicInfo = {
|
|
7079
|
+
firstName: data.firstName,
|
|
7080
|
+
lastName: data.lastName,
|
|
7081
|
+
email: data.email,
|
|
7082
|
+
phoneNumber: ((_a = data.profileData.basicInfo) == null ? void 0 : _a.phoneNumber) || "",
|
|
7083
|
+
profileImageUrl: ((_b = data.profileData.basicInfo) == null ? void 0 : _b.profileImageUrl) || "",
|
|
7084
|
+
gender: ((_c = data.profileData.basicInfo) == null ? void 0 : _c.gender) || "other",
|
|
7085
|
+
// Default to "other" if not provided
|
|
7086
|
+
bio: ((_d = data.profileData.basicInfo) == null ? void 0 : _d.bio) || "",
|
|
7087
|
+
title: "Practitioner",
|
|
7088
|
+
// Default title
|
|
7089
|
+
dateOfBirth: /* @__PURE__ */ new Date(),
|
|
7090
|
+
// Default to today
|
|
7091
|
+
languages: ["English"]
|
|
7092
|
+
// Default language
|
|
7093
|
+
};
|
|
7094
|
+
const certification = data.profileData.certification || {
|
|
7095
|
+
level: "aesthetician" /* AESTHETICIAN */,
|
|
7096
|
+
specialties: [],
|
|
7097
|
+
licenseNumber: "Pending",
|
|
7098
|
+
issuingAuthority: "Pending",
|
|
7099
|
+
issueDate: /* @__PURE__ */ new Date(),
|
|
7100
|
+
verificationStatus: "pending"
|
|
7101
|
+
};
|
|
7102
|
+
const createPractitionerData = {
|
|
7103
|
+
userRef: firebaseUser.uid,
|
|
7104
|
+
basicInfo,
|
|
7105
|
+
certification,
|
|
7106
|
+
status: "active" /* ACTIVE */,
|
|
7107
|
+
isActive: true,
|
|
7108
|
+
isVerified: false
|
|
7109
|
+
};
|
|
7110
|
+
try {
|
|
7111
|
+
practitioner = await practitionerService.createPractitioner(
|
|
7112
|
+
createPractitionerData
|
|
7113
|
+
);
|
|
7114
|
+
console.log("[AUTH] Practitioner profile created successfully", {
|
|
7115
|
+
practitionerId: practitioner.id
|
|
7116
|
+
});
|
|
7117
|
+
await this.userService.updateUser(firebaseUser.uid, {
|
|
7118
|
+
practitionerProfile: practitioner.id
|
|
7119
|
+
});
|
|
7120
|
+
console.log(
|
|
7121
|
+
"[AUTH] User updated with practitioner profile reference"
|
|
7122
|
+
);
|
|
7123
|
+
} catch (createError) {
|
|
7124
|
+
console.error(
|
|
7125
|
+
"[AUTH] Failed to create practitioner profile:",
|
|
7126
|
+
createError
|
|
7127
|
+
);
|
|
7128
|
+
throw createError;
|
|
7129
|
+
}
|
|
7130
|
+
}
|
|
7131
|
+
console.log("[AUTH] Practitioner signup completed successfully", {
|
|
7132
|
+
userId: user.uid,
|
|
7133
|
+
practitionerId: (practitioner == null ? void 0 : practitioner.id) || "unknown"
|
|
7134
|
+
});
|
|
7135
|
+
return {
|
|
7136
|
+
user,
|
|
7137
|
+
practitioner
|
|
7138
|
+
};
|
|
7139
|
+
} catch (error) {
|
|
7140
|
+
if (error instanceof import_zod18.z.ZodError) {
|
|
7141
|
+
console.error(
|
|
7142
|
+
"[AUTH] Zod validation error in signUpPractitioner:",
|
|
7143
|
+
JSON.stringify(error.errors, null, 2)
|
|
7144
|
+
);
|
|
7145
|
+
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7146
|
+
}
|
|
7147
|
+
const firebaseError = error;
|
|
7148
|
+
if (firebaseError.code === "auth/email-already-in-use" /* EMAIL_ALREADY_IN_USE */) {
|
|
7149
|
+
console.error("[AUTH] Email already in use:", data.email);
|
|
7150
|
+
throw AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
|
|
7151
|
+
}
|
|
7152
|
+
console.error("[AUTH] Unhandled error in signUpPractitioner:", error);
|
|
7153
|
+
throw error;
|
|
7154
|
+
}
|
|
7155
|
+
}
|
|
7156
|
+
/**
|
|
7157
|
+
* Signs in a user with email and password specifically for practitioner role
|
|
7158
|
+
* @param email - User's email
|
|
7159
|
+
* @param password - User's password
|
|
7160
|
+
* @returns Object containing the user and practitioner profile
|
|
7161
|
+
* @throws {AUTH_ERRORS.INVALID_ROLE} If user doesn't have practitioner role
|
|
7162
|
+
* @throws {AUTH_ERRORS.NOT_FOUND} If practitioner profile is not found
|
|
7163
|
+
*/
|
|
7164
|
+
async signInPractitioner(email, password) {
|
|
7165
|
+
var _a;
|
|
7166
|
+
try {
|
|
7167
|
+
console.log("[AUTH] Starting practitioner signin process", {
|
|
7168
|
+
email
|
|
7169
|
+
});
|
|
7170
|
+
const practitionerService = new PractitionerService(
|
|
7171
|
+
this.db,
|
|
7172
|
+
this.auth,
|
|
7173
|
+
this.app
|
|
7174
|
+
);
|
|
7175
|
+
const { user: firebaseUser } = await (0, import_auth5.signInWithEmailAndPassword)(
|
|
7176
|
+
this.auth,
|
|
7177
|
+
email,
|
|
7178
|
+
password
|
|
7179
|
+
);
|
|
7180
|
+
const user = await this.userService.getOrCreateUser(firebaseUser);
|
|
7181
|
+
console.log("[AUTH] User retrieved", { uid: user.uid });
|
|
7182
|
+
if (!((_a = user.roles) == null ? void 0 : _a.includes("practitioner" /* PRACTITIONER */))) {
|
|
7183
|
+
console.error("[AUTH] User is not a practitioner:", user.uid);
|
|
7184
|
+
throw AUTH_ERRORS.INVALID_ROLE;
|
|
7185
|
+
}
|
|
7186
|
+
if (!user.practitionerProfile) {
|
|
7187
|
+
console.error("[AUTH] User has no practitioner profile:", user.uid);
|
|
7188
|
+
throw AUTH_ERRORS.NOT_FOUND;
|
|
7189
|
+
}
|
|
7190
|
+
const practitioner = await practitionerService.getPractitioner(
|
|
7191
|
+
user.practitionerProfile
|
|
7192
|
+
);
|
|
7193
|
+
if (!practitioner) {
|
|
7194
|
+
console.error(
|
|
7195
|
+
"[AUTH] Practitioner profile not found:",
|
|
7196
|
+
user.practitionerProfile
|
|
7197
|
+
);
|
|
7198
|
+
throw AUTH_ERRORS.NOT_FOUND;
|
|
7199
|
+
}
|
|
7200
|
+
console.log("[AUTH] Practitioner signin completed successfully", {
|
|
7201
|
+
userId: user.uid,
|
|
7202
|
+
practitionerId: practitioner.id
|
|
7203
|
+
});
|
|
7204
|
+
return {
|
|
7205
|
+
user,
|
|
7206
|
+
practitioner
|
|
7207
|
+
};
|
|
7208
|
+
} catch (error) {
|
|
7209
|
+
console.error("[AUTH] Error in signInPractitioner:", error);
|
|
7210
|
+
throw error;
|
|
7211
|
+
}
|
|
7212
|
+
}
|
|
6952
7213
|
};
|
|
6953
7214
|
|
|
6954
7215
|
// src/services/notifications/notification.service.ts
|
|
@@ -13562,6 +13823,7 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
|
|
|
13562
13823
|
practitionerReviewInfoSchema,
|
|
13563
13824
|
practitionerReviewSchema,
|
|
13564
13825
|
practitionerSchema,
|
|
13826
|
+
practitionerSignupSchema,
|
|
13565
13827
|
practitionerTokenSchema,
|
|
13566
13828
|
practitionerWorkingHoursSchema,
|
|
13567
13829
|
preRequirementNotificationSchema,
|
package/dist/index.mjs
CHANGED
|
@@ -2989,6 +2989,22 @@ var createPractitionerTokenSchema = z11.object({
|
|
|
2989
2989
|
clinicId: z11.string().min(1),
|
|
2990
2990
|
expiresAt: z11.date().optional()
|
|
2991
2991
|
});
|
|
2992
|
+
var practitionerSignupSchema = z11.object({
|
|
2993
|
+
email: z11.string().email(),
|
|
2994
|
+
password: z11.string().min(8),
|
|
2995
|
+
firstName: z11.string().min(2).max(50),
|
|
2996
|
+
lastName: z11.string().min(2).max(50),
|
|
2997
|
+
token: z11.string().optional(),
|
|
2998
|
+
profileData: z11.object({
|
|
2999
|
+
basicInfo: z11.object({
|
|
3000
|
+
phoneNumber: z11.string().optional(),
|
|
3001
|
+
profileImageUrl: z11.string().optional(),
|
|
3002
|
+
gender: z11.enum(["male", "female", "other"]).optional(),
|
|
3003
|
+
bio: z11.string().optional()
|
|
3004
|
+
}).optional(),
|
|
3005
|
+
certification: z11.any().optional()
|
|
3006
|
+
}).optional()
|
|
3007
|
+
});
|
|
2992
3008
|
|
|
2993
3009
|
// src/validations/clinic.schema.ts
|
|
2994
3010
|
var clinicContactInfoSchema = z12.object({
|
|
@@ -3813,8 +3829,8 @@ var PractitionerService = class extends BaseService {
|
|
|
3813
3829
|
if (!clinic) {
|
|
3814
3830
|
throw new Error(`Clinic ${clinicId} not found`);
|
|
3815
3831
|
}
|
|
3816
|
-
const
|
|
3817
|
-
if (data.clinics) {
|
|
3832
|
+
const clinicsToAdd = /* @__PURE__ */ new Set([clinicId]);
|
|
3833
|
+
if (data.clinics && data.clinics.length > 0) {
|
|
3818
3834
|
for (const cId of data.clinics) {
|
|
3819
3835
|
if (cId !== clinicId) {
|
|
3820
3836
|
const otherClinic = await this.getClinicService().getClinic(cId);
|
|
@@ -3822,8 +3838,10 @@ var PractitionerService = class extends BaseService {
|
|
|
3822
3838
|
throw new Error(`Clinic ${cId} not found`);
|
|
3823
3839
|
}
|
|
3824
3840
|
}
|
|
3841
|
+
clinicsToAdd.add(cId);
|
|
3825
3842
|
}
|
|
3826
3843
|
}
|
|
3844
|
+
const clinics = Array.from(clinicsToAdd);
|
|
3827
3845
|
const defaultReviewInfo = {
|
|
3828
3846
|
totalReviews: 0,
|
|
3829
3847
|
averageRating: 0,
|
|
@@ -3835,7 +3853,21 @@ var PractitionerService = class extends BaseService {
|
|
|
3835
3853
|
recommendationPercentage: 0
|
|
3836
3854
|
};
|
|
3837
3855
|
const practitionerId = this.generateId();
|
|
3838
|
-
const clinicsInfo =
|
|
3856
|
+
const clinicsInfo = [];
|
|
3857
|
+
for (const cId of clinics) {
|
|
3858
|
+
const clinicData = await this.getClinicService().getClinic(cId);
|
|
3859
|
+
if (clinicData) {
|
|
3860
|
+
clinicsInfo.push({
|
|
3861
|
+
id: clinicData.id,
|
|
3862
|
+
name: clinicData.name,
|
|
3863
|
+
location: clinicData.location,
|
|
3864
|
+
contactInfo: clinicData.contactInfo,
|
|
3865
|
+
featuredPhoto: clinicData.coverPhoto || "",
|
|
3866
|
+
description: clinicData.description || null
|
|
3867
|
+
});
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3870
|
+
const finalClinicsInfo = validatedData.clinicsInfo && validatedData.clinicsInfo.length > 0 ? validatedData.clinicsInfo : clinicsInfo;
|
|
3839
3871
|
const proceduresInfo = [];
|
|
3840
3872
|
const practitionerData = {
|
|
3841
3873
|
id: practitionerId,
|
|
@@ -3845,7 +3877,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3845
3877
|
certification: validatedData.certification,
|
|
3846
3878
|
clinics,
|
|
3847
3879
|
clinicWorkingHours: validatedData.clinicWorkingHours || [],
|
|
3848
|
-
clinicsInfo,
|
|
3880
|
+
clinicsInfo: finalClinicsInfo,
|
|
3849
3881
|
procedures: [],
|
|
3850
3882
|
proceduresInfo,
|
|
3851
3883
|
reviewInfo: defaultReviewInfo,
|
|
@@ -6906,6 +6938,234 @@ var AuthService = class extends BaseService {
|
|
|
6906
6938
|
throw error;
|
|
6907
6939
|
}
|
|
6908
6940
|
}
|
|
6941
|
+
/**
|
|
6942
|
+
* Registers a new practitioner user with email and password
|
|
6943
|
+
* Can either create a new practitioner profile or claim an existing draft profile with a token
|
|
6944
|
+
*
|
|
6945
|
+
* @param data - Practitioner signup data containing either new profile details or token for claiming draft profile
|
|
6946
|
+
* @returns Object containing the created user and practitioner profile
|
|
6947
|
+
*/
|
|
6948
|
+
async signUpPractitioner(data) {
|
|
6949
|
+
var _a, _b, _c, _d;
|
|
6950
|
+
try {
|
|
6951
|
+
console.log("[AUTH] Starting practitioner signup process", {
|
|
6952
|
+
email: data.email,
|
|
6953
|
+
hasToken: !!data.token
|
|
6954
|
+
});
|
|
6955
|
+
try {
|
|
6956
|
+
await practitionerSignupSchema.parseAsync(data);
|
|
6957
|
+
console.log("[AUTH] Practitioner signup data validation passed");
|
|
6958
|
+
} catch (validationError) {
|
|
6959
|
+
console.error(
|
|
6960
|
+
"[AUTH] Validation error in signUpPractitioner:",
|
|
6961
|
+
validationError
|
|
6962
|
+
);
|
|
6963
|
+
throw validationError;
|
|
6964
|
+
}
|
|
6965
|
+
console.log("[AUTH] Creating Firebase user");
|
|
6966
|
+
let firebaseUser;
|
|
6967
|
+
try {
|
|
6968
|
+
const result = await createUserWithEmailAndPassword(
|
|
6969
|
+
this.auth,
|
|
6970
|
+
data.email,
|
|
6971
|
+
data.password
|
|
6972
|
+
);
|
|
6973
|
+
firebaseUser = result.user;
|
|
6974
|
+
console.log("[AUTH] Firebase user created successfully", {
|
|
6975
|
+
uid: firebaseUser.uid
|
|
6976
|
+
});
|
|
6977
|
+
} catch (firebaseError) {
|
|
6978
|
+
console.error("[AUTH] Firebase user creation failed:", firebaseError);
|
|
6979
|
+
throw firebaseError;
|
|
6980
|
+
}
|
|
6981
|
+
console.log("[AUTH] Creating user with PRACTITIONER role");
|
|
6982
|
+
let user;
|
|
6983
|
+
try {
|
|
6984
|
+
user = await this.userService.createUser(
|
|
6985
|
+
firebaseUser,
|
|
6986
|
+
["practitioner" /* PRACTITIONER */],
|
|
6987
|
+
{
|
|
6988
|
+
skipProfileCreation: true
|
|
6989
|
+
// We'll create the profile separately
|
|
6990
|
+
}
|
|
6991
|
+
);
|
|
6992
|
+
console.log("[AUTH] User with PRACTITIONER role created successfully", {
|
|
6993
|
+
userId: user.uid
|
|
6994
|
+
});
|
|
6995
|
+
} catch (userCreationError) {
|
|
6996
|
+
console.error("[AUTH] User creation failed:", userCreationError);
|
|
6997
|
+
throw userCreationError;
|
|
6998
|
+
}
|
|
6999
|
+
console.log("[AUTH] Initializing practitioner service");
|
|
7000
|
+
const practitionerService = new PractitionerService(
|
|
7001
|
+
this.db,
|
|
7002
|
+
this.auth,
|
|
7003
|
+
this.app
|
|
7004
|
+
);
|
|
7005
|
+
let practitioner = null;
|
|
7006
|
+
if (data.token) {
|
|
7007
|
+
console.log("[AUTH] Token provided, attempting to claim draft profile");
|
|
7008
|
+
try {
|
|
7009
|
+
practitioner = await practitionerService.validateTokenAndClaimProfile(
|
|
7010
|
+
data.token,
|
|
7011
|
+
firebaseUser.uid
|
|
7012
|
+
);
|
|
7013
|
+
if (!practitioner) {
|
|
7014
|
+
throw new Error("Invalid or expired invitation token");
|
|
7015
|
+
}
|
|
7016
|
+
console.log("[AUTH] Successfully claimed draft profile", {
|
|
7017
|
+
practitionerId: practitioner.id
|
|
7018
|
+
});
|
|
7019
|
+
await this.userService.updateUser(firebaseUser.uid, {
|
|
7020
|
+
practitionerProfile: practitioner.id
|
|
7021
|
+
});
|
|
7022
|
+
console.log(
|
|
7023
|
+
"[AUTH] User updated with practitioner profile reference"
|
|
7024
|
+
);
|
|
7025
|
+
} catch (tokenError) {
|
|
7026
|
+
console.error("[AUTH] Failed to claim draft profile:", tokenError);
|
|
7027
|
+
throw tokenError;
|
|
7028
|
+
}
|
|
7029
|
+
} else {
|
|
7030
|
+
console.log("[AUTH] Creating new practitioner profile");
|
|
7031
|
+
if (!data.profileData) {
|
|
7032
|
+
data.profileData = {};
|
|
7033
|
+
}
|
|
7034
|
+
const basicInfo = {
|
|
7035
|
+
firstName: data.firstName,
|
|
7036
|
+
lastName: data.lastName,
|
|
7037
|
+
email: data.email,
|
|
7038
|
+
phoneNumber: ((_a = data.profileData.basicInfo) == null ? void 0 : _a.phoneNumber) || "",
|
|
7039
|
+
profileImageUrl: ((_b = data.profileData.basicInfo) == null ? void 0 : _b.profileImageUrl) || "",
|
|
7040
|
+
gender: ((_c = data.profileData.basicInfo) == null ? void 0 : _c.gender) || "other",
|
|
7041
|
+
// Default to "other" if not provided
|
|
7042
|
+
bio: ((_d = data.profileData.basicInfo) == null ? void 0 : _d.bio) || "",
|
|
7043
|
+
title: "Practitioner",
|
|
7044
|
+
// Default title
|
|
7045
|
+
dateOfBirth: /* @__PURE__ */ new Date(),
|
|
7046
|
+
// Default to today
|
|
7047
|
+
languages: ["English"]
|
|
7048
|
+
// Default language
|
|
7049
|
+
};
|
|
7050
|
+
const certification = data.profileData.certification || {
|
|
7051
|
+
level: "aesthetician" /* AESTHETICIAN */,
|
|
7052
|
+
specialties: [],
|
|
7053
|
+
licenseNumber: "Pending",
|
|
7054
|
+
issuingAuthority: "Pending",
|
|
7055
|
+
issueDate: /* @__PURE__ */ new Date(),
|
|
7056
|
+
verificationStatus: "pending"
|
|
7057
|
+
};
|
|
7058
|
+
const createPractitionerData = {
|
|
7059
|
+
userRef: firebaseUser.uid,
|
|
7060
|
+
basicInfo,
|
|
7061
|
+
certification,
|
|
7062
|
+
status: "active" /* ACTIVE */,
|
|
7063
|
+
isActive: true,
|
|
7064
|
+
isVerified: false
|
|
7065
|
+
};
|
|
7066
|
+
try {
|
|
7067
|
+
practitioner = await practitionerService.createPractitioner(
|
|
7068
|
+
createPractitionerData
|
|
7069
|
+
);
|
|
7070
|
+
console.log("[AUTH] Practitioner profile created successfully", {
|
|
7071
|
+
practitionerId: practitioner.id
|
|
7072
|
+
});
|
|
7073
|
+
await this.userService.updateUser(firebaseUser.uid, {
|
|
7074
|
+
practitionerProfile: practitioner.id
|
|
7075
|
+
});
|
|
7076
|
+
console.log(
|
|
7077
|
+
"[AUTH] User updated with practitioner profile reference"
|
|
7078
|
+
);
|
|
7079
|
+
} catch (createError) {
|
|
7080
|
+
console.error(
|
|
7081
|
+
"[AUTH] Failed to create practitioner profile:",
|
|
7082
|
+
createError
|
|
7083
|
+
);
|
|
7084
|
+
throw createError;
|
|
7085
|
+
}
|
|
7086
|
+
}
|
|
7087
|
+
console.log("[AUTH] Practitioner signup completed successfully", {
|
|
7088
|
+
userId: user.uid,
|
|
7089
|
+
practitionerId: (practitioner == null ? void 0 : practitioner.id) || "unknown"
|
|
7090
|
+
});
|
|
7091
|
+
return {
|
|
7092
|
+
user,
|
|
7093
|
+
practitioner
|
|
7094
|
+
};
|
|
7095
|
+
} catch (error) {
|
|
7096
|
+
if (error instanceof z18.ZodError) {
|
|
7097
|
+
console.error(
|
|
7098
|
+
"[AUTH] Zod validation error in signUpPractitioner:",
|
|
7099
|
+
JSON.stringify(error.errors, null, 2)
|
|
7100
|
+
);
|
|
7101
|
+
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7102
|
+
}
|
|
7103
|
+
const firebaseError = error;
|
|
7104
|
+
if (firebaseError.code === "auth/email-already-in-use" /* EMAIL_ALREADY_IN_USE */) {
|
|
7105
|
+
console.error("[AUTH] Email already in use:", data.email);
|
|
7106
|
+
throw AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
|
|
7107
|
+
}
|
|
7108
|
+
console.error("[AUTH] Unhandled error in signUpPractitioner:", error);
|
|
7109
|
+
throw error;
|
|
7110
|
+
}
|
|
7111
|
+
}
|
|
7112
|
+
/**
|
|
7113
|
+
* Signs in a user with email and password specifically for practitioner role
|
|
7114
|
+
* @param email - User's email
|
|
7115
|
+
* @param password - User's password
|
|
7116
|
+
* @returns Object containing the user and practitioner profile
|
|
7117
|
+
* @throws {AUTH_ERRORS.INVALID_ROLE} If user doesn't have practitioner role
|
|
7118
|
+
* @throws {AUTH_ERRORS.NOT_FOUND} If practitioner profile is not found
|
|
7119
|
+
*/
|
|
7120
|
+
async signInPractitioner(email, password) {
|
|
7121
|
+
var _a;
|
|
7122
|
+
try {
|
|
7123
|
+
console.log("[AUTH] Starting practitioner signin process", {
|
|
7124
|
+
email
|
|
7125
|
+
});
|
|
7126
|
+
const practitionerService = new PractitionerService(
|
|
7127
|
+
this.db,
|
|
7128
|
+
this.auth,
|
|
7129
|
+
this.app
|
|
7130
|
+
);
|
|
7131
|
+
const { user: firebaseUser } = await signInWithEmailAndPassword(
|
|
7132
|
+
this.auth,
|
|
7133
|
+
email,
|
|
7134
|
+
password
|
|
7135
|
+
);
|
|
7136
|
+
const user = await this.userService.getOrCreateUser(firebaseUser);
|
|
7137
|
+
console.log("[AUTH] User retrieved", { uid: user.uid });
|
|
7138
|
+
if (!((_a = user.roles) == null ? void 0 : _a.includes("practitioner" /* PRACTITIONER */))) {
|
|
7139
|
+
console.error("[AUTH] User is not a practitioner:", user.uid);
|
|
7140
|
+
throw AUTH_ERRORS.INVALID_ROLE;
|
|
7141
|
+
}
|
|
7142
|
+
if (!user.practitionerProfile) {
|
|
7143
|
+
console.error("[AUTH] User has no practitioner profile:", user.uid);
|
|
7144
|
+
throw AUTH_ERRORS.NOT_FOUND;
|
|
7145
|
+
}
|
|
7146
|
+
const practitioner = await practitionerService.getPractitioner(
|
|
7147
|
+
user.practitionerProfile
|
|
7148
|
+
);
|
|
7149
|
+
if (!practitioner) {
|
|
7150
|
+
console.error(
|
|
7151
|
+
"[AUTH] Practitioner profile not found:",
|
|
7152
|
+
user.practitionerProfile
|
|
7153
|
+
);
|
|
7154
|
+
throw AUTH_ERRORS.NOT_FOUND;
|
|
7155
|
+
}
|
|
7156
|
+
console.log("[AUTH] Practitioner signin completed successfully", {
|
|
7157
|
+
userId: user.uid,
|
|
7158
|
+
practitionerId: practitioner.id
|
|
7159
|
+
});
|
|
7160
|
+
return {
|
|
7161
|
+
user,
|
|
7162
|
+
practitioner
|
|
7163
|
+
};
|
|
7164
|
+
} catch (error) {
|
|
7165
|
+
console.error("[AUTH] Error in signInPractitioner:", error);
|
|
7166
|
+
throw error;
|
|
7167
|
+
}
|
|
7168
|
+
}
|
|
6909
7169
|
};
|
|
6910
7170
|
|
|
6911
7171
|
// src/services/notifications/notification.service.ts
|
|
@@ -13715,6 +13975,7 @@ export {
|
|
|
13715
13975
|
practitionerReviewInfoSchema,
|
|
13716
13976
|
practitionerReviewSchema,
|
|
13717
13977
|
practitionerSchema,
|
|
13978
|
+
practitionerSignupSchema,
|
|
13718
13979
|
practitionerTokenSchema,
|
|
13719
13980
|
practitionerWorkingHoursSchema,
|
|
13720
13981
|
preRequirementNotificationSchema,
|
package/package.json
CHANGED
|
@@ -61,6 +61,16 @@ import { clinicAdminSignupSchema } from "../validations/clinic.schema";
|
|
|
61
61
|
import { ClinicGroupService } from "./clinic/clinic-group.service";
|
|
62
62
|
import { ClinicAdminService } from "./clinic/clinic-admin.service";
|
|
63
63
|
import { ClinicService } from "./clinic/clinic.service";
|
|
64
|
+
import {
|
|
65
|
+
Practitioner,
|
|
66
|
+
CreatePractitionerData,
|
|
67
|
+
PractitionerStatus,
|
|
68
|
+
PractitionerBasicInfo,
|
|
69
|
+
PractitionerCertification,
|
|
70
|
+
} from "../types/practitioner";
|
|
71
|
+
import { PractitionerService } from "./practitioner/practitioner.service";
|
|
72
|
+
import { practitionerSignupSchema } from "../validations/practitioner.schema";
|
|
73
|
+
import { CertificationLevel } from "../backoffice/types/static/certification.types";
|
|
64
74
|
|
|
65
75
|
export class AuthService extends BaseService {
|
|
66
76
|
private googleProvider = new GoogleAuthProvider();
|
|
@@ -858,4 +868,289 @@ export class AuthService extends BaseService {
|
|
|
858
868
|
throw error;
|
|
859
869
|
}
|
|
860
870
|
}
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Registers a new practitioner user with email and password
|
|
874
|
+
* Can either create a new practitioner profile or claim an existing draft profile with a token
|
|
875
|
+
*
|
|
876
|
+
* @param data - Practitioner signup data containing either new profile details or token for claiming draft profile
|
|
877
|
+
* @returns Object containing the created user and practitioner profile
|
|
878
|
+
*/
|
|
879
|
+
async signUpPractitioner(data: {
|
|
880
|
+
email: string;
|
|
881
|
+
password: string;
|
|
882
|
+
firstName: string;
|
|
883
|
+
lastName: string;
|
|
884
|
+
token?: string;
|
|
885
|
+
profileData?: Partial<CreatePractitionerData>;
|
|
886
|
+
}): Promise<{
|
|
887
|
+
user: User;
|
|
888
|
+
practitioner: Practitioner;
|
|
889
|
+
}> {
|
|
890
|
+
try {
|
|
891
|
+
console.log("[AUTH] Starting practitioner signup process", {
|
|
892
|
+
email: data.email,
|
|
893
|
+
hasToken: !!data.token,
|
|
894
|
+
});
|
|
895
|
+
|
|
896
|
+
// Validate data
|
|
897
|
+
try {
|
|
898
|
+
await practitionerSignupSchema.parseAsync(data);
|
|
899
|
+
console.log("[AUTH] Practitioner signup data validation passed");
|
|
900
|
+
} catch (validationError) {
|
|
901
|
+
console.error(
|
|
902
|
+
"[AUTH] Validation error in signUpPractitioner:",
|
|
903
|
+
validationError
|
|
904
|
+
);
|
|
905
|
+
throw validationError;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
// Create Firebase user
|
|
909
|
+
console.log("[AUTH] Creating Firebase user");
|
|
910
|
+
let firebaseUser;
|
|
911
|
+
try {
|
|
912
|
+
const result = await createUserWithEmailAndPassword(
|
|
913
|
+
this.auth,
|
|
914
|
+
data.email,
|
|
915
|
+
data.password
|
|
916
|
+
);
|
|
917
|
+
firebaseUser = result.user;
|
|
918
|
+
console.log("[AUTH] Firebase user created successfully", {
|
|
919
|
+
uid: firebaseUser.uid,
|
|
920
|
+
});
|
|
921
|
+
} catch (firebaseError) {
|
|
922
|
+
console.error("[AUTH] Firebase user creation failed:", firebaseError);
|
|
923
|
+
throw firebaseError;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// Create user with PRACTITIONER role
|
|
927
|
+
console.log("[AUTH] Creating user with PRACTITIONER role");
|
|
928
|
+
let user;
|
|
929
|
+
try {
|
|
930
|
+
user = await this.userService.createUser(
|
|
931
|
+
firebaseUser,
|
|
932
|
+
[UserRole.PRACTITIONER],
|
|
933
|
+
{
|
|
934
|
+
skipProfileCreation: true, // We'll create the profile separately
|
|
935
|
+
}
|
|
936
|
+
);
|
|
937
|
+
console.log("[AUTH] User with PRACTITIONER role created successfully", {
|
|
938
|
+
userId: user.uid,
|
|
939
|
+
});
|
|
940
|
+
} catch (userCreationError) {
|
|
941
|
+
console.error("[AUTH] User creation failed:", userCreationError);
|
|
942
|
+
throw userCreationError;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// Initialize practitioner service
|
|
946
|
+
console.log("[AUTH] Initializing practitioner service");
|
|
947
|
+
const practitionerService = new PractitionerService(
|
|
948
|
+
this.db,
|
|
949
|
+
this.auth,
|
|
950
|
+
this.app
|
|
951
|
+
);
|
|
952
|
+
|
|
953
|
+
let practitioner: Practitioner | null = null;
|
|
954
|
+
|
|
955
|
+
// Check if we're claiming an existing draft profile with a token
|
|
956
|
+
if (data.token) {
|
|
957
|
+
console.log("[AUTH] Token provided, attempting to claim draft profile");
|
|
958
|
+
|
|
959
|
+
try {
|
|
960
|
+
// Validate token and claim the profile
|
|
961
|
+
practitioner = await practitionerService.validateTokenAndClaimProfile(
|
|
962
|
+
data.token,
|
|
963
|
+
firebaseUser.uid
|
|
964
|
+
);
|
|
965
|
+
|
|
966
|
+
if (!practitioner) {
|
|
967
|
+
throw new Error("Invalid or expired invitation token");
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
console.log("[AUTH] Successfully claimed draft profile", {
|
|
971
|
+
practitionerId: practitioner.id,
|
|
972
|
+
});
|
|
973
|
+
|
|
974
|
+
// Link the practitioner profile to the user
|
|
975
|
+
await this.userService.updateUser(firebaseUser.uid, {
|
|
976
|
+
practitionerProfile: practitioner.id,
|
|
977
|
+
});
|
|
978
|
+
console.log(
|
|
979
|
+
"[AUTH] User updated with practitioner profile reference"
|
|
980
|
+
);
|
|
981
|
+
} catch (tokenError) {
|
|
982
|
+
console.error("[AUTH] Failed to claim draft profile:", tokenError);
|
|
983
|
+
throw tokenError;
|
|
984
|
+
}
|
|
985
|
+
} else {
|
|
986
|
+
console.log("[AUTH] Creating new practitioner profile");
|
|
987
|
+
|
|
988
|
+
if (!data.profileData) {
|
|
989
|
+
data.profileData = {};
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
// We need to create a full PractitionerBasicInfo object
|
|
993
|
+
const basicInfo: PractitionerBasicInfo = {
|
|
994
|
+
firstName: data.firstName,
|
|
995
|
+
lastName: data.lastName,
|
|
996
|
+
email: data.email,
|
|
997
|
+
phoneNumber: data.profileData.basicInfo?.phoneNumber || "",
|
|
998
|
+
profileImageUrl: data.profileData.basicInfo?.profileImageUrl || "",
|
|
999
|
+
gender: data.profileData.basicInfo?.gender || "other", // Default to "other" if not provided
|
|
1000
|
+
bio: data.profileData.basicInfo?.bio || "",
|
|
1001
|
+
title: "Practitioner", // Default title
|
|
1002
|
+
dateOfBirth: new Date(), // Default to today
|
|
1003
|
+
languages: ["English"], // Default language
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
// Basic certification information with placeholders
|
|
1007
|
+
const certification: PractitionerCertification = data.profileData
|
|
1008
|
+
.certification || {
|
|
1009
|
+
level: CertificationLevel.AESTHETICIAN,
|
|
1010
|
+
specialties: [],
|
|
1011
|
+
licenseNumber: "Pending",
|
|
1012
|
+
issuingAuthority: "Pending",
|
|
1013
|
+
issueDate: new Date(),
|
|
1014
|
+
verificationStatus: "pending",
|
|
1015
|
+
};
|
|
1016
|
+
|
|
1017
|
+
// Create basic profile data
|
|
1018
|
+
const createPractitionerData: CreatePractitionerData = {
|
|
1019
|
+
userRef: firebaseUser.uid,
|
|
1020
|
+
basicInfo,
|
|
1021
|
+
certification,
|
|
1022
|
+
status: PractitionerStatus.ACTIVE,
|
|
1023
|
+
isActive: true,
|
|
1024
|
+
isVerified: false,
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
try {
|
|
1028
|
+
practitioner = await practitionerService.createPractitioner(
|
|
1029
|
+
createPractitionerData
|
|
1030
|
+
);
|
|
1031
|
+
console.log("[AUTH] Practitioner profile created successfully", {
|
|
1032
|
+
practitionerId: practitioner.id,
|
|
1033
|
+
});
|
|
1034
|
+
|
|
1035
|
+
// Link the practitioner profile to the user
|
|
1036
|
+
await this.userService.updateUser(firebaseUser.uid, {
|
|
1037
|
+
practitionerProfile: practitioner.id,
|
|
1038
|
+
});
|
|
1039
|
+
console.log(
|
|
1040
|
+
"[AUTH] User updated with practitioner profile reference"
|
|
1041
|
+
);
|
|
1042
|
+
} catch (createError) {
|
|
1043
|
+
console.error(
|
|
1044
|
+
"[AUTH] Failed to create practitioner profile:",
|
|
1045
|
+
createError
|
|
1046
|
+
);
|
|
1047
|
+
throw createError;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
console.log("[AUTH] Practitioner signup completed successfully", {
|
|
1052
|
+
userId: user.uid,
|
|
1053
|
+
practitionerId: practitioner?.id || "unknown",
|
|
1054
|
+
});
|
|
1055
|
+
|
|
1056
|
+
return {
|
|
1057
|
+
user,
|
|
1058
|
+
practitioner,
|
|
1059
|
+
};
|
|
1060
|
+
} catch (error) {
|
|
1061
|
+
if (error instanceof z.ZodError) {
|
|
1062
|
+
console.error(
|
|
1063
|
+
"[AUTH] Zod validation error in signUpPractitioner:",
|
|
1064
|
+
JSON.stringify(error.errors, null, 2)
|
|
1065
|
+
);
|
|
1066
|
+
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
const firebaseError = error as FirebaseError;
|
|
1070
|
+
if (firebaseError.code === FirebaseErrorCode.EMAIL_ALREADY_IN_USE) {
|
|
1071
|
+
console.error("[AUTH] Email already in use:", data.email);
|
|
1072
|
+
throw AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
console.error("[AUTH] Unhandled error in signUpPractitioner:", error);
|
|
1076
|
+
throw error;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* Signs in a user with email and password specifically for practitioner role
|
|
1082
|
+
* @param email - User's email
|
|
1083
|
+
* @param password - User's password
|
|
1084
|
+
* @returns Object containing the user and practitioner profile
|
|
1085
|
+
* @throws {AUTH_ERRORS.INVALID_ROLE} If user doesn't have practitioner role
|
|
1086
|
+
* @throws {AUTH_ERRORS.NOT_FOUND} If practitioner profile is not found
|
|
1087
|
+
*/
|
|
1088
|
+
async signInPractitioner(
|
|
1089
|
+
email: string,
|
|
1090
|
+
password: string
|
|
1091
|
+
): Promise<{
|
|
1092
|
+
user: User;
|
|
1093
|
+
practitioner: Practitioner;
|
|
1094
|
+
}> {
|
|
1095
|
+
try {
|
|
1096
|
+
console.log("[AUTH] Starting practitioner signin process", {
|
|
1097
|
+
email: email,
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
// Initialize required service
|
|
1101
|
+
const practitionerService = new PractitionerService(
|
|
1102
|
+
this.db,
|
|
1103
|
+
this.auth,
|
|
1104
|
+
this.app
|
|
1105
|
+
);
|
|
1106
|
+
|
|
1107
|
+
// Sign in with email/password
|
|
1108
|
+
const { user: firebaseUser } = await signInWithEmailAndPassword(
|
|
1109
|
+
this.auth,
|
|
1110
|
+
email,
|
|
1111
|
+
password
|
|
1112
|
+
);
|
|
1113
|
+
|
|
1114
|
+
// Get or create user
|
|
1115
|
+
const user = await this.userService.getOrCreateUser(firebaseUser);
|
|
1116
|
+
console.log("[AUTH] User retrieved", { uid: user.uid });
|
|
1117
|
+
|
|
1118
|
+
// Check if user has practitioner role
|
|
1119
|
+
if (!user.roles?.includes(UserRole.PRACTITIONER)) {
|
|
1120
|
+
console.error("[AUTH] User is not a practitioner:", user.uid);
|
|
1121
|
+
throw AUTH_ERRORS.INVALID_ROLE;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
// Check and get practitioner profile
|
|
1125
|
+
if (!user.practitionerProfile) {
|
|
1126
|
+
console.error("[AUTH] User has no practitioner profile:", user.uid);
|
|
1127
|
+
throw AUTH_ERRORS.NOT_FOUND;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
// Get practitioner profile
|
|
1131
|
+
const practitioner = await practitionerService.getPractitioner(
|
|
1132
|
+
user.practitionerProfile
|
|
1133
|
+
);
|
|
1134
|
+
if (!practitioner) {
|
|
1135
|
+
console.error(
|
|
1136
|
+
"[AUTH] Practitioner profile not found:",
|
|
1137
|
+
user.practitionerProfile
|
|
1138
|
+
);
|
|
1139
|
+
throw AUTH_ERRORS.NOT_FOUND;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
console.log("[AUTH] Practitioner signin completed successfully", {
|
|
1143
|
+
userId: user.uid,
|
|
1144
|
+
practitionerId: practitioner.id,
|
|
1145
|
+
});
|
|
1146
|
+
|
|
1147
|
+
return {
|
|
1148
|
+
user,
|
|
1149
|
+
practitioner,
|
|
1150
|
+
};
|
|
1151
|
+
} catch (error) {
|
|
1152
|
+
console.error("[AUTH] Error in signInPractitioner:", error);
|
|
1153
|
+
throw error;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
861
1156
|
}
|
|
@@ -176,21 +176,28 @@ export class PractitionerService extends BaseService {
|
|
|
176
176
|
throw new Error(`Clinic ${clinicId} not found`);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
//
|
|
180
|
-
|
|
179
|
+
// Make sure the primary clinic (clinicId) is always included
|
|
180
|
+
// Merge the clinics array with the primary clinicId, avoiding duplicates
|
|
181
|
+
const clinicsToAdd = new Set<string>([clinicId]);
|
|
181
182
|
|
|
182
|
-
//
|
|
183
|
-
if (data.clinics) {
|
|
183
|
+
// Add additional clinics if provided
|
|
184
|
+
if (data.clinics && data.clinics.length > 0) {
|
|
184
185
|
for (const cId of data.clinics) {
|
|
186
|
+
// Verify each additional clinic exists
|
|
185
187
|
if (cId !== clinicId) {
|
|
188
|
+
// Skip checking the primary clinic again
|
|
186
189
|
const otherClinic = await this.getClinicService().getClinic(cId);
|
|
187
190
|
if (!otherClinic) {
|
|
188
191
|
throw new Error(`Clinic ${cId} not found`);
|
|
189
192
|
}
|
|
190
193
|
}
|
|
194
|
+
clinicsToAdd.add(cId);
|
|
191
195
|
}
|
|
192
196
|
}
|
|
193
197
|
|
|
198
|
+
// Convert Set to Array
|
|
199
|
+
const clinics = Array.from(clinicsToAdd);
|
|
200
|
+
|
|
194
201
|
// Initialize default review info for new practitioners
|
|
195
202
|
const defaultReviewInfo: PractitionerReviewInfo = {
|
|
196
203
|
totalReviews: 0,
|
|
@@ -206,7 +213,30 @@ export class PractitionerService extends BaseService {
|
|
|
206
213
|
// Generate ID for the new practitioner
|
|
207
214
|
const practitionerId = this.generateId();
|
|
208
215
|
|
|
209
|
-
|
|
216
|
+
// Create clinicsInfo from the merged clinics array
|
|
217
|
+
const clinicsInfo: ClinicInfo[] = [];
|
|
218
|
+
|
|
219
|
+
// Populate clinicsInfo for each clinic
|
|
220
|
+
for (const cId of clinics) {
|
|
221
|
+
const clinicData = await this.getClinicService().getClinic(cId);
|
|
222
|
+
if (clinicData) {
|
|
223
|
+
clinicsInfo.push({
|
|
224
|
+
id: clinicData.id,
|
|
225
|
+
name: clinicData.name,
|
|
226
|
+
location: clinicData.location,
|
|
227
|
+
contactInfo: clinicData.contactInfo,
|
|
228
|
+
featuredPhoto: clinicData.coverPhoto || "",
|
|
229
|
+
description: clinicData.description || null,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Use provided clinicsInfo if available, otherwise use the ones we just created
|
|
235
|
+
const finalClinicsInfo =
|
|
236
|
+
validatedData.clinicsInfo && validatedData.clinicsInfo.length > 0
|
|
237
|
+
? validatedData.clinicsInfo
|
|
238
|
+
: clinicsInfo;
|
|
239
|
+
|
|
210
240
|
const proceduresInfo: ProcedureSummaryInfo[] = [];
|
|
211
241
|
|
|
212
242
|
const practitionerData: Omit<Practitioner, "createdAt" | "updatedAt"> & {
|
|
@@ -219,7 +249,7 @@ export class PractitionerService extends BaseService {
|
|
|
219
249
|
certification: validatedData.certification,
|
|
220
250
|
clinics: clinics,
|
|
221
251
|
clinicWorkingHours: validatedData.clinicWorkingHours || [],
|
|
222
|
-
clinicsInfo:
|
|
252
|
+
clinicsInfo: finalClinicsInfo,
|
|
223
253
|
procedures: [],
|
|
224
254
|
proceduresInfo: proceduresInfo,
|
|
225
255
|
reviewInfo: defaultReviewInfo,
|
|
@@ -189,3 +189,27 @@ export const createPractitionerTokenSchema = z.object({
|
|
|
189
189
|
clinicId: z.string().min(1),
|
|
190
190
|
expiresAt: z.date().optional(),
|
|
191
191
|
});
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Simplified schema for practitioner signup
|
|
195
|
+
*/
|
|
196
|
+
export const practitionerSignupSchema = z.object({
|
|
197
|
+
email: z.string().email(),
|
|
198
|
+
password: z.string().min(8),
|
|
199
|
+
firstName: z.string().min(2).max(50),
|
|
200
|
+
lastName: z.string().min(2).max(50),
|
|
201
|
+
token: z.string().optional(),
|
|
202
|
+
profileData: z
|
|
203
|
+
.object({
|
|
204
|
+
basicInfo: z
|
|
205
|
+
.object({
|
|
206
|
+
phoneNumber: z.string().optional(),
|
|
207
|
+
profileImageUrl: z.string().optional(),
|
|
208
|
+
gender: z.enum(["male", "female", "other"]).optional(),
|
|
209
|
+
bio: z.string().optional(),
|
|
210
|
+
})
|
|
211
|
+
.optional(),
|
|
212
|
+
certification: z.any().optional(),
|
|
213
|
+
})
|
|
214
|
+
.optional(),
|
|
215
|
+
});
|