@blackcode_sa/metaestetics-api 1.14.43 → 1.14.45
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 +21 -3
- package/dist/admin/index.d.ts +21 -3
- package/dist/index.d.mts +53 -3
- package/dist/index.d.ts +53 -3
- package/dist/index.js +184 -11
- package/dist/index.mjs +184 -11
- package/package.json +1 -1
- package/src/services/appointment/appointment.service.ts +167 -5
- package/src/services/appointment/utils/zone-management.utils.ts +5 -1
- package/src/services/appointment/utils/zone-photo.utils.ts +91 -3
- package/src/types/appointment/index.ts +21 -3
- package/src/validations/appointment.schema.ts +10 -2
package/dist/admin/index.d.mts
CHANGED
|
@@ -1677,9 +1677,20 @@ interface BeforeAfterPerZone {
|
|
|
1677
1677
|
before: MediaResource | null;
|
|
1678
1678
|
/** URL for after photo or null if not available */
|
|
1679
1679
|
after: MediaResource | null;
|
|
1680
|
-
/** Optional note for the
|
|
1681
|
-
afterNote?: string | null;
|
|
1680
|
+
/** Optional note for the before photo */
|
|
1682
1681
|
beforeNote?: string | null;
|
|
1682
|
+
/** Optional note for the after photo */
|
|
1683
|
+
afterNote?: string | null;
|
|
1684
|
+
/** Whether this photo pair (before AND after) should be visible to the patient */
|
|
1685
|
+
showToPatient?: boolean;
|
|
1686
|
+
/** Whether the before note should be visible to the patient */
|
|
1687
|
+
beforeNoteVisibleToPatient?: boolean;
|
|
1688
|
+
/** Whether the after note should be visible to the patient */
|
|
1689
|
+
afterNoteVisibleToPatient?: boolean;
|
|
1690
|
+
/** Timestamp when visibility was last updated */
|
|
1691
|
+
visibilityUpdatedAt?: Timestamp;
|
|
1692
|
+
/** ID of the doctor who last updated visibility */
|
|
1693
|
+
visibilityUpdatedBy?: string;
|
|
1683
1694
|
}
|
|
1684
1695
|
/**
|
|
1685
1696
|
* Interface for zone item data (products or notes per zone)
|
|
@@ -1786,7 +1797,14 @@ interface AppointmentMetadata {
|
|
|
1786
1797
|
extendedProcedures?: ExtendedProcedureInfo[];
|
|
1787
1798
|
recommendedProcedures: RecommendedProcedure[];
|
|
1788
1799
|
finalbilling: FinalBilling | null;
|
|
1789
|
-
|
|
1800
|
+
/** Final treatment notes shared with patient */
|
|
1801
|
+
finalizationNotesShared?: string | null;
|
|
1802
|
+
/** Final treatment notes for internal use only (not shared with patient) */
|
|
1803
|
+
finalizationNotesInternal?: string | null;
|
|
1804
|
+
/**
|
|
1805
|
+
* @deprecated Use finalizationNotesShared instead. Kept for backward compatibility during migration.
|
|
1806
|
+
*/
|
|
1807
|
+
finalizationNotes?: string | null;
|
|
1790
1808
|
/**
|
|
1791
1809
|
* @deprecated Use zonesData instead
|
|
1792
1810
|
*/
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -1677,9 +1677,20 @@ interface BeforeAfterPerZone {
|
|
|
1677
1677
|
before: MediaResource | null;
|
|
1678
1678
|
/** URL for after photo or null if not available */
|
|
1679
1679
|
after: MediaResource | null;
|
|
1680
|
-
/** Optional note for the
|
|
1681
|
-
afterNote?: string | null;
|
|
1680
|
+
/** Optional note for the before photo */
|
|
1682
1681
|
beforeNote?: string | null;
|
|
1682
|
+
/** Optional note for the after photo */
|
|
1683
|
+
afterNote?: string | null;
|
|
1684
|
+
/** Whether this photo pair (before AND after) should be visible to the patient */
|
|
1685
|
+
showToPatient?: boolean;
|
|
1686
|
+
/** Whether the before note should be visible to the patient */
|
|
1687
|
+
beforeNoteVisibleToPatient?: boolean;
|
|
1688
|
+
/** Whether the after note should be visible to the patient */
|
|
1689
|
+
afterNoteVisibleToPatient?: boolean;
|
|
1690
|
+
/** Timestamp when visibility was last updated */
|
|
1691
|
+
visibilityUpdatedAt?: Timestamp;
|
|
1692
|
+
/** ID of the doctor who last updated visibility */
|
|
1693
|
+
visibilityUpdatedBy?: string;
|
|
1683
1694
|
}
|
|
1684
1695
|
/**
|
|
1685
1696
|
* Interface for zone item data (products or notes per zone)
|
|
@@ -1786,7 +1797,14 @@ interface AppointmentMetadata {
|
|
|
1786
1797
|
extendedProcedures?: ExtendedProcedureInfo[];
|
|
1787
1798
|
recommendedProcedures: RecommendedProcedure[];
|
|
1788
1799
|
finalbilling: FinalBilling | null;
|
|
1789
|
-
|
|
1800
|
+
/** Final treatment notes shared with patient */
|
|
1801
|
+
finalizationNotesShared?: string | null;
|
|
1802
|
+
/** Final treatment notes for internal use only (not shared with patient) */
|
|
1803
|
+
finalizationNotesInternal?: string | null;
|
|
1804
|
+
/**
|
|
1805
|
+
* @deprecated Use finalizationNotesShared instead. Kept for backward compatibility during migration.
|
|
1806
|
+
*/
|
|
1807
|
+
finalizationNotes?: string | null;
|
|
1790
1808
|
/**
|
|
1791
1809
|
* @deprecated Use zonesData instead
|
|
1792
1810
|
*/
|
package/dist/index.d.mts
CHANGED
|
@@ -5604,9 +5604,20 @@ interface BeforeAfterPerZone {
|
|
|
5604
5604
|
before: MediaResource | null;
|
|
5605
5605
|
/** URL for after photo or null if not available */
|
|
5606
5606
|
after: MediaResource | null;
|
|
5607
|
-
/** Optional note for the
|
|
5608
|
-
afterNote?: string | null;
|
|
5607
|
+
/** Optional note for the before photo */
|
|
5609
5608
|
beforeNote?: string | null;
|
|
5609
|
+
/** Optional note for the after photo */
|
|
5610
|
+
afterNote?: string | null;
|
|
5611
|
+
/** Whether this photo pair (before AND after) should be visible to the patient */
|
|
5612
|
+
showToPatient?: boolean;
|
|
5613
|
+
/** Whether the before note should be visible to the patient */
|
|
5614
|
+
beforeNoteVisibleToPatient?: boolean;
|
|
5615
|
+
/** Whether the after note should be visible to the patient */
|
|
5616
|
+
afterNoteVisibleToPatient?: boolean;
|
|
5617
|
+
/** Timestamp when visibility was last updated */
|
|
5618
|
+
visibilityUpdatedAt?: Timestamp;
|
|
5619
|
+
/** ID of the doctor who last updated visibility */
|
|
5620
|
+
visibilityUpdatedBy?: string;
|
|
5610
5621
|
}
|
|
5611
5622
|
/**
|
|
5612
5623
|
* Interface for zone photo upload data
|
|
@@ -5723,7 +5734,14 @@ interface AppointmentMetadata {
|
|
|
5723
5734
|
extendedProcedures?: ExtendedProcedureInfo[];
|
|
5724
5735
|
recommendedProcedures: RecommendedProcedure[];
|
|
5725
5736
|
finalbilling: FinalBilling | null;
|
|
5726
|
-
|
|
5737
|
+
/** Final treatment notes shared with patient */
|
|
5738
|
+
finalizationNotesShared?: string | null;
|
|
5739
|
+
/** Final treatment notes for internal use only (not shared with patient) */
|
|
5740
|
+
finalizationNotesInternal?: string | null;
|
|
5741
|
+
/**
|
|
5742
|
+
* @deprecated Use finalizationNotesShared instead. Kept for backward compatibility during migration.
|
|
5743
|
+
*/
|
|
5744
|
+
finalizationNotes?: string | null;
|
|
5727
5745
|
/**
|
|
5728
5746
|
* @deprecated Use zonesData instead
|
|
5729
5747
|
*/
|
|
@@ -7694,6 +7712,29 @@ declare class AppointmentService extends BaseService {
|
|
|
7694
7712
|
* @returns The updated appointment
|
|
7695
7713
|
*/
|
|
7696
7714
|
updateZonePhotoNotes(appointmentId: string, zoneId: string, photoIndex: number, beforeNote?: string, afterNote?: string): Promise<Appointment>;
|
|
7715
|
+
/**
|
|
7716
|
+
* Updates visibility of a photo pair (before AND after together)
|
|
7717
|
+
*
|
|
7718
|
+
* @param appointmentId ID of the appointment
|
|
7719
|
+
* @param zoneId Zone ID
|
|
7720
|
+
* @param photoIndex Index of the photo entry
|
|
7721
|
+
* @param showToPatient Whether the photo pair should be visible to patient
|
|
7722
|
+
* @param doctorId ID of the doctor making the change (for audit trail)
|
|
7723
|
+
* @returns The updated appointment
|
|
7724
|
+
*/
|
|
7725
|
+
updateZonePhotoVisibility(appointmentId: string, zoneId: string, photoIndex: number, showToPatient: boolean, doctorId: string): Promise<Appointment>;
|
|
7726
|
+
/**
|
|
7727
|
+
* Updates visibility of a photo note (before or after)
|
|
7728
|
+
*
|
|
7729
|
+
* @param appointmentId ID of the appointment
|
|
7730
|
+
* @param zoneId Zone ID
|
|
7731
|
+
* @param photoIndex Index of the photo entry
|
|
7732
|
+
* @param noteType Type of note ('before' or 'after')
|
|
7733
|
+
* @param visibleToPatient Whether the note should be visible to patient
|
|
7734
|
+
* @param doctorId ID of the doctor making the change (for audit trail)
|
|
7735
|
+
* @returns The updated appointment
|
|
7736
|
+
*/
|
|
7737
|
+
updateZonePhotoNoteVisibility(appointmentId: string, zoneId: string, photoIndex: number, noteType: 'before' | 'after', visibleToPatient: boolean, doctorId: string): Promise<Appointment>;
|
|
7697
7738
|
/**
|
|
7698
7739
|
* Gets a specific photo entry from a zone
|
|
7699
7740
|
*
|
|
@@ -7703,6 +7744,15 @@ declare class AppointmentService extends BaseService {
|
|
|
7703
7744
|
* @returns Photo entry
|
|
7704
7745
|
*/
|
|
7705
7746
|
getZonePhotoEntry(appointmentId: string, zoneId: string, photoIndex: number): Promise<BeforeAfterPerZone>;
|
|
7747
|
+
/**
|
|
7748
|
+
* Updates finalization notes (shared with patient and/or internal only)
|
|
7749
|
+
*
|
|
7750
|
+
* @param appointmentId ID of the appointment
|
|
7751
|
+
* @param sharedNotes Notes to be shared with patient (optional)
|
|
7752
|
+
* @param internalNotes Notes for internal use only (optional)
|
|
7753
|
+
* @returns The updated appointment
|
|
7754
|
+
*/
|
|
7755
|
+
updateFinalizationNotes(appointmentId: string, sharedNotes?: string | null, internalNotes?: string | null): Promise<Appointment>;
|
|
7706
7756
|
/**
|
|
7707
7757
|
* Gets all next steps recommendations for a patient from their past appointments.
|
|
7708
7758
|
* Returns recommendations with context about which appointment, practitioner, and clinic suggested them.
|
package/dist/index.d.ts
CHANGED
|
@@ -5604,9 +5604,20 @@ interface BeforeAfterPerZone {
|
|
|
5604
5604
|
before: MediaResource | null;
|
|
5605
5605
|
/** URL for after photo or null if not available */
|
|
5606
5606
|
after: MediaResource | null;
|
|
5607
|
-
/** Optional note for the
|
|
5608
|
-
afterNote?: string | null;
|
|
5607
|
+
/** Optional note for the before photo */
|
|
5609
5608
|
beforeNote?: string | null;
|
|
5609
|
+
/** Optional note for the after photo */
|
|
5610
|
+
afterNote?: string | null;
|
|
5611
|
+
/** Whether this photo pair (before AND after) should be visible to the patient */
|
|
5612
|
+
showToPatient?: boolean;
|
|
5613
|
+
/** Whether the before note should be visible to the patient */
|
|
5614
|
+
beforeNoteVisibleToPatient?: boolean;
|
|
5615
|
+
/** Whether the after note should be visible to the patient */
|
|
5616
|
+
afterNoteVisibleToPatient?: boolean;
|
|
5617
|
+
/** Timestamp when visibility was last updated */
|
|
5618
|
+
visibilityUpdatedAt?: Timestamp;
|
|
5619
|
+
/** ID of the doctor who last updated visibility */
|
|
5620
|
+
visibilityUpdatedBy?: string;
|
|
5610
5621
|
}
|
|
5611
5622
|
/**
|
|
5612
5623
|
* Interface for zone photo upload data
|
|
@@ -5723,7 +5734,14 @@ interface AppointmentMetadata {
|
|
|
5723
5734
|
extendedProcedures?: ExtendedProcedureInfo[];
|
|
5724
5735
|
recommendedProcedures: RecommendedProcedure[];
|
|
5725
5736
|
finalbilling: FinalBilling | null;
|
|
5726
|
-
|
|
5737
|
+
/** Final treatment notes shared with patient */
|
|
5738
|
+
finalizationNotesShared?: string | null;
|
|
5739
|
+
/** Final treatment notes for internal use only (not shared with patient) */
|
|
5740
|
+
finalizationNotesInternal?: string | null;
|
|
5741
|
+
/**
|
|
5742
|
+
* @deprecated Use finalizationNotesShared instead. Kept for backward compatibility during migration.
|
|
5743
|
+
*/
|
|
5744
|
+
finalizationNotes?: string | null;
|
|
5727
5745
|
/**
|
|
5728
5746
|
* @deprecated Use zonesData instead
|
|
5729
5747
|
*/
|
|
@@ -7694,6 +7712,29 @@ declare class AppointmentService extends BaseService {
|
|
|
7694
7712
|
* @returns The updated appointment
|
|
7695
7713
|
*/
|
|
7696
7714
|
updateZonePhotoNotes(appointmentId: string, zoneId: string, photoIndex: number, beforeNote?: string, afterNote?: string): Promise<Appointment>;
|
|
7715
|
+
/**
|
|
7716
|
+
* Updates visibility of a photo pair (before AND after together)
|
|
7717
|
+
*
|
|
7718
|
+
* @param appointmentId ID of the appointment
|
|
7719
|
+
* @param zoneId Zone ID
|
|
7720
|
+
* @param photoIndex Index of the photo entry
|
|
7721
|
+
* @param showToPatient Whether the photo pair should be visible to patient
|
|
7722
|
+
* @param doctorId ID of the doctor making the change (for audit trail)
|
|
7723
|
+
* @returns The updated appointment
|
|
7724
|
+
*/
|
|
7725
|
+
updateZonePhotoVisibility(appointmentId: string, zoneId: string, photoIndex: number, showToPatient: boolean, doctorId: string): Promise<Appointment>;
|
|
7726
|
+
/**
|
|
7727
|
+
* Updates visibility of a photo note (before or after)
|
|
7728
|
+
*
|
|
7729
|
+
* @param appointmentId ID of the appointment
|
|
7730
|
+
* @param zoneId Zone ID
|
|
7731
|
+
* @param photoIndex Index of the photo entry
|
|
7732
|
+
* @param noteType Type of note ('before' or 'after')
|
|
7733
|
+
* @param visibleToPatient Whether the note should be visible to patient
|
|
7734
|
+
* @param doctorId ID of the doctor making the change (for audit trail)
|
|
7735
|
+
* @returns The updated appointment
|
|
7736
|
+
*/
|
|
7737
|
+
updateZonePhotoNoteVisibility(appointmentId: string, zoneId: string, photoIndex: number, noteType: 'before' | 'after', visibleToPatient: boolean, doctorId: string): Promise<Appointment>;
|
|
7697
7738
|
/**
|
|
7698
7739
|
* Gets a specific photo entry from a zone
|
|
7699
7740
|
*
|
|
@@ -7703,6 +7744,15 @@ declare class AppointmentService extends BaseService {
|
|
|
7703
7744
|
* @returns Photo entry
|
|
7704
7745
|
*/
|
|
7705
7746
|
getZonePhotoEntry(appointmentId: string, zoneId: string, photoIndex: number): Promise<BeforeAfterPerZone>;
|
|
7747
|
+
/**
|
|
7748
|
+
* Updates finalization notes (shared with patient and/or internal only)
|
|
7749
|
+
*
|
|
7750
|
+
* @param appointmentId ID of the appointment
|
|
7751
|
+
* @param sharedNotes Notes to be shared with patient (optional)
|
|
7752
|
+
* @param internalNotes Notes for internal use only (optional)
|
|
7753
|
+
* @returns The updated appointment
|
|
7754
|
+
*/
|
|
7755
|
+
updateFinalizationNotes(appointmentId: string, sharedNotes?: string | null, internalNotes?: string | null): Promise<Appointment>;
|
|
7706
7756
|
/**
|
|
7707
7757
|
* Gets all next steps recommendations for a patient from their past appointments.
|
|
7708
7758
|
* Returns recommendations with context about which appointment, practitioner, and clinic suggested them.
|
package/dist/index.js
CHANGED
|
@@ -3903,8 +3903,14 @@ var finalizedDetailsSchema = import_zod3.z.object({
|
|
|
3903
3903
|
var beforeAfterPerZoneSchema = import_zod3.z.object({
|
|
3904
3904
|
before: mediaResourceSchema.nullable(),
|
|
3905
3905
|
after: mediaResourceSchema.nullable(),
|
|
3906
|
+
beforeNote: import_zod3.z.string().nullable().optional(),
|
|
3906
3907
|
afterNote: import_zod3.z.string().nullable().optional(),
|
|
3907
|
-
|
|
3908
|
+
showToPatient: import_zod3.z.boolean().optional().default(false),
|
|
3909
|
+
beforeNoteVisibleToPatient: import_zod3.z.boolean().optional().default(false),
|
|
3910
|
+
afterNoteVisibleToPatient: import_zod3.z.boolean().optional().default(false),
|
|
3911
|
+
visibilityUpdatedAt: import_zod3.z.any().optional(),
|
|
3912
|
+
// Timestamp
|
|
3913
|
+
visibilityUpdatedBy: import_zod3.z.string().optional()
|
|
3908
3914
|
});
|
|
3909
3915
|
var billingPerZoneSchema = import_zod3.z.object({
|
|
3910
3916
|
Product: import_zod3.z.string().min(MIN_STRING_LENGTH, "Product name is required"),
|
|
@@ -3962,6 +3968,7 @@ var zoneItemDataSchema = import_zod3.z.object({
|
|
|
3962
3968
|
}
|
|
3963
3969
|
),
|
|
3964
3970
|
notes: import_zod3.z.string().max(MAX_STRING_LENGTH_LONG, "Notes too long").optional(),
|
|
3971
|
+
notesVisibleToPatient: import_zod3.z.boolean().optional().default(false),
|
|
3965
3972
|
subtotal: import_zod3.z.number().min(0, "Subtotal must be non-negative").optional(),
|
|
3966
3973
|
ionNumber: import_zod3.z.string().optional(),
|
|
3967
3974
|
createdAt: import_zod3.z.string().optional(),
|
|
@@ -4025,7 +4032,10 @@ var appointmentMetadataSchema = import_zod3.z.object({
|
|
|
4025
4032
|
recommendedProcedures: import_zod3.z.array(recommendedProcedureSchema).optional().default([]),
|
|
4026
4033
|
zoneBilling: import_zod3.z.record(import_zod3.z.string(), billingPerZoneSchema).nullable().optional(),
|
|
4027
4034
|
finalbilling: finalBillingSchema.nullable(),
|
|
4028
|
-
|
|
4035
|
+
finalizationNotesShared: import_zod3.z.string().nullable().optional(),
|
|
4036
|
+
finalizationNotesInternal: import_zod3.z.string().nullable().optional(),
|
|
4037
|
+
finalizationNotes: import_zod3.z.string().nullable().optional()
|
|
4038
|
+
// @deprecated - kept for backward compatibility
|
|
4029
4039
|
});
|
|
4030
4040
|
var createAppointmentSchema = import_zod3.z.object({
|
|
4031
4041
|
clinicBranchId: import_zod3.z.string().min(MIN_STRING_LENGTH, "Clinic branch ID is required"),
|
|
@@ -4826,10 +4836,14 @@ function initializeMetadata(appointment) {
|
|
|
4826
4836
|
extendedProcedures: [],
|
|
4827
4837
|
recommendedProcedures: [],
|
|
4828
4838
|
finalbilling: null,
|
|
4839
|
+
finalizationNotesShared: null,
|
|
4840
|
+
finalizationNotesInternal: null,
|
|
4829
4841
|
finalizationNotes: null
|
|
4842
|
+
// @deprecated - kept for backward compatibility
|
|
4830
4843
|
};
|
|
4831
4844
|
}
|
|
4832
4845
|
async function addItemToZoneUtil(db, appointmentId, zoneId, item) {
|
|
4846
|
+
var _a;
|
|
4833
4847
|
validateZoneKeyFormat(zoneId);
|
|
4834
4848
|
const appointment = await getAppointmentOrThrow(db, appointmentId);
|
|
4835
4849
|
const metadata = initializeMetadata(appointment);
|
|
@@ -4843,6 +4857,8 @@ async function addItemToZoneUtil(db, appointmentId, zoneId, item) {
|
|
|
4843
4857
|
parentZone: zoneId,
|
|
4844
4858
|
// Set parentZone to the zone key
|
|
4845
4859
|
subtotal: calculateItemSubtotal(item),
|
|
4860
|
+
// Set default visibility to false (privacy-first) if notes exist and visibility not explicitly set
|
|
4861
|
+
notesVisibleToPatient: (_a = item.notesVisibleToPatient) != null ? _a : item.notes ? false : void 0,
|
|
4846
4862
|
createdAt: now,
|
|
4847
4863
|
updatedAt: now
|
|
4848
4864
|
};
|
|
@@ -5342,7 +5358,17 @@ async function getRecommendedProceduresUtil(db, appointmentId) {
|
|
|
5342
5358
|
|
|
5343
5359
|
// src/services/appointment/utils/zone-photo.utils.ts
|
|
5344
5360
|
var import_firestore13 = require("firebase/firestore");
|
|
5345
|
-
|
|
5361
|
+
function addVisibilityAudit(updates, doctorId) {
|
|
5362
|
+
if (updates.showToPatient !== void 0 || updates.beforeNoteVisibleToPatient !== void 0 || updates.afterNoteVisibleToPatient !== void 0) {
|
|
5363
|
+
return {
|
|
5364
|
+
...updates,
|
|
5365
|
+
visibilityUpdatedAt: (0, import_firestore13.serverTimestamp)(),
|
|
5366
|
+
visibilityUpdatedBy: doctorId
|
|
5367
|
+
};
|
|
5368
|
+
}
|
|
5369
|
+
return updates;
|
|
5370
|
+
}
|
|
5371
|
+
async function updateZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex, updates, doctorId) {
|
|
5346
5372
|
var _a;
|
|
5347
5373
|
const appointment = await getAppointmentOrThrow(db, appointmentId);
|
|
5348
5374
|
const zonePhotos = (_a = appointment.metadata) == null ? void 0 : _a.zonePhotos;
|
|
@@ -5353,11 +5379,12 @@ async function updateZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex, u
|
|
|
5353
5379
|
if (photoIndex < 0 || photoIndex >= zoneArray.length) {
|
|
5354
5380
|
throw new Error(`Invalid photo index ${photoIndex} for zone ${zoneId}. Must be between 0 and ${zoneArray.length - 1}`);
|
|
5355
5381
|
}
|
|
5382
|
+
const updatesWithAudit = doctorId ? addVisibilityAudit(updates, doctorId) : updates;
|
|
5356
5383
|
const updatedZonePhotos = { ...zonePhotos };
|
|
5357
5384
|
updatedZonePhotos[zoneId] = [...zoneArray];
|
|
5358
5385
|
updatedZonePhotos[zoneId][photoIndex] = {
|
|
5359
5386
|
...zoneArray[photoIndex],
|
|
5360
|
-
...
|
|
5387
|
+
...updatesWithAudit
|
|
5361
5388
|
};
|
|
5362
5389
|
const appointmentRef = (0, import_firestore13.doc)(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
5363
5390
|
await (0, import_firestore13.updateDoc)(appointmentRef, {
|
|
@@ -5401,6 +5428,20 @@ async function getZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex) {
|
|
|
5401
5428
|
}
|
|
5402
5429
|
return zoneArray[photoIndex];
|
|
5403
5430
|
}
|
|
5431
|
+
async function updateZonePhotoVisibilityUtil(db, appointmentId, zoneId, photoIndex, showToPatient, doctorId) {
|
|
5432
|
+
return updateZonePhotoEntryUtil(
|
|
5433
|
+
db,
|
|
5434
|
+
appointmentId,
|
|
5435
|
+
zoneId,
|
|
5436
|
+
photoIndex,
|
|
5437
|
+
{ showToPatient },
|
|
5438
|
+
doctorId
|
|
5439
|
+
);
|
|
5440
|
+
}
|
|
5441
|
+
async function updateZonePhotoNoteVisibilityUtil(db, appointmentId, zoneId, photoIndex, noteType, visibleToPatient, doctorId) {
|
|
5442
|
+
const updates = noteType === "before" ? { beforeNoteVisibleToPatient: visibleToPatient } : { afterNoteVisibleToPatient: visibleToPatient };
|
|
5443
|
+
return updateZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex, updates, doctorId);
|
|
5444
|
+
}
|
|
5404
5445
|
|
|
5405
5446
|
// src/services/appointment/appointment.service.ts
|
|
5406
5447
|
var AppointmentService = class extends BaseService {
|
|
@@ -6267,6 +6308,7 @@ var AppointmentService = class extends BaseService {
|
|
|
6267
6308
|
* @returns The updated appointment
|
|
6268
6309
|
*/
|
|
6269
6310
|
async updateAppointmentZonePhoto(appointmentId, zoneId, photoType, mediaMetadata, notes) {
|
|
6311
|
+
var _a, _b, _c, _d;
|
|
6270
6312
|
try {
|
|
6271
6313
|
console.log(
|
|
6272
6314
|
`[APPOINTMENT_SERVICE] Updating appointment metadata for ${photoType} photo in zone ${zoneId}`
|
|
@@ -6284,7 +6326,10 @@ var AppointmentService = class extends BaseService {
|
|
|
6284
6326
|
recommendedProcedures: [],
|
|
6285
6327
|
zoneBilling: null,
|
|
6286
6328
|
finalbilling: null,
|
|
6329
|
+
finalizationNotesShared: null,
|
|
6330
|
+
finalizationNotesInternal: null,
|
|
6287
6331
|
finalizationNotes: null
|
|
6332
|
+
// @deprecated - kept for backward compatibility
|
|
6288
6333
|
};
|
|
6289
6334
|
let currentZonePhotos = {};
|
|
6290
6335
|
if (currentMetadata.zonePhotos) {
|
|
@@ -6299,7 +6344,11 @@ var AppointmentService = class extends BaseService {
|
|
|
6299
6344
|
before: oldData.before || null,
|
|
6300
6345
|
after: oldData.after || null,
|
|
6301
6346
|
beforeNote: null,
|
|
6302
|
-
afterNote: null
|
|
6347
|
+
afterNote: null,
|
|
6348
|
+
showToPatient: false,
|
|
6349
|
+
// Default: not visible to patient (privacy-first)
|
|
6350
|
+
beforeNoteVisibleToPatient: false,
|
|
6351
|
+
afterNoteVisibleToPatient: false
|
|
6303
6352
|
}
|
|
6304
6353
|
];
|
|
6305
6354
|
}
|
|
@@ -6312,7 +6361,13 @@ var AppointmentService = class extends BaseService {
|
|
|
6312
6361
|
before: photoType === "before" ? mediaMetadata.url : null,
|
|
6313
6362
|
after: photoType === "after" ? mediaMetadata.url : null,
|
|
6314
6363
|
beforeNote: photoType === "before" ? notes || null : null,
|
|
6315
|
-
afterNote: photoType === "after" ? notes || null : null
|
|
6364
|
+
afterNote: photoType === "after" ? notes || null : null,
|
|
6365
|
+
showToPatient: false,
|
|
6366
|
+
// Default: not visible to patient
|
|
6367
|
+
beforeNoteVisibleToPatient: false,
|
|
6368
|
+
// Default: not visible to patient
|
|
6369
|
+
afterNoteVisibleToPatient: false
|
|
6370
|
+
// Default: not visible to patient
|
|
6316
6371
|
};
|
|
6317
6372
|
currentZonePhotos[zoneId] = [...currentZonePhotos[zoneId], newEntry];
|
|
6318
6373
|
if (currentZonePhotos[zoneId].length > 10) {
|
|
@@ -6331,7 +6386,10 @@ var AppointmentService = class extends BaseService {
|
|
|
6331
6386
|
zoneBilling: currentMetadata.zoneBilling
|
|
6332
6387
|
},
|
|
6333
6388
|
finalbilling: currentMetadata.finalbilling,
|
|
6334
|
-
|
|
6389
|
+
finalizationNotesShared: (_a = currentMetadata.finalizationNotesShared) != null ? _a : null,
|
|
6390
|
+
finalizationNotesInternal: (_b = currentMetadata.finalizationNotesInternal) != null ? _b : null,
|
|
6391
|
+
finalizationNotes: (_d = (_c = currentMetadata.finalizationNotes) != null ? _c : currentMetadata.finalizationNotesShared) != null ? _d : null
|
|
6392
|
+
// @deprecated - migrate from old field if exists
|
|
6335
6393
|
},
|
|
6336
6394
|
updatedAt: (0, import_firestore14.serverTimestamp)()
|
|
6337
6395
|
};
|
|
@@ -6385,7 +6443,7 @@ var AppointmentService = class extends BaseService {
|
|
|
6385
6443
|
* @returns The updated appointment
|
|
6386
6444
|
*/
|
|
6387
6445
|
async deleteZonePhoto(appointmentId, zoneId, photoIndex) {
|
|
6388
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
6446
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
6389
6447
|
try {
|
|
6390
6448
|
console.log(
|
|
6391
6449
|
`[APPOINTMENT_SERVICE] Deleting zone photo index ${photoIndex} for zone ${zoneId} in appointment ${appointmentId}`
|
|
@@ -6442,7 +6500,10 @@ var AppointmentService = class extends BaseService {
|
|
|
6442
6500
|
zoneBilling: appointment.metadata.zoneBilling
|
|
6443
6501
|
},
|
|
6444
6502
|
finalbilling: ((_h = appointment.metadata) == null ? void 0 : _h.finalbilling) || null,
|
|
6445
|
-
|
|
6503
|
+
finalizationNotesShared: (_l = (_k = (_i = appointment.metadata) == null ? void 0 : _i.finalizationNotesShared) != null ? _k : (_j = appointment.metadata) == null ? void 0 : _j.finalizationNotes) != null ? _l : null,
|
|
6504
|
+
finalizationNotesInternal: (_n = (_m = appointment.metadata) == null ? void 0 : _m.finalizationNotesInternal) != null ? _n : null,
|
|
6505
|
+
finalizationNotes: (_p = (_o = appointment.metadata) == null ? void 0 : _o.finalizationNotes) != null ? _p : null
|
|
6506
|
+
// @deprecated
|
|
6446
6507
|
},
|
|
6447
6508
|
updatedAt: (0, import_firestore14.serverTimestamp)()
|
|
6448
6509
|
};
|
|
@@ -6641,7 +6702,7 @@ var AppointmentService = class extends BaseService {
|
|
|
6641
6702
|
* @returns The updated appointment with recalculated billing
|
|
6642
6703
|
*/
|
|
6643
6704
|
async recalculateFinalBilling(appointmentId, taxRate) {
|
|
6644
|
-
var _a;
|
|
6705
|
+
var _a, _b, _c, _d, _e;
|
|
6645
6706
|
try {
|
|
6646
6707
|
console.log(
|
|
6647
6708
|
`[APPOINTMENT_SERVICE] Recalculating final billing for appointment ${appointmentId}`
|
|
@@ -6663,7 +6724,10 @@ var AppointmentService = class extends BaseService {
|
|
|
6663
6724
|
extendedProcedures: [],
|
|
6664
6725
|
recommendedProcedures: [],
|
|
6665
6726
|
finalbilling: null,
|
|
6727
|
+
finalizationNotesShared: null,
|
|
6728
|
+
finalizationNotesInternal: null,
|
|
6666
6729
|
finalizationNotes: null
|
|
6730
|
+
// @deprecated
|
|
6667
6731
|
};
|
|
6668
6732
|
const shouldUpdatePaymentStatus = finalbilling.finalPrice > 0 && appointment.paymentStatus === "not_applicable" /* NOT_APPLICABLE */;
|
|
6669
6733
|
const updateData = {
|
|
@@ -6679,7 +6743,10 @@ var AppointmentService = class extends BaseService {
|
|
|
6679
6743
|
zoneBilling: currentMetadata.zoneBilling
|
|
6680
6744
|
},
|
|
6681
6745
|
finalbilling,
|
|
6682
|
-
|
|
6746
|
+
finalizationNotesShared: (_b = currentMetadata.finalizationNotesShared) != null ? _b : null,
|
|
6747
|
+
finalizationNotesInternal: (_c = currentMetadata.finalizationNotesInternal) != null ? _c : null,
|
|
6748
|
+
finalizationNotes: (_e = (_d = currentMetadata.finalizationNotes) != null ? _d : currentMetadata.finalizationNotesShared) != null ? _e : null
|
|
6749
|
+
// @deprecated
|
|
6683
6750
|
},
|
|
6684
6751
|
...shouldUpdatePaymentStatus && {
|
|
6685
6752
|
paymentStatus: "unpaid" /* UNPAID */
|
|
@@ -6879,6 +6946,64 @@ var AppointmentService = class extends BaseService {
|
|
|
6879
6946
|
throw error;
|
|
6880
6947
|
}
|
|
6881
6948
|
}
|
|
6949
|
+
/**
|
|
6950
|
+
* Updates visibility of a photo pair (before AND after together)
|
|
6951
|
+
*
|
|
6952
|
+
* @param appointmentId ID of the appointment
|
|
6953
|
+
* @param zoneId Zone ID
|
|
6954
|
+
* @param photoIndex Index of the photo entry
|
|
6955
|
+
* @param showToPatient Whether the photo pair should be visible to patient
|
|
6956
|
+
* @param doctorId ID of the doctor making the change (for audit trail)
|
|
6957
|
+
* @returns The updated appointment
|
|
6958
|
+
*/
|
|
6959
|
+
async updateZonePhotoVisibility(appointmentId, zoneId, photoIndex, showToPatient, doctorId) {
|
|
6960
|
+
try {
|
|
6961
|
+
console.log(
|
|
6962
|
+
`[APPOINTMENT_SERVICE] Updating photo visibility at index ${photoIndex} for zone ${zoneId} to ${showToPatient}`
|
|
6963
|
+
);
|
|
6964
|
+
return await updateZonePhotoVisibilityUtil(
|
|
6965
|
+
this.db,
|
|
6966
|
+
appointmentId,
|
|
6967
|
+
zoneId,
|
|
6968
|
+
photoIndex,
|
|
6969
|
+
showToPatient,
|
|
6970
|
+
doctorId
|
|
6971
|
+
);
|
|
6972
|
+
} catch (error) {
|
|
6973
|
+
console.error(`[APPOINTMENT_SERVICE] Error updating zone photo visibility:`, error);
|
|
6974
|
+
throw error;
|
|
6975
|
+
}
|
|
6976
|
+
}
|
|
6977
|
+
/**
|
|
6978
|
+
* Updates visibility of a photo note (before or after)
|
|
6979
|
+
*
|
|
6980
|
+
* @param appointmentId ID of the appointment
|
|
6981
|
+
* @param zoneId Zone ID
|
|
6982
|
+
* @param photoIndex Index of the photo entry
|
|
6983
|
+
* @param noteType Type of note ('before' or 'after')
|
|
6984
|
+
* @param visibleToPatient Whether the note should be visible to patient
|
|
6985
|
+
* @param doctorId ID of the doctor making the change (for audit trail)
|
|
6986
|
+
* @returns The updated appointment
|
|
6987
|
+
*/
|
|
6988
|
+
async updateZonePhotoNoteVisibility(appointmentId, zoneId, photoIndex, noteType, visibleToPatient, doctorId) {
|
|
6989
|
+
try {
|
|
6990
|
+
console.log(
|
|
6991
|
+
`[APPOINTMENT_SERVICE] Updating ${noteType} note visibility at index ${photoIndex} for zone ${zoneId} to ${visibleToPatient}`
|
|
6992
|
+
);
|
|
6993
|
+
return await updateZonePhotoNoteVisibilityUtil(
|
|
6994
|
+
this.db,
|
|
6995
|
+
appointmentId,
|
|
6996
|
+
zoneId,
|
|
6997
|
+
photoIndex,
|
|
6998
|
+
noteType,
|
|
6999
|
+
visibleToPatient,
|
|
7000
|
+
doctorId
|
|
7001
|
+
);
|
|
7002
|
+
} catch (error) {
|
|
7003
|
+
console.error(`[APPOINTMENT_SERVICE] Error updating zone photo note visibility:`, error);
|
|
7004
|
+
throw error;
|
|
7005
|
+
}
|
|
7006
|
+
}
|
|
6882
7007
|
/**
|
|
6883
7008
|
* Gets a specific photo entry from a zone
|
|
6884
7009
|
*
|
|
@@ -6898,6 +7023,54 @@ var AppointmentService = class extends BaseService {
|
|
|
6898
7023
|
throw error;
|
|
6899
7024
|
}
|
|
6900
7025
|
}
|
|
7026
|
+
/**
|
|
7027
|
+
* Updates finalization notes (shared with patient and/or internal only)
|
|
7028
|
+
*
|
|
7029
|
+
* @param appointmentId ID of the appointment
|
|
7030
|
+
* @param sharedNotes Notes to be shared with patient (optional)
|
|
7031
|
+
* @param internalNotes Notes for internal use only (optional)
|
|
7032
|
+
* @returns The updated appointment
|
|
7033
|
+
*/
|
|
7034
|
+
async updateFinalizationNotes(appointmentId, sharedNotes, internalNotes) {
|
|
7035
|
+
try {
|
|
7036
|
+
const appointment = await this.getAppointmentById(appointmentId);
|
|
7037
|
+
if (!appointment) {
|
|
7038
|
+
throw new Error(`Appointment ${appointmentId} not found`);
|
|
7039
|
+
}
|
|
7040
|
+
const currentMetadata = appointment.metadata || {
|
|
7041
|
+
selectedZones: null,
|
|
7042
|
+
zonePhotos: null,
|
|
7043
|
+
zonesData: null,
|
|
7044
|
+
appointmentProducts: [],
|
|
7045
|
+
extendedProcedures: [],
|
|
7046
|
+
recommendedProcedures: [],
|
|
7047
|
+
finalbilling: null,
|
|
7048
|
+
finalizationNotesShared: null,
|
|
7049
|
+
finalizationNotesInternal: null,
|
|
7050
|
+
finalizationNotes: null
|
|
7051
|
+
};
|
|
7052
|
+
const updateData = {
|
|
7053
|
+
metadata: {
|
|
7054
|
+
selectedZones: currentMetadata.selectedZones,
|
|
7055
|
+
zonePhotos: currentMetadata.zonePhotos,
|
|
7056
|
+
zonesData: currentMetadata.zonesData || null,
|
|
7057
|
+
appointmentProducts: currentMetadata.appointmentProducts || [],
|
|
7058
|
+
extendedProcedures: currentMetadata.extendedProcedures || [],
|
|
7059
|
+
recommendedProcedures: currentMetadata.recommendedProcedures || [],
|
|
7060
|
+
finalbilling: currentMetadata.finalbilling,
|
|
7061
|
+
finalizationNotesShared: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotesShared,
|
|
7062
|
+
finalizationNotesInternal: internalNotes !== void 0 ? internalNotes : currentMetadata.finalizationNotesInternal,
|
|
7063
|
+
// Keep deprecated field for backward compatibility during migration
|
|
7064
|
+
finalizationNotes: sharedNotes !== void 0 ? sharedNotes : currentMetadata.finalizationNotes || currentMetadata.finalizationNotesShared
|
|
7065
|
+
},
|
|
7066
|
+
updatedAt: (0, import_firestore14.serverTimestamp)()
|
|
7067
|
+
};
|
|
7068
|
+
return await this.updateAppointment(appointmentId, updateData);
|
|
7069
|
+
} catch (error) {
|
|
7070
|
+
console.error(`[APPOINTMENT_SERVICE] Error updating finalization notes:`, error);
|
|
7071
|
+
throw error;
|
|
7072
|
+
}
|
|
7073
|
+
}
|
|
6901
7074
|
/**
|
|
6902
7075
|
* Gets all next steps recommendations for a patient from their past appointments.
|
|
6903
7076
|
* Returns recommendations with context about which appointment, practitioner, and clinic suggested them.
|