@blackcode_sa/metaestetics-api 1.12.30 → 1.12.32
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 +54 -1
- package/dist/index.d.ts +54 -1
- package/dist/index.js +5 -0
- package/dist/index.mjs +4 -0
- package/package.json +1 -1
- package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -0
- package/src/types/appointment/index.ts +9 -8
- package/src/types/patient/aesthetic-analysis.types.ts +66 -0
- package/src/types/patient/index.ts +1 -0
- package/src/validations/patient/aesthetic-analysis.schema.ts +55 -0
package/dist/index.d.mts
CHANGED
|
@@ -3234,6 +3234,59 @@ interface UpdateMedicationData extends Partial<AddMedicationData> {
|
|
|
3234
3234
|
}
|
|
3235
3235
|
declare const DEFAULT_MEDICAL_INFO: Omit<PatientMedicalInfo, "patientId" | "lastUpdated" | "updatedBy">;
|
|
3236
3236
|
|
|
3237
|
+
declare const AESTHETIC_ANALYSIS_COLLECTION = "aesthetic-analysis";
|
|
3238
|
+
type AestheticAnalysisStatus = 'incomplete' | 'ready_for_planning' | 'treatment_planned';
|
|
3239
|
+
interface ClinicalFindingDetail {
|
|
3240
|
+
severity: string;
|
|
3241
|
+
impact: string;
|
|
3242
|
+
notes?: string;
|
|
3243
|
+
}
|
|
3244
|
+
interface ClinicalFindings {
|
|
3245
|
+
[category: string]: {
|
|
3246
|
+
[concern: string]: ClinicalFindingDetail;
|
|
3247
|
+
};
|
|
3248
|
+
}
|
|
3249
|
+
interface PatientGoals {
|
|
3250
|
+
timeline?: string;
|
|
3251
|
+
budget?: string;
|
|
3252
|
+
naturalness: number;
|
|
3253
|
+
priorities: string[];
|
|
3254
|
+
selectedTemplate?: string;
|
|
3255
|
+
}
|
|
3256
|
+
interface AssessmentScales {
|
|
3257
|
+
[scaleName: string]: string;
|
|
3258
|
+
}
|
|
3259
|
+
interface AestheticAnalysis {
|
|
3260
|
+
id: string;
|
|
3261
|
+
patientId: string;
|
|
3262
|
+
appointmentId?: string;
|
|
3263
|
+
selectedConcerns: string[];
|
|
3264
|
+
clinicalFindings: ClinicalFindings;
|
|
3265
|
+
patientGoals: PatientGoals;
|
|
3266
|
+
assessmentScales: AssessmentScales;
|
|
3267
|
+
completionPercentage: number;
|
|
3268
|
+
status: AestheticAnalysisStatus;
|
|
3269
|
+
lastUpdatedBy: string;
|
|
3270
|
+
lastUpdatedByRole: 'PATIENT' | 'PRACTITIONER';
|
|
3271
|
+
createdAt?: Timestamp | any;
|
|
3272
|
+
updatedAt?: Timestamp | any;
|
|
3273
|
+
}
|
|
3274
|
+
interface CreateAestheticAnalysisData {
|
|
3275
|
+
patientId: string;
|
|
3276
|
+
appointmentId?: string;
|
|
3277
|
+
selectedConcerns: string[];
|
|
3278
|
+
clinicalFindings: ClinicalFindings;
|
|
3279
|
+
patientGoals: PatientGoals;
|
|
3280
|
+
assessmentScales?: AssessmentScales;
|
|
3281
|
+
}
|
|
3282
|
+
interface UpdateAestheticAnalysisData {
|
|
3283
|
+
appointmentId?: string;
|
|
3284
|
+
selectedConcerns?: string[];
|
|
3285
|
+
clinicalFindings?: ClinicalFindings;
|
|
3286
|
+
patientGoals?: PatientGoals;
|
|
3287
|
+
assessmentScales?: AssessmentScales;
|
|
3288
|
+
}
|
|
3289
|
+
|
|
3237
3290
|
declare const PATIENTS_COLLECTION = "patients";
|
|
3238
3291
|
declare const PATIENT_SENSITIVE_INFO_COLLECTION = "sensitive-info";
|
|
3239
3292
|
declare const PATIENT_MEDICAL_HISTORY_COLLECTION = "medical-history";
|
|
@@ -6969,4 +7022,4 @@ declare const getFirebaseApp: () => Promise<FirebaseApp>;
|
|
|
6969
7022
|
declare const getFirebaseStorage: () => Promise<FirebaseStorage>;
|
|
6970
7023
|
declare const getFirebaseFunctions: () => Promise<Functions>;
|
|
6971
7024
|
|
|
6972
|
-
export { APPOINTMENTS_COLLECTION, 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 AppointmentCancelledNotification, type AppointmentMediaItem, type AppointmentMetadata, type AppointmentReminderNotification, type AppointmentRescheduledProposalNotification, AppointmentService, AppointmentStatus, type AppointmentStatusChangeNotification, AuthService, type BaseDocumentElement, type BaseNotification, BaseService, type BeforeAfterPerZone, type BillingInfo, type BillingPerZone, type BillingTransaction, BillingTransactionType, BillingTransactionsService, type BinaryChoiceElement, BlockingCondition, type Brand, BrandService, CALENDAR_COLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_GROUPS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarServiceV3, 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, ConstantsService, type ContactPerson, Contraindication, type ContraindicationDynamic, CosmeticAllergySubtype, type CreateAdminTokenData, type CreateAppointmentData, type CreateAppointmentHttpData, type CreateAppointmentParams, type CreateBillingTransactionData, type CreateBlockingEventParams, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreateManualPatientData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePatientTokenData, type CreatePractitionerData, type CreatePractitionerInviteData, type CreatePractitionerTokenData, type CreateProcedureData, type CreateSyncedCalendarData, type CreateUserData, Currency, DEFAULT_MEDICAL_INFO, DOCTOR_FORMS_SUBCOLLECTION, DOCUMENTATION_TEMPLATES_COLLECTION, type DatePickerElement, type DateRange, type DigitalSignatureElement, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, type DynamicTextElement, DynamicVariable, type EmergencyContact, EnvironmentalAllergySubtype, ExternalCalendarService, FILLED_DOCUMENTS_COLLECTION, type FileUploadElement, type FilledDocument, type FilledDocumentFileValue, FilledDocumentService, FilledDocumentStatus, type FinalBilling, type FirebaseUser, FoodAllergySubtype, type FormReminderNotification, type FormSubmissionConfirmationNotification, type GamificationInfo, Gender, type GeneralMessageNotification, type HeadingElement, HeadingLevel, INVITE_TOKENS_COLLECTION, Language, type LinkedFormInfo, type ListElement, ListType, type LocationData, MEDIA_METADATA_COLLECTION, MediaAccessLevel, type MediaMetadata, type MediaResource, MediaService, MediaType, MedicationAllergySubtype, type MultipleChoiceElement, NOTIFICATIONS_COLLECTION, type Notification, NotificationService, NotificationStatus, NotificationType, PATIENTS_COLLECTION, PATIENT_APPOINTMENTS_COLLECTION, PATIENT_LOCATION_INFO_COLLECTION, PATIENT_MEDICAL_HISTORY_COLLECTION, PATIENT_MEDICAL_INFO_COLLECTION, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, PATIENT_SENSITIVE_INFO_COLLECTION, PRACTITIONERS_COLLECTION, PRACTITIONER_INVITES_COLLECTION, PROCEDURES_COLLECTION, type ParagraphElement, type PatientClinic, type PatientDoctor, PatientInstructionStatus, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileForDoctor, type PatientProfileInfo, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, type PatientRequirementsFilters, PatientRequirementsService, type PatientReviewInfo, type PatientSensitiveInfo, PatientService, type PatientToken, PatientTokenStatus, type PaymentConfirmationNotification, PaymentStatus, type PlanDetails, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerBasicInfo, type PractitionerCertification, type PractitionerClinicProcedures, type PractitionerClinicWorkingHours, type PractitionerInvite, type PractitionerInviteFilters, PractitionerInviteService, PractitionerInviteStatus, type PractitionerProfileInfo, type PractitionerReview, type PractitionerReviewInfo, PractitionerService, PractitionerStatus, type PractitionerToken, PractitionerTokenStatus, type PractitionerWorkingHours, type PreRequirementNotification, PricingMeasure, type Procedure, type ProcedureCategorization, type ProcedureExtendedInfo, ProcedureFamily, type ProcedureInfo, type ProcedureProduct, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type ProcedureSummaryInfo, type Product, ProductService, type ProposedWorkingHours, REGISTER_TOKENS_COLLECTION, REVIEWS_COLLECTION, type RatingScaleElement, type RequesterInfo, type Requirement, type RequirementInstructionDueNotification, RequirementType, type Review, type ReviewRequestNotification, ReviewService, SYNCED_CALENDARS_COLLECTION, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type SignatureElement, type SingleChoiceElement, type StripeTransactionData, type Subcategory, SubcategoryService, SubscriptionModel, SubscriptionStatus, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, type Technology, type TechnologyDocumentationTemplate, TechnologyService, type TextInputElement, type TimeSlot, TimeUnit, TreatmentBenefit, type TreatmentBenefitDynamic, USERS_COLLECTION, USER_FORMS_SUBCOLLECTION, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateBlockingEventParams, 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 UpdatePractitionerInviteData, type UpdateProcedureData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type VitalStats, type WorkingHours, type ZonePhotoUploadData, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseFunctions, getFirebaseInstance, getFirebaseStorage, initializeFirebase };
|
|
7025
|
+
export { AESTHETIC_ANALYSIS_COLLECTION, APPOINTMENTS_COLLECTION, type AddAllergyData, type AddBlockingConditionData, type AddContraindicationData, type AddMedicationData, type AddressData, type AdminInfo, type AdminToken, AdminTokenStatus, type AestheticAnalysis, type AestheticAnalysisStatus, type Allergy, type AllergySubtype, AllergyType, type AllergyTypeWithSubtype, type Appointment, type AppointmentCancelledNotification, type AppointmentMediaItem, type AppointmentMetadata, type AppointmentReminderNotification, type AppointmentRescheduledProposalNotification, AppointmentService, AppointmentStatus, type AppointmentStatusChangeNotification, type AssessmentScales, AuthService, type BaseDocumentElement, type BaseNotification, BaseService, type BeforeAfterPerZone, type BillingInfo, type BillingPerZone, type BillingTransaction, BillingTransactionType, BillingTransactionsService, type BinaryChoiceElement, BlockingCondition, type Brand, BrandService, CALENDAR_COLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_GROUPS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarServiceV3, 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 ClinicalFindingDetail, type ClinicalFindings, ConstantsService, type ContactPerson, Contraindication, type ContraindicationDynamic, CosmeticAllergySubtype, type CreateAdminTokenData, type CreateAestheticAnalysisData, type CreateAppointmentData, type CreateAppointmentHttpData, type CreateAppointmentParams, type CreateBillingTransactionData, type CreateBlockingEventParams, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreateManualPatientData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePatientTokenData, type CreatePractitionerData, type CreatePractitionerInviteData, type CreatePractitionerTokenData, type CreateProcedureData, type CreateSyncedCalendarData, type CreateUserData, Currency, DEFAULT_MEDICAL_INFO, DOCTOR_FORMS_SUBCOLLECTION, DOCUMENTATION_TEMPLATES_COLLECTION, type DatePickerElement, type DateRange, type DigitalSignatureElement, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, type DynamicTextElement, DynamicVariable, type EmergencyContact, EnvironmentalAllergySubtype, ExternalCalendarService, FILLED_DOCUMENTS_COLLECTION, type FileUploadElement, type FilledDocument, type FilledDocumentFileValue, FilledDocumentService, FilledDocumentStatus, type FinalBilling, type FirebaseUser, FoodAllergySubtype, type FormReminderNotification, type FormSubmissionConfirmationNotification, type GamificationInfo, Gender, type GeneralMessageNotification, type HeadingElement, HeadingLevel, INVITE_TOKENS_COLLECTION, Language, type LinkedFormInfo, type ListElement, ListType, type LocationData, MEDIA_METADATA_COLLECTION, MediaAccessLevel, type MediaMetadata, type MediaResource, MediaService, MediaType, MedicationAllergySubtype, type MultipleChoiceElement, NOTIFICATIONS_COLLECTION, type Notification, NotificationService, NotificationStatus, NotificationType, PATIENTS_COLLECTION, PATIENT_APPOINTMENTS_COLLECTION, PATIENT_LOCATION_INFO_COLLECTION, PATIENT_MEDICAL_HISTORY_COLLECTION, PATIENT_MEDICAL_INFO_COLLECTION, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, PATIENT_SENSITIVE_INFO_COLLECTION, PRACTITIONERS_COLLECTION, PRACTITIONER_INVITES_COLLECTION, PROCEDURES_COLLECTION, type ParagraphElement, type PatientClinic, type PatientDoctor, type PatientGoals, PatientInstructionStatus, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileForDoctor, type PatientProfileInfo, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, type PatientRequirementsFilters, PatientRequirementsService, type PatientReviewInfo, type PatientSensitiveInfo, PatientService, type PatientToken, PatientTokenStatus, type PaymentConfirmationNotification, PaymentStatus, type PlanDetails, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerBasicInfo, type PractitionerCertification, type PractitionerClinicProcedures, type PractitionerClinicWorkingHours, type PractitionerInvite, type PractitionerInviteFilters, PractitionerInviteService, PractitionerInviteStatus, type PractitionerProfileInfo, type PractitionerReview, type PractitionerReviewInfo, PractitionerService, PractitionerStatus, type PractitionerToken, PractitionerTokenStatus, type PractitionerWorkingHours, type PreRequirementNotification, PricingMeasure, type Procedure, type ProcedureCategorization, type ProcedureExtendedInfo, ProcedureFamily, type ProcedureInfo, type ProcedureProduct, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type ProcedureSummaryInfo, type Product, ProductService, type ProposedWorkingHours, REGISTER_TOKENS_COLLECTION, REVIEWS_COLLECTION, type RatingScaleElement, type RequesterInfo, type Requirement, type RequirementInstructionDueNotification, RequirementType, type Review, type ReviewRequestNotification, ReviewService, SYNCED_CALENDARS_COLLECTION, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type SignatureElement, type SingleChoiceElement, type StripeTransactionData, type Subcategory, SubcategoryService, SubscriptionModel, SubscriptionStatus, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, type Technology, type TechnologyDocumentationTemplate, TechnologyService, type TextInputElement, type TimeSlot, TimeUnit, TreatmentBenefit, type TreatmentBenefitDynamic, USERS_COLLECTION, USER_FORMS_SUBCOLLECTION, type UpdateAestheticAnalysisData, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateBlockingEventParams, 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 UpdatePractitionerInviteData, type UpdateProcedureData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type VitalStats, type WorkingHours, type ZonePhotoUploadData, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseFunctions, getFirebaseInstance, getFirebaseStorage, initializeFirebase };
|
package/dist/index.d.ts
CHANGED
|
@@ -3234,6 +3234,59 @@ interface UpdateMedicationData extends Partial<AddMedicationData> {
|
|
|
3234
3234
|
}
|
|
3235
3235
|
declare const DEFAULT_MEDICAL_INFO: Omit<PatientMedicalInfo, "patientId" | "lastUpdated" | "updatedBy">;
|
|
3236
3236
|
|
|
3237
|
+
declare const AESTHETIC_ANALYSIS_COLLECTION = "aesthetic-analysis";
|
|
3238
|
+
type AestheticAnalysisStatus = 'incomplete' | 'ready_for_planning' | 'treatment_planned';
|
|
3239
|
+
interface ClinicalFindingDetail {
|
|
3240
|
+
severity: string;
|
|
3241
|
+
impact: string;
|
|
3242
|
+
notes?: string;
|
|
3243
|
+
}
|
|
3244
|
+
interface ClinicalFindings {
|
|
3245
|
+
[category: string]: {
|
|
3246
|
+
[concern: string]: ClinicalFindingDetail;
|
|
3247
|
+
};
|
|
3248
|
+
}
|
|
3249
|
+
interface PatientGoals {
|
|
3250
|
+
timeline?: string;
|
|
3251
|
+
budget?: string;
|
|
3252
|
+
naturalness: number;
|
|
3253
|
+
priorities: string[];
|
|
3254
|
+
selectedTemplate?: string;
|
|
3255
|
+
}
|
|
3256
|
+
interface AssessmentScales {
|
|
3257
|
+
[scaleName: string]: string;
|
|
3258
|
+
}
|
|
3259
|
+
interface AestheticAnalysis {
|
|
3260
|
+
id: string;
|
|
3261
|
+
patientId: string;
|
|
3262
|
+
appointmentId?: string;
|
|
3263
|
+
selectedConcerns: string[];
|
|
3264
|
+
clinicalFindings: ClinicalFindings;
|
|
3265
|
+
patientGoals: PatientGoals;
|
|
3266
|
+
assessmentScales: AssessmentScales;
|
|
3267
|
+
completionPercentage: number;
|
|
3268
|
+
status: AestheticAnalysisStatus;
|
|
3269
|
+
lastUpdatedBy: string;
|
|
3270
|
+
lastUpdatedByRole: 'PATIENT' | 'PRACTITIONER';
|
|
3271
|
+
createdAt?: Timestamp | any;
|
|
3272
|
+
updatedAt?: Timestamp | any;
|
|
3273
|
+
}
|
|
3274
|
+
interface CreateAestheticAnalysisData {
|
|
3275
|
+
patientId: string;
|
|
3276
|
+
appointmentId?: string;
|
|
3277
|
+
selectedConcerns: string[];
|
|
3278
|
+
clinicalFindings: ClinicalFindings;
|
|
3279
|
+
patientGoals: PatientGoals;
|
|
3280
|
+
assessmentScales?: AssessmentScales;
|
|
3281
|
+
}
|
|
3282
|
+
interface UpdateAestheticAnalysisData {
|
|
3283
|
+
appointmentId?: string;
|
|
3284
|
+
selectedConcerns?: string[];
|
|
3285
|
+
clinicalFindings?: ClinicalFindings;
|
|
3286
|
+
patientGoals?: PatientGoals;
|
|
3287
|
+
assessmentScales?: AssessmentScales;
|
|
3288
|
+
}
|
|
3289
|
+
|
|
3237
3290
|
declare const PATIENTS_COLLECTION = "patients";
|
|
3238
3291
|
declare const PATIENT_SENSITIVE_INFO_COLLECTION = "sensitive-info";
|
|
3239
3292
|
declare const PATIENT_MEDICAL_HISTORY_COLLECTION = "medical-history";
|
|
@@ -6969,4 +7022,4 @@ declare const getFirebaseApp: () => Promise<FirebaseApp>;
|
|
|
6969
7022
|
declare const getFirebaseStorage: () => Promise<FirebaseStorage>;
|
|
6970
7023
|
declare const getFirebaseFunctions: () => Promise<Functions>;
|
|
6971
7024
|
|
|
6972
|
-
export { APPOINTMENTS_COLLECTION, 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 AppointmentCancelledNotification, type AppointmentMediaItem, type AppointmentMetadata, type AppointmentReminderNotification, type AppointmentRescheduledProposalNotification, AppointmentService, AppointmentStatus, type AppointmentStatusChangeNotification, AuthService, type BaseDocumentElement, type BaseNotification, BaseService, type BeforeAfterPerZone, type BillingInfo, type BillingPerZone, type BillingTransaction, BillingTransactionType, BillingTransactionsService, type BinaryChoiceElement, BlockingCondition, type Brand, BrandService, CALENDAR_COLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_GROUPS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarServiceV3, 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, ConstantsService, type ContactPerson, Contraindication, type ContraindicationDynamic, CosmeticAllergySubtype, type CreateAdminTokenData, type CreateAppointmentData, type CreateAppointmentHttpData, type CreateAppointmentParams, type CreateBillingTransactionData, type CreateBlockingEventParams, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreateManualPatientData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePatientTokenData, type CreatePractitionerData, type CreatePractitionerInviteData, type CreatePractitionerTokenData, type CreateProcedureData, type CreateSyncedCalendarData, type CreateUserData, Currency, DEFAULT_MEDICAL_INFO, DOCTOR_FORMS_SUBCOLLECTION, DOCUMENTATION_TEMPLATES_COLLECTION, type DatePickerElement, type DateRange, type DigitalSignatureElement, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, type DynamicTextElement, DynamicVariable, type EmergencyContact, EnvironmentalAllergySubtype, ExternalCalendarService, FILLED_DOCUMENTS_COLLECTION, type FileUploadElement, type FilledDocument, type FilledDocumentFileValue, FilledDocumentService, FilledDocumentStatus, type FinalBilling, type FirebaseUser, FoodAllergySubtype, type FormReminderNotification, type FormSubmissionConfirmationNotification, type GamificationInfo, Gender, type GeneralMessageNotification, type HeadingElement, HeadingLevel, INVITE_TOKENS_COLLECTION, Language, type LinkedFormInfo, type ListElement, ListType, type LocationData, MEDIA_METADATA_COLLECTION, MediaAccessLevel, type MediaMetadata, type MediaResource, MediaService, MediaType, MedicationAllergySubtype, type MultipleChoiceElement, NOTIFICATIONS_COLLECTION, type Notification, NotificationService, NotificationStatus, NotificationType, PATIENTS_COLLECTION, PATIENT_APPOINTMENTS_COLLECTION, PATIENT_LOCATION_INFO_COLLECTION, PATIENT_MEDICAL_HISTORY_COLLECTION, PATIENT_MEDICAL_INFO_COLLECTION, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, PATIENT_SENSITIVE_INFO_COLLECTION, PRACTITIONERS_COLLECTION, PRACTITIONER_INVITES_COLLECTION, PROCEDURES_COLLECTION, type ParagraphElement, type PatientClinic, type PatientDoctor, PatientInstructionStatus, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileForDoctor, type PatientProfileInfo, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, type PatientRequirementsFilters, PatientRequirementsService, type PatientReviewInfo, type PatientSensitiveInfo, PatientService, type PatientToken, PatientTokenStatus, type PaymentConfirmationNotification, PaymentStatus, type PlanDetails, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerBasicInfo, type PractitionerCertification, type PractitionerClinicProcedures, type PractitionerClinicWorkingHours, type PractitionerInvite, type PractitionerInviteFilters, PractitionerInviteService, PractitionerInviteStatus, type PractitionerProfileInfo, type PractitionerReview, type PractitionerReviewInfo, PractitionerService, PractitionerStatus, type PractitionerToken, PractitionerTokenStatus, type PractitionerWorkingHours, type PreRequirementNotification, PricingMeasure, type Procedure, type ProcedureCategorization, type ProcedureExtendedInfo, ProcedureFamily, type ProcedureInfo, type ProcedureProduct, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type ProcedureSummaryInfo, type Product, ProductService, type ProposedWorkingHours, REGISTER_TOKENS_COLLECTION, REVIEWS_COLLECTION, type RatingScaleElement, type RequesterInfo, type Requirement, type RequirementInstructionDueNotification, RequirementType, type Review, type ReviewRequestNotification, ReviewService, SYNCED_CALENDARS_COLLECTION, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type SignatureElement, type SingleChoiceElement, type StripeTransactionData, type Subcategory, SubcategoryService, SubscriptionModel, SubscriptionStatus, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, type Technology, type TechnologyDocumentationTemplate, TechnologyService, type TextInputElement, type TimeSlot, TimeUnit, TreatmentBenefit, type TreatmentBenefitDynamic, USERS_COLLECTION, USER_FORMS_SUBCOLLECTION, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateBlockingEventParams, 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 UpdatePractitionerInviteData, type UpdateProcedureData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type VitalStats, type WorkingHours, type ZonePhotoUploadData, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseFunctions, getFirebaseInstance, getFirebaseStorage, initializeFirebase };
|
|
7025
|
+
export { AESTHETIC_ANALYSIS_COLLECTION, APPOINTMENTS_COLLECTION, type AddAllergyData, type AddBlockingConditionData, type AddContraindicationData, type AddMedicationData, type AddressData, type AdminInfo, type AdminToken, AdminTokenStatus, type AestheticAnalysis, type AestheticAnalysisStatus, type Allergy, type AllergySubtype, AllergyType, type AllergyTypeWithSubtype, type Appointment, type AppointmentCancelledNotification, type AppointmentMediaItem, type AppointmentMetadata, type AppointmentReminderNotification, type AppointmentRescheduledProposalNotification, AppointmentService, AppointmentStatus, type AppointmentStatusChangeNotification, type AssessmentScales, AuthService, type BaseDocumentElement, type BaseNotification, BaseService, type BeforeAfterPerZone, type BillingInfo, type BillingPerZone, type BillingTransaction, BillingTransactionType, BillingTransactionsService, type BinaryChoiceElement, BlockingCondition, type Brand, BrandService, CALENDAR_COLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_GROUPS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarServiceV3, 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 ClinicalFindingDetail, type ClinicalFindings, ConstantsService, type ContactPerson, Contraindication, type ContraindicationDynamic, CosmeticAllergySubtype, type CreateAdminTokenData, type CreateAestheticAnalysisData, type CreateAppointmentData, type CreateAppointmentHttpData, type CreateAppointmentParams, type CreateBillingTransactionData, type CreateBlockingEventParams, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreateManualPatientData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePatientTokenData, type CreatePractitionerData, type CreatePractitionerInviteData, type CreatePractitionerTokenData, type CreateProcedureData, type CreateSyncedCalendarData, type CreateUserData, Currency, DEFAULT_MEDICAL_INFO, DOCTOR_FORMS_SUBCOLLECTION, DOCUMENTATION_TEMPLATES_COLLECTION, type DatePickerElement, type DateRange, type DigitalSignatureElement, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, type DynamicTextElement, DynamicVariable, type EmergencyContact, EnvironmentalAllergySubtype, ExternalCalendarService, FILLED_DOCUMENTS_COLLECTION, type FileUploadElement, type FilledDocument, type FilledDocumentFileValue, FilledDocumentService, FilledDocumentStatus, type FinalBilling, type FirebaseUser, FoodAllergySubtype, type FormReminderNotification, type FormSubmissionConfirmationNotification, type GamificationInfo, Gender, type GeneralMessageNotification, type HeadingElement, HeadingLevel, INVITE_TOKENS_COLLECTION, Language, type LinkedFormInfo, type ListElement, ListType, type LocationData, MEDIA_METADATA_COLLECTION, MediaAccessLevel, type MediaMetadata, type MediaResource, MediaService, MediaType, MedicationAllergySubtype, type MultipleChoiceElement, NOTIFICATIONS_COLLECTION, type Notification, NotificationService, NotificationStatus, NotificationType, PATIENTS_COLLECTION, PATIENT_APPOINTMENTS_COLLECTION, PATIENT_LOCATION_INFO_COLLECTION, PATIENT_MEDICAL_HISTORY_COLLECTION, PATIENT_MEDICAL_INFO_COLLECTION, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, PATIENT_SENSITIVE_INFO_COLLECTION, PRACTITIONERS_COLLECTION, PRACTITIONER_INVITES_COLLECTION, PROCEDURES_COLLECTION, type ParagraphElement, type PatientClinic, type PatientDoctor, type PatientGoals, PatientInstructionStatus, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileForDoctor, type PatientProfileInfo, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, type PatientRequirementsFilters, PatientRequirementsService, type PatientReviewInfo, type PatientSensitiveInfo, PatientService, type PatientToken, PatientTokenStatus, type PaymentConfirmationNotification, PaymentStatus, type PlanDetails, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerBasicInfo, type PractitionerCertification, type PractitionerClinicProcedures, type PractitionerClinicWorkingHours, type PractitionerInvite, type PractitionerInviteFilters, PractitionerInviteService, PractitionerInviteStatus, type PractitionerProfileInfo, type PractitionerReview, type PractitionerReviewInfo, PractitionerService, PractitionerStatus, type PractitionerToken, PractitionerTokenStatus, type PractitionerWorkingHours, type PreRequirementNotification, PricingMeasure, type Procedure, type ProcedureCategorization, type ProcedureExtendedInfo, ProcedureFamily, type ProcedureInfo, type ProcedureProduct, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type ProcedureSummaryInfo, type Product, ProductService, type ProposedWorkingHours, REGISTER_TOKENS_COLLECTION, REVIEWS_COLLECTION, type RatingScaleElement, type RequesterInfo, type Requirement, type RequirementInstructionDueNotification, RequirementType, type Review, type ReviewRequestNotification, ReviewService, SYNCED_CALENDARS_COLLECTION, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type SignatureElement, type SingleChoiceElement, type StripeTransactionData, type Subcategory, SubcategoryService, SubscriptionModel, SubscriptionStatus, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, type Technology, type TechnologyDocumentationTemplate, TechnologyService, type TextInputElement, type TimeSlot, TimeUnit, TreatmentBenefit, type TreatmentBenefitDynamic, USERS_COLLECTION, USER_FORMS_SUBCOLLECTION, type UpdateAestheticAnalysisData, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateBlockingEventParams, 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 UpdatePractitionerInviteData, type UpdateProcedureData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type VitalStats, type WorkingHours, type ZonePhotoUploadData, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseFunctions, getFirebaseInstance, getFirebaseStorage, initializeFirebase };
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
AESTHETIC_ANALYSIS_COLLECTION: () => AESTHETIC_ANALYSIS_COLLECTION,
|
|
33
34
|
APPOINTMENTS_COLLECTION: () => APPOINTMENTS_COLLECTION,
|
|
34
35
|
AdminTokenStatus: () => AdminTokenStatus,
|
|
35
36
|
AllergyType: () => AllergyType,
|
|
@@ -1248,6 +1249,9 @@ var DEFAULT_MEDICAL_INFO = {
|
|
|
1248
1249
|
currentMedications: []
|
|
1249
1250
|
};
|
|
1250
1251
|
|
|
1252
|
+
// src/types/patient/aesthetic-analysis.types.ts
|
|
1253
|
+
var AESTHETIC_ANALYSIS_COLLECTION = "aesthetic-analysis";
|
|
1254
|
+
|
|
1251
1255
|
// src/types/patient/index.ts
|
|
1252
1256
|
var PATIENTS_COLLECTION = "patients";
|
|
1253
1257
|
var PATIENT_SENSITIVE_INFO_COLLECTION = "sensitive-info";
|
|
@@ -18277,6 +18281,7 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
|
|
|
18277
18281
|
})(RequirementType || {});
|
|
18278
18282
|
// Annotate the CommonJS export names for ESM import in node:
|
|
18279
18283
|
0 && (module.exports = {
|
|
18284
|
+
AESTHETIC_ANALYSIS_COLLECTION,
|
|
18280
18285
|
APPOINTMENTS_COLLECTION,
|
|
18281
18286
|
AdminTokenStatus,
|
|
18282
18287
|
AllergyType,
|
package/dist/index.mjs
CHANGED
|
@@ -1148,6 +1148,9 @@ var DEFAULT_MEDICAL_INFO = {
|
|
|
1148
1148
|
currentMedications: []
|
|
1149
1149
|
};
|
|
1150
1150
|
|
|
1151
|
+
// src/types/patient/aesthetic-analysis.types.ts
|
|
1152
|
+
var AESTHETIC_ANALYSIS_COLLECTION = "aesthetic-analysis";
|
|
1153
|
+
|
|
1151
1154
|
// src/types/patient/index.ts
|
|
1152
1155
|
var PATIENTS_COLLECTION = "patients";
|
|
1153
1156
|
var PATIENT_SENSITIVE_INFO_COLLECTION = "sensitive-info";
|
|
@@ -18612,6 +18615,7 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
|
|
|
18612
18615
|
return RequirementType2;
|
|
18613
18616
|
})(RequirementType || {});
|
|
18614
18617
|
export {
|
|
18618
|
+
AESTHETIC_ANALYSIS_COLLECTION,
|
|
18615
18619
|
APPOINTMENTS_COLLECTION,
|
|
18616
18620
|
AdminTokenStatus,
|
|
18617
18621
|
AllergyType,
|
package/package.json
CHANGED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { getDoc, updateDoc, setDoc, serverTimestamp, Firestore, doc } from 'firebase/firestore';
|
|
2
|
+
import {
|
|
3
|
+
AestheticAnalysis,
|
|
4
|
+
CreateAestheticAnalysisData,
|
|
5
|
+
UpdateAestheticAnalysisData,
|
|
6
|
+
AESTHETIC_ANALYSIS_COLLECTION,
|
|
7
|
+
PATIENTS_COLLECTION,
|
|
8
|
+
AestheticAnalysisStatus,
|
|
9
|
+
} from '../../../types/patient';
|
|
10
|
+
import { UserRole } from '../../../types';
|
|
11
|
+
import {
|
|
12
|
+
createAestheticAnalysisSchema,
|
|
13
|
+
updateAestheticAnalysisSchema,
|
|
14
|
+
aestheticAnalysisSchema,
|
|
15
|
+
} from '../../../validations/patient/aesthetic-analysis.schema';
|
|
16
|
+
import { getPatientDocRef } from './docs.utils';
|
|
17
|
+
import { AuthError } from '../../../errors/auth.errors';
|
|
18
|
+
import { getPractitionerProfileByUserRef } from './practitioner.utils';
|
|
19
|
+
import { getClinicAdminByUserRef } from '../../clinic/utils/admin.utils';
|
|
20
|
+
|
|
21
|
+
export const getAestheticAnalysisDocRef = (db: Firestore, patientId: string) => {
|
|
22
|
+
return doc(db, PATIENTS_COLLECTION, patientId, AESTHETIC_ANALYSIS_COLLECTION, patientId);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const checkAestheticAnalysisAccessUtil = async (
|
|
26
|
+
db: Firestore,
|
|
27
|
+
patientId: string,
|
|
28
|
+
requesterId: string,
|
|
29
|
+
requesterRoles: UserRole[]
|
|
30
|
+
): Promise<void> => {
|
|
31
|
+
const patientDoc = await getDoc(getPatientDocRef(db, patientId));
|
|
32
|
+
if (!patientDoc.exists()) {
|
|
33
|
+
throw new Error('Patient profile not found');
|
|
34
|
+
}
|
|
35
|
+
const patientData = patientDoc.data() as any;
|
|
36
|
+
|
|
37
|
+
if (patientData.userRef && patientData.userRef === requesterId) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (requesterRoles.includes(UserRole.PRACTITIONER)) {
|
|
42
|
+
const practitionerProfile = await getPractitionerProfileByUserRef(db, requesterId);
|
|
43
|
+
if (practitionerProfile && patientData.doctorIds?.includes(practitionerProfile.id)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (requesterRoles.includes(UserRole.CLINIC_ADMIN)) {
|
|
49
|
+
const adminProfile = await getClinicAdminByUserRef(db, requesterId);
|
|
50
|
+
if (adminProfile && adminProfile.clinicsManaged) {
|
|
51
|
+
const hasAccess = adminProfile.clinicsManaged.some((managedClinicId) =>
|
|
52
|
+
patientData.clinicIds?.includes(managedClinicId)
|
|
53
|
+
);
|
|
54
|
+
if (hasAccess) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
throw new AuthError(
|
|
61
|
+
'Unauthorized access to aesthetic analysis.',
|
|
62
|
+
'AUTH/UNAUTHORIZED_ACCESS',
|
|
63
|
+
403
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const calculateCompletionPercentage = (data: Partial<AestheticAnalysis>): number => {
|
|
68
|
+
let completed = 0;
|
|
69
|
+
const total = 4;
|
|
70
|
+
|
|
71
|
+
if (data.selectedConcerns && data.selectedConcerns.length > 0) completed++;
|
|
72
|
+
|
|
73
|
+
if (data.patientGoals && (
|
|
74
|
+
data.patientGoals.timeline ||
|
|
75
|
+
data.patientGoals.budget ||
|
|
76
|
+
data.patientGoals.selectedTemplate
|
|
77
|
+
)) completed++;
|
|
78
|
+
|
|
79
|
+
if (data.assessmentScales && Object.keys(data.assessmentScales).length > 0) completed++;
|
|
80
|
+
|
|
81
|
+
if (data.clinicalFindings && Object.keys(data.clinicalFindings).length > 0) completed++;
|
|
82
|
+
|
|
83
|
+
return Math.round((completed / total) * 100);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const determineStatus = (completionPercentage: number, selectedConcerns: string[]): AestheticAnalysisStatus => {
|
|
87
|
+
if (completionPercentage < 50) {
|
|
88
|
+
return 'incomplete';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (completionPercentage >= 50 && selectedConcerns.length > 0) {
|
|
92
|
+
return 'ready_for_planning';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return 'incomplete';
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const getAestheticAnalysisUtil = async (
|
|
99
|
+
db: Firestore,
|
|
100
|
+
patientId: string,
|
|
101
|
+
requesterId: string,
|
|
102
|
+
requesterRoles: UserRole[]
|
|
103
|
+
): Promise<AestheticAnalysis | null> => {
|
|
104
|
+
await checkAestheticAnalysisAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
105
|
+
|
|
106
|
+
const docRef = getAestheticAnalysisDocRef(db, patientId);
|
|
107
|
+
const snapshot = await getDoc(docRef);
|
|
108
|
+
|
|
109
|
+
if (!snapshot.exists()) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const data = snapshot.data();
|
|
114
|
+
return aestheticAnalysisSchema.parse({
|
|
115
|
+
...data,
|
|
116
|
+
id: patientId,
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const createOrUpdateAestheticAnalysisUtil = async (
|
|
121
|
+
db: Firestore,
|
|
122
|
+
patientId: string,
|
|
123
|
+
data: CreateAestheticAnalysisData | UpdateAestheticAnalysisData,
|
|
124
|
+
requesterId: string,
|
|
125
|
+
requesterRoles: UserRole[],
|
|
126
|
+
isUpdate: boolean = false
|
|
127
|
+
): Promise<void> => {
|
|
128
|
+
await checkAestheticAnalysisAccessUtil(db, patientId, requesterId, requesterRoles);
|
|
129
|
+
|
|
130
|
+
const validatedData = isUpdate
|
|
131
|
+
? updateAestheticAnalysisSchema.parse(data)
|
|
132
|
+
: createAestheticAnalysisSchema.parse(data);
|
|
133
|
+
|
|
134
|
+
const docRef = getAestheticAnalysisDocRef(db, patientId);
|
|
135
|
+
const snapshot = await getDoc(docRef);
|
|
136
|
+
|
|
137
|
+
const requesterRole = requesterRoles.includes(UserRole.PRACTITIONER) ? 'PRACTITIONER' : 'PATIENT';
|
|
138
|
+
|
|
139
|
+
const existingData = snapshot.exists() ? snapshot.data() : null;
|
|
140
|
+
const mergedData: any = {
|
|
141
|
+
...(existingData || {}),
|
|
142
|
+
...validatedData,
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const completionPercentage = calculateCompletionPercentage(mergedData);
|
|
146
|
+
const status = determineStatus(
|
|
147
|
+
completionPercentage,
|
|
148
|
+
mergedData.selectedConcerns || []
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
if (!snapshot.exists()) {
|
|
152
|
+
await setDoc(docRef, {
|
|
153
|
+
id: patientId,
|
|
154
|
+
patientId,
|
|
155
|
+
selectedConcerns: [],
|
|
156
|
+
clinicalFindings: {},
|
|
157
|
+
assessmentScales: {},
|
|
158
|
+
...validatedData,
|
|
159
|
+
completionPercentage,
|
|
160
|
+
status,
|
|
161
|
+
lastUpdatedBy: requesterId,
|
|
162
|
+
lastUpdatedByRole: requesterRole,
|
|
163
|
+
createdAt: serverTimestamp(),
|
|
164
|
+
updatedAt: serverTimestamp(),
|
|
165
|
+
});
|
|
166
|
+
} else {
|
|
167
|
+
await updateDoc(docRef, {
|
|
168
|
+
...validatedData,
|
|
169
|
+
completionPercentage,
|
|
170
|
+
status,
|
|
171
|
+
lastUpdatedBy: requesterId,
|
|
172
|
+
lastUpdatedByRole: requesterRole,
|
|
173
|
+
updatedAt: serverTimestamp(),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
};
|
|
@@ -76,8 +76,8 @@ export interface ProcedureExtendedInfo {
|
|
|
76
76
|
procedureTechnologyName: string;
|
|
77
77
|
procedureProductBrandId: string;
|
|
78
78
|
procedureProductBrandName: string;
|
|
79
|
-
procedureProductId: string;
|
|
80
|
-
procedureProductName: string;
|
|
79
|
+
procedureProductId: string; // We need to have more than one product allowed in this data, this is coming from aggregation, so please update aggregation and this data type
|
|
80
|
+
procedureProductName: string; // We need to have more than one product allowed in this data, this is coming from aggregation, so please update aggregation and this data type
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
/**
|
|
@@ -134,7 +134,7 @@ export interface ZonePhotoUploadData {
|
|
|
134
134
|
/**
|
|
135
135
|
* Interface for billing information per zone
|
|
136
136
|
*/
|
|
137
|
-
export interface BillingPerZone {
|
|
137
|
+
export interface BillingPerZone { // We should rename this to ZoneItemData and we should expend it as per our documentations (will be used for both zone items in step 3 and summary and pricing in the step 4)
|
|
138
138
|
/** Product name/description */
|
|
139
139
|
Product: string;
|
|
140
140
|
/** Product ID */
|
|
@@ -168,11 +168,11 @@ export interface FinalBilling {
|
|
|
168
168
|
/** Final price including tax */
|
|
169
169
|
finalPrice: number;
|
|
170
170
|
/** Total final quantity across all zones */
|
|
171
|
-
finalQuantity: number;
|
|
171
|
+
finalQuantity: number; // Not sure we should keep this as well, we keep track of this per item
|
|
172
172
|
/** Currency for the final billing */
|
|
173
173
|
currency: Currency;
|
|
174
174
|
/** Unit of measurement for the final billing */
|
|
175
|
-
unitOfMeasurement: PricingMeasure;
|
|
175
|
+
unitOfMeasurement: PricingMeasure; // NO need to keep this, we keep track of this per item
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
/**
|
|
@@ -180,15 +180,16 @@ export interface FinalBilling {
|
|
|
180
180
|
*/
|
|
181
181
|
export interface AppointmentMetadata {
|
|
182
182
|
/** Array of selected zones for the appointment */
|
|
183
|
-
selectedZones: string[] | null;
|
|
183
|
+
selectedZones: string[] | null; // We are not going to accept any structure (category.zone.subzone), here we will only accept zone (category.zone), nothing more, nothing less
|
|
184
184
|
/** Map of zone photos with before/after images and notes */
|
|
185
|
-
zonePhotos: Record<string, BeforeAfterPerZone> | null;
|
|
185
|
+
zonePhotos: Record<string, BeforeAfterPerZone> | null; // head.forhead: {object}, head: {object}, but it can't have head.forhead.forhedLeft: {object}
|
|
186
186
|
/** Map of billing information per zone */
|
|
187
|
-
zoneBilling: Record<string, BillingPerZone> | null;
|
|
187
|
+
zoneBilling: Record<string, BillingPerZone> | null; // This is going to change, name it zonesData, and expand this to accept more than one item per key (which is basically zone like category.zone)
|
|
188
188
|
/** Final billing calculations for the appointment */
|
|
189
189
|
finalbilling: FinalBilling | null;
|
|
190
190
|
/** Final note for the appointment */
|
|
191
191
|
finalizationNotes: string | null;
|
|
192
|
+
// TO-DO: We need to add extended procedures info (when we add multiple procedures, different than default one defined above)
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
/**
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Timestamp } from 'firebase/firestore';
|
|
2
|
+
|
|
3
|
+
export const AESTHETIC_ANALYSIS_COLLECTION = 'aesthetic-analysis';
|
|
4
|
+
|
|
5
|
+
export type AestheticAnalysisStatus = 'incomplete' | 'ready_for_planning' | 'treatment_planned';
|
|
6
|
+
|
|
7
|
+
export interface ClinicalFindingDetail {
|
|
8
|
+
severity: string;
|
|
9
|
+
impact: string;
|
|
10
|
+
notes?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ClinicalFindings {
|
|
14
|
+
[category: string]: {
|
|
15
|
+
[concern: string]: ClinicalFindingDetail;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PatientGoals {
|
|
20
|
+
timeline?: string;
|
|
21
|
+
budget?: string;
|
|
22
|
+
naturalness: number;
|
|
23
|
+
priorities: string[];
|
|
24
|
+
selectedTemplate?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface AssessmentScales {
|
|
28
|
+
[scaleName: string]: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface AestheticAnalysis {
|
|
32
|
+
id: string;
|
|
33
|
+
patientId: string;
|
|
34
|
+
appointmentId?: string;
|
|
35
|
+
|
|
36
|
+
selectedConcerns: string[];
|
|
37
|
+
clinicalFindings: ClinicalFindings;
|
|
38
|
+
patientGoals: PatientGoals;
|
|
39
|
+
assessmentScales: AssessmentScales;
|
|
40
|
+
|
|
41
|
+
completionPercentage: number;
|
|
42
|
+
status: AestheticAnalysisStatus;
|
|
43
|
+
|
|
44
|
+
lastUpdatedBy: string;
|
|
45
|
+
lastUpdatedByRole: 'PATIENT' | 'PRACTITIONER';
|
|
46
|
+
|
|
47
|
+
createdAt?: Timestamp | any;
|
|
48
|
+
updatedAt?: Timestamp | any;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface CreateAestheticAnalysisData {
|
|
52
|
+
patientId: string;
|
|
53
|
+
appointmentId?: string;
|
|
54
|
+
selectedConcerns: string[];
|
|
55
|
+
clinicalFindings: ClinicalFindings;
|
|
56
|
+
patientGoals: PatientGoals;
|
|
57
|
+
assessmentScales?: AssessmentScales;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface UpdateAestheticAnalysisData {
|
|
61
|
+
appointmentId?: string;
|
|
62
|
+
selectedConcerns?: string[];
|
|
63
|
+
clinicalFindings?: ClinicalFindings;
|
|
64
|
+
patientGoals?: PatientGoals;
|
|
65
|
+
assessmentScales?: AssessmentScales;
|
|
66
|
+
}
|
|
@@ -256,6 +256,7 @@ export interface RequesterInfo {
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
export * from "./medical-info.types";
|
|
259
|
+
export * from "./aesthetic-analysis.types";
|
|
259
260
|
|
|
260
261
|
// This is a type that combines all the patient data - used only in UI Frontend App
|
|
261
262
|
export interface PatientProfileComplete {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
export const clinicalFindingDetailSchema = z.object({
|
|
4
|
+
severity: z.string().min(1, 'Severity is required'),
|
|
5
|
+
impact: z.string().min(1, 'Impact is required'),
|
|
6
|
+
notes: z.string().optional(),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const clinicalFindingsSchema = z.record(
|
|
10
|
+
z.string(),
|
|
11
|
+
z.record(z.string(), clinicalFindingDetailSchema)
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
export const patientGoalsSchema = z.object({
|
|
15
|
+
timeline: z.string().optional(),
|
|
16
|
+
budget: z.string().optional(),
|
|
17
|
+
naturalness: z.number().min(0).max(100, 'Naturalness must be between 0 and 100'),
|
|
18
|
+
priorities: z.array(z.string()),
|
|
19
|
+
selectedTemplate: z.string().optional(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const assessmentScalesSchema = z.record(z.string(), z.string());
|
|
23
|
+
|
|
24
|
+
export const createAestheticAnalysisSchema = z.object({
|
|
25
|
+
patientId: z.string().min(1, 'Patient ID is required'),
|
|
26
|
+
appointmentId: z.string().optional(),
|
|
27
|
+
selectedConcerns: z.array(z.string()),
|
|
28
|
+
clinicalFindings: clinicalFindingsSchema,
|
|
29
|
+
patientGoals: patientGoalsSchema,
|
|
30
|
+
assessmentScales: assessmentScalesSchema.optional(),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export const updateAestheticAnalysisSchema = z.object({
|
|
34
|
+
appointmentId: z.string().optional(),
|
|
35
|
+
selectedConcerns: z.array(z.string()).optional(),
|
|
36
|
+
clinicalFindings: clinicalFindingsSchema.optional(),
|
|
37
|
+
patientGoals: patientGoalsSchema.partial().optional(),
|
|
38
|
+
assessmentScales: assessmentScalesSchema.optional(),
|
|
39
|
+
}).partial();
|
|
40
|
+
|
|
41
|
+
export const aestheticAnalysisSchema = z.object({
|
|
42
|
+
id: z.string(),
|
|
43
|
+
patientId: z.string(),
|
|
44
|
+
appointmentId: z.string().optional(),
|
|
45
|
+
selectedConcerns: z.array(z.string()),
|
|
46
|
+
clinicalFindings: clinicalFindingsSchema,
|
|
47
|
+
patientGoals: patientGoalsSchema,
|
|
48
|
+
assessmentScales: assessmentScalesSchema,
|
|
49
|
+
completionPercentage: z.number().min(0).max(100),
|
|
50
|
+
status: z.enum(['incomplete', 'ready_for_planning', 'treatment_planned']),
|
|
51
|
+
lastUpdatedBy: z.string(),
|
|
52
|
+
lastUpdatedByRole: z.enum(['PATIENT', 'PRACTITIONER']),
|
|
53
|
+
createdAt: z.any(),
|
|
54
|
+
updatedAt: z.any(),
|
|
55
|
+
});
|