@blackcode_sa/metaestetics-api 1.15.17-staging.10 → 1.15.17-staging.12

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
@@ -5600,6 +5600,14 @@ interface UpdateProcedureData {
5600
5600
  photos?: MediaResource[];
5601
5601
  resourceRequirements?: ResourceRequirement[];
5602
5602
  }
5603
+ /**
5604
+ * Info returned by getProcedureDeletionInfo() to drive the deletion UI.
5605
+ */
5606
+ interface ProcedureDeletionInfo {
5607
+ hasBeenUsed: boolean;
5608
+ futureAppointmentCount: number;
5609
+ linkedResourceCount: number;
5610
+ }
5603
5611
  /**
5604
5612
  * Collection name for procedures in Firestore
5605
5613
  */
@@ -7668,9 +7676,24 @@ declare class ProcedureService extends BaseService {
7668
7676
  */
7669
7677
  deactivateProcedure(id: string): Promise<void>;
7670
7678
  /**
7671
- * Deletes a procedure permanently
7672
- * @param id - The ID of the procedure to delete
7673
- * @returns A boolean indicating if the deletion was successful
7679
+ * Reactivates a previously deactivated procedure
7680
+ */
7681
+ reactivateProcedure(id: string): Promise<void>;
7682
+ /**
7683
+ * Checks if a procedure has ever been used in any appointment
7684
+ * by querying the "calendar" collection group for events with this procedureId.
7685
+ */
7686
+ procedureHasBeenUsed(procedureId: string): Promise<boolean>;
7687
+ /**
7688
+ * Gathers info needed by the deletion UI: whether the procedure was used,
7689
+ * how many future appointments exist, and how many resources are linked.
7690
+ */
7691
+ getProcedureDeletionInfo(procedureId: string): Promise<ProcedureDeletionInfo>;
7692
+ /**
7693
+ * Permanently deletes a procedure that has never been used in any appointment.
7694
+ * Throws if the procedure has appointment history.
7695
+ * The onDeleteProcedure Cloud Function trigger handles all cleanup
7696
+ * (calendar events, practitioner/clinic aggregations, resource links).
7674
7697
  */
7675
7698
  deleteProcedure(id: string): Promise<boolean>;
7676
7699
  /**
@@ -10376,4 +10399,4 @@ declare const PERMISSION_CATEGORIES: readonly ["Clinic", "Calendar", "Appointmen
10376
10399
  */
10377
10400
  declare function resolveEffectiveTier(subscriptionModel: string): string;
10378
10401
 
10379
- export { AESTHETIC_ANALYSIS_COLLECTION, ANALYTICS_COLLECTION, APPOINTMENTS_COLLECTION, type ASAClassification, AcquisitionSource, 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, AnalyticsCloudService, type AnalyticsDateRange, type AnalyticsFilters, type AnalyticsMetadata, type AnalyticsPeriod, AnalyticsService, type AnesthesiaHistory, type Appointment, type AppointmentCancelledNotification, type AppointmentMediaItem, type AppointmentMetadata, type AppointmentProductMetadata, type AppointmentReminderNotification, type AppointmentRescheduledProposalNotification, type AppointmentRescheduledReminderNotification, AppointmentService, AppointmentStatus, type AppointmentStatusChangeNotification, type AppointmentTrend, type AssessmentScales, AuthService, BODY_ASSESSMENT_COLLECTION, type BaseDocumentElement, type BaseMetrics, type BaseNotification, BaseService, type BeforeAfterPerZone, type BillingInfo, type BillingPerZone, type BillingTransaction, BillingTransactionType, BillingTransactionsService, type BinaryChoiceElement, type BleedingRisk, type BleedingRiskLevel, BlockingCondition, type BodyAssessment, type BodyAssessmentStatus, type BodyCompositionData, type BodyMeasurementsData, type BodySymmetryData, type BodyZone, type BodyZoneAssessment, type BranchAddonDefinition, type BranchAddonTierPrice, type Brand, BrandService, type Break, CALENDAR_COLLECTION, CANCELLATION_ANALYTICS_SUBCOLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_ANALYTICS_SUBCOLLECTION, CLINIC_GROUPS_COLLECTION, CONCERNS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarServiceV3, CalendarSyncStatus, type CancellationMetrics, type CancellationRateTrend, type CancellationReasonStats, type Category, CategoryService, CertificationLevel, CertificationSpecialty, type ClearanceStatus, type Clinic, type ClinicAdmin, ClinicAdminService, type ClinicAdminSignupData, type ClinicAnalytics, type ClinicBranchSetupData, type ClinicComparisonMetrics, type ClinicContactInfo, type ClinicGroup, ClinicGroupService, type ClinicGroupSetupData, type ClinicInfo, type ClinicLocation, ClinicPhotoTag, type ClinicReview, type ClinicReviewInfo, ClinicRole, ClinicService, type ClinicStaffInvite, type ClinicStaffMember, ClinicTag, type ClinicTags, type ClinicalFindingDetail, type ClinicalFindings, type Concern, type ConcernTreatment, ConstantsService, type ContactPerson, Contraindication, type ContraindicationDynamic, CosmeticAllergySubtype, type CostPerPatientMetrics, type CreateAdminTokenData, type CreateAestheticAnalysisData, type CreateAppointmentData, type CreateAppointmentHttpData, type CreateAppointmentParams, type CreateBillingTransactionData, type CreateBlockingEventParams, type CreateBodyAssessmentData, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreateHairScalpAssessmentData, type CreateManualPatientData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePatientTokenData, type CreatePractitionerData, type CreatePractitionerInviteData, type CreatePractitionerTokenData, type CreatePreSurgicalAssessmentData, type CreateProcedureData, type CreateResourceBlockingEventParams, type CreateResourceData, type CreateSkinQualityAssessmentData, type CreateSyncedCalendarData, type CreateUserData, Currency, DASHBOARD_ANALYTICS_SUBCOLLECTION, DEFAULT_MEDICAL_INFO, DEFAULT_PLAN_CONFIG, DEFAULT_ROLE_PERMISSIONS, DOCTOR_FORMS_SUBCOLLECTION, DOCUMENTATION_TEMPLATES_COLLECTION, type DashboardAnalytics, type DatePickerElement, type DateRange, type DigitalSignatureElement, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, type DurationTrend, type DynamicTextElement, DynamicVariable, type ElastosisGrade, type EmergencyContact, type EntityType, EnvironmentalAllergySubtype, type ExtendedProcedureInfo, ExternalCalendarService, FILLED_DOCUMENTS_COLLECTION, type FileUploadElement, type FilledDocument, type FilledDocumentFileValue, FilledDocumentService, FilledDocumentStatus, type FinalBilling, type FirebaseUser, type FitzpatrickType, FoodAllergySubtype, type FormReminderNotification, type FormSubmissionConfirmationNotification, type GamificationInfo, Gender, type GeneralMessageNotification, type GlogauClassification, type GroupedAnalyticsBase, type GroupedPatientBehaviorMetrics, type GroupedPatientRetentionMetrics, type GroupedPractitionerPerformanceMetrics, type GroupedProcedurePerformanceMetrics, type GroupedProductUsageMetrics, type GroupedRevenueMetrics, type GroupedTimeEfficiencyMetrics, type GroupingPeriod, HAIR_SCALP_ASSESSMENT_COLLECTION, type HairCharacteristics, type HairColor, type HairDensity, type HairLossPattern, type HairLossType, type HairLossZone, type HairLossZoneAssessment, type HairScalpAssessment, type HairScalpAssessmentStatus, type HairTextureGrade, type HairType, type HeadingElement, HeadingLevel, INVITE_TOKENS_COLLECTION, type LabResult, Language, type LinkedFormInfo, type ListElement, ListType, type LocalizedString, type LocationData, type LudwigStage, MEDIA_METADATA_COLLECTION, MediaAccessLevel, type MediaMetadata, type MediaResource, MediaService, MediaType, MedicationAllergySubtype, type MultipleChoiceElement, type MuscleDefinitionLevel, NOTIFICATIONS_COLLECTION, NO_SHOW_ANALYTICS_SUBCOLLECTION, type NextStepsRecommendation, type NoShowMetrics, type NorwoodStage, type Notification, NotificationService, NotificationStatus, NotificationType, type OverallReviewAverages, 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, PERMISSION_CATEGORIES, PERMISSION_KEYS, PERMISSION_LABELS, PLAN_CONFIG_HISTORY_PATH, PLAN_CONFIG_PATH, PRACTITIONERS_COLLECTION, PRACTITIONER_ANALYTICS_SUBCOLLECTION, PRACTITIONER_INVITES_COLLECTION, PRE_SURGICAL_ASSESSMENT_COLLECTION, PROCEDURES_COLLECTION, PROCEDURE_ANALYTICS_SUBCOLLECTION, type ParagraphElement, type PatientAnalytics, type PatientClinic, type PatientDoctor, type PatientGoals, PatientInstructionStatus, type PatientLifetimeValueMetrics, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileForDoctor, type PatientProfileInfo, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, type PatientRequirementsFilters, PatientRequirementsService, type PatientRetentionMetrics, type PatientReviewInfo, type PatientSensitiveInfo, PatientService, type PatientToken, PatientTokenStatus, type PaymentConfirmationNotification, PaymentStatus, type PaymentStatusBreakdown, type PermissionKey, type PlanConfigDocument, type PlanDefinition, type PlanDetails, type PoreSizeLevel, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerAnalytics, 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, type PreSurgicalAssessment, type PreSurgicalAssessmentStatus, PricingMeasure, type Procedure, type ProcedureAddonDefinition, type ProcedureAnalytics, type ProcedureCategorization, type ProcedureExtendedInfo, ProcedureFamily, type ProcedureInfo, type ProcedurePopularity, type ProcedureProduct, type ProcedureProfitability, type ProcedureRecommendationNotification, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type ProcedureSummaryInfo, type Product, type ProductRevenueMetrics, ProductService, type ProductUsageByProcedure, type ProductUsageMetrics, type ProposedWorkingHours, REGISTER_TOKENS_COLLECTION, RESOURCES_COLLECTION, RESOURCE_CALENDAR_SUBCOLLECTION, RESOURCE_INSTANCES_SUBCOLLECTION, REVENUE_ANALYTICS_SUBCOLLECTION, REVIEWS_COLLECTION, type RatingScaleElement, type ReadStoredAnalyticsOptions, type RecommendedProcedure, type RequesterInfo, type Requirement, type RequirementInstructionDueNotification, type RequirementSourceProcedure, RequirementType, type Resource, type ResourceBookingInfo, type ResourceCalendarEvent, ResourceCategory, type ResourceInstance, type ResourceRequirement, ResourceService, ResourceStatus, type RevenueMetrics, type RevenueTrend, type Review, type ReviewAnalyticsMetrics, ReviewAnalyticsService, type ReviewDetail, type ReviewMetrics, type ReviewRequestNotification, ReviewService, type ReviewTrend, type RolePermissionConfig, SKIN_QUALITY_ASSESSMENT_COLLECTION, SYNCED_CALENDARS_COLLECTION, type ScalpCondition, type ScalpRednessLevel, type ScalpScalinessLevel, type ScalpSebumLevel, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type SeatAddonDefinition, type SeverityLevel, type SignatureElement, type SingleChoiceElement, type SkinCharacteristics, type SkinConditionEntry, type SkinConditionType, type SkinElasticityLevel, type SkinHydrationLevel, type SkinQualityAssessment, type SkinQualityAssessmentStatus, type SkinQualityScales, type SkinSensitivityLevel, type SkinTextureLevel, type SkinZone, type SkinZoneAssessment, type SmokingStatus, type StaffDisplayInfo, StaffInviteStatus, type StoredCancellationMetrics, type StoredClinicAnalytics, type StoredDashboardAnalytics, type StoredNoShowMetrics, type StoredPractitionerAnalytics, type StoredProcedureAnalytics, type StoredRevenueMetrics, type StoredTimeEfficiencyMetrics, type StripeTransactionData, type Subcategory, SubcategoryService, SubscriptionModel, SubscriptionStatus, type SupportedLanguage, type SurgicalSiteAssessment, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, TIER_CONFIG, TIME_EFFICIENCY_ANALYTICS_SUBCOLLECTION, type Technology, type TechnologyDocumentationTemplate, TechnologyService, type TextInputElement, type TierConfig, type TierDefinition, TierLimitError, type TierLimits, type TimeEfficiencyMetrics, type TimeSlot, TimeUnit, type TissueQualityLevel, TreatmentBenefit, type TreatmentBenefitDynamic, type TreatmentRelevance, type TrendPeriod, USERS_COLLECTION, USER_FORMS_SUBCOLLECTION, type UpdateAestheticAnalysisData, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateBlockingEventParams, type UpdateBodyAssessmentData, type UpdateCalendarEventData, type UpdateClinicAdminData, type UpdateClinicData, type UpdateClinicGroupData, type UpdateContraindicationData, type UpdateDocumentTemplateData, type UpdateHairScalpAssessmentData, type UpdateMedicationData, type UpdatePatientLocationInfoData, type UpdatePatientMedicalInfoData, type UpdatePatientProfileData, type UpdatePatientSensitiveInfoData, type UpdatePractitionerData, type UpdatePractitionerInviteData, type UpdatePreSurgicalAssessmentData, type UpdateProcedureData, type UpdateResourceBlockingEventParams, type UpdateResourceData, type UpdateSkinQualityAssessmentData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type VitalStats, type WorkingHours, type ZoneItemData, type ZonePhotoUploadData, enforceBranchLimit, enforceProcedureLimit, enforceProviderLimit, getEffectiveTier, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseFunctions, getFirebaseInstance, getFirebaseStorage, initializeFirebase, resolveEffectiveTier };
10402
+ export { AESTHETIC_ANALYSIS_COLLECTION, ANALYTICS_COLLECTION, APPOINTMENTS_COLLECTION, type ASAClassification, AcquisitionSource, 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, AnalyticsCloudService, type AnalyticsDateRange, type AnalyticsFilters, type AnalyticsMetadata, type AnalyticsPeriod, AnalyticsService, type AnesthesiaHistory, type Appointment, type AppointmentCancelledNotification, type AppointmentMediaItem, type AppointmentMetadata, type AppointmentProductMetadata, type AppointmentReminderNotification, type AppointmentRescheduledProposalNotification, type AppointmentRescheduledReminderNotification, AppointmentService, AppointmentStatus, type AppointmentStatusChangeNotification, type AppointmentTrend, type AssessmentScales, AuthService, BODY_ASSESSMENT_COLLECTION, type BaseDocumentElement, type BaseMetrics, type BaseNotification, BaseService, type BeforeAfterPerZone, type BillingInfo, type BillingPerZone, type BillingTransaction, BillingTransactionType, BillingTransactionsService, type BinaryChoiceElement, type BleedingRisk, type BleedingRiskLevel, BlockingCondition, type BodyAssessment, type BodyAssessmentStatus, type BodyCompositionData, type BodyMeasurementsData, type BodySymmetryData, type BodyZone, type BodyZoneAssessment, type BranchAddonDefinition, type BranchAddonTierPrice, type Brand, BrandService, type Break, CALENDAR_COLLECTION, CANCELLATION_ANALYTICS_SUBCOLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_ANALYTICS_SUBCOLLECTION, CLINIC_GROUPS_COLLECTION, CONCERNS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarServiceV3, CalendarSyncStatus, type CancellationMetrics, type CancellationRateTrend, type CancellationReasonStats, type Category, CategoryService, CertificationLevel, CertificationSpecialty, type ClearanceStatus, type Clinic, type ClinicAdmin, ClinicAdminService, type ClinicAdminSignupData, type ClinicAnalytics, type ClinicBranchSetupData, type ClinicComparisonMetrics, type ClinicContactInfo, type ClinicGroup, ClinicGroupService, type ClinicGroupSetupData, type ClinicInfo, type ClinicLocation, ClinicPhotoTag, type ClinicReview, type ClinicReviewInfo, ClinicRole, ClinicService, type ClinicStaffInvite, type ClinicStaffMember, ClinicTag, type ClinicTags, type ClinicalFindingDetail, type ClinicalFindings, type Concern, type ConcernTreatment, ConstantsService, type ContactPerson, Contraindication, type ContraindicationDynamic, CosmeticAllergySubtype, type CostPerPatientMetrics, type CreateAdminTokenData, type CreateAestheticAnalysisData, type CreateAppointmentData, type CreateAppointmentHttpData, type CreateAppointmentParams, type CreateBillingTransactionData, type CreateBlockingEventParams, type CreateBodyAssessmentData, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreateHairScalpAssessmentData, type CreateManualPatientData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePatientTokenData, type CreatePractitionerData, type CreatePractitionerInviteData, type CreatePractitionerTokenData, type CreatePreSurgicalAssessmentData, type CreateProcedureData, type CreateResourceBlockingEventParams, type CreateResourceData, type CreateSkinQualityAssessmentData, type CreateSyncedCalendarData, type CreateUserData, Currency, DASHBOARD_ANALYTICS_SUBCOLLECTION, DEFAULT_MEDICAL_INFO, DEFAULT_PLAN_CONFIG, DEFAULT_ROLE_PERMISSIONS, DOCTOR_FORMS_SUBCOLLECTION, DOCUMENTATION_TEMPLATES_COLLECTION, type DashboardAnalytics, type DatePickerElement, type DateRange, type DigitalSignatureElement, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, type DurationTrend, type DynamicTextElement, DynamicVariable, type ElastosisGrade, type EmergencyContact, type EntityType, EnvironmentalAllergySubtype, type ExtendedProcedureInfo, ExternalCalendarService, FILLED_DOCUMENTS_COLLECTION, type FileUploadElement, type FilledDocument, type FilledDocumentFileValue, FilledDocumentService, FilledDocumentStatus, type FinalBilling, type FirebaseUser, type FitzpatrickType, FoodAllergySubtype, type FormReminderNotification, type FormSubmissionConfirmationNotification, type GamificationInfo, Gender, type GeneralMessageNotification, type GlogauClassification, type GroupedAnalyticsBase, type GroupedPatientBehaviorMetrics, type GroupedPatientRetentionMetrics, type GroupedPractitionerPerformanceMetrics, type GroupedProcedurePerformanceMetrics, type GroupedProductUsageMetrics, type GroupedRevenueMetrics, type GroupedTimeEfficiencyMetrics, type GroupingPeriod, HAIR_SCALP_ASSESSMENT_COLLECTION, type HairCharacteristics, type HairColor, type HairDensity, type HairLossPattern, type HairLossType, type HairLossZone, type HairLossZoneAssessment, type HairScalpAssessment, type HairScalpAssessmentStatus, type HairTextureGrade, type HairType, type HeadingElement, HeadingLevel, INVITE_TOKENS_COLLECTION, type LabResult, Language, type LinkedFormInfo, type ListElement, ListType, type LocalizedString, type LocationData, type LudwigStage, MEDIA_METADATA_COLLECTION, MediaAccessLevel, type MediaMetadata, type MediaResource, MediaService, MediaType, MedicationAllergySubtype, type MultipleChoiceElement, type MuscleDefinitionLevel, NOTIFICATIONS_COLLECTION, NO_SHOW_ANALYTICS_SUBCOLLECTION, type NextStepsRecommendation, type NoShowMetrics, type NorwoodStage, type Notification, NotificationService, NotificationStatus, NotificationType, type OverallReviewAverages, 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, PERMISSION_CATEGORIES, PERMISSION_KEYS, PERMISSION_LABELS, PLAN_CONFIG_HISTORY_PATH, PLAN_CONFIG_PATH, PRACTITIONERS_COLLECTION, PRACTITIONER_ANALYTICS_SUBCOLLECTION, PRACTITIONER_INVITES_COLLECTION, PRE_SURGICAL_ASSESSMENT_COLLECTION, PROCEDURES_COLLECTION, PROCEDURE_ANALYTICS_SUBCOLLECTION, type ParagraphElement, type PatientAnalytics, type PatientClinic, type PatientDoctor, type PatientGoals, PatientInstructionStatus, type PatientLifetimeValueMetrics, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileForDoctor, type PatientProfileInfo, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, type PatientRequirementsFilters, PatientRequirementsService, type PatientRetentionMetrics, type PatientReviewInfo, type PatientSensitiveInfo, PatientService, type PatientToken, PatientTokenStatus, type PaymentConfirmationNotification, PaymentStatus, type PaymentStatusBreakdown, type PermissionKey, type PlanConfigDocument, type PlanDefinition, type PlanDetails, type PoreSizeLevel, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerAnalytics, 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, type PreSurgicalAssessment, type PreSurgicalAssessmentStatus, PricingMeasure, type Procedure, type ProcedureAddonDefinition, type ProcedureAnalytics, type ProcedureCategorization, type ProcedureDeletionInfo, type ProcedureExtendedInfo, ProcedureFamily, type ProcedureInfo, type ProcedurePopularity, type ProcedureProduct, type ProcedureProfitability, type ProcedureRecommendationNotification, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type ProcedureSummaryInfo, type Product, type ProductRevenueMetrics, ProductService, type ProductUsageByProcedure, type ProductUsageMetrics, type ProposedWorkingHours, REGISTER_TOKENS_COLLECTION, RESOURCES_COLLECTION, RESOURCE_CALENDAR_SUBCOLLECTION, RESOURCE_INSTANCES_SUBCOLLECTION, REVENUE_ANALYTICS_SUBCOLLECTION, REVIEWS_COLLECTION, type RatingScaleElement, type ReadStoredAnalyticsOptions, type RecommendedProcedure, type RequesterInfo, type Requirement, type RequirementInstructionDueNotification, type RequirementSourceProcedure, RequirementType, type Resource, type ResourceBookingInfo, type ResourceCalendarEvent, ResourceCategory, type ResourceInstance, type ResourceRequirement, ResourceService, ResourceStatus, type RevenueMetrics, type RevenueTrend, type Review, type ReviewAnalyticsMetrics, ReviewAnalyticsService, type ReviewDetail, type ReviewMetrics, type ReviewRequestNotification, ReviewService, type ReviewTrend, type RolePermissionConfig, SKIN_QUALITY_ASSESSMENT_COLLECTION, SYNCED_CALENDARS_COLLECTION, type ScalpCondition, type ScalpRednessLevel, type ScalpScalinessLevel, type ScalpSebumLevel, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type SeatAddonDefinition, type SeverityLevel, type SignatureElement, type SingleChoiceElement, type SkinCharacteristics, type SkinConditionEntry, type SkinConditionType, type SkinElasticityLevel, type SkinHydrationLevel, type SkinQualityAssessment, type SkinQualityAssessmentStatus, type SkinQualityScales, type SkinSensitivityLevel, type SkinTextureLevel, type SkinZone, type SkinZoneAssessment, type SmokingStatus, type StaffDisplayInfo, StaffInviteStatus, type StoredCancellationMetrics, type StoredClinicAnalytics, type StoredDashboardAnalytics, type StoredNoShowMetrics, type StoredPractitionerAnalytics, type StoredProcedureAnalytics, type StoredRevenueMetrics, type StoredTimeEfficiencyMetrics, type StripeTransactionData, type Subcategory, SubcategoryService, SubscriptionModel, SubscriptionStatus, type SupportedLanguage, type SurgicalSiteAssessment, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, TIER_CONFIG, TIME_EFFICIENCY_ANALYTICS_SUBCOLLECTION, type Technology, type TechnologyDocumentationTemplate, TechnologyService, type TextInputElement, type TierConfig, type TierDefinition, TierLimitError, type TierLimits, type TimeEfficiencyMetrics, type TimeSlot, TimeUnit, type TissueQualityLevel, TreatmentBenefit, type TreatmentBenefitDynamic, type TreatmentRelevance, type TrendPeriod, USERS_COLLECTION, USER_FORMS_SUBCOLLECTION, type UpdateAestheticAnalysisData, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateBlockingEventParams, type UpdateBodyAssessmentData, type UpdateCalendarEventData, type UpdateClinicAdminData, type UpdateClinicData, type UpdateClinicGroupData, type UpdateContraindicationData, type UpdateDocumentTemplateData, type UpdateHairScalpAssessmentData, type UpdateMedicationData, type UpdatePatientLocationInfoData, type UpdatePatientMedicalInfoData, type UpdatePatientProfileData, type UpdatePatientSensitiveInfoData, type UpdatePractitionerData, type UpdatePractitionerInviteData, type UpdatePreSurgicalAssessmentData, type UpdateProcedureData, type UpdateResourceBlockingEventParams, type UpdateResourceData, type UpdateSkinQualityAssessmentData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type VitalStats, type WorkingHours, type ZoneItemData, type ZonePhotoUploadData, enforceBranchLimit, enforceProcedureLimit, enforceProviderLimit, getEffectiveTier, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseFunctions, getFirebaseInstance, getFirebaseStorage, initializeFirebase, resolveEffectiveTier };
package/dist/index.d.ts CHANGED
@@ -5600,6 +5600,14 @@ interface UpdateProcedureData {
5600
5600
  photos?: MediaResource[];
5601
5601
  resourceRequirements?: ResourceRequirement[];
5602
5602
  }
5603
+ /**
5604
+ * Info returned by getProcedureDeletionInfo() to drive the deletion UI.
5605
+ */
5606
+ interface ProcedureDeletionInfo {
5607
+ hasBeenUsed: boolean;
5608
+ futureAppointmentCount: number;
5609
+ linkedResourceCount: number;
5610
+ }
5603
5611
  /**
5604
5612
  * Collection name for procedures in Firestore
5605
5613
  */
@@ -7668,9 +7676,24 @@ declare class ProcedureService extends BaseService {
7668
7676
  */
7669
7677
  deactivateProcedure(id: string): Promise<void>;
7670
7678
  /**
7671
- * Deletes a procedure permanently
7672
- * @param id - The ID of the procedure to delete
7673
- * @returns A boolean indicating if the deletion was successful
7679
+ * Reactivates a previously deactivated procedure
7680
+ */
7681
+ reactivateProcedure(id: string): Promise<void>;
7682
+ /**
7683
+ * Checks if a procedure has ever been used in any appointment
7684
+ * by querying the "calendar" collection group for events with this procedureId.
7685
+ */
7686
+ procedureHasBeenUsed(procedureId: string): Promise<boolean>;
7687
+ /**
7688
+ * Gathers info needed by the deletion UI: whether the procedure was used,
7689
+ * how many future appointments exist, and how many resources are linked.
7690
+ */
7691
+ getProcedureDeletionInfo(procedureId: string): Promise<ProcedureDeletionInfo>;
7692
+ /**
7693
+ * Permanently deletes a procedure that has never been used in any appointment.
7694
+ * Throws if the procedure has appointment history.
7695
+ * The onDeleteProcedure Cloud Function trigger handles all cleanup
7696
+ * (calendar events, practitioner/clinic aggregations, resource links).
7674
7697
  */
7675
7698
  deleteProcedure(id: string): Promise<boolean>;
7676
7699
  /**
@@ -10376,4 +10399,4 @@ declare const PERMISSION_CATEGORIES: readonly ["Clinic", "Calendar", "Appointmen
10376
10399
  */
10377
10400
  declare function resolveEffectiveTier(subscriptionModel: string): string;
10378
10401
 
10379
- export { AESTHETIC_ANALYSIS_COLLECTION, ANALYTICS_COLLECTION, APPOINTMENTS_COLLECTION, type ASAClassification, AcquisitionSource, 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, AnalyticsCloudService, type AnalyticsDateRange, type AnalyticsFilters, type AnalyticsMetadata, type AnalyticsPeriod, AnalyticsService, type AnesthesiaHistory, type Appointment, type AppointmentCancelledNotification, type AppointmentMediaItem, type AppointmentMetadata, type AppointmentProductMetadata, type AppointmentReminderNotification, type AppointmentRescheduledProposalNotification, type AppointmentRescheduledReminderNotification, AppointmentService, AppointmentStatus, type AppointmentStatusChangeNotification, type AppointmentTrend, type AssessmentScales, AuthService, BODY_ASSESSMENT_COLLECTION, type BaseDocumentElement, type BaseMetrics, type BaseNotification, BaseService, type BeforeAfterPerZone, type BillingInfo, type BillingPerZone, type BillingTransaction, BillingTransactionType, BillingTransactionsService, type BinaryChoiceElement, type BleedingRisk, type BleedingRiskLevel, BlockingCondition, type BodyAssessment, type BodyAssessmentStatus, type BodyCompositionData, type BodyMeasurementsData, type BodySymmetryData, type BodyZone, type BodyZoneAssessment, type BranchAddonDefinition, type BranchAddonTierPrice, type Brand, BrandService, type Break, CALENDAR_COLLECTION, CANCELLATION_ANALYTICS_SUBCOLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_ANALYTICS_SUBCOLLECTION, CLINIC_GROUPS_COLLECTION, CONCERNS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarServiceV3, CalendarSyncStatus, type CancellationMetrics, type CancellationRateTrend, type CancellationReasonStats, type Category, CategoryService, CertificationLevel, CertificationSpecialty, type ClearanceStatus, type Clinic, type ClinicAdmin, ClinicAdminService, type ClinicAdminSignupData, type ClinicAnalytics, type ClinicBranchSetupData, type ClinicComparisonMetrics, type ClinicContactInfo, type ClinicGroup, ClinicGroupService, type ClinicGroupSetupData, type ClinicInfo, type ClinicLocation, ClinicPhotoTag, type ClinicReview, type ClinicReviewInfo, ClinicRole, ClinicService, type ClinicStaffInvite, type ClinicStaffMember, ClinicTag, type ClinicTags, type ClinicalFindingDetail, type ClinicalFindings, type Concern, type ConcernTreatment, ConstantsService, type ContactPerson, Contraindication, type ContraindicationDynamic, CosmeticAllergySubtype, type CostPerPatientMetrics, type CreateAdminTokenData, type CreateAestheticAnalysisData, type CreateAppointmentData, type CreateAppointmentHttpData, type CreateAppointmentParams, type CreateBillingTransactionData, type CreateBlockingEventParams, type CreateBodyAssessmentData, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreateHairScalpAssessmentData, type CreateManualPatientData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePatientTokenData, type CreatePractitionerData, type CreatePractitionerInviteData, type CreatePractitionerTokenData, type CreatePreSurgicalAssessmentData, type CreateProcedureData, type CreateResourceBlockingEventParams, type CreateResourceData, type CreateSkinQualityAssessmentData, type CreateSyncedCalendarData, type CreateUserData, Currency, DASHBOARD_ANALYTICS_SUBCOLLECTION, DEFAULT_MEDICAL_INFO, DEFAULT_PLAN_CONFIG, DEFAULT_ROLE_PERMISSIONS, DOCTOR_FORMS_SUBCOLLECTION, DOCUMENTATION_TEMPLATES_COLLECTION, type DashboardAnalytics, type DatePickerElement, type DateRange, type DigitalSignatureElement, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, type DurationTrend, type DynamicTextElement, DynamicVariable, type ElastosisGrade, type EmergencyContact, type EntityType, EnvironmentalAllergySubtype, type ExtendedProcedureInfo, ExternalCalendarService, FILLED_DOCUMENTS_COLLECTION, type FileUploadElement, type FilledDocument, type FilledDocumentFileValue, FilledDocumentService, FilledDocumentStatus, type FinalBilling, type FirebaseUser, type FitzpatrickType, FoodAllergySubtype, type FormReminderNotification, type FormSubmissionConfirmationNotification, type GamificationInfo, Gender, type GeneralMessageNotification, type GlogauClassification, type GroupedAnalyticsBase, type GroupedPatientBehaviorMetrics, type GroupedPatientRetentionMetrics, type GroupedPractitionerPerformanceMetrics, type GroupedProcedurePerformanceMetrics, type GroupedProductUsageMetrics, type GroupedRevenueMetrics, type GroupedTimeEfficiencyMetrics, type GroupingPeriod, HAIR_SCALP_ASSESSMENT_COLLECTION, type HairCharacteristics, type HairColor, type HairDensity, type HairLossPattern, type HairLossType, type HairLossZone, type HairLossZoneAssessment, type HairScalpAssessment, type HairScalpAssessmentStatus, type HairTextureGrade, type HairType, type HeadingElement, HeadingLevel, INVITE_TOKENS_COLLECTION, type LabResult, Language, type LinkedFormInfo, type ListElement, ListType, type LocalizedString, type LocationData, type LudwigStage, MEDIA_METADATA_COLLECTION, MediaAccessLevel, type MediaMetadata, type MediaResource, MediaService, MediaType, MedicationAllergySubtype, type MultipleChoiceElement, type MuscleDefinitionLevel, NOTIFICATIONS_COLLECTION, NO_SHOW_ANALYTICS_SUBCOLLECTION, type NextStepsRecommendation, type NoShowMetrics, type NorwoodStage, type Notification, NotificationService, NotificationStatus, NotificationType, type OverallReviewAverages, 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, PERMISSION_CATEGORIES, PERMISSION_KEYS, PERMISSION_LABELS, PLAN_CONFIG_HISTORY_PATH, PLAN_CONFIG_PATH, PRACTITIONERS_COLLECTION, PRACTITIONER_ANALYTICS_SUBCOLLECTION, PRACTITIONER_INVITES_COLLECTION, PRE_SURGICAL_ASSESSMENT_COLLECTION, PROCEDURES_COLLECTION, PROCEDURE_ANALYTICS_SUBCOLLECTION, type ParagraphElement, type PatientAnalytics, type PatientClinic, type PatientDoctor, type PatientGoals, PatientInstructionStatus, type PatientLifetimeValueMetrics, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileForDoctor, type PatientProfileInfo, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, type PatientRequirementsFilters, PatientRequirementsService, type PatientRetentionMetrics, type PatientReviewInfo, type PatientSensitiveInfo, PatientService, type PatientToken, PatientTokenStatus, type PaymentConfirmationNotification, PaymentStatus, type PaymentStatusBreakdown, type PermissionKey, type PlanConfigDocument, type PlanDefinition, type PlanDetails, type PoreSizeLevel, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerAnalytics, 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, type PreSurgicalAssessment, type PreSurgicalAssessmentStatus, PricingMeasure, type Procedure, type ProcedureAddonDefinition, type ProcedureAnalytics, type ProcedureCategorization, type ProcedureExtendedInfo, ProcedureFamily, type ProcedureInfo, type ProcedurePopularity, type ProcedureProduct, type ProcedureProfitability, type ProcedureRecommendationNotification, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type ProcedureSummaryInfo, type Product, type ProductRevenueMetrics, ProductService, type ProductUsageByProcedure, type ProductUsageMetrics, type ProposedWorkingHours, REGISTER_TOKENS_COLLECTION, RESOURCES_COLLECTION, RESOURCE_CALENDAR_SUBCOLLECTION, RESOURCE_INSTANCES_SUBCOLLECTION, REVENUE_ANALYTICS_SUBCOLLECTION, REVIEWS_COLLECTION, type RatingScaleElement, type ReadStoredAnalyticsOptions, type RecommendedProcedure, type RequesterInfo, type Requirement, type RequirementInstructionDueNotification, type RequirementSourceProcedure, RequirementType, type Resource, type ResourceBookingInfo, type ResourceCalendarEvent, ResourceCategory, type ResourceInstance, type ResourceRequirement, ResourceService, ResourceStatus, type RevenueMetrics, type RevenueTrend, type Review, type ReviewAnalyticsMetrics, ReviewAnalyticsService, type ReviewDetail, type ReviewMetrics, type ReviewRequestNotification, ReviewService, type ReviewTrend, type RolePermissionConfig, SKIN_QUALITY_ASSESSMENT_COLLECTION, SYNCED_CALENDARS_COLLECTION, type ScalpCondition, type ScalpRednessLevel, type ScalpScalinessLevel, type ScalpSebumLevel, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type SeatAddonDefinition, type SeverityLevel, type SignatureElement, type SingleChoiceElement, type SkinCharacteristics, type SkinConditionEntry, type SkinConditionType, type SkinElasticityLevel, type SkinHydrationLevel, type SkinQualityAssessment, type SkinQualityAssessmentStatus, type SkinQualityScales, type SkinSensitivityLevel, type SkinTextureLevel, type SkinZone, type SkinZoneAssessment, type SmokingStatus, type StaffDisplayInfo, StaffInviteStatus, type StoredCancellationMetrics, type StoredClinicAnalytics, type StoredDashboardAnalytics, type StoredNoShowMetrics, type StoredPractitionerAnalytics, type StoredProcedureAnalytics, type StoredRevenueMetrics, type StoredTimeEfficiencyMetrics, type StripeTransactionData, type Subcategory, SubcategoryService, SubscriptionModel, SubscriptionStatus, type SupportedLanguage, type SurgicalSiteAssessment, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, TIER_CONFIG, TIME_EFFICIENCY_ANALYTICS_SUBCOLLECTION, type Technology, type TechnologyDocumentationTemplate, TechnologyService, type TextInputElement, type TierConfig, type TierDefinition, TierLimitError, type TierLimits, type TimeEfficiencyMetrics, type TimeSlot, TimeUnit, type TissueQualityLevel, TreatmentBenefit, type TreatmentBenefitDynamic, type TreatmentRelevance, type TrendPeriod, USERS_COLLECTION, USER_FORMS_SUBCOLLECTION, type UpdateAestheticAnalysisData, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateBlockingEventParams, type UpdateBodyAssessmentData, type UpdateCalendarEventData, type UpdateClinicAdminData, type UpdateClinicData, type UpdateClinicGroupData, type UpdateContraindicationData, type UpdateDocumentTemplateData, type UpdateHairScalpAssessmentData, type UpdateMedicationData, type UpdatePatientLocationInfoData, type UpdatePatientMedicalInfoData, type UpdatePatientProfileData, type UpdatePatientSensitiveInfoData, type UpdatePractitionerData, type UpdatePractitionerInviteData, type UpdatePreSurgicalAssessmentData, type UpdateProcedureData, type UpdateResourceBlockingEventParams, type UpdateResourceData, type UpdateSkinQualityAssessmentData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type VitalStats, type WorkingHours, type ZoneItemData, type ZonePhotoUploadData, enforceBranchLimit, enforceProcedureLimit, enforceProviderLimit, getEffectiveTier, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseFunctions, getFirebaseInstance, getFirebaseStorage, initializeFirebase, resolveEffectiveTier };
10402
+ export { AESTHETIC_ANALYSIS_COLLECTION, ANALYTICS_COLLECTION, APPOINTMENTS_COLLECTION, type ASAClassification, AcquisitionSource, 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, AnalyticsCloudService, type AnalyticsDateRange, type AnalyticsFilters, type AnalyticsMetadata, type AnalyticsPeriod, AnalyticsService, type AnesthesiaHistory, type Appointment, type AppointmentCancelledNotification, type AppointmentMediaItem, type AppointmentMetadata, type AppointmentProductMetadata, type AppointmentReminderNotification, type AppointmentRescheduledProposalNotification, type AppointmentRescheduledReminderNotification, AppointmentService, AppointmentStatus, type AppointmentStatusChangeNotification, type AppointmentTrend, type AssessmentScales, AuthService, BODY_ASSESSMENT_COLLECTION, type BaseDocumentElement, type BaseMetrics, type BaseNotification, BaseService, type BeforeAfterPerZone, type BillingInfo, type BillingPerZone, type BillingTransaction, BillingTransactionType, BillingTransactionsService, type BinaryChoiceElement, type BleedingRisk, type BleedingRiskLevel, BlockingCondition, type BodyAssessment, type BodyAssessmentStatus, type BodyCompositionData, type BodyMeasurementsData, type BodySymmetryData, type BodyZone, type BodyZoneAssessment, type BranchAddonDefinition, type BranchAddonTierPrice, type Brand, BrandService, type Break, CALENDAR_COLLECTION, CANCELLATION_ANALYTICS_SUBCOLLECTION, CLINICS_COLLECTION, CLINIC_ADMINS_COLLECTION, CLINIC_ANALYTICS_SUBCOLLECTION, CLINIC_GROUPS_COLLECTION, CONCERNS_COLLECTION, type CalendarEvent, CalendarEventStatus, type CalendarEventTime, CalendarEventType, CalendarServiceV2, CalendarServiceV3, CalendarSyncStatus, type CancellationMetrics, type CancellationRateTrend, type CancellationReasonStats, type Category, CategoryService, CertificationLevel, CertificationSpecialty, type ClearanceStatus, type Clinic, type ClinicAdmin, ClinicAdminService, type ClinicAdminSignupData, type ClinicAnalytics, type ClinicBranchSetupData, type ClinicComparisonMetrics, type ClinicContactInfo, type ClinicGroup, ClinicGroupService, type ClinicGroupSetupData, type ClinicInfo, type ClinicLocation, ClinicPhotoTag, type ClinicReview, type ClinicReviewInfo, ClinicRole, ClinicService, type ClinicStaffInvite, type ClinicStaffMember, ClinicTag, type ClinicTags, type ClinicalFindingDetail, type ClinicalFindings, type Concern, type ConcernTreatment, ConstantsService, type ContactPerson, Contraindication, type ContraindicationDynamic, CosmeticAllergySubtype, type CostPerPatientMetrics, type CreateAdminTokenData, type CreateAestheticAnalysisData, type CreateAppointmentData, type CreateAppointmentHttpData, type CreateAppointmentParams, type CreateBillingTransactionData, type CreateBlockingEventParams, type CreateBodyAssessmentData, type CreateCalendarEventData, type CreateClinicAdminData, type CreateClinicData, type CreateClinicGroupData, type CreateDefaultClinicGroupData, type CreateDocumentTemplateData, type CreateDraftPractitionerData, type CreateHairScalpAssessmentData, type CreateManualPatientData, type CreatePatientLocationInfoData, type CreatePatientMedicalInfoData, type CreatePatientProfileData, type CreatePatientSensitiveInfoData, type CreatePatientTokenData, type CreatePractitionerData, type CreatePractitionerInviteData, type CreatePractitionerTokenData, type CreatePreSurgicalAssessmentData, type CreateProcedureData, type CreateResourceBlockingEventParams, type CreateResourceData, type CreateSkinQualityAssessmentData, type CreateSyncedCalendarData, type CreateUserData, Currency, DASHBOARD_ANALYTICS_SUBCOLLECTION, DEFAULT_MEDICAL_INFO, DEFAULT_PLAN_CONFIG, DEFAULT_ROLE_PERMISSIONS, DOCTOR_FORMS_SUBCOLLECTION, DOCUMENTATION_TEMPLATES_COLLECTION, type DashboardAnalytics, type DatePickerElement, type DateRange, type DigitalSignatureElement, type DoctorInfo, type DocumentElement, DocumentElementType, type DocumentTemplate, DocumentationTemplateService, type DurationTrend, type DynamicTextElement, DynamicVariable, type ElastosisGrade, type EmergencyContact, type EntityType, EnvironmentalAllergySubtype, type ExtendedProcedureInfo, ExternalCalendarService, FILLED_DOCUMENTS_COLLECTION, type FileUploadElement, type FilledDocument, type FilledDocumentFileValue, FilledDocumentService, FilledDocumentStatus, type FinalBilling, type FirebaseUser, type FitzpatrickType, FoodAllergySubtype, type FormReminderNotification, type FormSubmissionConfirmationNotification, type GamificationInfo, Gender, type GeneralMessageNotification, type GlogauClassification, type GroupedAnalyticsBase, type GroupedPatientBehaviorMetrics, type GroupedPatientRetentionMetrics, type GroupedPractitionerPerformanceMetrics, type GroupedProcedurePerformanceMetrics, type GroupedProductUsageMetrics, type GroupedRevenueMetrics, type GroupedTimeEfficiencyMetrics, type GroupingPeriod, HAIR_SCALP_ASSESSMENT_COLLECTION, type HairCharacteristics, type HairColor, type HairDensity, type HairLossPattern, type HairLossType, type HairLossZone, type HairLossZoneAssessment, type HairScalpAssessment, type HairScalpAssessmentStatus, type HairTextureGrade, type HairType, type HeadingElement, HeadingLevel, INVITE_TOKENS_COLLECTION, type LabResult, Language, type LinkedFormInfo, type ListElement, ListType, type LocalizedString, type LocationData, type LudwigStage, MEDIA_METADATA_COLLECTION, MediaAccessLevel, type MediaMetadata, type MediaResource, MediaService, MediaType, MedicationAllergySubtype, type MultipleChoiceElement, type MuscleDefinitionLevel, NOTIFICATIONS_COLLECTION, NO_SHOW_ANALYTICS_SUBCOLLECTION, type NextStepsRecommendation, type NoShowMetrics, type NorwoodStage, type Notification, NotificationService, NotificationStatus, NotificationType, type OverallReviewAverages, 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, PERMISSION_CATEGORIES, PERMISSION_KEYS, PERMISSION_LABELS, PLAN_CONFIG_HISTORY_PATH, PLAN_CONFIG_PATH, PRACTITIONERS_COLLECTION, PRACTITIONER_ANALYTICS_SUBCOLLECTION, PRACTITIONER_INVITES_COLLECTION, PRE_SURGICAL_ASSESSMENT_COLLECTION, PROCEDURES_COLLECTION, PROCEDURE_ANALYTICS_SUBCOLLECTION, type ParagraphElement, type PatientAnalytics, type PatientClinic, type PatientDoctor, type PatientGoals, PatientInstructionStatus, type PatientLifetimeValueMetrics, type PatientLocationInfo, type PatientMedicalInfo, type PatientProfile, type PatientProfileComplete, type PatientProfileForDoctor, type PatientProfileInfo, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, type PatientRequirementsFilters, PatientRequirementsService, type PatientRetentionMetrics, type PatientReviewInfo, type PatientSensitiveInfo, PatientService, type PatientToken, PatientTokenStatus, type PaymentConfirmationNotification, PaymentStatus, type PaymentStatusBreakdown, type PermissionKey, type PlanConfigDocument, type PlanDefinition, type PlanDetails, type PoreSizeLevel, type PostRequirementNotification, PracticeType, type Practitioner, type PractitionerAnalytics, 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, type PreSurgicalAssessment, type PreSurgicalAssessmentStatus, PricingMeasure, type Procedure, type ProcedureAddonDefinition, type ProcedureAnalytics, type ProcedureCategorization, type ProcedureDeletionInfo, type ProcedureExtendedInfo, ProcedureFamily, type ProcedureInfo, type ProcedurePopularity, type ProcedureProduct, type ProcedureProfitability, type ProcedureRecommendationNotification, type ProcedureReview, type ProcedureReviewInfo, ProcedureService, type ProcedureSummaryInfo, type Product, type ProductRevenueMetrics, ProductService, type ProductUsageByProcedure, type ProductUsageMetrics, type ProposedWorkingHours, REGISTER_TOKENS_COLLECTION, RESOURCES_COLLECTION, RESOURCE_CALENDAR_SUBCOLLECTION, RESOURCE_INSTANCES_SUBCOLLECTION, REVENUE_ANALYTICS_SUBCOLLECTION, REVIEWS_COLLECTION, type RatingScaleElement, type ReadStoredAnalyticsOptions, type RecommendedProcedure, type RequesterInfo, type Requirement, type RequirementInstructionDueNotification, type RequirementSourceProcedure, RequirementType, type Resource, type ResourceBookingInfo, type ResourceCalendarEvent, ResourceCategory, type ResourceInstance, type ResourceRequirement, ResourceService, ResourceStatus, type RevenueMetrics, type RevenueTrend, type Review, type ReviewAnalyticsMetrics, ReviewAnalyticsService, type ReviewDetail, type ReviewMetrics, type ReviewRequestNotification, ReviewService, type ReviewTrend, type RolePermissionConfig, SKIN_QUALITY_ASSESSMENT_COLLECTION, SYNCED_CALENDARS_COLLECTION, type ScalpCondition, type ScalpRednessLevel, type ScalpScalinessLevel, type ScalpSebumLevel, type SearchAppointmentsParams, type SearchCalendarEventsParams, SearchLocationEnum, type SearchPatientsParams, type SeatAddonDefinition, type SeverityLevel, type SignatureElement, type SingleChoiceElement, type SkinCharacteristics, type SkinConditionEntry, type SkinConditionType, type SkinElasticityLevel, type SkinHydrationLevel, type SkinQualityAssessment, type SkinQualityAssessmentStatus, type SkinQualityScales, type SkinSensitivityLevel, type SkinTextureLevel, type SkinZone, type SkinZoneAssessment, type SmokingStatus, type StaffDisplayInfo, StaffInviteStatus, type StoredCancellationMetrics, type StoredClinicAnalytics, type StoredDashboardAnalytics, type StoredNoShowMetrics, type StoredPractitionerAnalytics, type StoredProcedureAnalytics, type StoredRevenueMetrics, type StoredTimeEfficiencyMetrics, type StripeTransactionData, type Subcategory, SubcategoryService, SubscriptionModel, SubscriptionStatus, type SupportedLanguage, type SurgicalSiteAssessment, type SyncedCalendar, type SyncedCalendarEvent, SyncedCalendarProvider, SyncedCalendarsService, TIER_CONFIG, TIME_EFFICIENCY_ANALYTICS_SUBCOLLECTION, type Technology, type TechnologyDocumentationTemplate, TechnologyService, type TextInputElement, type TierConfig, type TierDefinition, TierLimitError, type TierLimits, type TimeEfficiencyMetrics, type TimeSlot, TimeUnit, type TissueQualityLevel, TreatmentBenefit, type TreatmentBenefitDynamic, type TreatmentRelevance, type TrendPeriod, USERS_COLLECTION, USER_FORMS_SUBCOLLECTION, type UpdateAestheticAnalysisData, type UpdateAllergyData, type UpdateAppointmentData, type UpdateAppointmentParams, type UpdateBlockingConditionData, type UpdateBlockingEventParams, type UpdateBodyAssessmentData, type UpdateCalendarEventData, type UpdateClinicAdminData, type UpdateClinicData, type UpdateClinicGroupData, type UpdateContraindicationData, type UpdateDocumentTemplateData, type UpdateHairScalpAssessmentData, type UpdateMedicationData, type UpdatePatientLocationInfoData, type UpdatePatientMedicalInfoData, type UpdatePatientProfileData, type UpdatePatientSensitiveInfoData, type UpdatePractitionerData, type UpdatePractitionerInviteData, type UpdatePreSurgicalAssessmentData, type UpdateProcedureData, type UpdateResourceBlockingEventParams, type UpdateResourceData, type UpdateSkinQualityAssessmentData, type UpdateSyncedCalendarData, type UpdateVitalStatsData, type User, UserRole, UserService, type VitalStats, type WorkingHours, type ZoneItemData, type ZonePhotoUploadData, enforceBranchLimit, enforceProcedureLimit, enforceProviderLimit, getEffectiveTier, getFirebaseApp, getFirebaseAuth, getFirebaseDB, getFirebaseFunctions, getFirebaseInstance, getFirebaseStorage, initializeFirebase, resolveEffectiveTier };
package/dist/index.js CHANGED
@@ -24024,8 +24024,7 @@ var ProcedureService = class extends BaseService {
24024
24024
  async getProceduresByClinicBranch(clinicBranchId, excludeDraftPractitioners = false) {
24025
24025
  const q = (0, import_firestore64.query)(
24026
24026
  (0, import_firestore64.collection)(this.db, PROCEDURES_COLLECTION),
24027
- (0, import_firestore64.where)("clinicBranchId", "==", clinicBranchId),
24028
- (0, import_firestore64.where)("isActive", "==", true)
24027
+ (0, import_firestore64.where)("clinicBranchId", "==", clinicBranchId)
24029
24028
  );
24030
24029
  const snapshot = await (0, import_firestore64.getDocs)(q);
24031
24030
  const procedures = snapshot.docs.map((doc54) => doc54.data());
@@ -24110,6 +24109,8 @@ var ProcedureService = class extends BaseService {
24110
24109
  updatedProcedureData.duration = validatedData.duration;
24111
24110
  if (validatedData.isActive !== void 0)
24112
24111
  updatedProcedureData.isActive = validatedData.isActive;
24112
+ if (validatedData.resourceRequirements !== void 0)
24113
+ updatedProcedureData.resourceRequirements = validatedData.resourceRequirements;
24113
24114
  let practitionerChanged = false;
24114
24115
  let clinicChanged = false;
24115
24116
  const oldPractitionerId = existingProcedure.practitionerId;
@@ -24243,9 +24244,65 @@ var ProcedureService = class extends BaseService {
24243
24244
  });
24244
24245
  }
24245
24246
  /**
24246
- * Deletes a procedure permanently
24247
- * @param id - The ID of the procedure to delete
24248
- * @returns A boolean indicating if the deletion was successful
24247
+ * Reactivates a previously deactivated procedure
24248
+ */
24249
+ async reactivateProcedure(id) {
24250
+ const procedureRef = (0, import_firestore64.doc)(this.db, PROCEDURES_COLLECTION, id);
24251
+ const procedureSnap = await (0, import_firestore64.getDoc)(procedureRef);
24252
+ if (!procedureSnap.exists()) {
24253
+ console.warn(`Procedure ${id} not found for reactivation.`);
24254
+ return;
24255
+ }
24256
+ await (0, import_firestore64.updateDoc)(procedureRef, {
24257
+ isActive: true,
24258
+ updatedAt: (0, import_firestore64.serverTimestamp)()
24259
+ });
24260
+ }
24261
+ /**
24262
+ * Checks if a procedure has ever been used in any appointment
24263
+ * by querying the "calendar" collection group for events with this procedureId.
24264
+ */
24265
+ async procedureHasBeenUsed(procedureId) {
24266
+ const calendarQuery = (0, import_firestore64.query)(
24267
+ (0, import_firestore64.collectionGroup)(this.db, "calendar"),
24268
+ (0, import_firestore64.where)("procedureId", "==", procedureId),
24269
+ (0, import_firestore64.limit)(1)
24270
+ );
24271
+ const snapshot = await (0, import_firestore64.getDocs)(calendarQuery);
24272
+ return !snapshot.empty;
24273
+ }
24274
+ /**
24275
+ * Gathers info needed by the deletion UI: whether the procedure was used,
24276
+ * how many future appointments exist, and how many resources are linked.
24277
+ */
24278
+ async getProcedureDeletionInfo(procedureId) {
24279
+ var _a;
24280
+ const procedureRef = (0, import_firestore64.doc)(this.db, PROCEDURES_COLLECTION, procedureId);
24281
+ const procedureSnap = await (0, import_firestore64.getDoc)(procedureRef);
24282
+ if (!procedureSnap.exists()) {
24283
+ return { hasBeenUsed: false, futureAppointmentCount: 0, linkedResourceCount: 0 };
24284
+ }
24285
+ const procedure = procedureSnap.data();
24286
+ const hasBeenUsed = await this.procedureHasBeenUsed(procedureId);
24287
+ let futureAppointmentCount = 0;
24288
+ if (hasBeenUsed) {
24289
+ const now = import_firestore64.Timestamp.now();
24290
+ const futureQuery = (0, import_firestore64.query)(
24291
+ (0, import_firestore64.collectionGroup)(this.db, "calendar"),
24292
+ (0, import_firestore64.where)("procedureId", "==", procedureId),
24293
+ (0, import_firestore64.where)("eventTime.start", ">", now)
24294
+ );
24295
+ const futureSnap = await (0, import_firestore64.getDocs)(futureQuery);
24296
+ futureAppointmentCount = futureSnap.size;
24297
+ }
24298
+ const linkedResourceCount = ((_a = procedure.resourceRequirements) == null ? void 0 : _a.length) || 0;
24299
+ return { hasBeenUsed, futureAppointmentCount, linkedResourceCount };
24300
+ }
24301
+ /**
24302
+ * Permanently deletes a procedure that has never been used in any appointment.
24303
+ * Throws if the procedure has appointment history.
24304
+ * The onDeleteProcedure Cloud Function trigger handles all cleanup
24305
+ * (calendar events, practitioner/clinic aggregations, resource links).
24249
24306
  */
24250
24307
  async deleteProcedure(id) {
24251
24308
  const procedureRef = (0, import_firestore64.doc)(this.db, PROCEDURES_COLLECTION, id);
@@ -24253,6 +24310,12 @@ var ProcedureService = class extends BaseService {
24253
24310
  if (!procedureSnapshot.exists()) {
24254
24311
  return false;
24255
24312
  }
24313
+ const hasBeenUsed = await this.procedureHasBeenUsed(id);
24314
+ if (hasBeenUsed) {
24315
+ throw new Error(
24316
+ "Cannot permanently delete a procedure that has appointment history. Use deactivation instead."
24317
+ );
24318
+ }
24256
24319
  await (0, import_firestore64.deleteDoc)(procedureRef);
24257
24320
  return true;
24258
24321
  }
package/dist/index.mjs CHANGED
@@ -23278,7 +23278,8 @@ import {
23278
23278
  orderBy as orderBy19,
23279
23279
  limit as limit17,
23280
23280
  startAfter as startAfter14,
23281
- documentId as documentId2
23281
+ documentId as documentId2,
23282
+ collectionGroup as collectionGroup3
23282
23283
  } from "firebase/firestore";
23283
23284
 
23284
23285
  // src/validations/procedure.schema.ts
@@ -24243,8 +24244,7 @@ var ProcedureService = class extends BaseService {
24243
24244
  async getProceduresByClinicBranch(clinicBranchId, excludeDraftPractitioners = false) {
24244
24245
  const q = query34(
24245
24246
  collection34(this.db, PROCEDURES_COLLECTION),
24246
- where34("clinicBranchId", "==", clinicBranchId),
24247
- where34("isActive", "==", true)
24247
+ where34("clinicBranchId", "==", clinicBranchId)
24248
24248
  );
24249
24249
  const snapshot = await getDocs34(q);
24250
24250
  const procedures = snapshot.docs.map((doc54) => doc54.data());
@@ -24329,6 +24329,8 @@ var ProcedureService = class extends BaseService {
24329
24329
  updatedProcedureData.duration = validatedData.duration;
24330
24330
  if (validatedData.isActive !== void 0)
24331
24331
  updatedProcedureData.isActive = validatedData.isActive;
24332
+ if (validatedData.resourceRequirements !== void 0)
24333
+ updatedProcedureData.resourceRequirements = validatedData.resourceRequirements;
24332
24334
  let practitionerChanged = false;
24333
24335
  let clinicChanged = false;
24334
24336
  const oldPractitionerId = existingProcedure.practitionerId;
@@ -24462,9 +24464,65 @@ var ProcedureService = class extends BaseService {
24462
24464
  });
24463
24465
  }
24464
24466
  /**
24465
- * Deletes a procedure permanently
24466
- * @param id - The ID of the procedure to delete
24467
- * @returns A boolean indicating if the deletion was successful
24467
+ * Reactivates a previously deactivated procedure
24468
+ */
24469
+ async reactivateProcedure(id) {
24470
+ const procedureRef = doc45(this.db, PROCEDURES_COLLECTION, id);
24471
+ const procedureSnap = await getDoc46(procedureRef);
24472
+ if (!procedureSnap.exists()) {
24473
+ console.warn(`Procedure ${id} not found for reactivation.`);
24474
+ return;
24475
+ }
24476
+ await updateDoc40(procedureRef, {
24477
+ isActive: true,
24478
+ updatedAt: serverTimestamp35()
24479
+ });
24480
+ }
24481
+ /**
24482
+ * Checks if a procedure has ever been used in any appointment
24483
+ * by querying the "calendar" collection group for events with this procedureId.
24484
+ */
24485
+ async procedureHasBeenUsed(procedureId) {
24486
+ const calendarQuery = query34(
24487
+ collectionGroup3(this.db, "calendar"),
24488
+ where34("procedureId", "==", procedureId),
24489
+ limit17(1)
24490
+ );
24491
+ const snapshot = await getDocs34(calendarQuery);
24492
+ return !snapshot.empty;
24493
+ }
24494
+ /**
24495
+ * Gathers info needed by the deletion UI: whether the procedure was used,
24496
+ * how many future appointments exist, and how many resources are linked.
24497
+ */
24498
+ async getProcedureDeletionInfo(procedureId) {
24499
+ var _a;
24500
+ const procedureRef = doc45(this.db, PROCEDURES_COLLECTION, procedureId);
24501
+ const procedureSnap = await getDoc46(procedureRef);
24502
+ if (!procedureSnap.exists()) {
24503
+ return { hasBeenUsed: false, futureAppointmentCount: 0, linkedResourceCount: 0 };
24504
+ }
24505
+ const procedure = procedureSnap.data();
24506
+ const hasBeenUsed = await this.procedureHasBeenUsed(procedureId);
24507
+ let futureAppointmentCount = 0;
24508
+ if (hasBeenUsed) {
24509
+ const now = Timestamp36.now();
24510
+ const futureQuery = query34(
24511
+ collectionGroup3(this.db, "calendar"),
24512
+ where34("procedureId", "==", procedureId),
24513
+ where34("eventTime.start", ">", now)
24514
+ );
24515
+ const futureSnap = await getDocs34(futureQuery);
24516
+ futureAppointmentCount = futureSnap.size;
24517
+ }
24518
+ const linkedResourceCount = ((_a = procedure.resourceRequirements) == null ? void 0 : _a.length) || 0;
24519
+ return { hasBeenUsed, futureAppointmentCount, linkedResourceCount };
24520
+ }
24521
+ /**
24522
+ * Permanently deletes a procedure that has never been used in any appointment.
24523
+ * Throws if the procedure has appointment history.
24524
+ * The onDeleteProcedure Cloud Function trigger handles all cleanup
24525
+ * (calendar events, practitioner/clinic aggregations, resource links).
24468
24526
  */
24469
24527
  async deleteProcedure(id) {
24470
24528
  const procedureRef = doc45(this.db, PROCEDURES_COLLECTION, id);
@@ -24472,6 +24530,12 @@ var ProcedureService = class extends BaseService {
24472
24530
  if (!procedureSnapshot.exists()) {
24473
24531
  return false;
24474
24532
  }
24533
+ const hasBeenUsed = await this.procedureHasBeenUsed(id);
24534
+ if (hasBeenUsed) {
24535
+ throw new Error(
24536
+ "Cannot permanently delete a procedure that has appointment history. Use deactivation instead."
24537
+ );
24538
+ }
24475
24539
  await deleteDoc19(procedureRef);
24476
24540
  return true;
24477
24541
  }
@@ -26943,7 +27007,7 @@ var CategoryService = class extends BaseService {
26943
27007
  import {
26944
27008
  addDoc as addDoc6,
26945
27009
  collection as collection39,
26946
- collectionGroup as collectionGroup3,
27010
+ collectionGroup as collectionGroup4,
26947
27011
  deleteDoc as deleteDoc22,
26948
27012
  doc as doc50,
26949
27013
  getDoc as getDoc51,
@@ -27066,7 +27130,7 @@ var SubcategoryService = class extends BaseService {
27066
27130
  lastVisible ? startAfter17(lastVisible) : void 0
27067
27131
  ].filter((c) => !!c);
27068
27132
  const q = query39(
27069
- collectionGroup3(this.db, SUBCATEGORIES_COLLECTION),
27133
+ collectionGroup4(this.db, SUBCATEGORIES_COLLECTION),
27070
27134
  ...constraints
27071
27135
  );
27072
27136
  const querySnapshot = await getDocs39(q);
@@ -27105,7 +27169,7 @@ var SubcategoryService = class extends BaseService {
27105
27169
  */
27106
27170
  async getAllForFilter() {
27107
27171
  const q = query39(
27108
- collectionGroup3(this.db, SUBCATEGORIES_COLLECTION),
27172
+ collectionGroup4(this.db, SUBCATEGORIES_COLLECTION),
27109
27173
  where39("isActive", "==", true)
27110
27174
  );
27111
27175
  const querySnapshot = await getDocs39(q);
@@ -27261,7 +27325,7 @@ var SubcategoryService = class extends BaseService {
27261
27325
  const queryConstraints = [...constraints, limit20(PAGE_SIZE)];
27262
27326
  if (cursor) queryConstraints.push(startAfter17(cursor));
27263
27327
  const q = query39(
27264
- collectionGroup3(this.db, SUBCATEGORIES_COLLECTION),
27328
+ collectionGroup4(this.db, SUBCATEGORIES_COLLECTION),
27265
27329
  ...queryConstraints
27266
27330
  );
27267
27331
  const snapshot = await getDocs39(q);
@@ -28224,7 +28288,7 @@ var TechnologyService = class extends BaseService {
28224
28288
  import {
28225
28289
  addDoc as addDoc8,
28226
28290
  collection as collection41,
28227
- collectionGroup as collectionGroup4,
28291
+ collectionGroup as collectionGroup5,
28228
28292
  doc as doc52,
28229
28293
  getDoc as getDoc53,
28230
28294
  getDocs as getDocs41,
@@ -28291,7 +28355,7 @@ var ProductService = class extends BaseService {
28291
28355
  constraints.push(startAfter19(lastVisible));
28292
28356
  }
28293
28357
  constraints.push(limit22(rowsPerPage));
28294
- const q = query41(collectionGroup4(this.db, PRODUCTS_COLLECTION), ...constraints);
28358
+ const q = query41(collectionGroup5(this.db, PRODUCTS_COLLECTION), ...constraints);
28295
28359
  const snapshot = await getDocs41(q);
28296
28360
  const products = snapshot.docs.map(
28297
28361
  (doc54) => ({
@@ -28317,7 +28381,7 @@ var ProductService = class extends BaseService {
28317
28381
  if (technologyId) {
28318
28382
  constraints.push(where41("technologyId", "==", technologyId));
28319
28383
  }
28320
- const q = query41(collectionGroup4(this.db, PRODUCTS_COLLECTION), ...constraints);
28384
+ const q = query41(collectionGroup5(this.db, PRODUCTS_COLLECTION), ...constraints);
28321
28385
  const snapshot = await getCountFromServer7(q);
28322
28386
  return snapshot.data().count;
28323
28387
  }
@@ -28331,7 +28395,7 @@ var ProductService = class extends BaseService {
28331
28395
  bySubcategory: {},
28332
28396
  byTechnology: {}
28333
28397
  };
28334
- const q = query41(collectionGroup4(this.db, PRODUCTS_COLLECTION), where41("isActive", "==", true));
28398
+ const q = query41(collectionGroup5(this.db, PRODUCTS_COLLECTION), where41("isActive", "==", true));
28335
28399
  const snapshot = await getDocs41(q);
28336
28400
  snapshot.docs.forEach((doc54) => {
28337
28401
  const product = doc54.data();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.15.17-staging.10",
4
+ "version": "1.15.17-staging.12",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -20,6 +20,7 @@ import {
20
20
  startAfter,
21
21
  QueryConstraint,
22
22
  documentId,
23
+ collectionGroup,
23
24
  } from 'firebase/firestore';
24
25
  import { BaseService } from '../base.service';
25
26
  import { enforceProcedureLimit } from '../tier-enforcement';
@@ -29,6 +30,7 @@ import {
29
30
  UpdateProcedureData,
30
31
  PROCEDURES_COLLECTION,
31
32
  ProcedureSummaryInfo,
33
+ ProcedureDeletionInfo,
32
34
  } from '../../types/procedure';
33
35
  import { createProcedureSchema, updateProcedureSchema } from '../../validations/procedure.schema';
34
36
  import { z } from 'zod';
@@ -1128,7 +1130,6 @@ export class ProcedureService extends BaseService {
1128
1130
  const q = query(
1129
1131
  collection(this.db, PROCEDURES_COLLECTION),
1130
1132
  where('clinicBranchId', '==', clinicBranchId),
1131
- where('isActive', '==', true),
1132
1133
  );
1133
1134
  const snapshot = await getDocs(q);
1134
1135
  const procedures = snapshot.docs.map(doc => doc.data() as Procedure);
@@ -1232,6 +1233,8 @@ export class ProcedureService extends BaseService {
1232
1233
  updatedProcedureData.duration = validatedData.duration;
1233
1234
  if (validatedData.isActive !== undefined)
1234
1235
  updatedProcedureData.isActive = validatedData.isActive;
1236
+ if (validatedData.resourceRequirements !== undefined)
1237
+ updatedProcedureData.resourceRequirements = validatedData.resourceRequirements;
1235
1238
 
1236
1239
  let practitionerChanged = false;
1237
1240
  let clinicChanged = false;
@@ -1405,20 +1408,91 @@ export class ProcedureService extends BaseService {
1405
1408
  }
1406
1409
 
1407
1410
  /**
1408
- * Deletes a procedure permanently
1409
- * @param id - The ID of the procedure to delete
1410
- * @returns A boolean indicating if the deletion was successful
1411
+ * Reactivates a previously deactivated procedure
1412
+ */
1413
+ async reactivateProcedure(id: string): Promise<void> {
1414
+ const procedureRef = doc(this.db, PROCEDURES_COLLECTION, id);
1415
+ const procedureSnap = await getDoc(procedureRef);
1416
+ if (!procedureSnap.exists()) {
1417
+ console.warn(`Procedure ${id} not found for reactivation.`);
1418
+ return;
1419
+ }
1420
+
1421
+ await updateDoc(procedureRef, {
1422
+ isActive: true,
1423
+ updatedAt: serverTimestamp(),
1424
+ });
1425
+ }
1426
+
1427
+ /**
1428
+ * Checks if a procedure has ever been used in any appointment
1429
+ * by querying the "calendar" collection group for events with this procedureId.
1430
+ */
1431
+ async procedureHasBeenUsed(procedureId: string): Promise<boolean> {
1432
+ const calendarQuery = query(
1433
+ collectionGroup(this.db, 'calendar'),
1434
+ where('procedureId', '==', procedureId),
1435
+ limit(1)
1436
+ );
1437
+ const snapshot = await getDocs(calendarQuery);
1438
+ return !snapshot.empty;
1439
+ }
1440
+
1441
+ /**
1442
+ * Gathers info needed by the deletion UI: whether the procedure was used,
1443
+ * how many future appointments exist, and how many resources are linked.
1444
+ */
1445
+ async getProcedureDeletionInfo(procedureId: string): Promise<ProcedureDeletionInfo> {
1446
+ const procedureRef = doc(this.db, PROCEDURES_COLLECTION, procedureId);
1447
+ const procedureSnap = await getDoc(procedureRef);
1448
+
1449
+ if (!procedureSnap.exists()) {
1450
+ return { hasBeenUsed: false, futureAppointmentCount: 0, linkedResourceCount: 0 };
1451
+ }
1452
+
1453
+ const procedure = procedureSnap.data() as Procedure;
1454
+ const hasBeenUsed = await this.procedureHasBeenUsed(procedureId);
1455
+
1456
+ // Count future calendar events for this procedure
1457
+ let futureAppointmentCount = 0;
1458
+ if (hasBeenUsed) {
1459
+ const now = Timestamp.now();
1460
+ const futureQuery = query(
1461
+ collectionGroup(this.db, 'calendar'),
1462
+ where('procedureId', '==', procedureId),
1463
+ where('eventTime.start', '>', now)
1464
+ );
1465
+ const futureSnap = await getDocs(futureQuery);
1466
+ futureAppointmentCount = futureSnap.size;
1467
+ }
1468
+
1469
+ const linkedResourceCount = procedure.resourceRequirements?.length || 0;
1470
+
1471
+ return { hasBeenUsed, futureAppointmentCount, linkedResourceCount };
1472
+ }
1473
+
1474
+ /**
1475
+ * Permanently deletes a procedure that has never been used in any appointment.
1476
+ * Throws if the procedure has appointment history.
1477
+ * The onDeleteProcedure Cloud Function trigger handles all cleanup
1478
+ * (calendar events, practitioner/clinic aggregations, resource links).
1411
1479
  */
1412
1480
  async deleteProcedure(id: string): Promise<boolean> {
1413
1481
  const procedureRef = doc(this.db, PROCEDURES_COLLECTION, id);
1414
1482
  const procedureSnapshot = await getDoc(procedureRef);
1415
1483
 
1416
1484
  if (!procedureSnapshot.exists()) {
1417
- // Already deleted or never existed
1418
1485
  return false;
1419
1486
  }
1420
1487
 
1421
- // Delete the procedure document
1488
+ // Guard: only allow hard delete if procedure was never used
1489
+ const hasBeenUsed = await this.procedureHasBeenUsed(id);
1490
+ if (hasBeenUsed) {
1491
+ throw new Error(
1492
+ 'Cannot permanently delete a procedure that has appointment history. Use deactivation instead.'
1493
+ );
1494
+ }
1495
+
1422
1496
  await deleteDoc(procedureRef);
1423
1497
  return true;
1424
1498
  }
@@ -155,6 +155,15 @@ export interface UpdateProcedureData {
155
155
  resourceRequirements?: ResourceRequirement[];
156
156
  }
157
157
 
158
+ /**
159
+ * Info returned by getProcedureDeletionInfo() to drive the deletion UI.
160
+ */
161
+ export interface ProcedureDeletionInfo {
162
+ hasBeenUsed: boolean;
163
+ futureAppointmentCount: number;
164
+ linkedResourceCount: number;
165
+ }
166
+
158
167
  /**
159
168
  * Collection name for procedures in Firestore
160
169
  */