@blackcode_sa/metaestetics-api 1.12.47 → 1.12.49

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
@@ -16326,7 +16326,8 @@ var createProcedureSchema = import_zod26.z.object({
16326
16326
  price: import_zod26.z.number().min(0),
16327
16327
  currency: import_zod26.z.nativeEnum(Currency),
16328
16328
  pricingMeasure: import_zod26.z.nativeEnum(PricingMeasure),
16329
- productsMetadata: import_zod26.z.array(procedureProductDataSchema).min(1).optional(),
16329
+ productsMetadata: import_zod26.z.array(procedureProductDataSchema).optional(),
16330
+ // No min(1) - allow empty for product-free procedures
16330
16331
  duration: import_zod26.z.number().min(1).max(480),
16331
16332
  // Max 8 hours
16332
16333
  practitionerId: import_zod26.z.string().min(1),
@@ -16340,7 +16341,8 @@ var updateProcedureSchema = import_zod26.z.object({
16340
16341
  price: import_zod26.z.number().min(0).optional(),
16341
16342
  currency: import_zod26.z.nativeEnum(Currency).optional(),
16342
16343
  pricingMeasure: import_zod26.z.nativeEnum(PricingMeasure).optional(),
16343
- productsMetadata: import_zod26.z.array(procedureProductDataSchema).min(1).optional(),
16344
+ productsMetadata: import_zod26.z.array(procedureProductDataSchema).optional(),
16345
+ // No min(1) - allow empty for product-free procedures
16344
16346
  duration: import_zod26.z.number().min(0).optional(),
16345
16347
  isActive: import_zod26.z.boolean().optional(),
16346
16348
  practitionerId: import_zod26.z.string().optional(),
@@ -16493,20 +16495,29 @@ var ProcedureService = class extends BaseService {
16493
16495
  async createProcedure(data) {
16494
16496
  var _a, _b, _c;
16495
16497
  const validatedData = createProcedureSchema.parse(data);
16496
- if (!validatedData.productId) {
16497
- throw new Error("productId is required for regular procedures. Use createConsultationProcedure for product-free procedures.");
16498
- }
16498
+ const isProductFree = !validatedData.productId;
16499
16499
  const procedureId = this.generateId();
16500
- const [category, subcategory, technology, product] = await Promise.all([
16500
+ const baseEntitiesPromises = [
16501
16501
  this.categoryService.getById(validatedData.categoryId),
16502
16502
  this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
16503
- this.technologyService.getById(validatedData.technologyId),
16504
- this.productService.getById(validatedData.technologyId, validatedData.productId)
16505
- // Safe: validated above
16506
- ]);
16507
- if (!category || !subcategory || !technology || !product) {
16503
+ this.technologyService.getById(validatedData.technologyId)
16504
+ ];
16505
+ if (!isProductFree) {
16506
+ baseEntitiesPromises.push(
16507
+ this.productService.getById(validatedData.technologyId, validatedData.productId)
16508
+ );
16509
+ }
16510
+ const results = await Promise.all(baseEntitiesPromises);
16511
+ const category = results[0];
16512
+ const subcategory = results[1];
16513
+ const technology = results[2];
16514
+ const product = isProductFree ? void 0 : results[3] || void 0;
16515
+ if (!category || !subcategory || !technology) {
16508
16516
  throw new Error("One or more required base entities not found");
16509
16517
  }
16518
+ if (!isProductFree && !product) {
16519
+ throw new Error("Product not found for regular procedure");
16520
+ }
16510
16521
  const clinicRef = (0, import_firestore55.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
16511
16522
  const clinicSnapshot = await (0, import_firestore55.getDoc)(clinicRef);
16512
16523
  if (!clinicSnapshot.exists()) {
@@ -16611,23 +16622,35 @@ var ProcedureService = class extends BaseService {
16611
16622
  if (!practitionerIds || practitionerIds.length === 0) {
16612
16623
  throw new Error("Practitioner IDs array cannot be empty.");
16613
16624
  }
16614
- if (!baseData.productId) {
16615
- throw new Error("productId is required for regular procedures. Use createConsultationProcedure for product-free procedures.");
16616
- }
16625
+ const isProductFree = !baseData.productId;
16617
16626
  const validationData = { ...baseData, practitionerId: practitionerIds[0] };
16618
16627
  const validatedData = createProcedureSchema.parse(validationData);
16619
- const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
16628
+ const baseEntitiesPromises = [
16620
16629
  this.categoryService.getById(validatedData.categoryId),
16621
16630
  this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
16622
- this.technologyService.getById(validatedData.technologyId),
16623
- this.productService.getById(validatedData.technologyId, validatedData.productId),
16624
- // Safe: validated above
16625
- (0, import_firestore55.getDoc)((0, import_firestore55.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
16631
+ this.technologyService.getById(validatedData.technologyId)
16632
+ ];
16633
+ if (!isProductFree) {
16634
+ baseEntitiesPromises.push(
16635
+ this.productService.getById(validatedData.technologyId, validatedData.productId)
16636
+ );
16637
+ }
16638
+ const clinicSnapshotPromise = (0, import_firestore55.getDoc)((0, import_firestore55.doc)(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId));
16639
+ const [baseResults, clinicSnapshot] = await Promise.all([
16640
+ Promise.all(baseEntitiesPromises),
16641
+ clinicSnapshotPromise
16626
16642
  ]);
16627
- if (!category || !subcategory || !technology || !product) {
16643
+ const category = baseResults[0];
16644
+ const subcategory = baseResults[1];
16645
+ const technology = baseResults[2];
16646
+ const product = isProductFree ? void 0 : baseResults[3] || void 0;
16647
+ if (!category || !subcategory || !technology) {
16628
16648
  throw new Error("One or more required base entities not found");
16629
16649
  }
16630
- if (!clinicSnapshot.exists()) {
16650
+ if (!isProductFree && !product) {
16651
+ throw new Error("Product not found for regular procedure");
16652
+ }
16653
+ if (!clinicSnapshot || !clinicSnapshot.exists()) {
16631
16654
  throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
16632
16655
  }
16633
16656
  const clinic = clinicSnapshot.data();
package/dist/index.mjs CHANGED
@@ -16574,7 +16574,8 @@ var createProcedureSchema = z26.object({
16574
16574
  price: z26.number().min(0),
16575
16575
  currency: z26.nativeEnum(Currency),
16576
16576
  pricingMeasure: z26.nativeEnum(PricingMeasure),
16577
- productsMetadata: z26.array(procedureProductDataSchema).min(1).optional(),
16577
+ productsMetadata: z26.array(procedureProductDataSchema).optional(),
16578
+ // No min(1) - allow empty for product-free procedures
16578
16579
  duration: z26.number().min(1).max(480),
16579
16580
  // Max 8 hours
16580
16581
  practitionerId: z26.string().min(1),
@@ -16588,7 +16589,8 @@ var updateProcedureSchema = z26.object({
16588
16589
  price: z26.number().min(0).optional(),
16589
16590
  currency: z26.nativeEnum(Currency).optional(),
16590
16591
  pricingMeasure: z26.nativeEnum(PricingMeasure).optional(),
16591
- productsMetadata: z26.array(procedureProductDataSchema).min(1).optional(),
16592
+ productsMetadata: z26.array(procedureProductDataSchema).optional(),
16593
+ // No min(1) - allow empty for product-free procedures
16592
16594
  duration: z26.number().min(0).optional(),
16593
16595
  isActive: z26.boolean().optional(),
16594
16596
  practitionerId: z26.string().optional(),
@@ -16741,20 +16743,29 @@ var ProcedureService = class extends BaseService {
16741
16743
  async createProcedure(data) {
16742
16744
  var _a, _b, _c;
16743
16745
  const validatedData = createProcedureSchema.parse(data);
16744
- if (!validatedData.productId) {
16745
- throw new Error("productId is required for regular procedures. Use createConsultationProcedure for product-free procedures.");
16746
- }
16746
+ const isProductFree = !validatedData.productId;
16747
16747
  const procedureId = this.generateId();
16748
- const [category, subcategory, technology, product] = await Promise.all([
16748
+ const baseEntitiesPromises = [
16749
16749
  this.categoryService.getById(validatedData.categoryId),
16750
16750
  this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
16751
- this.technologyService.getById(validatedData.technologyId),
16752
- this.productService.getById(validatedData.technologyId, validatedData.productId)
16753
- // Safe: validated above
16754
- ]);
16755
- if (!category || !subcategory || !technology || !product) {
16751
+ this.technologyService.getById(validatedData.technologyId)
16752
+ ];
16753
+ if (!isProductFree) {
16754
+ baseEntitiesPromises.push(
16755
+ this.productService.getById(validatedData.technologyId, validatedData.productId)
16756
+ );
16757
+ }
16758
+ const results = await Promise.all(baseEntitiesPromises);
16759
+ const category = results[0];
16760
+ const subcategory = results[1];
16761
+ const technology = results[2];
16762
+ const product = isProductFree ? void 0 : results[3] || void 0;
16763
+ if (!category || !subcategory || !technology) {
16756
16764
  throw new Error("One or more required base entities not found");
16757
16765
  }
16766
+ if (!isProductFree && !product) {
16767
+ throw new Error("Product not found for regular procedure");
16768
+ }
16758
16769
  const clinicRef = doc36(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
16759
16770
  const clinicSnapshot = await getDoc37(clinicRef);
16760
16771
  if (!clinicSnapshot.exists()) {
@@ -16859,23 +16870,35 @@ var ProcedureService = class extends BaseService {
16859
16870
  if (!practitionerIds || practitionerIds.length === 0) {
16860
16871
  throw new Error("Practitioner IDs array cannot be empty.");
16861
16872
  }
16862
- if (!baseData.productId) {
16863
- throw new Error("productId is required for regular procedures. Use createConsultationProcedure for product-free procedures.");
16864
- }
16873
+ const isProductFree = !baseData.productId;
16865
16874
  const validationData = { ...baseData, practitionerId: practitionerIds[0] };
16866
16875
  const validatedData = createProcedureSchema.parse(validationData);
16867
- const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
16876
+ const baseEntitiesPromises = [
16868
16877
  this.categoryService.getById(validatedData.categoryId),
16869
16878
  this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
16870
- this.technologyService.getById(validatedData.technologyId),
16871
- this.productService.getById(validatedData.technologyId, validatedData.productId),
16872
- // Safe: validated above
16873
- getDoc37(doc36(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId))
16879
+ this.technologyService.getById(validatedData.technologyId)
16880
+ ];
16881
+ if (!isProductFree) {
16882
+ baseEntitiesPromises.push(
16883
+ this.productService.getById(validatedData.technologyId, validatedData.productId)
16884
+ );
16885
+ }
16886
+ const clinicSnapshotPromise = getDoc37(doc36(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId));
16887
+ const [baseResults, clinicSnapshot] = await Promise.all([
16888
+ Promise.all(baseEntitiesPromises),
16889
+ clinicSnapshotPromise
16874
16890
  ]);
16875
- if (!category || !subcategory || !technology || !product) {
16891
+ const category = baseResults[0];
16892
+ const subcategory = baseResults[1];
16893
+ const technology = baseResults[2];
16894
+ const product = isProductFree ? void 0 : baseResults[3] || void 0;
16895
+ if (!category || !subcategory || !technology) {
16876
16896
  throw new Error("One or more required base entities not found");
16877
16897
  }
16878
- if (!clinicSnapshot.exists()) {
16898
+ if (!isProductFree && !product) {
16899
+ throw new Error("Product not found for regular procedure");
16900
+ }
16901
+ if (!clinicSnapshot || !clinicSnapshot.exists()) {
16879
16902
  throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
16880
16903
  }
16881
16904
  const clinic = clinicSnapshot.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.12.47",
4
+ "version": "1.12.49",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -194,26 +194,41 @@ export class ProcedureService extends BaseService {
194
194
  async createProcedure(data: CreateProcedureData): Promise<Procedure> {
195
195
  const validatedData = createProcedureSchema.parse(data);
196
196
 
197
- // Validate that productId is provided (regular procedures require products)
198
- if (!validatedData.productId) {
199
- throw new Error('productId is required for regular procedures. Use createConsultationProcedure for product-free procedures.');
200
- }
197
+ // Check if this is a product-free procedure (e.g., free consultation)
198
+ const isProductFree = !validatedData.productId;
201
199
 
202
200
  // Generate procedure ID first so we can use it for media uploads
203
201
  const procedureId = this.generateId();
204
202
 
205
- // Get references to related entities (Category, Subcategory, Technology, Product)
206
- const [category, subcategory, technology, product] = await Promise.all([
203
+ // Get references to related entities (Category, Subcategory, Technology, and optionally Product)
204
+ const baseEntitiesPromises = [
207
205
  this.categoryService.getById(validatedData.categoryId),
208
206
  this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
209
207
  this.technologyService.getById(validatedData.technologyId),
210
- this.productService.getById(validatedData.technologyId, validatedData.productId!), // Safe: validated above
211
- ]);
208
+ ];
209
+
210
+ // Only fetch product if productId is provided
211
+ if (!isProductFree) {
212
+ baseEntitiesPromises.push(
213
+ this.productService.getById(validatedData.technologyId, validatedData.productId!)
214
+ );
215
+ }
212
216
 
213
- if (!category || !subcategory || !technology || !product) {
217
+ const results = await Promise.all(baseEntitiesPromises);
218
+ const category = results[0] as Category | null;
219
+ const subcategory = results[1] as Subcategory | null;
220
+ const technology = results[2] as Technology | null;
221
+ const product = isProductFree ? undefined : ((results[3] as Product | null) || undefined);
222
+
223
+ if (!category || !subcategory || !technology) {
214
224
  throw new Error('One or more required base entities not found');
215
225
  }
216
226
 
227
+ // For regular procedures, validate product exists
228
+ if (!isProductFree && !product) {
229
+ throw new Error('Product not found for regular procedure');
230
+ }
231
+
217
232
  // Get clinic and practitioner information for aggregation
218
233
  const clinicRef = doc(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId);
219
234
  const clinicSnapshot = await getDoc(clinicRef);
@@ -343,28 +358,50 @@ export class ProcedureService extends BaseService {
343
358
  throw new Error('Practitioner IDs array cannot be empty.');
344
359
  }
345
360
 
346
- // Validate that productId is provided (regular procedures require products)
347
- if (!baseData.productId) {
348
- throw new Error('productId is required for regular procedures. Use createConsultationProcedure for product-free procedures.');
349
- }
361
+ // Check if this is a product-free procedure
362
+ const isProductFree = !baseData.productId;
350
363
 
351
364
  // Add a dummy practitionerId for the validation schema to pass
352
365
  const validationData = { ...baseData, practitionerId: practitionerIds[0] };
353
366
  const validatedData = createProcedureSchema.parse(validationData);
354
367
 
355
368
  // 2. Fetch common data once to avoid redundant reads
356
- const [category, subcategory, technology, product, clinicSnapshot] = await Promise.all([
369
+ const baseEntitiesPromises = [
357
370
  this.categoryService.getById(validatedData.categoryId),
358
371
  this.subcategoryService.getById(validatedData.categoryId, validatedData.subcategoryId),
359
372
  this.technologyService.getById(validatedData.technologyId),
360
- this.productService.getById(validatedData.technologyId, validatedData.productId!), // Safe: validated above
361
- getDoc(doc(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId)),
373
+ ];
374
+
375
+ // Only fetch product if productId is provided
376
+ if (!isProductFree) {
377
+ baseEntitiesPromises.push(
378
+ this.productService.getById(validatedData.technologyId, validatedData.productId!)
379
+ );
380
+ }
381
+
382
+ // Fetch clinic separately to maintain type safety
383
+ const clinicSnapshotPromise = getDoc(doc(this.db, CLINICS_COLLECTION, validatedData.clinicBranchId));
384
+
385
+ const [baseResults, clinicSnapshot] = await Promise.all([
386
+ Promise.all(baseEntitiesPromises),
387
+ clinicSnapshotPromise
362
388
  ]);
389
+
390
+ const category = baseResults[0] as Category | null;
391
+ const subcategory = baseResults[1] as Subcategory | null;
392
+ const technology = baseResults[2] as Technology | null;
393
+ const product = isProductFree ? undefined : ((baseResults[3] as Product | null) || undefined);
363
394
 
364
- if (!category || !subcategory || !technology || !product) {
395
+ if (!category || !subcategory || !technology) {
365
396
  throw new Error('One or more required base entities not found');
366
397
  }
367
- if (!clinicSnapshot.exists()) {
398
+
399
+ // For regular procedures, validate product exists
400
+ if (!isProductFree && !product) {
401
+ throw new Error('Product not found for regular procedure');
402
+ }
403
+
404
+ if (!clinicSnapshot || !clinicSnapshot.exists()) {
368
405
  throw new Error(`Clinic with ID ${validatedData.clinicBranchId} not found`);
369
406
  }
370
407
  const clinic = clinicSnapshot.data() as Clinic;
@@ -56,7 +56,7 @@ export const createProcedureSchema = z.object({
56
56
  price: z.number().min(0),
57
57
  currency: z.nativeEnum(Currency),
58
58
  pricingMeasure: z.nativeEnum(PricingMeasure),
59
- productsMetadata: z.array(procedureProductDataSchema).min(1).optional(),
59
+ productsMetadata: z.array(procedureProductDataSchema).optional(), // No min(1) - allow empty for product-free procedures
60
60
  duration: z.number().min(1).max(480), // Max 8 hours
61
61
  practitionerId: z.string().min(1),
62
62
  clinicBranchId: z.string().min(1),
@@ -73,7 +73,7 @@ export const updateProcedureSchema = z.object({
73
73
  price: z.number().min(0).optional(),
74
74
  currency: z.nativeEnum(Currency).optional(),
75
75
  pricingMeasure: z.nativeEnum(PricingMeasure).optional(),
76
- productsMetadata: z.array(procedureProductDataSchema).min(1).optional(),
76
+ productsMetadata: z.array(procedureProductDataSchema).optional(), // No min(1) - allow empty for product-free procedures
77
77
  duration: z.number().min(0).optional(),
78
78
  isActive: z.boolean().optional(),
79
79
  practitionerId: z.string().optional(),