@blackcode_sa/metaestetics-api 1.5.52 → 1.6.0

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 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({
@@ -6949,6 +6966,234 @@ var AuthService = class extends BaseService {
6949
6966
  throw error;
6950
6967
  }
6951
6968
  }
6969
+ /**
6970
+ * Registers a new practitioner user with email and password
6971
+ * Can either create a new practitioner profile or claim an existing draft profile with a token
6972
+ *
6973
+ * @param data - Practitioner signup data containing either new profile details or token for claiming draft profile
6974
+ * @returns Object containing the created user and practitioner profile
6975
+ */
6976
+ async signUpPractitioner(data) {
6977
+ var _a, _b, _c, _d;
6978
+ try {
6979
+ console.log("[AUTH] Starting practitioner signup process", {
6980
+ email: data.email,
6981
+ hasToken: !!data.token
6982
+ });
6983
+ try {
6984
+ await practitionerSignupSchema.parseAsync(data);
6985
+ console.log("[AUTH] Practitioner signup data validation passed");
6986
+ } catch (validationError) {
6987
+ console.error(
6988
+ "[AUTH] Validation error in signUpPractitioner:",
6989
+ validationError
6990
+ );
6991
+ throw validationError;
6992
+ }
6993
+ console.log("[AUTH] Creating Firebase user");
6994
+ let firebaseUser;
6995
+ try {
6996
+ const result = await (0, import_auth5.createUserWithEmailAndPassword)(
6997
+ this.auth,
6998
+ data.email,
6999
+ data.password
7000
+ );
7001
+ firebaseUser = result.user;
7002
+ console.log("[AUTH] Firebase user created successfully", {
7003
+ uid: firebaseUser.uid
7004
+ });
7005
+ } catch (firebaseError) {
7006
+ console.error("[AUTH] Firebase user creation failed:", firebaseError);
7007
+ throw firebaseError;
7008
+ }
7009
+ console.log("[AUTH] Creating user with PRACTITIONER role");
7010
+ let user;
7011
+ try {
7012
+ user = await this.userService.createUser(
7013
+ firebaseUser,
7014
+ ["practitioner" /* PRACTITIONER */],
7015
+ {
7016
+ skipProfileCreation: true
7017
+ // We'll create the profile separately
7018
+ }
7019
+ );
7020
+ console.log("[AUTH] User with PRACTITIONER role created successfully", {
7021
+ userId: user.uid
7022
+ });
7023
+ } catch (userCreationError) {
7024
+ console.error("[AUTH] User creation failed:", userCreationError);
7025
+ throw userCreationError;
7026
+ }
7027
+ console.log("[AUTH] Initializing practitioner service");
7028
+ const practitionerService = new PractitionerService(
7029
+ this.db,
7030
+ this.auth,
7031
+ this.app
7032
+ );
7033
+ let practitioner = null;
7034
+ if (data.token) {
7035
+ console.log("[AUTH] Token provided, attempting to claim draft profile");
7036
+ try {
7037
+ practitioner = await practitionerService.validateTokenAndClaimProfile(
7038
+ data.token,
7039
+ firebaseUser.uid
7040
+ );
7041
+ if (!practitioner) {
7042
+ throw new Error("Invalid or expired invitation token");
7043
+ }
7044
+ console.log("[AUTH] Successfully claimed draft profile", {
7045
+ practitionerId: practitioner.id
7046
+ });
7047
+ await this.userService.updateUser(firebaseUser.uid, {
7048
+ practitionerProfile: practitioner.id
7049
+ });
7050
+ console.log(
7051
+ "[AUTH] User updated with practitioner profile reference"
7052
+ );
7053
+ } catch (tokenError) {
7054
+ console.error("[AUTH] Failed to claim draft profile:", tokenError);
7055
+ throw tokenError;
7056
+ }
7057
+ } else {
7058
+ console.log("[AUTH] Creating new practitioner profile");
7059
+ if (!data.profileData) {
7060
+ data.profileData = {};
7061
+ }
7062
+ const basicInfo = {
7063
+ firstName: data.firstName,
7064
+ lastName: data.lastName,
7065
+ email: data.email,
7066
+ phoneNumber: ((_a = data.profileData.basicInfo) == null ? void 0 : _a.phoneNumber) || "",
7067
+ profileImageUrl: ((_b = data.profileData.basicInfo) == null ? void 0 : _b.profileImageUrl) || "",
7068
+ gender: ((_c = data.profileData.basicInfo) == null ? void 0 : _c.gender) || "other",
7069
+ // Default to "other" if not provided
7070
+ bio: ((_d = data.profileData.basicInfo) == null ? void 0 : _d.bio) || "",
7071
+ title: "Practitioner",
7072
+ // Default title
7073
+ dateOfBirth: /* @__PURE__ */ new Date(),
7074
+ // Default to today
7075
+ languages: ["English"]
7076
+ // Default language
7077
+ };
7078
+ const certification = data.profileData.certification || {
7079
+ level: "aesthetician" /* AESTHETICIAN */,
7080
+ specialties: [],
7081
+ licenseNumber: "Pending",
7082
+ issuingAuthority: "Pending",
7083
+ issueDate: /* @__PURE__ */ new Date(),
7084
+ verificationStatus: "pending"
7085
+ };
7086
+ const createPractitionerData = {
7087
+ userRef: firebaseUser.uid,
7088
+ basicInfo,
7089
+ certification,
7090
+ status: "active" /* ACTIVE */,
7091
+ isActive: true,
7092
+ isVerified: false
7093
+ };
7094
+ try {
7095
+ practitioner = await practitionerService.createPractitioner(
7096
+ createPractitionerData
7097
+ );
7098
+ console.log("[AUTH] Practitioner profile created successfully", {
7099
+ practitionerId: practitioner.id
7100
+ });
7101
+ await this.userService.updateUser(firebaseUser.uid, {
7102
+ practitionerProfile: practitioner.id
7103
+ });
7104
+ console.log(
7105
+ "[AUTH] User updated with practitioner profile reference"
7106
+ );
7107
+ } catch (createError) {
7108
+ console.error(
7109
+ "[AUTH] Failed to create practitioner profile:",
7110
+ createError
7111
+ );
7112
+ throw createError;
7113
+ }
7114
+ }
7115
+ console.log("[AUTH] Practitioner signup completed successfully", {
7116
+ userId: user.uid,
7117
+ practitionerId: (practitioner == null ? void 0 : practitioner.id) || "unknown"
7118
+ });
7119
+ return {
7120
+ user,
7121
+ practitioner
7122
+ };
7123
+ } catch (error) {
7124
+ if (error instanceof import_zod18.z.ZodError) {
7125
+ console.error(
7126
+ "[AUTH] Zod validation error in signUpPractitioner:",
7127
+ JSON.stringify(error.errors, null, 2)
7128
+ );
7129
+ throw AUTH_ERRORS.VALIDATION_ERROR;
7130
+ }
7131
+ const firebaseError = error;
7132
+ if (firebaseError.code === "auth/email-already-in-use" /* EMAIL_ALREADY_IN_USE */) {
7133
+ console.error("[AUTH] Email already in use:", data.email);
7134
+ throw AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
7135
+ }
7136
+ console.error("[AUTH] Unhandled error in signUpPractitioner:", error);
7137
+ throw error;
7138
+ }
7139
+ }
7140
+ /**
7141
+ * Signs in a user with email and password specifically for practitioner role
7142
+ * @param email - User's email
7143
+ * @param password - User's password
7144
+ * @returns Object containing the user and practitioner profile
7145
+ * @throws {AUTH_ERRORS.INVALID_ROLE} If user doesn't have practitioner role
7146
+ * @throws {AUTH_ERRORS.NOT_FOUND} If practitioner profile is not found
7147
+ */
7148
+ async signInPractitioner(email, password) {
7149
+ var _a;
7150
+ try {
7151
+ console.log("[AUTH] Starting practitioner signin process", {
7152
+ email
7153
+ });
7154
+ const practitionerService = new PractitionerService(
7155
+ this.db,
7156
+ this.auth,
7157
+ this.app
7158
+ );
7159
+ const { user: firebaseUser } = await (0, import_auth5.signInWithEmailAndPassword)(
7160
+ this.auth,
7161
+ email,
7162
+ password
7163
+ );
7164
+ const user = await this.userService.getOrCreateUser(firebaseUser);
7165
+ console.log("[AUTH] User retrieved", { uid: user.uid });
7166
+ if (!((_a = user.roles) == null ? void 0 : _a.includes("practitioner" /* PRACTITIONER */))) {
7167
+ console.error("[AUTH] User is not a practitioner:", user.uid);
7168
+ throw AUTH_ERRORS.INVALID_ROLE;
7169
+ }
7170
+ if (!user.practitionerProfile) {
7171
+ console.error("[AUTH] User has no practitioner profile:", user.uid);
7172
+ throw AUTH_ERRORS.NOT_FOUND;
7173
+ }
7174
+ const practitioner = await practitionerService.getPractitioner(
7175
+ user.practitionerProfile
7176
+ );
7177
+ if (!practitioner) {
7178
+ console.error(
7179
+ "[AUTH] Practitioner profile not found:",
7180
+ user.practitionerProfile
7181
+ );
7182
+ throw AUTH_ERRORS.NOT_FOUND;
7183
+ }
7184
+ console.log("[AUTH] Practitioner signin completed successfully", {
7185
+ userId: user.uid,
7186
+ practitionerId: practitioner.id
7187
+ });
7188
+ return {
7189
+ user,
7190
+ practitioner
7191
+ };
7192
+ } catch (error) {
7193
+ console.error("[AUTH] Error in signInPractitioner:", error);
7194
+ throw error;
7195
+ }
7196
+ }
6952
7197
  };
6953
7198
 
6954
7199
  // src/services/notifications/notification.service.ts
@@ -13562,6 +13807,7 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
13562
13807
  practitionerReviewInfoSchema,
13563
13808
  practitionerReviewSchema,
13564
13809
  practitionerSchema,
13810
+ practitionerSignupSchema,
13565
13811
  practitionerTokenSchema,
13566
13812
  practitionerWorkingHoursSchema,
13567
13813
  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({
@@ -6906,6 +6922,234 @@ var AuthService = class extends BaseService {
6906
6922
  throw error;
6907
6923
  }
6908
6924
  }
6925
+ /**
6926
+ * Registers a new practitioner user with email and password
6927
+ * Can either create a new practitioner profile or claim an existing draft profile with a token
6928
+ *
6929
+ * @param data - Practitioner signup data containing either new profile details or token for claiming draft profile
6930
+ * @returns Object containing the created user and practitioner profile
6931
+ */
6932
+ async signUpPractitioner(data) {
6933
+ var _a, _b, _c, _d;
6934
+ try {
6935
+ console.log("[AUTH] Starting practitioner signup process", {
6936
+ email: data.email,
6937
+ hasToken: !!data.token
6938
+ });
6939
+ try {
6940
+ await practitionerSignupSchema.parseAsync(data);
6941
+ console.log("[AUTH] Practitioner signup data validation passed");
6942
+ } catch (validationError) {
6943
+ console.error(
6944
+ "[AUTH] Validation error in signUpPractitioner:",
6945
+ validationError
6946
+ );
6947
+ throw validationError;
6948
+ }
6949
+ console.log("[AUTH] Creating Firebase user");
6950
+ let firebaseUser;
6951
+ try {
6952
+ const result = await createUserWithEmailAndPassword(
6953
+ this.auth,
6954
+ data.email,
6955
+ data.password
6956
+ );
6957
+ firebaseUser = result.user;
6958
+ console.log("[AUTH] Firebase user created successfully", {
6959
+ uid: firebaseUser.uid
6960
+ });
6961
+ } catch (firebaseError) {
6962
+ console.error("[AUTH] Firebase user creation failed:", firebaseError);
6963
+ throw firebaseError;
6964
+ }
6965
+ console.log("[AUTH] Creating user with PRACTITIONER role");
6966
+ let user;
6967
+ try {
6968
+ user = await this.userService.createUser(
6969
+ firebaseUser,
6970
+ ["practitioner" /* PRACTITIONER */],
6971
+ {
6972
+ skipProfileCreation: true
6973
+ // We'll create the profile separately
6974
+ }
6975
+ );
6976
+ console.log("[AUTH] User with PRACTITIONER role created successfully", {
6977
+ userId: user.uid
6978
+ });
6979
+ } catch (userCreationError) {
6980
+ console.error("[AUTH] User creation failed:", userCreationError);
6981
+ throw userCreationError;
6982
+ }
6983
+ console.log("[AUTH] Initializing practitioner service");
6984
+ const practitionerService = new PractitionerService(
6985
+ this.db,
6986
+ this.auth,
6987
+ this.app
6988
+ );
6989
+ let practitioner = null;
6990
+ if (data.token) {
6991
+ console.log("[AUTH] Token provided, attempting to claim draft profile");
6992
+ try {
6993
+ practitioner = await practitionerService.validateTokenAndClaimProfile(
6994
+ data.token,
6995
+ firebaseUser.uid
6996
+ );
6997
+ if (!practitioner) {
6998
+ throw new Error("Invalid or expired invitation token");
6999
+ }
7000
+ console.log("[AUTH] Successfully claimed draft profile", {
7001
+ practitionerId: practitioner.id
7002
+ });
7003
+ await this.userService.updateUser(firebaseUser.uid, {
7004
+ practitionerProfile: practitioner.id
7005
+ });
7006
+ console.log(
7007
+ "[AUTH] User updated with practitioner profile reference"
7008
+ );
7009
+ } catch (tokenError) {
7010
+ console.error("[AUTH] Failed to claim draft profile:", tokenError);
7011
+ throw tokenError;
7012
+ }
7013
+ } else {
7014
+ console.log("[AUTH] Creating new practitioner profile");
7015
+ if (!data.profileData) {
7016
+ data.profileData = {};
7017
+ }
7018
+ const basicInfo = {
7019
+ firstName: data.firstName,
7020
+ lastName: data.lastName,
7021
+ email: data.email,
7022
+ phoneNumber: ((_a = data.profileData.basicInfo) == null ? void 0 : _a.phoneNumber) || "",
7023
+ profileImageUrl: ((_b = data.profileData.basicInfo) == null ? void 0 : _b.profileImageUrl) || "",
7024
+ gender: ((_c = data.profileData.basicInfo) == null ? void 0 : _c.gender) || "other",
7025
+ // Default to "other" if not provided
7026
+ bio: ((_d = data.profileData.basicInfo) == null ? void 0 : _d.bio) || "",
7027
+ title: "Practitioner",
7028
+ // Default title
7029
+ dateOfBirth: /* @__PURE__ */ new Date(),
7030
+ // Default to today
7031
+ languages: ["English"]
7032
+ // Default language
7033
+ };
7034
+ const certification = data.profileData.certification || {
7035
+ level: "aesthetician" /* AESTHETICIAN */,
7036
+ specialties: [],
7037
+ licenseNumber: "Pending",
7038
+ issuingAuthority: "Pending",
7039
+ issueDate: /* @__PURE__ */ new Date(),
7040
+ verificationStatus: "pending"
7041
+ };
7042
+ const createPractitionerData = {
7043
+ userRef: firebaseUser.uid,
7044
+ basicInfo,
7045
+ certification,
7046
+ status: "active" /* ACTIVE */,
7047
+ isActive: true,
7048
+ isVerified: false
7049
+ };
7050
+ try {
7051
+ practitioner = await practitionerService.createPractitioner(
7052
+ createPractitionerData
7053
+ );
7054
+ console.log("[AUTH] Practitioner profile created successfully", {
7055
+ practitionerId: practitioner.id
7056
+ });
7057
+ await this.userService.updateUser(firebaseUser.uid, {
7058
+ practitionerProfile: practitioner.id
7059
+ });
7060
+ console.log(
7061
+ "[AUTH] User updated with practitioner profile reference"
7062
+ );
7063
+ } catch (createError) {
7064
+ console.error(
7065
+ "[AUTH] Failed to create practitioner profile:",
7066
+ createError
7067
+ );
7068
+ throw createError;
7069
+ }
7070
+ }
7071
+ console.log("[AUTH] Practitioner signup completed successfully", {
7072
+ userId: user.uid,
7073
+ practitionerId: (practitioner == null ? void 0 : practitioner.id) || "unknown"
7074
+ });
7075
+ return {
7076
+ user,
7077
+ practitioner
7078
+ };
7079
+ } catch (error) {
7080
+ if (error instanceof z18.ZodError) {
7081
+ console.error(
7082
+ "[AUTH] Zod validation error in signUpPractitioner:",
7083
+ JSON.stringify(error.errors, null, 2)
7084
+ );
7085
+ throw AUTH_ERRORS.VALIDATION_ERROR;
7086
+ }
7087
+ const firebaseError = error;
7088
+ if (firebaseError.code === "auth/email-already-in-use" /* EMAIL_ALREADY_IN_USE */) {
7089
+ console.error("[AUTH] Email already in use:", data.email);
7090
+ throw AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
7091
+ }
7092
+ console.error("[AUTH] Unhandled error in signUpPractitioner:", error);
7093
+ throw error;
7094
+ }
7095
+ }
7096
+ /**
7097
+ * Signs in a user with email and password specifically for practitioner role
7098
+ * @param email - User's email
7099
+ * @param password - User's password
7100
+ * @returns Object containing the user and practitioner profile
7101
+ * @throws {AUTH_ERRORS.INVALID_ROLE} If user doesn't have practitioner role
7102
+ * @throws {AUTH_ERRORS.NOT_FOUND} If practitioner profile is not found
7103
+ */
7104
+ async signInPractitioner(email, password) {
7105
+ var _a;
7106
+ try {
7107
+ console.log("[AUTH] Starting practitioner signin process", {
7108
+ email
7109
+ });
7110
+ const practitionerService = new PractitionerService(
7111
+ this.db,
7112
+ this.auth,
7113
+ this.app
7114
+ );
7115
+ const { user: firebaseUser } = await signInWithEmailAndPassword(
7116
+ this.auth,
7117
+ email,
7118
+ password
7119
+ );
7120
+ const user = await this.userService.getOrCreateUser(firebaseUser);
7121
+ console.log("[AUTH] User retrieved", { uid: user.uid });
7122
+ if (!((_a = user.roles) == null ? void 0 : _a.includes("practitioner" /* PRACTITIONER */))) {
7123
+ console.error("[AUTH] User is not a practitioner:", user.uid);
7124
+ throw AUTH_ERRORS.INVALID_ROLE;
7125
+ }
7126
+ if (!user.practitionerProfile) {
7127
+ console.error("[AUTH] User has no practitioner profile:", user.uid);
7128
+ throw AUTH_ERRORS.NOT_FOUND;
7129
+ }
7130
+ const practitioner = await practitionerService.getPractitioner(
7131
+ user.practitionerProfile
7132
+ );
7133
+ if (!practitioner) {
7134
+ console.error(
7135
+ "[AUTH] Practitioner profile not found:",
7136
+ user.practitionerProfile
7137
+ );
7138
+ throw AUTH_ERRORS.NOT_FOUND;
7139
+ }
7140
+ console.log("[AUTH] Practitioner signin completed successfully", {
7141
+ userId: user.uid,
7142
+ practitionerId: practitioner.id
7143
+ });
7144
+ return {
7145
+ user,
7146
+ practitioner
7147
+ };
7148
+ } catch (error) {
7149
+ console.error("[AUTH] Error in signInPractitioner:", error);
7150
+ throw error;
7151
+ }
7152
+ }
6909
7153
  };
6910
7154
 
6911
7155
  // src/services/notifications/notification.service.ts
@@ -13715,6 +13959,7 @@ export {
13715
13959
  practitionerReviewInfoSchema,
13716
13960
  practitionerReviewSchema,
13717
13961
  practitionerSchema,
13962
+ practitionerSignupSchema,
13718
13963
  practitionerTokenSchema,
13719
13964
  practitionerWorkingHoursSchema,
13720
13965
  preRequirementNotificationSchema,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.5.52",
4
+ "version": "1.6.0",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
@@ -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
  }
@@ -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
+ });