@blackcode_sa/metaestetics-api 1.6.4 → 1.6.5

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.mjs CHANGED
@@ -340,7 +340,6 @@ var finalizedDetailsSchema = z2.object({
340
340
  notes: z2.string().max(MAX_STRING_LENGTH_LONG, "Finalization notes too long").optional()
341
341
  });
342
342
  var createAppointmentSchema = z2.object({
343
- calendarEventId: z2.string().min(MIN_STRING_LENGTH, "Calendar event ID is required"),
344
343
  clinicBranchId: z2.string().min(MIN_STRING_LENGTH, "Clinic branch ID is required"),
345
344
  practitionerId: z2.string().min(MIN_STRING_LENGTH, "Practitioner ID is required"),
346
345
  patientId: z2.string().min(MIN_STRING_LENGTH, "Patient ID is required"),
@@ -377,6 +376,7 @@ var updateAppointmentSchema = z2.object({
377
376
  paymentTransactionId: z2.any().optional().nullable(),
378
377
  completedPreRequirements: z2.union([z2.array(z2.string()), z2.any()]).optional(),
379
378
  completedPostRequirements: z2.union([z2.array(z2.string()), z2.any()]).optional(),
379
+ linkedFormIds: z2.union([z2.array(z2.string()), z2.any()]).optional(),
380
380
  pendingUserFormsIds: z2.union([z2.array(z2.string()), z2.any()]).optional(),
381
381
  appointmentStartTime: z2.any().refine(
382
382
  (val) => val === void 0 || val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || typeof val === "number",
@@ -7690,7 +7690,8 @@ var createProcedureSchema = z20.object({
7690
7690
  duration: z20.number().min(1).max(480),
7691
7691
  // Max 8 hours
7692
7692
  practitionerId: z20.string().min(1),
7693
- clinicBranchId: z20.string().min(1)
7693
+ clinicBranchId: z20.string().min(1),
7694
+ photos: z20.array(z20.string()).optional()
7694
7695
  });
7695
7696
  var updateProcedureSchema = z20.object({
7696
7697
  name: z20.string().min(3).max(100).optional(),
@@ -7705,7 +7706,8 @@ var updateProcedureSchema = z20.object({
7705
7706
  subcategoryId: z20.string().optional(),
7706
7707
  technologyId: z20.string().optional(),
7707
7708
  productId: z20.string().optional(),
7708
- clinicBranchId: z20.string().optional()
7709
+ clinicBranchId: z20.string().optional(),
7710
+ photos: z20.array(z20.string()).optional()
7709
7711
  });
7710
7712
  var procedureSchema = createProcedureSchema.extend({
7711
7713
  id: z20.string().min(1),
@@ -7719,6 +7721,8 @@ var procedureSchema = createProcedureSchema.extend({
7719
7721
  // We'll validate the full product object separately
7720
7722
  blockingConditions: z20.array(z20.any()),
7721
7723
  // We'll validate blocking conditions separately
7724
+ contraindications: z20.array(z20.any()),
7725
+ // We'll validate contraindications separately
7722
7726
  treatmentBenefits: z20.array(z20.any()),
7723
7727
  // We'll validate treatment benefits separately
7724
7728
  preRequirements: z20.array(z20.any()),
@@ -7823,6 +7827,7 @@ var ProcedureService = class extends BaseService {
7823
7827
  technology,
7824
7828
  product,
7825
7829
  blockingConditions: technology.blockingConditions,
7830
+ contraindications: technology.contraindications || [],
7826
7831
  treatmentBenefits: technology.benefits,
7827
7832
  preRequirements: technology.requirements.pre,
7828
7833
  postRequirements: technology.requirements.post,
@@ -12243,7 +12248,7 @@ import {
12243
12248
  arrayUnion as arrayUnion8,
12244
12249
  arrayRemove as arrayRemove7
12245
12250
  } from "firebase/firestore";
12246
- import { getFunctions, httpsCallable } from "firebase/functions";
12251
+ import { getFunctions } from "firebase/functions";
12247
12252
 
12248
12253
  // src/services/appointment/utils/appointment.utils.ts
12249
12254
  import {
@@ -12266,166 +12271,6 @@ import {
12266
12271
  var TECHNOLOGIES_COLLECTION = "technologies";
12267
12272
 
12268
12273
  // src/services/appointment/utils/appointment.utils.ts
12269
- async function fetchAggregatedInfoUtil(db, clinicId, practitionerId, patientId, procedureId) {
12270
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
12271
- try {
12272
- const [clinicDoc, practitionerDoc, patientDoc, procedureDoc] = await Promise.all([
12273
- getDoc28(doc26(db, CLINICS_COLLECTION, clinicId)),
12274
- getDoc28(doc26(db, PRACTITIONERS_COLLECTION, practitionerId)),
12275
- getDoc28(doc26(db, PATIENTS_COLLECTION, patientId)),
12276
- getDoc28(doc26(db, PROCEDURES_COLLECTION, procedureId))
12277
- ]);
12278
- if (!clinicDoc.exists()) {
12279
- throw new Error(`Clinic with ID ${clinicId} not found`);
12280
- }
12281
- if (!practitionerDoc.exists()) {
12282
- throw new Error(`Practitioner with ID ${practitionerId} not found`);
12283
- }
12284
- if (!patientDoc.exists()) {
12285
- throw new Error(`Patient with ID ${patientId} not found`);
12286
- }
12287
- if (!procedureDoc.exists()) {
12288
- throw new Error(`Procedure with ID ${procedureId} not found`);
12289
- }
12290
- const clinicData = clinicDoc.data();
12291
- const practitionerData = practitionerDoc.data();
12292
- const patientData = patientDoc.data();
12293
- const procedureData = procedureDoc.data();
12294
- const clinicInfo = {
12295
- id: clinicId,
12296
- featuredPhoto: ((_a = clinicData.featuredPhotos) == null ? void 0 : _a[0]) || "",
12297
- name: clinicData.name,
12298
- description: clinicData.description || null,
12299
- location: clinicData.location,
12300
- contactInfo: clinicData.contactInfo
12301
- };
12302
- const practitionerInfo = {
12303
- id: practitionerId,
12304
- practitionerPhoto: ((_b = practitionerData.basicInfo) == null ? void 0 : _b.profileImageUrl) || null,
12305
- name: `${((_c = practitionerData.basicInfo) == null ? void 0 : _c.firstName) || ""} ${((_d = practitionerData.basicInfo) == null ? void 0 : _d.lastName) || ""}`.trim(),
12306
- email: ((_e = practitionerData.basicInfo) == null ? void 0 : _e.email) || "",
12307
- phone: ((_f = practitionerData.basicInfo) == null ? void 0 : _f.phoneNumber) || null,
12308
- certification: practitionerData.certification
12309
- };
12310
- const patientInfo = {
12311
- id: patientId,
12312
- fullName: patientData.displayName || "",
12313
- email: patientData.email || "",
12314
- phone: patientData.phoneNumber || null,
12315
- dateOfBirth: patientData.dateOfBirth || Timestamp27.now(),
12316
- gender: patientData.gender || "other"
12317
- };
12318
- const procedureInfo = {
12319
- id: procedureId,
12320
- name: procedureData.name,
12321
- description: procedureData.description,
12322
- photo: procedureData.photo || "",
12323
- family: procedureData.family,
12324
- categoryName: ((_g = procedureData.category) == null ? void 0 : _g.name) || "",
12325
- subcategoryName: ((_h = procedureData.subcategory) == null ? void 0 : _h.name) || "",
12326
- technologyName: ((_i = procedureData.technology) == null ? void 0 : _i.name) || "",
12327
- brandName: ((_j = procedureData.product) == null ? void 0 : _j.brand) || "",
12328
- productName: ((_k = procedureData.product) == null ? void 0 : _k.name) || "",
12329
- price: procedureData.price || 0,
12330
- pricingMeasure: procedureData.pricingMeasure,
12331
- currency: procedureData.currency,
12332
- duration: procedureData.duration || 0,
12333
- clinicId,
12334
- clinicName: clinicInfo.name,
12335
- practitionerId,
12336
- practitionerName: practitionerInfo.name
12337
- };
12338
- let technologyId = "";
12339
- if ((_l = procedureData.technology) == null ? void 0 : _l.id) {
12340
- technologyId = procedureData.technology.id;
12341
- }
12342
- let blockingConditions = [];
12343
- let contraindications = [];
12344
- let preProcedureRequirements = [];
12345
- let postProcedureRequirements = [];
12346
- if (technologyId) {
12347
- const technologyDoc = await getDoc28(
12348
- doc26(db, TECHNOLOGIES_COLLECTION, technologyId)
12349
- );
12350
- if (technologyDoc.exists()) {
12351
- const technologyData = technologyDoc.data();
12352
- blockingConditions = technologyData.blockingConditions || [];
12353
- contraindications = technologyData.contraindications || [];
12354
- preProcedureRequirements = ((_m = technologyData.requirements) == null ? void 0 : _m.pre) || [];
12355
- postProcedureRequirements = ((_n = technologyData.requirements) == null ? void 0 : _n.post) || [];
12356
- }
12357
- } else {
12358
- blockingConditions = procedureData.blockingConditions || [];
12359
- contraindications = procedureData.contraindications || [];
12360
- preProcedureRequirements = procedureData.preRequirements || [];
12361
- postProcedureRequirements = procedureData.postRequirements || [];
12362
- }
12363
- return {
12364
- clinicInfo,
12365
- practitionerInfo,
12366
- patientInfo,
12367
- procedureInfo,
12368
- blockingConditions,
12369
- contraindications,
12370
- preProcedureRequirements,
12371
- postProcedureRequirements
12372
- };
12373
- } catch (error) {
12374
- console.error("Error fetching aggregated info:", error);
12375
- throw error;
12376
- }
12377
- }
12378
- async function createAppointmentUtil2(db, data, aggregatedInfo, generateId2) {
12379
- try {
12380
- const appointmentId = generateId2();
12381
- const appointment = {
12382
- id: appointmentId,
12383
- calendarEventId: data.calendarEventId,
12384
- clinicBranchId: data.clinicBranchId,
12385
- clinicInfo: aggregatedInfo.clinicInfo,
12386
- practitionerId: data.practitionerId,
12387
- practitionerInfo: aggregatedInfo.practitionerInfo,
12388
- patientId: data.patientId,
12389
- patientInfo: aggregatedInfo.patientInfo,
12390
- procedureId: data.procedureId,
12391
- procedureInfo: aggregatedInfo.procedureInfo,
12392
- status: data.initialStatus,
12393
- bookingTime: Timestamp27.now(),
12394
- appointmentStartTime: data.appointmentStartTime,
12395
- appointmentEndTime: data.appointmentEndTime,
12396
- patientNotes: data.patientNotes || null,
12397
- cost: data.cost,
12398
- currency: data.currency,
12399
- paymentStatus: data.initialPaymentStatus || "unpaid" /* UNPAID */,
12400
- blockingConditions: aggregatedInfo.blockingConditions,
12401
- contraindications: aggregatedInfo.contraindications,
12402
- preProcedureRequirements: aggregatedInfo.preProcedureRequirements,
12403
- postProcedureRequirements: aggregatedInfo.postProcedureRequirements,
12404
- completedPreRequirements: [],
12405
- completedPostRequirements: [],
12406
- createdAt: serverTimestamp23(),
12407
- updatedAt: serverTimestamp23()
12408
- };
12409
- if (data.initialStatus === "confirmed" /* CONFIRMED */) {
12410
- appointment.confirmationTime = Timestamp27.now();
12411
- }
12412
- await setDoc23(doc26(db, APPOINTMENTS_COLLECTION, appointmentId), appointment);
12413
- const calendarEventRef = doc26(db, CALENDAR_COLLECTION, data.calendarEventId);
12414
- await updateDoc25(calendarEventRef, {
12415
- appointmentId,
12416
- updatedAt: serverTimestamp23()
12417
- });
12418
- const now = Timestamp27.now();
12419
- return {
12420
- ...appointment,
12421
- createdAt: now,
12422
- updatedAt: now
12423
- };
12424
- } catch (error) {
12425
- console.error("Error creating appointment:", error);
12426
- throw error;
12427
- }
12428
- }
12429
12274
  async function updateAppointmentUtil2(db, appointmentId, data) {
12430
12275
  try {
12431
12276
  const appointmentRef = doc26(db, APPOINTMENTS_COLLECTION, appointmentId);
@@ -12633,78 +12478,6 @@ var AppointmentService = class extends BaseService {
12633
12478
  this.filledDocumentService = filledDocumentService;
12634
12479
  this.functions = getFunctions(app, "europe-west6");
12635
12480
  }
12636
- /**
12637
- * Test method using the callable function version of getAvailableBookingSlots
12638
- * For development and testing purposes only - not for production use
12639
- *
12640
- * @param clinicId ID of the clinic
12641
- * @param practitionerId ID of the practitioner
12642
- * @param procedureId ID of the procedure
12643
- * @param startDate Start date of the time range to check
12644
- * @param endDate End date of the time range to check
12645
- * @returns Test result from the callable function
12646
- */
12647
- async testGetAvailableBookingSlots(clinicId, practitionerId, procedureId, startDate, endDate) {
12648
- try {
12649
- console.log(
12650
- `[APPOINTMENT_SERVICE] Testing callable function for clinic: ${clinicId}, practitioner: ${practitionerId}, procedure: ${procedureId}`
12651
- );
12652
- const getAvailableBookingSlotsCallable = httpsCallable(
12653
- this.functions,
12654
- "getAvailableBookingSlots"
12655
- );
12656
- const result = await getAvailableBookingSlotsCallable({
12657
- clinicId,
12658
- practitionerId,
12659
- procedureId,
12660
- timeframe: {
12661
- start: startDate.getTime(),
12662
- end: endDate.getTime()
12663
- }
12664
- });
12665
- console.log(
12666
- "[APPOINTMENT_SERVICE] Callable function test result:",
12667
- result.data
12668
- );
12669
- return result.data;
12670
- } catch (error) {
12671
- console.error(
12672
- "[APPOINTMENT_SERVICE] Error testing callable function:",
12673
- error
12674
- );
12675
- throw error;
12676
- }
12677
- }
12678
- /**
12679
- * Gets available booking slots for a specific clinic, practitioner, and procedure.
12680
- *
12681
- * @param clinicId ID of the clinic
12682
- * @param practitionerId ID of the practitioner
12683
- * @param procedureId ID of the procedure
12684
- * @param startDate Start date of the time range to check
12685
- * @param endDate End date of the time range to check
12686
- * @returns Array of available booking slots
12687
- */
12688
- async getAvailableBookingSlots(clinicId, practitionerId, procedureId, startDate, endDate) {
12689
- try {
12690
- console.log(
12691
- `[APPOINTMENT_SERVICE] Getting available booking slots for clinic: ${clinicId}, practitioner: ${practitionerId}, procedure: ${procedureId}`
12692
- );
12693
- return this.getAvailableBookingSlotsHttp(
12694
- clinicId,
12695
- practitionerId,
12696
- procedureId,
12697
- startDate,
12698
- endDate
12699
- );
12700
- } catch (error) {
12701
- console.error(
12702
- "[APPOINTMENT_SERVICE] Error getting available booking slots:",
12703
- error
12704
- );
12705
- throw error;
12706
- }
12707
- }
12708
12481
  /**
12709
12482
  * Gets available booking slots for a specific clinic, practitioner, and procedure using HTTP request.
12710
12483
  * This is an alternative implementation using direct HTTP request instead of callable function.
@@ -12806,34 +12579,81 @@ var AppointmentService = class extends BaseService {
12806
12579
  }
12807
12580
  }
12808
12581
  /**
12809
- * Creates a new appointment.
12582
+ * Creates an appointment via the Cloud Function orchestrateAppointmentCreation
12810
12583
  *
12811
- * @param data Data needed to create the appointment
12584
+ * @param data - CreateAppointmentData object
12812
12585
  * @returns The created appointment
12813
12586
  */
12814
- async createAppointment(data) {
12587
+ async createAppointmentHttp(data) {
12815
12588
  try {
12816
- console.log("[APPOINTMENT_SERVICE] Creating appointment");
12817
- const validatedData = await createAppointmentSchema.parseAsync(data);
12818
- const aggregatedInfo = await fetchAggregatedInfoUtil(
12819
- this.db,
12820
- validatedData.clinicBranchId,
12821
- validatedData.practitionerId,
12822
- validatedData.patientId,
12823
- validatedData.procedureId
12589
+ console.log(
12590
+ "[APPOINTMENT_SERVICE] Creating appointment via cloud function"
12824
12591
  );
12825
- const appointment = await createAppointmentUtil2(
12826
- this.db,
12827
- validatedData,
12828
- aggregatedInfo,
12829
- this.generateId.bind(this)
12592
+ const currentUser = this.auth.currentUser;
12593
+ if (!currentUser) {
12594
+ throw new Error("User must be authenticated to create an appointment");
12595
+ }
12596
+ const idToken = await currentUser.getIdToken();
12597
+ const functionUrl = `https://europe-west6-metaestetics.cloudfunctions.net/bookingApi/orchestrateAppointmentCreation`;
12598
+ const requestData = {
12599
+ patientId: data.patientId,
12600
+ procedureId: data.procedureId,
12601
+ appointmentStartTime: data.appointmentStartTime.toMillis ? data.appointmentStartTime.toMillis() : new Date(data.appointmentStartTime).getTime(),
12602
+ appointmentEndTime: data.appointmentEndTime.toMillis ? data.appointmentEndTime.toMillis() : new Date(data.appointmentEndTime).getTime(),
12603
+ patientNotes: data.patientNotes || null
12604
+ };
12605
+ console.log(
12606
+ `[APPOINTMENT_SERVICE] Making fetch request to ${functionUrl}`
12830
12607
  );
12608
+ const response = await fetch(functionUrl, {
12609
+ method: "POST",
12610
+ mode: "cors",
12611
+ cache: "no-cache",
12612
+ credentials: "omit",
12613
+ headers: {
12614
+ "Content-Type": "application/json",
12615
+ Authorization: `Bearer ${idToken}`
12616
+ },
12617
+ redirect: "follow",
12618
+ referrerPolicy: "no-referrer",
12619
+ body: JSON.stringify(requestData)
12620
+ });
12831
12621
  console.log(
12832
- `[APPOINTMENT_SERVICE] Appointment created with ID: ${appointment.id}`
12622
+ `[APPOINTMENT_SERVICE] Received response ${response.status}: ${response.statusText}`
12833
12623
  );
12834
- return appointment;
12624
+ if (!response.ok) {
12625
+ const errorText = await response.text();
12626
+ console.error(
12627
+ `[APPOINTMENT_SERVICE] Error response details: ${errorText}`
12628
+ );
12629
+ throw new Error(
12630
+ `Failed to create appointment: ${response.status} ${response.statusText} - ${errorText}`
12631
+ );
12632
+ }
12633
+ const result = await response.json();
12634
+ if (!result.success) {
12635
+ throw new Error(result.error || "Failed to create appointment");
12636
+ }
12637
+ if (result.appointmentData) {
12638
+ console.log(
12639
+ `[APPOINTMENT_SERVICE] Appointment created with ID: ${result.appointmentId}`
12640
+ );
12641
+ return result.appointmentData;
12642
+ }
12643
+ const createdAppointment = await this.getAppointmentById(
12644
+ result.appointmentId
12645
+ );
12646
+ if (!createdAppointment) {
12647
+ throw new Error(
12648
+ `Failed to retrieve created appointment with ID: ${result.appointmentId}`
12649
+ );
12650
+ }
12651
+ return createdAppointment;
12835
12652
  } catch (error) {
12836
- console.error("[APPOINTMENT_SERVICE] Error creating appointment:", error);
12653
+ console.error(
12654
+ "[APPOINTMENT_SERVICE] Error creating appointment via cloud function:",
12655
+ error
12656
+ );
12837
12657
  throw error;
12838
12658
  }
12839
12659
  }
@@ -13323,38 +13143,6 @@ var AppointmentService = class extends BaseService {
13323
13143
  };
13324
13144
  return this.updateAppointment(appointmentId, updateData);
13325
13145
  }
13326
- /**
13327
- * Marks pre-procedure requirements as completed.
13328
- *
13329
- * @param appointmentId ID of the appointment
13330
- * @param requirementIds IDs of the requirements to mark as completed
13331
- * @returns The updated appointment
13332
- */
13333
- async completePreRequirements(appointmentId, requirementIds) {
13334
- console.log(
13335
- `[APPOINTMENT_SERVICE] Marking pre-requirements as completed for appointment: ${appointmentId}`
13336
- );
13337
- const updateData = {
13338
- completedPreRequirements: requirementIds
13339
- };
13340
- return this.updateAppointment(appointmentId, updateData);
13341
- }
13342
- /**
13343
- * Marks post-procedure requirements as completed.
13344
- *
13345
- * @param appointmentId ID of the appointment
13346
- * @param requirementIds IDs of the requirements to mark as completed
13347
- * @returns The updated appointment
13348
- */
13349
- async completePostRequirements(appointmentId, requirementIds) {
13350
- console.log(
13351
- `[APPOINTMENT_SERVICE] Marking post-requirements as completed for appointment: ${appointmentId}`
13352
- );
13353
- const updateData = {
13354
- completedPostRequirements: requirementIds
13355
- };
13356
- return this.updateAppointment(appointmentId, updateData);
13357
- }
13358
13146
  /**
13359
13147
  * Updates the internal notes of an appointment.
13360
13148
  *
@@ -13371,25 +13159,6 @@ var AppointmentService = class extends BaseService {
13371
13159
  };
13372
13160
  return this.updateAppointment(appointmentId, updateData);
13373
13161
  }
13374
- /**
13375
- * Debug helper: Get the current user's ID token for testing purposes
13376
- * Use this token in Postman with Authorization: Bearer TOKEN
13377
- */
13378
- async getDebugToken() {
13379
- try {
13380
- const currentUser = this.auth.currentUser;
13381
- if (!currentUser) {
13382
- console.log("[APPOINTMENT_SERVICE] No user is signed in");
13383
- return null;
13384
- }
13385
- const idToken = await currentUser.getIdToken();
13386
- console.log("[APPOINTMENT_SERVICE] Debug token:", idToken);
13387
- return idToken;
13388
- } catch (error) {
13389
- console.error("[APPOINTMENT_SERVICE] Error getting debug token:", error);
13390
- return null;
13391
- }
13392
- }
13393
13162
  };
13394
13163
 
13395
13164
  // src/services/patient/patientRequirements.service.ts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.6.4",
4
+ "version": "1.6.5",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",