@blackcode_sa/metaestetics-api 1.12.2 → 1.12.4

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.js CHANGED
@@ -37,6 +37,7 @@ __export(index_exports, {
37
37
  AppointmentStatus: () => AppointmentStatus,
38
38
  AuthService: () => AuthService,
39
39
  BaseService: () => BaseService,
40
+ BillingTransactionType: () => BillingTransactionType,
40
41
  BlockingCondition: () => BlockingCondition,
41
42
  BrandService: () => BrandService,
42
43
  CALENDAR_COLLECTION: () => CALENDAR_COLLECTION,
@@ -120,6 +121,7 @@ __export(index_exports, {
120
121
  SearchLocationEnum: () => SearchLocationEnum,
121
122
  SubcategoryService: () => SubcategoryService,
122
123
  SubscriptionModel: () => SubscriptionModel,
124
+ SubscriptionStatus: () => SubscriptionStatus,
123
125
  SyncedCalendarProvider: () => SyncedCalendarProvider,
124
126
  SyncedCalendarsService: () => SyncedCalendarsService,
125
127
  TechnologyService: () => TechnologyService,
@@ -888,6 +890,23 @@ var SubscriptionModel = /* @__PURE__ */ ((SubscriptionModel2) => {
888
890
  SubscriptionModel2["ENTERPRISE"] = "enterprise";
889
891
  return SubscriptionModel2;
890
892
  })(SubscriptionModel || {});
893
+ var SubscriptionStatus = /* @__PURE__ */ ((SubscriptionStatus2) => {
894
+ SubscriptionStatus2["ACTIVE"] = "active";
895
+ SubscriptionStatus2["PENDING_CANCELLATION"] = "pending_cancellation";
896
+ SubscriptionStatus2["CANCELED"] = "canceled";
897
+ SubscriptionStatus2["PAST_DUE"] = "past_due";
898
+ SubscriptionStatus2["TRIALING"] = "trialing";
899
+ return SubscriptionStatus2;
900
+ })(SubscriptionStatus || {});
901
+ var BillingTransactionType = /* @__PURE__ */ ((BillingTransactionType2) => {
902
+ BillingTransactionType2["SUBSCRIPTION_ACTIVATED"] = "subscription_activated";
903
+ BillingTransactionType2["SUBSCRIPTION_RENEWED"] = "subscription_renewed";
904
+ BillingTransactionType2["SUBSCRIPTION_UPDATED"] = "subscription_updated";
905
+ BillingTransactionType2["SUBSCRIPTION_CANCELED"] = "subscription_canceled";
906
+ BillingTransactionType2["SUBSCRIPTION_REACTIVATED"] = "subscription_reactivated";
907
+ BillingTransactionType2["SUBSCRIPTION_DELETED"] = "subscription_deleted";
908
+ return BillingTransactionType2;
909
+ })(BillingTransactionType || {});
891
910
 
892
911
  // src/types/patient/medical-info.types.ts
893
912
  var PATIENT_MEDICAL_INFO_COLLECTION = "medical_info";
@@ -3508,6 +3527,50 @@ var adminTokenSchema = import_zod10.z.object({
3508
3527
  expiresAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp))
3509
3528
  // Timestamp
3510
3529
  });
3530
+ var stripeTransactionDataSchema = import_zod10.z.object({
3531
+ sessionId: import_zod10.z.string().optional(),
3532
+ subscriptionId: import_zod10.z.string().optional(),
3533
+ invoiceId: import_zod10.z.string().optional(),
3534
+ priceId: import_zod10.z.string(),
3535
+ customerId: import_zod10.z.string()
3536
+ });
3537
+ var planDetailsSchema = import_zod10.z.object({
3538
+ planName: import_zod10.z.string(),
3539
+ planPeriod: import_zod10.z.string(),
3540
+ planDisplayName: import_zod10.z.string()
3541
+ });
3542
+ var billingInfoSchema = import_zod10.z.object({
3543
+ stripeCustomerId: import_zod10.z.string(),
3544
+ subscriptionStatus: import_zod10.z.nativeEnum(SubscriptionStatus),
3545
+ planType: import_zod10.z.string(),
3546
+ stripeSubscriptionId: import_zod10.z.string().nullable(),
3547
+ stripePriceId: import_zod10.z.string().nullable(),
3548
+ currentPeriodStart: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)).nullable(),
3549
+ currentPeriodEnd: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)).nullable(),
3550
+ updatedAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp))
3551
+ });
3552
+ var billingTransactionSchema = import_zod10.z.object({
3553
+ id: import_zod10.z.string(),
3554
+ clinicGroupId: import_zod10.z.string(),
3555
+ type: import_zod10.z.nativeEnum(BillingTransactionType),
3556
+ description: import_zod10.z.string(),
3557
+ amount: import_zod10.z.number(),
3558
+ currency: import_zod10.z.string(),
3559
+ stripeData: stripeTransactionDataSchema,
3560
+ planDetails: planDetailsSchema,
3561
+ metadata: import_zod10.z.record(import_zod10.z.any()).optional(),
3562
+ timestamp: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp)),
3563
+ createdAt: import_zod10.z.instanceof(Date).or(import_zod10.z.instanceof(import_firestore9.Timestamp))
3564
+ });
3565
+ var createBillingTransactionSchema = import_zod10.z.object({
3566
+ type: import_zod10.z.nativeEnum(BillingTransactionType),
3567
+ description: import_zod10.z.string(),
3568
+ amount: import_zod10.z.number(),
3569
+ currency: import_zod10.z.string(),
3570
+ stripeData: stripeTransactionDataSchema,
3571
+ planDetails: planDetailsSchema,
3572
+ metadata: import_zod10.z.record(import_zod10.z.any()).optional()
3573
+ });
3511
3574
  var createAdminTokenSchema = import_zod10.z.object({
3512
3575
  expiresInDays: import_zod10.z.number().min(1).max(30).optional(),
3513
3576
  email: import_zod10.z.string().email().optional().nullable()
@@ -3534,6 +3597,7 @@ var clinicGroupSchema = import_zod10.z.object({
3534
3597
  practiceType: import_zod10.z.nativeEnum(PracticeType).optional(),
3535
3598
  languages: import_zod10.z.array(import_zod10.z.nativeEnum(Language)).optional(),
3536
3599
  subscriptionModel: import_zod10.z.nativeEnum(SubscriptionModel),
3600
+ billing: billingInfoSchema.optional(),
3537
3601
  calendarSyncEnabled: import_zod10.z.boolean().optional(),
3538
3602
  autoConfirmAppointments: import_zod10.z.boolean().optional(),
3539
3603
  businessIdentificationNumber: import_zod10.z.string().optional().nullable(),
@@ -3599,6 +3663,7 @@ var createClinicGroupSchema = import_zod10.z.object({
3599
3663
  practiceType: import_zod10.z.nativeEnum(PracticeType).optional(),
3600
3664
  languages: import_zod10.z.array(import_zod10.z.nativeEnum(Language)).optional(),
3601
3665
  subscriptionModel: import_zod10.z.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
3666
+ billing: billingInfoSchema.optional(),
3602
3667
  calendarSyncEnabled: import_zod10.z.boolean().optional(),
3603
3668
  autoConfirmAppointments: import_zod10.z.boolean().optional(),
3604
3669
  businessIdentificationNumber: import_zod10.z.string().optional().nullable(),
@@ -16544,6 +16609,26 @@ var CategoryService = class extends BaseService {
16544
16609
  })
16545
16610
  );
16546
16611
  }
16612
+ /**
16613
+ * Vraća sve kategorije za određenu familiju za potrebe filtera (bez paginacije)
16614
+ * @param family - Familija procedura (aesthetics/surgery)
16615
+ * @returns Lista aktivnih kategorija koje pripadaju traženoj familiji
16616
+ */
16617
+ async getAllForFilterByFamily(family) {
16618
+ const q = (0, import_firestore50.query)(
16619
+ this.categoriesRef,
16620
+ (0, import_firestore50.where)("family", "==", family),
16621
+ (0, import_firestore50.where)("isActive", "==", true),
16622
+ (0, import_firestore50.orderBy)("name")
16623
+ );
16624
+ const snapshot = await (0, import_firestore50.getDocs)(q);
16625
+ return snapshot.docs.map(
16626
+ (doc38) => ({
16627
+ id: doc38.id,
16628
+ ...doc38.data()
16629
+ })
16630
+ );
16631
+ }
16547
16632
  /**
16548
16633
  * Vraća sve kategorije sa paginacijom
16549
16634
  * @param options - Pagination and filter options
@@ -17177,7 +17262,9 @@ var TechnologyService = class extends BaseService {
17177
17262
  if (!technology) {
17178
17263
  throw new Error(`Technology with id ${technologyId} not found`);
17179
17264
  }
17180
- const updatedContraindications = (technology.contraindications || []).filter((c) => c.id !== contraindication.id);
17265
+ const updatedContraindications = (technology.contraindications || []).filter(
17266
+ (c) => c.id !== contraindication.id
17267
+ );
17181
17268
  await (0, import_firestore52.updateDoc)(docRef, {
17182
17269
  contraindications: updatedContraindications,
17183
17270
  updatedAt: /* @__PURE__ */ new Date()
@@ -17198,9 +17285,7 @@ var TechnologyService = class extends BaseService {
17198
17285
  throw new Error(`Technology with id ${technologyId} not found`);
17199
17286
  }
17200
17287
  const contraindications = technology.contraindications || [];
17201
- const index = contraindications.findIndex(
17202
- (c) => c.id === contraindication.id
17203
- );
17288
+ const index = contraindications.findIndex((c) => c.id === contraindication.id);
17204
17289
  if (index === -1) {
17205
17290
  console.warn(
17206
17291
  `Contraindication with id ${contraindication.id} not found for technology ${technologyId}. No update performed.`
@@ -17249,9 +17334,7 @@ var TechnologyService = class extends BaseService {
17249
17334
  if (!technology) {
17250
17335
  throw new Error(`Technology with id ${technologyId} not found`);
17251
17336
  }
17252
- const updatedBenefits = (technology.benefits || []).filter(
17253
- (b) => b.id !== benefit.id
17254
- );
17337
+ const updatedBenefits = (technology.benefits || []).filter((b) => b.id !== benefit.id);
17255
17338
  await (0, import_firestore52.updateDoc)(docRef, {
17256
17339
  benefits: updatedBenefits,
17257
17340
  updatedAt: /* @__PURE__ */ new Date()
@@ -17357,9 +17440,7 @@ var TechnologyService = class extends BaseService {
17357
17440
  * );
17358
17441
  */
17359
17442
  validateCertification(requiredCertification, practitionerCertification) {
17360
- const doctorLevel = Object.values(CertificationLevel).indexOf(
17361
- practitionerCertification.level
17362
- );
17443
+ const doctorLevel = Object.values(CertificationLevel).indexOf(practitionerCertification.level);
17363
17444
  const requiredLevel = Object.values(CertificationLevel).indexOf(
17364
17445
  requiredCertification.minimumLevel
17365
17446
  );
@@ -17400,18 +17481,11 @@ var TechnologyService = class extends BaseService {
17400
17481
  async getAllowedTechnologies(practitioner) {
17401
17482
  const allTechnologies = await this.getAll();
17402
17483
  const allowedTechnologies = allTechnologies.technologies.filter(
17403
- (technology) => this.validateCertification(
17404
- technology.certificationRequirement,
17405
- practitioner.certification
17406
- )
17484
+ (technology) => this.validateCertification(technology.certificationRequirement, practitioner.certification)
17407
17485
  );
17408
17486
  const families = [...new Set(allowedTechnologies.map((t) => t.family))];
17409
- const categories = [
17410
- ...new Set(allowedTechnologies.map((t) => t.categoryId))
17411
- ];
17412
- const subcategories = [
17413
- ...new Set(allowedTechnologies.map((t) => t.subcategoryId))
17414
- ];
17487
+ const categories = [...new Set(allowedTechnologies.map((t) => t.categoryId))];
17488
+ const subcategories = [...new Set(allowedTechnologies.map((t) => t.subcategoryId))];
17415
17489
  return {
17416
17490
  technologies: allowedTechnologies,
17417
17491
  families,
@@ -17419,6 +17493,25 @@ var TechnologyService = class extends BaseService {
17419
17493
  subcategories
17420
17494
  };
17421
17495
  }
17496
+ /**
17497
+ * Gets all active technologies for a subcategory for filter dropdowns (by subcategory only).
17498
+ * @param subcategoryId - The ID of the subcategory.
17499
+ */
17500
+ async getAllForFilterBySubcategory(subcategoryId) {
17501
+ const q = (0, import_firestore52.query)(
17502
+ (0, import_firestore52.collection)(this.db, TECHNOLOGIES_COLLECTION),
17503
+ (0, import_firestore52.where)("isActive", "==", true),
17504
+ (0, import_firestore52.where)("subcategoryId", "==", subcategoryId),
17505
+ (0, import_firestore52.orderBy)("name")
17506
+ );
17507
+ const snapshot = await (0, import_firestore52.getDocs)(q);
17508
+ return snapshot.docs.map(
17509
+ (doc38) => ({
17510
+ id: doc38.id,
17511
+ ...doc38.data()
17512
+ })
17513
+ );
17514
+ }
17422
17515
  /**
17423
17516
  * Gets all active technologies for a subcategory for filter dropdowns.
17424
17517
  * @param categoryId - The ID of the parent category.
@@ -17473,12 +17566,7 @@ var ProductService = class extends BaseService {
17473
17566
  * @returns Firestore collection reference
17474
17567
  */
17475
17568
  getProductsRef(technologyId) {
17476
- return (0, import_firestore53.collection)(
17477
- this.db,
17478
- TECHNOLOGIES_COLLECTION,
17479
- technologyId,
17480
- PRODUCTS_COLLECTION
17481
- );
17569
+ return (0, import_firestore53.collection)(this.db, TECHNOLOGIES_COLLECTION, technologyId, PRODUCTS_COLLECTION);
17482
17570
  }
17483
17571
  /**
17484
17572
  * Creates a new product under technology
@@ -17493,10 +17581,7 @@ var ProductService = class extends BaseService {
17493
17581
  updatedAt: now,
17494
17582
  isActive: true
17495
17583
  };
17496
- const productRef = await (0, import_firestore53.addDoc)(
17497
- this.getProductsRef(technologyId),
17498
- newProduct
17499
- );
17584
+ const productRef = await (0, import_firestore53.addDoc)(this.getProductsRef(technologyId), newProduct);
17500
17585
  return { id: productRef.id, ...newProduct };
17501
17586
  }
17502
17587
  /**
@@ -17504,17 +17589,8 @@ var ProductService = class extends BaseService {
17504
17589
  * This uses a collectionGroup query to search across all technologies.
17505
17590
  */
17506
17591
  async getAll(options) {
17507
- const {
17508
- rowsPerPage,
17509
- lastVisible,
17510
- categoryId,
17511
- subcategoryId,
17512
- technologyId
17513
- } = options;
17514
- const constraints = [
17515
- (0, import_firestore53.where)("isActive", "==", true),
17516
- (0, import_firestore53.orderBy)("name")
17517
- ];
17592
+ const { rowsPerPage, lastVisible, categoryId, subcategoryId, technologyId } = options;
17593
+ const constraints = [(0, import_firestore53.where)("isActive", "==", true), (0, import_firestore53.orderBy)("name")];
17518
17594
  if (categoryId) {
17519
17595
  constraints.push((0, import_firestore53.where)("categoryId", "==", categoryId));
17520
17596
  }
@@ -17528,10 +17604,7 @@ var ProductService = class extends BaseService {
17528
17604
  constraints.push((0, import_firestore53.startAfter)(lastVisible));
17529
17605
  }
17530
17606
  constraints.push((0, import_firestore53.limit)(rowsPerPage));
17531
- const q = (0, import_firestore53.query)(
17532
- (0, import_firestore53.collectionGroup)(this.db, PRODUCTS_COLLECTION),
17533
- ...constraints
17534
- );
17607
+ const q = (0, import_firestore53.query)((0, import_firestore53.collectionGroup)(this.db, PRODUCTS_COLLECTION), ...constraints);
17535
17608
  const snapshot = await (0, import_firestore53.getDocs)(q);
17536
17609
  const products = snapshot.docs.map(
17537
17610
  (doc38) => ({
@@ -17557,10 +17630,7 @@ var ProductService = class extends BaseService {
17557
17630
  if (technologyId) {
17558
17631
  constraints.push((0, import_firestore53.where)("technologyId", "==", technologyId));
17559
17632
  }
17560
- const q = (0, import_firestore53.query)(
17561
- (0, import_firestore53.collectionGroup)(this.db, PRODUCTS_COLLECTION),
17562
- ...constraints
17563
- );
17633
+ const q = (0, import_firestore53.query)((0, import_firestore53.collectionGroup)(this.db, PRODUCTS_COLLECTION), ...constraints);
17564
17634
  const snapshot = await (0, import_firestore53.getCountFromServer)(q);
17565
17635
  return snapshot.data().count;
17566
17636
  }
@@ -17569,10 +17639,7 @@ var ProductService = class extends BaseService {
17569
17639
  * This uses a single collectionGroup query for efficiency.
17570
17640
  */
17571
17641
  async getProductCounts() {
17572
- const q = (0, import_firestore53.query)(
17573
- (0, import_firestore53.collectionGroup)(this.db, PRODUCTS_COLLECTION),
17574
- (0, import_firestore53.where)("isActive", "==", true)
17575
- );
17642
+ const q = (0, import_firestore53.query)((0, import_firestore53.collectionGroup)(this.db, PRODUCTS_COLLECTION), (0, import_firestore53.where)("isActive", "==", true));
17576
17643
  const snapshot = await (0, import_firestore53.getDocs)(q);
17577
17644
  const counts = {
17578
17645
  byCategory: {},
@@ -17597,6 +17664,23 @@ var ProductService = class extends BaseService {
17597
17664
  });
17598
17665
  return counts;
17599
17666
  }
17667
+ /**
17668
+ * Gets all products for a specific technology (non-paginated, for filters/dropdowns)
17669
+ */
17670
+ async getAllByTechnology(technologyId) {
17671
+ const q = (0, import_firestore53.query)(
17672
+ this.getProductsRef(technologyId),
17673
+ (0, import_firestore53.where)("isActive", "==", true),
17674
+ (0, import_firestore53.orderBy)("name")
17675
+ );
17676
+ const snapshot = await (0, import_firestore53.getDocs)(q);
17677
+ return snapshot.docs.map(
17678
+ (doc38) => ({
17679
+ id: doc38.id,
17680
+ ...doc38.data()
17681
+ })
17682
+ );
17683
+ }
17600
17684
  /**
17601
17685
  * Gets all products for a brand by filtering through all technologies
17602
17686
  */
@@ -17945,6 +18029,7 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
17945
18029
  AppointmentStatus,
17946
18030
  AuthService,
17947
18031
  BaseService,
18032
+ BillingTransactionType,
17948
18033
  BlockingCondition,
17949
18034
  BrandService,
17950
18035
  CALENDAR_COLLECTION,
@@ -18028,6 +18113,7 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
18028
18113
  SearchLocationEnum,
18029
18114
  SubcategoryService,
18030
18115
  SubscriptionModel,
18116
+ SubscriptionStatus,
18031
18117
  SyncedCalendarProvider,
18032
18118
  SyncedCalendarsService,
18033
18119
  TechnologyService,
package/dist/index.mjs CHANGED
@@ -772,6 +772,23 @@ var SubscriptionModel = /* @__PURE__ */ ((SubscriptionModel2) => {
772
772
  SubscriptionModel2["ENTERPRISE"] = "enterprise";
773
773
  return SubscriptionModel2;
774
774
  })(SubscriptionModel || {});
775
+ var SubscriptionStatus = /* @__PURE__ */ ((SubscriptionStatus2) => {
776
+ SubscriptionStatus2["ACTIVE"] = "active";
777
+ SubscriptionStatus2["PENDING_CANCELLATION"] = "pending_cancellation";
778
+ SubscriptionStatus2["CANCELED"] = "canceled";
779
+ SubscriptionStatus2["PAST_DUE"] = "past_due";
780
+ SubscriptionStatus2["TRIALING"] = "trialing";
781
+ return SubscriptionStatus2;
782
+ })(SubscriptionStatus || {});
783
+ var BillingTransactionType = /* @__PURE__ */ ((BillingTransactionType2) => {
784
+ BillingTransactionType2["SUBSCRIPTION_ACTIVATED"] = "subscription_activated";
785
+ BillingTransactionType2["SUBSCRIPTION_RENEWED"] = "subscription_renewed";
786
+ BillingTransactionType2["SUBSCRIPTION_UPDATED"] = "subscription_updated";
787
+ BillingTransactionType2["SUBSCRIPTION_CANCELED"] = "subscription_canceled";
788
+ BillingTransactionType2["SUBSCRIPTION_REACTIVATED"] = "subscription_reactivated";
789
+ BillingTransactionType2["SUBSCRIPTION_DELETED"] = "subscription_deleted";
790
+ return BillingTransactionType2;
791
+ })(BillingTransactionType || {});
775
792
 
776
793
  // src/types/patient/medical-info.types.ts
777
794
  var PATIENT_MEDICAL_INFO_COLLECTION = "medical_info";
@@ -3490,6 +3507,50 @@ var adminTokenSchema = z10.object({
3490
3507
  expiresAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6))
3491
3508
  // Timestamp
3492
3509
  });
3510
+ var stripeTransactionDataSchema = z10.object({
3511
+ sessionId: z10.string().optional(),
3512
+ subscriptionId: z10.string().optional(),
3513
+ invoiceId: z10.string().optional(),
3514
+ priceId: z10.string(),
3515
+ customerId: z10.string()
3516
+ });
3517
+ var planDetailsSchema = z10.object({
3518
+ planName: z10.string(),
3519
+ planPeriod: z10.string(),
3520
+ planDisplayName: z10.string()
3521
+ });
3522
+ var billingInfoSchema = z10.object({
3523
+ stripeCustomerId: z10.string(),
3524
+ subscriptionStatus: z10.nativeEnum(SubscriptionStatus),
3525
+ planType: z10.string(),
3526
+ stripeSubscriptionId: z10.string().nullable(),
3527
+ stripePriceId: z10.string().nullable(),
3528
+ currentPeriodStart: z10.instanceof(Date).or(z10.instanceof(Timestamp6)).nullable(),
3529
+ currentPeriodEnd: z10.instanceof(Date).or(z10.instanceof(Timestamp6)).nullable(),
3530
+ updatedAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6))
3531
+ });
3532
+ var billingTransactionSchema = z10.object({
3533
+ id: z10.string(),
3534
+ clinicGroupId: z10.string(),
3535
+ type: z10.nativeEnum(BillingTransactionType),
3536
+ description: z10.string(),
3537
+ amount: z10.number(),
3538
+ currency: z10.string(),
3539
+ stripeData: stripeTransactionDataSchema,
3540
+ planDetails: planDetailsSchema,
3541
+ metadata: z10.record(z10.any()).optional(),
3542
+ timestamp: z10.instanceof(Date).or(z10.instanceof(Timestamp6)),
3543
+ createdAt: z10.instanceof(Date).or(z10.instanceof(Timestamp6))
3544
+ });
3545
+ var createBillingTransactionSchema = z10.object({
3546
+ type: z10.nativeEnum(BillingTransactionType),
3547
+ description: z10.string(),
3548
+ amount: z10.number(),
3549
+ currency: z10.string(),
3550
+ stripeData: stripeTransactionDataSchema,
3551
+ planDetails: planDetailsSchema,
3552
+ metadata: z10.record(z10.any()).optional()
3553
+ });
3493
3554
  var createAdminTokenSchema = z10.object({
3494
3555
  expiresInDays: z10.number().min(1).max(30).optional(),
3495
3556
  email: z10.string().email().optional().nullable()
@@ -3516,6 +3577,7 @@ var clinicGroupSchema = z10.object({
3516
3577
  practiceType: z10.nativeEnum(PracticeType).optional(),
3517
3578
  languages: z10.array(z10.nativeEnum(Language)).optional(),
3518
3579
  subscriptionModel: z10.nativeEnum(SubscriptionModel),
3580
+ billing: billingInfoSchema.optional(),
3519
3581
  calendarSyncEnabled: z10.boolean().optional(),
3520
3582
  autoConfirmAppointments: z10.boolean().optional(),
3521
3583
  businessIdentificationNumber: z10.string().optional().nullable(),
@@ -3581,6 +3643,7 @@ var createClinicGroupSchema = z10.object({
3581
3643
  practiceType: z10.nativeEnum(PracticeType).optional(),
3582
3644
  languages: z10.array(z10.nativeEnum(Language)).optional(),
3583
3645
  subscriptionModel: z10.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
3646
+ billing: billingInfoSchema.optional(),
3584
3647
  calendarSyncEnabled: z10.boolean().optional(),
3585
3648
  autoConfirmAppointments: z10.boolean().optional(),
3586
3649
  businessIdentificationNumber: z10.string().optional().nullable(),
@@ -16829,6 +16892,26 @@ var CategoryService = class extends BaseService {
16829
16892
  })
16830
16893
  );
16831
16894
  }
16895
+ /**
16896
+ * Vraća sve kategorije za određenu familiju za potrebe filtera (bez paginacije)
16897
+ * @param family - Familija procedura (aesthetics/surgery)
16898
+ * @returns Lista aktivnih kategorija koje pripadaju traženoj familiji
16899
+ */
16900
+ async getAllForFilterByFamily(family) {
16901
+ const q = query32(
16902
+ this.categoriesRef,
16903
+ where32("family", "==", family),
16904
+ where32("isActive", "==", true),
16905
+ orderBy19("name")
16906
+ );
16907
+ const snapshot = await getDocs32(q);
16908
+ return snapshot.docs.map(
16909
+ (doc38) => ({
16910
+ id: doc38.id,
16911
+ ...doc38.data()
16912
+ })
16913
+ );
16914
+ }
16832
16915
  /**
16833
16916
  * Vraća sve kategorije sa paginacijom
16834
16917
  * @param options - Pagination and filter options
@@ -17492,7 +17575,9 @@ var TechnologyService = class extends BaseService {
17492
17575
  if (!technology) {
17493
17576
  throw new Error(`Technology with id ${technologyId} not found`);
17494
17577
  }
17495
- const updatedContraindications = (technology.contraindications || []).filter((c) => c.id !== contraindication.id);
17578
+ const updatedContraindications = (technology.contraindications || []).filter(
17579
+ (c) => c.id !== contraindication.id
17580
+ );
17496
17581
  await updateDoc33(docRef, {
17497
17582
  contraindications: updatedContraindications,
17498
17583
  updatedAt: /* @__PURE__ */ new Date()
@@ -17513,9 +17598,7 @@ var TechnologyService = class extends BaseService {
17513
17598
  throw new Error(`Technology with id ${technologyId} not found`);
17514
17599
  }
17515
17600
  const contraindications = technology.contraindications || [];
17516
- const index = contraindications.findIndex(
17517
- (c) => c.id === contraindication.id
17518
- );
17601
+ const index = contraindications.findIndex((c) => c.id === contraindication.id);
17519
17602
  if (index === -1) {
17520
17603
  console.warn(
17521
17604
  `Contraindication with id ${contraindication.id} not found for technology ${technologyId}. No update performed.`
@@ -17564,9 +17647,7 @@ var TechnologyService = class extends BaseService {
17564
17647
  if (!technology) {
17565
17648
  throw new Error(`Technology with id ${technologyId} not found`);
17566
17649
  }
17567
- const updatedBenefits = (technology.benefits || []).filter(
17568
- (b) => b.id !== benefit.id
17569
- );
17650
+ const updatedBenefits = (technology.benefits || []).filter((b) => b.id !== benefit.id);
17570
17651
  await updateDoc33(docRef, {
17571
17652
  benefits: updatedBenefits,
17572
17653
  updatedAt: /* @__PURE__ */ new Date()
@@ -17672,9 +17753,7 @@ var TechnologyService = class extends BaseService {
17672
17753
  * );
17673
17754
  */
17674
17755
  validateCertification(requiredCertification, practitionerCertification) {
17675
- const doctorLevel = Object.values(CertificationLevel).indexOf(
17676
- practitionerCertification.level
17677
- );
17756
+ const doctorLevel = Object.values(CertificationLevel).indexOf(practitionerCertification.level);
17678
17757
  const requiredLevel = Object.values(CertificationLevel).indexOf(
17679
17758
  requiredCertification.minimumLevel
17680
17759
  );
@@ -17715,18 +17794,11 @@ var TechnologyService = class extends BaseService {
17715
17794
  async getAllowedTechnologies(practitioner) {
17716
17795
  const allTechnologies = await this.getAll();
17717
17796
  const allowedTechnologies = allTechnologies.technologies.filter(
17718
- (technology) => this.validateCertification(
17719
- technology.certificationRequirement,
17720
- practitioner.certification
17721
- )
17797
+ (technology) => this.validateCertification(technology.certificationRequirement, practitioner.certification)
17722
17798
  );
17723
17799
  const families = [...new Set(allowedTechnologies.map((t) => t.family))];
17724
- const categories = [
17725
- ...new Set(allowedTechnologies.map((t) => t.categoryId))
17726
- ];
17727
- const subcategories = [
17728
- ...new Set(allowedTechnologies.map((t) => t.subcategoryId))
17729
- ];
17800
+ const categories = [...new Set(allowedTechnologies.map((t) => t.categoryId))];
17801
+ const subcategories = [...new Set(allowedTechnologies.map((t) => t.subcategoryId))];
17730
17802
  return {
17731
17803
  technologies: allowedTechnologies,
17732
17804
  families,
@@ -17734,6 +17806,25 @@ var TechnologyService = class extends BaseService {
17734
17806
  subcategories
17735
17807
  };
17736
17808
  }
17809
+ /**
17810
+ * Gets all active technologies for a subcategory for filter dropdowns (by subcategory only).
17811
+ * @param subcategoryId - The ID of the subcategory.
17812
+ */
17813
+ async getAllForFilterBySubcategory(subcategoryId) {
17814
+ const q = query34(
17815
+ collection34(this.db, TECHNOLOGIES_COLLECTION),
17816
+ where34("isActive", "==", true),
17817
+ where34("subcategoryId", "==", subcategoryId),
17818
+ orderBy21("name")
17819
+ );
17820
+ const snapshot = await getDocs34(q);
17821
+ return snapshot.docs.map(
17822
+ (doc38) => ({
17823
+ id: doc38.id,
17824
+ ...doc38.data()
17825
+ })
17826
+ );
17827
+ }
17737
17828
  /**
17738
17829
  * Gets all active technologies for a subcategory for filter dropdowns.
17739
17830
  * @param categoryId - The ID of the parent category.
@@ -17802,12 +17893,7 @@ var ProductService = class extends BaseService {
17802
17893
  * @returns Firestore collection reference
17803
17894
  */
17804
17895
  getProductsRef(technologyId) {
17805
- return collection35(
17806
- this.db,
17807
- TECHNOLOGIES_COLLECTION,
17808
- technologyId,
17809
- PRODUCTS_COLLECTION
17810
- );
17896
+ return collection35(this.db, TECHNOLOGIES_COLLECTION, technologyId, PRODUCTS_COLLECTION);
17811
17897
  }
17812
17898
  /**
17813
17899
  * Creates a new product under technology
@@ -17822,10 +17908,7 @@ var ProductService = class extends BaseService {
17822
17908
  updatedAt: now,
17823
17909
  isActive: true
17824
17910
  };
17825
- const productRef = await addDoc7(
17826
- this.getProductsRef(technologyId),
17827
- newProduct
17828
- );
17911
+ const productRef = await addDoc7(this.getProductsRef(technologyId), newProduct);
17829
17912
  return { id: productRef.id, ...newProduct };
17830
17913
  }
17831
17914
  /**
@@ -17833,17 +17916,8 @@ var ProductService = class extends BaseService {
17833
17916
  * This uses a collectionGroup query to search across all technologies.
17834
17917
  */
17835
17918
  async getAll(options) {
17836
- const {
17837
- rowsPerPage,
17838
- lastVisible,
17839
- categoryId,
17840
- subcategoryId,
17841
- technologyId
17842
- } = options;
17843
- const constraints = [
17844
- where35("isActive", "==", true),
17845
- orderBy22("name")
17846
- ];
17919
+ const { rowsPerPage, lastVisible, categoryId, subcategoryId, technologyId } = options;
17920
+ const constraints = [where35("isActive", "==", true), orderBy22("name")];
17847
17921
  if (categoryId) {
17848
17922
  constraints.push(where35("categoryId", "==", categoryId));
17849
17923
  }
@@ -17857,10 +17931,7 @@ var ProductService = class extends BaseService {
17857
17931
  constraints.push(startAfter18(lastVisible));
17858
17932
  }
17859
17933
  constraints.push(limit20(rowsPerPage));
17860
- const q = query35(
17861
- collectionGroup3(this.db, PRODUCTS_COLLECTION),
17862
- ...constraints
17863
- );
17934
+ const q = query35(collectionGroup3(this.db, PRODUCTS_COLLECTION), ...constraints);
17864
17935
  const snapshot = await getDocs35(q);
17865
17936
  const products = snapshot.docs.map(
17866
17937
  (doc38) => ({
@@ -17886,10 +17957,7 @@ var ProductService = class extends BaseService {
17886
17957
  if (technologyId) {
17887
17958
  constraints.push(where35("technologyId", "==", technologyId));
17888
17959
  }
17889
- const q = query35(
17890
- collectionGroup3(this.db, PRODUCTS_COLLECTION),
17891
- ...constraints
17892
- );
17960
+ const q = query35(collectionGroup3(this.db, PRODUCTS_COLLECTION), ...constraints);
17893
17961
  const snapshot = await getCountFromServer6(q);
17894
17962
  return snapshot.data().count;
17895
17963
  }
@@ -17898,10 +17966,7 @@ var ProductService = class extends BaseService {
17898
17966
  * This uses a single collectionGroup query for efficiency.
17899
17967
  */
17900
17968
  async getProductCounts() {
17901
- const q = query35(
17902
- collectionGroup3(this.db, PRODUCTS_COLLECTION),
17903
- where35("isActive", "==", true)
17904
- );
17969
+ const q = query35(collectionGroup3(this.db, PRODUCTS_COLLECTION), where35("isActive", "==", true));
17905
17970
  const snapshot = await getDocs35(q);
17906
17971
  const counts = {
17907
17972
  byCategory: {},
@@ -17926,6 +17991,23 @@ var ProductService = class extends BaseService {
17926
17991
  });
17927
17992
  return counts;
17928
17993
  }
17994
+ /**
17995
+ * Gets all products for a specific technology (non-paginated, for filters/dropdowns)
17996
+ */
17997
+ async getAllByTechnology(technologyId) {
17998
+ const q = query35(
17999
+ this.getProductsRef(technologyId),
18000
+ where35("isActive", "==", true),
18001
+ orderBy22("name")
18002
+ );
18003
+ const snapshot = await getDocs35(q);
18004
+ return snapshot.docs.map(
18005
+ (doc38) => ({
18006
+ id: doc38.id,
18007
+ ...doc38.data()
18008
+ })
18009
+ );
18010
+ }
17929
18011
  /**
17930
18012
  * Gets all products for a brand by filtering through all technologies
17931
18013
  */
@@ -18280,6 +18362,7 @@ export {
18280
18362
  AppointmentStatus,
18281
18363
  AuthService,
18282
18364
  BaseService,
18365
+ BillingTransactionType,
18283
18366
  BlockingCondition,
18284
18367
  BrandService,
18285
18368
  CALENDAR_COLLECTION,
@@ -18363,6 +18446,7 @@ export {
18363
18446
  SearchLocationEnum,
18364
18447
  SubcategoryService,
18365
18448
  SubscriptionModel,
18449
+ SubscriptionStatus,
18366
18450
  SyncedCalendarProvider,
18367
18451
  SyncedCalendarsService,
18368
18452
  TechnologyService,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.12.2",
4
+ "version": "1.12.4",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",