@blackcode_sa/metaestetics-api 1.14.56 → 1.14.57
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/admin/index.d.mts +4 -2
- package/dist/admin/index.d.ts +4 -2
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +101 -15
- package/dist/index.mjs +229 -141
- package/package.json +1 -1
- package/src/services/appointment/appointment.service.ts +41 -9
- package/src/services/appointment/utils/extended-procedure.utils.ts +1 -0
- package/src/services/appointment/utils/form-initialization.utils.ts +2 -0
- package/src/services/appointment/utils/zone-management.utils.ts +50 -3
- package/src/services/appointment/utils/zone-photo.utils.ts +39 -1
- package/src/types/appointment/index.ts +4 -2
- package/src/validations/appointment.schema.ts +2 -1
package/dist/admin/index.d.mts
CHANGED
|
@@ -1659,6 +1659,7 @@ interface LinkedFormInfo {
|
|
|
1659
1659
|
path: string;
|
|
1660
1660
|
submittedAt?: Timestamp;
|
|
1661
1661
|
completedAt?: Timestamp;
|
|
1662
|
+
procedureId?: string;
|
|
1662
1663
|
}
|
|
1663
1664
|
/**
|
|
1664
1665
|
* Interface for summarized patient review information linked to an appointment.
|
|
@@ -1713,8 +1714,8 @@ interface ZoneItemData {
|
|
|
1713
1714
|
notes?: string;
|
|
1714
1715
|
notesVisibleToPatient?: boolean;
|
|
1715
1716
|
subtotal?: number;
|
|
1716
|
-
ionNumber?: string;
|
|
1717
|
-
expiryDate?: string;
|
|
1717
|
+
ionNumber?: string | null;
|
|
1718
|
+
expiryDate?: string | null;
|
|
1718
1719
|
createdAt?: string;
|
|
1719
1720
|
updatedAt?: string;
|
|
1720
1721
|
}
|
|
@@ -1767,6 +1768,7 @@ interface ExtendedProcedureInfo {
|
|
|
1767
1768
|
procedureId: string;
|
|
1768
1769
|
procedureName: string;
|
|
1769
1770
|
procedureDescription?: string;
|
|
1771
|
+
procedurePrice?: number;
|
|
1770
1772
|
procedureFamily?: ProcedureFamily;
|
|
1771
1773
|
procedureCategoryId: string;
|
|
1772
1774
|
procedureCategoryName: string;
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -1659,6 +1659,7 @@ interface LinkedFormInfo {
|
|
|
1659
1659
|
path: string;
|
|
1660
1660
|
submittedAt?: Timestamp;
|
|
1661
1661
|
completedAt?: Timestamp;
|
|
1662
|
+
procedureId?: string;
|
|
1662
1663
|
}
|
|
1663
1664
|
/**
|
|
1664
1665
|
* Interface for summarized patient review information linked to an appointment.
|
|
@@ -1713,8 +1714,8 @@ interface ZoneItemData {
|
|
|
1713
1714
|
notes?: string;
|
|
1714
1715
|
notesVisibleToPatient?: boolean;
|
|
1715
1716
|
subtotal?: number;
|
|
1716
|
-
ionNumber?: string;
|
|
1717
|
-
expiryDate?: string;
|
|
1717
|
+
ionNumber?: string | null;
|
|
1718
|
+
expiryDate?: string | null;
|
|
1718
1719
|
createdAt?: string;
|
|
1719
1720
|
updatedAt?: string;
|
|
1720
1721
|
}
|
|
@@ -1767,6 +1768,7 @@ interface ExtendedProcedureInfo {
|
|
|
1767
1768
|
procedureId: string;
|
|
1768
1769
|
procedureName: string;
|
|
1769
1770
|
procedureDescription?: string;
|
|
1771
|
+
procedurePrice?: number;
|
|
1770
1772
|
procedureFamily?: ProcedureFamily;
|
|
1771
1773
|
procedureCategoryId: string;
|
|
1772
1774
|
procedureCategoryName: string;
|
package/dist/index.d.mts
CHANGED
|
@@ -5586,6 +5586,7 @@ interface LinkedFormInfo {
|
|
|
5586
5586
|
path: string;
|
|
5587
5587
|
submittedAt?: Timestamp;
|
|
5588
5588
|
completedAt?: Timestamp;
|
|
5589
|
+
procedureId?: string;
|
|
5589
5590
|
}
|
|
5590
5591
|
/**
|
|
5591
5592
|
* Interface for summarized patient review information linked to an appointment.
|
|
@@ -5650,8 +5651,8 @@ interface ZoneItemData {
|
|
|
5650
5651
|
notes?: string;
|
|
5651
5652
|
notesVisibleToPatient?: boolean;
|
|
5652
5653
|
subtotal?: number;
|
|
5653
|
-
ionNumber?: string;
|
|
5654
|
-
expiryDate?: string;
|
|
5654
|
+
ionNumber?: string | null;
|
|
5655
|
+
expiryDate?: string | null;
|
|
5655
5656
|
createdAt?: string;
|
|
5656
5657
|
updatedAt?: string;
|
|
5657
5658
|
}
|
|
@@ -5704,6 +5705,7 @@ interface ExtendedProcedureInfo {
|
|
|
5704
5705
|
procedureId: string;
|
|
5705
5706
|
procedureName: string;
|
|
5706
5707
|
procedureDescription?: string;
|
|
5708
|
+
procedurePrice?: number;
|
|
5707
5709
|
procedureFamily?: ProcedureFamily;
|
|
5708
5710
|
procedureCategoryId: string;
|
|
5709
5711
|
procedureCategoryName: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -5586,6 +5586,7 @@ interface LinkedFormInfo {
|
|
|
5586
5586
|
path: string;
|
|
5587
5587
|
submittedAt?: Timestamp;
|
|
5588
5588
|
completedAt?: Timestamp;
|
|
5589
|
+
procedureId?: string;
|
|
5589
5590
|
}
|
|
5590
5591
|
/**
|
|
5591
5592
|
* Interface for summarized patient review information linked to an appointment.
|
|
@@ -5650,8 +5651,8 @@ interface ZoneItemData {
|
|
|
5650
5651
|
notes?: string;
|
|
5651
5652
|
notesVisibleToPatient?: boolean;
|
|
5652
5653
|
subtotal?: number;
|
|
5653
|
-
ionNumber?: string;
|
|
5654
|
-
expiryDate?: string;
|
|
5654
|
+
ionNumber?: string | null;
|
|
5655
|
+
expiryDate?: string | null;
|
|
5655
5656
|
createdAt?: string;
|
|
5656
5657
|
updatedAt?: string;
|
|
5657
5658
|
}
|
|
@@ -5704,6 +5705,7 @@ interface ExtendedProcedureInfo {
|
|
|
5704
5705
|
procedureId: string;
|
|
5705
5706
|
procedureName: string;
|
|
5706
5707
|
procedureDescription?: string;
|
|
5708
|
+
procedurePrice?: number;
|
|
5707
5709
|
procedureFamily?: ProcedureFamily;
|
|
5708
5710
|
procedureCategoryId: string;
|
|
5709
5711
|
procedureCategoryName: string;
|
package/dist/index.js
CHANGED
|
@@ -3970,7 +3970,10 @@ var zoneItemDataSchema = import_zod3.z.object({
|
|
|
3970
3970
|
notes: import_zod3.z.string().max(MAX_STRING_LENGTH_LONG, "Notes too long").optional(),
|
|
3971
3971
|
notesVisibleToPatient: import_zod3.z.boolean().optional().default(false),
|
|
3972
3972
|
subtotal: import_zod3.z.number().min(0, "Subtotal must be non-negative").optional(),
|
|
3973
|
-
ionNumber: import_zod3.z.string().optional(),
|
|
3973
|
+
ionNumber: import_zod3.z.string().nullable().optional(),
|
|
3974
|
+
// Batch/Lot number - can be null to clear/delete
|
|
3975
|
+
expiryDate: import_zod3.z.string().nullable().optional(),
|
|
3976
|
+
// ISO date string (YYYY-MM-DD) - can be null to clear/delete
|
|
3974
3977
|
createdAt: import_zod3.z.string().optional(),
|
|
3975
3978
|
updatedAt: import_zod3.z.string().optional()
|
|
3976
3979
|
}).refine(
|
|
@@ -4900,6 +4903,7 @@ async function removeItemFromZoneUtil(db, appointmentId, zoneId, itemIndex) {
|
|
|
4900
4903
|
return getAppointmentOrThrow(db, appointmentId);
|
|
4901
4904
|
}
|
|
4902
4905
|
async function updateZoneItemUtil(db, appointmentId, zoneId, itemIndex, updates) {
|
|
4906
|
+
var _a, _b, _c, _d;
|
|
4903
4907
|
validateZoneKeyFormat(zoneId);
|
|
4904
4908
|
const appointment = await getAppointmentOrThrow(db, appointmentId);
|
|
4905
4909
|
const metadata = initializeMetadata(appointment);
|
|
@@ -4910,17 +4914,37 @@ async function updateZoneItemUtil(db, appointmentId, zoneId, itemIndex, updates)
|
|
|
4910
4914
|
if (itemIndex < 0 || itemIndex >= items.length) {
|
|
4911
4915
|
throw new Error(`Invalid item index ${itemIndex} for zone ${zoneId}`);
|
|
4912
4916
|
}
|
|
4917
|
+
const cleanUpdates = Object.fromEntries(
|
|
4918
|
+
Object.entries(updates).filter(([_, value]) => value !== void 0).map(([key, value]) => [
|
|
4919
|
+
key,
|
|
4920
|
+
value === "" ? null : value
|
|
4921
|
+
// Convert empty strings to null
|
|
4922
|
+
])
|
|
4923
|
+
);
|
|
4924
|
+
console.log(`[updateZoneItemUtil] Updates received:`, {
|
|
4925
|
+
itemIndex,
|
|
4926
|
+
zoneId,
|
|
4927
|
+
rawUpdates: updates,
|
|
4928
|
+
cleanUpdates,
|
|
4929
|
+
hasIonNumber: "ionNumber" in cleanUpdates,
|
|
4930
|
+
hasExpiryDate: "expiryDate" in cleanUpdates,
|
|
4931
|
+
ionNumberValue: cleanUpdates.ionNumber,
|
|
4932
|
+
expiryDateValue: cleanUpdates.expiryDate
|
|
4933
|
+
});
|
|
4913
4934
|
items[itemIndex] = {
|
|
4914
4935
|
...items[itemIndex],
|
|
4915
|
-
...
|
|
4936
|
+
...cleanUpdates,
|
|
4916
4937
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4917
4938
|
};
|
|
4918
|
-
console.log(`[updateZoneItemUtil]
|
|
4939
|
+
console.log(`[updateZoneItemUtil] Item after update:`, {
|
|
4919
4940
|
itemIndex,
|
|
4941
|
+
ionNumber: items[itemIndex].ionNumber,
|
|
4942
|
+
expiryDate: items[itemIndex].expiryDate,
|
|
4920
4943
|
quantity: items[itemIndex].quantity,
|
|
4921
4944
|
priceOverrideAmount: items[itemIndex].priceOverrideAmount,
|
|
4922
4945
|
price: items[itemIndex].price,
|
|
4923
|
-
oldSubtotal: items[itemIndex].subtotal
|
|
4946
|
+
oldSubtotal: items[itemIndex].subtotal,
|
|
4947
|
+
allItemKeys: Object.keys(items[itemIndex])
|
|
4924
4948
|
});
|
|
4925
4949
|
items[itemIndex].subtotal = calculateItemSubtotal(items[itemIndex]);
|
|
4926
4950
|
console.log(`[updateZoneItemUtil] AFTER recalculation:`, {
|
|
@@ -4928,13 +4952,30 @@ async function updateZoneItemUtil(db, appointmentId, zoneId, itemIndex, updates)
|
|
|
4928
4952
|
newSubtotal: items[itemIndex].subtotal
|
|
4929
4953
|
});
|
|
4930
4954
|
const finalbilling = calculateFinalBilling(metadata.zonesData, 0.081);
|
|
4955
|
+
console.log(`[updateZoneItemUtil] Saving to Firestore:`, {
|
|
4956
|
+
appointmentId,
|
|
4957
|
+
zoneId,
|
|
4958
|
+
itemIndex,
|
|
4959
|
+
itemToSave: items[itemIndex],
|
|
4960
|
+
itemIonNumber: items[itemIndex].ionNumber,
|
|
4961
|
+
itemExpiryDate: items[itemIndex].expiryDate,
|
|
4962
|
+
zonesDataKeys: Object.keys(metadata.zonesData),
|
|
4963
|
+
zoneItemsCount: (_a = metadata.zonesData[zoneId]) == null ? void 0 : _a.length
|
|
4964
|
+
});
|
|
4931
4965
|
const appointmentRef = (0, import_firestore8.doc)(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
4932
4966
|
await (0, import_firestore7.updateDoc)(appointmentRef, {
|
|
4933
4967
|
"metadata.zonesData": metadata.zonesData,
|
|
4934
4968
|
"metadata.finalbilling": finalbilling,
|
|
4935
4969
|
updatedAt: (0, import_firestore7.serverTimestamp)()
|
|
4936
4970
|
});
|
|
4937
|
-
|
|
4971
|
+
const savedAppointment = await getAppointmentOrThrow(db, appointmentId);
|
|
4972
|
+
const savedItem = (_d = (_c = (_b = savedAppointment.metadata) == null ? void 0 : _b.zonesData) == null ? void 0 : _c[zoneId]) == null ? void 0 : _d[itemIndex];
|
|
4973
|
+
console.log(`[updateZoneItemUtil] Verification after save:`, {
|
|
4974
|
+
savedItemIonNumber: savedItem == null ? void 0 : savedItem.ionNumber,
|
|
4975
|
+
savedItemExpiryDate: savedItem == null ? void 0 : savedItem.expiryDate,
|
|
4976
|
+
savedItemKeys: savedItem ? Object.keys(savedItem) : []
|
|
4977
|
+
});
|
|
4978
|
+
return savedAppointment;
|
|
4938
4979
|
}
|
|
4939
4980
|
async function overridePriceForZoneItemUtil(db, appointmentId, zoneId, itemIndex, newPrice) {
|
|
4940
4981
|
return updateZoneItemUtil(db, appointmentId, zoneId, itemIndex, {
|
|
@@ -5064,7 +5105,9 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
5064
5105
|
isRequired,
|
|
5065
5106
|
sortingOrder: templateRef.sortingOrder,
|
|
5066
5107
|
status: existingForm.status || "pending" /* PENDING */,
|
|
5067
|
-
path: `${APPOINTMENTS_COLLECTION}/${appointmentId}/${formSubcollectionPath}/${existingForm.id}
|
|
5108
|
+
path: `${APPOINTMENTS_COLLECTION}/${appointmentId}/${formSubcollectionPath}/${existingForm.id}`,
|
|
5109
|
+
procedureId
|
|
5110
|
+
// Track which procedure this form belongs to
|
|
5068
5111
|
};
|
|
5069
5112
|
initializedFormsInfo.push(linkedForm);
|
|
5070
5113
|
if (!allLinkedFormIds.includes(existingForm.id)) {
|
|
@@ -5118,7 +5161,9 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
5118
5161
|
isRequired,
|
|
5119
5162
|
sortingOrder: templateRef.sortingOrder,
|
|
5120
5163
|
status: "pending" /* PENDING */,
|
|
5121
|
-
path: docRef.path
|
|
5164
|
+
path: docRef.path,
|
|
5165
|
+
procedureId
|
|
5166
|
+
// Track which procedure this form belongs to
|
|
5122
5167
|
};
|
|
5123
5168
|
initializedFormsInfo.push(linkedForm);
|
|
5124
5169
|
const formType = isProcedureSpecific ? "procedure-specific" : "general/shared";
|
|
@@ -5311,6 +5356,7 @@ async function createExtendedProcedureInfo(db, procedureId) {
|
|
|
5311
5356
|
procedureId,
|
|
5312
5357
|
procedureName: data.name,
|
|
5313
5358
|
procedureDescription: data.description || "",
|
|
5359
|
+
procedurePrice: data.price || 0,
|
|
5314
5360
|
procedureFamily: data.family,
|
|
5315
5361
|
// Use embedded family object
|
|
5316
5362
|
procedureCategoryId: data.category.id,
|
|
@@ -5638,16 +5684,37 @@ async function getZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex) {
|
|
|
5638
5684
|
return zoneArray[photoIndex];
|
|
5639
5685
|
}
|
|
5640
5686
|
async function updateZonePhotoVisibilityUtil(db, appointmentId, zoneId, photoIndex, showToPatient, doctorId) {
|
|
5687
|
+
const updates = { showToPatient };
|
|
5688
|
+
if (!showToPatient) {
|
|
5689
|
+
updates.beforeNoteVisibleToPatient = false;
|
|
5690
|
+
updates.afterNoteVisibleToPatient = false;
|
|
5691
|
+
}
|
|
5641
5692
|
return updateZonePhotoEntryUtil(
|
|
5642
5693
|
db,
|
|
5643
5694
|
appointmentId,
|
|
5644
5695
|
zoneId,
|
|
5645
5696
|
photoIndex,
|
|
5646
|
-
|
|
5697
|
+
updates,
|
|
5647
5698
|
doctorId
|
|
5648
5699
|
);
|
|
5649
5700
|
}
|
|
5650
5701
|
async function updateZonePhotoNoteVisibilityUtil(db, appointmentId, zoneId, photoIndex, noteType, visibleToPatient, doctorId) {
|
|
5702
|
+
var _a;
|
|
5703
|
+
const appointment = await getAppointmentOrThrow(db, appointmentId);
|
|
5704
|
+
const zonePhotos = (_a = appointment.metadata) == null ? void 0 : _a.zonePhotos;
|
|
5705
|
+
if (!zonePhotos || !zonePhotos[zoneId] || !Array.isArray(zonePhotos[zoneId])) {
|
|
5706
|
+
throw new Error(`No photos found for zone ${zoneId} in appointment ${appointmentId}`);
|
|
5707
|
+
}
|
|
5708
|
+
const zoneArray = zonePhotos[zoneId];
|
|
5709
|
+
if (photoIndex < 0 || photoIndex >= zoneArray.length) {
|
|
5710
|
+
throw new Error(`Invalid photo index ${photoIndex} for zone ${zoneId}. Must be between 0 and ${zoneArray.length - 1}`);
|
|
5711
|
+
}
|
|
5712
|
+
const photoEntry = zoneArray[photoIndex];
|
|
5713
|
+
if (visibleToPatient && !photoEntry.showToPatient) {
|
|
5714
|
+
throw new Error(
|
|
5715
|
+
'Cannot make note visible to patient: The photo pair must be visible to the patient first. Please enable "Show to Patient" for the photo pair before making notes visible.'
|
|
5716
|
+
);
|
|
5717
|
+
}
|
|
5651
5718
|
const updates = noteType === "before" ? { beforeNoteVisibleToPatient: visibleToPatient } : { afterNoteVisibleToPatient: visibleToPatient };
|
|
5652
5719
|
return updateZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex, updates, doctorId);
|
|
5653
5720
|
}
|
|
@@ -7291,6 +7358,8 @@ var AppointmentService = class extends BaseService {
|
|
|
7291
7358
|
finalizationNotesInternal: currentMetadata.finalizationNotesInternal,
|
|
7292
7359
|
finalizationNotes: currentMetadata.finalizationNotes
|
|
7293
7360
|
});
|
|
7361
|
+
const normalizedSharedNotes = sharedNotes !== void 0 ? sharedNotes === "" || sharedNotes === null ? null : sharedNotes : currentMetadata.finalizationNotesShared;
|
|
7362
|
+
const normalizedInternalNotes = internalNotes !== void 0 ? internalNotes === "" || internalNotes === null ? null : internalNotes : currentMetadata.finalizationNotesInternal;
|
|
7294
7363
|
const metadataUpdate = {
|
|
7295
7364
|
selectedZones: currentMetadata.selectedZones,
|
|
7296
7365
|
zonePhotos: currentMetadata.zonePhotos,
|
|
@@ -7299,21 +7368,38 @@ var AppointmentService = class extends BaseService {
|
|
|
7299
7368
|
extendedProcedures: currentMetadata.extendedProcedures || [],
|
|
7300
7369
|
recommendedProcedures: currentMetadata.recommendedProcedures || [],
|
|
7301
7370
|
finalbilling: currentMetadata.finalbilling,
|
|
7302
|
-
finalizationNotesShared:
|
|
7303
|
-
finalizationNotesInternal:
|
|
7371
|
+
finalizationNotesShared: normalizedSharedNotes,
|
|
7372
|
+
finalizationNotesInternal: normalizedInternalNotes,
|
|
7304
7373
|
// Keep deprecated field for backward compatibility during migration
|
|
7305
|
-
finalizationNotes:
|
|
7374
|
+
finalizationNotes: normalizedSharedNotes !== null && normalizedSharedNotes !== void 0 ? normalizedSharedNotes : currentMetadata.finalizationNotes || currentMetadata.finalizationNotesShared
|
|
7306
7375
|
};
|
|
7307
7376
|
console.log("\u{1F50D} [APPOINTMENT_SERVICE] Update data metadata:", {
|
|
7308
7377
|
finalizationNotesShared: metadataUpdate.finalizationNotesShared,
|
|
7309
7378
|
finalizationNotesInternal: metadataUpdate.finalizationNotesInternal,
|
|
7310
|
-
finalizationNotes: metadataUpdate.finalizationNotes
|
|
7379
|
+
finalizationNotes: metadataUpdate.finalizationNotes,
|
|
7380
|
+
normalizedSharedNotes,
|
|
7381
|
+
normalizedInternalNotes
|
|
7311
7382
|
});
|
|
7312
|
-
const
|
|
7313
|
-
|
|
7383
|
+
const appointmentRef = (0, import_firestore14.doc)(this.db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
7384
|
+
const updateFields = {
|
|
7385
|
+
"metadata.finalizationNotesShared": normalizedSharedNotes,
|
|
7386
|
+
"metadata.finalizationNotesInternal": normalizedInternalNotes,
|
|
7387
|
+
"metadata.finalizationNotes": normalizedSharedNotes !== null && normalizedSharedNotes !== void 0 ? normalizedSharedNotes : currentMetadata.finalizationNotes || currentMetadata.finalizationNotesShared,
|
|
7314
7388
|
updatedAt: (0, import_firestore14.serverTimestamp)()
|
|
7315
7389
|
};
|
|
7316
|
-
|
|
7390
|
+
console.log("\u{1F50D} [APPOINTMENT_SERVICE] Direct Firestore update with dot notation:", {
|
|
7391
|
+
appointmentId,
|
|
7392
|
+
updateFields: {
|
|
7393
|
+
"metadata.finalizationNotesShared": updateFields["metadata.finalizationNotesShared"],
|
|
7394
|
+
"metadata.finalizationNotesInternal": updateFields["metadata.finalizationNotesInternal"],
|
|
7395
|
+
"metadata.finalizationNotes": updateFields["metadata.finalizationNotes"]
|
|
7396
|
+
}
|
|
7397
|
+
});
|
|
7398
|
+
await (0, import_firestore14.updateDoc)(appointmentRef, updateFields);
|
|
7399
|
+
const result = await this.getAppointmentById(appointmentId);
|
|
7400
|
+
if (!result) {
|
|
7401
|
+
throw new Error(`Failed to retrieve updated appointment ${appointmentId}`);
|
|
7402
|
+
}
|
|
7317
7403
|
console.log("\u{1F50D} [APPOINTMENT_SERVICE] After update, result metadata:", {
|
|
7318
7404
|
finalizationNotesShared: (_a = result.metadata) == null ? void 0 : _a.finalizationNotesShared,
|
|
7319
7405
|
finalizationNotesInternal: (_b = result.metadata) == null ? void 0 : _b.finalizationNotesInternal,
|