@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 +44 -21
- package/dist/index.mjs +44 -21
- package/package.json +1 -1
- package/src/services/procedure/procedure.service.ts +55 -18
- package/src/validations/procedure.schema.ts +2 -2
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).
|
|
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).
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
16505
|
-
|
|
16506
|
-
|
|
16507
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
16624
|
-
|
|
16625
|
-
|
|
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
|
-
|
|
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 (!
|
|
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).
|
|
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).
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
16753
|
-
|
|
16754
|
-
|
|
16755
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
16872
|
-
|
|
16873
|
-
|
|
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
|
-
|
|
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 (!
|
|
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
|
@@ -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
|
-
//
|
|
198
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
347
|
-
|
|
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
|
|
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
|
-
|
|
361
|
-
|
|
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
|
|
395
|
+
if (!category || !subcategory || !technology) {
|
|
365
396
|
throw new Error('One or more required base entities not found');
|
|
366
397
|
}
|
|
367
|
-
|
|
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)
|
|
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)
|
|
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(),
|