@blackcode_sa/metaestetics-api 1.7.13 → 1.7.14
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 +6 -6
- package/dist/admin/index.d.ts +6 -6
- package/dist/index.d.mts +130 -113
- package/dist/index.d.ts +130 -113
- package/dist/index.js +69 -4
- package/dist/index.mjs +69 -4
- package/package.json +1 -1
- package/src/services/procedure/procedure.service.ts +94 -2
- package/src/types/procedure/index.ts +4 -3
- package/src/validations/procedure.schema.ts +3 -3
package/dist/admin/index.d.mts
CHANGED
|
@@ -661,6 +661,11 @@ declare enum Currency {
|
|
|
661
661
|
AUD = "AUD"
|
|
662
662
|
}
|
|
663
663
|
|
|
664
|
+
/**
|
|
665
|
+
* Type that allows a field to be either a URL string or a File object
|
|
666
|
+
*/
|
|
667
|
+
type MediaResource = string | File | Blob;
|
|
668
|
+
|
|
664
669
|
/**
|
|
665
670
|
* Procedure represents a specific medical procedure that can be performed by a practitioner in a clinic
|
|
666
671
|
* It inherits properties from technology and adds clinic/practitioner specific details
|
|
@@ -671,7 +676,7 @@ interface Procedure {
|
|
|
671
676
|
/** Name of the procedure */
|
|
672
677
|
name: string;
|
|
673
678
|
/** Photos of the procedure */
|
|
674
|
-
photos?:
|
|
679
|
+
photos?: MediaResource[];
|
|
675
680
|
/** Detailed description of the procedure */
|
|
676
681
|
description: string;
|
|
677
682
|
/** Family of procedures this belongs to (aesthetics/surgery) */
|
|
@@ -1019,11 +1024,6 @@ declare enum ClinicTag {
|
|
|
1019
1024
|
HOLIDAY_HOURS = "holiday_hours"
|
|
1020
1025
|
}
|
|
1021
1026
|
|
|
1022
|
-
/**
|
|
1023
|
-
* Type that allows a field to be either a URL string or a File object
|
|
1024
|
-
*/
|
|
1025
|
-
type MediaResource = string | File | Blob;
|
|
1026
|
-
|
|
1027
1027
|
/**
|
|
1028
1028
|
* Interface for clinic contact information
|
|
1029
1029
|
*/
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -661,6 +661,11 @@ declare enum Currency {
|
|
|
661
661
|
AUD = "AUD"
|
|
662
662
|
}
|
|
663
663
|
|
|
664
|
+
/**
|
|
665
|
+
* Type that allows a field to be either a URL string or a File object
|
|
666
|
+
*/
|
|
667
|
+
type MediaResource = string | File | Blob;
|
|
668
|
+
|
|
664
669
|
/**
|
|
665
670
|
* Procedure represents a specific medical procedure that can be performed by a practitioner in a clinic
|
|
666
671
|
* It inherits properties from technology and adds clinic/practitioner specific details
|
|
@@ -671,7 +676,7 @@ interface Procedure {
|
|
|
671
676
|
/** Name of the procedure */
|
|
672
677
|
name: string;
|
|
673
678
|
/** Photos of the procedure */
|
|
674
|
-
photos?:
|
|
679
|
+
photos?: MediaResource[];
|
|
675
680
|
/** Detailed description of the procedure */
|
|
676
681
|
description: string;
|
|
677
682
|
/** Family of procedures this belongs to (aesthetics/surgery) */
|
|
@@ -1019,11 +1024,6 @@ declare enum ClinicTag {
|
|
|
1019
1024
|
HOLIDAY_HOURS = "holiday_hours"
|
|
1020
1025
|
}
|
|
1021
1026
|
|
|
1022
|
-
/**
|
|
1023
|
-
* Type that allows a field to be either a URL string or a File object
|
|
1024
|
-
*/
|
|
1025
|
-
type MediaResource = string | File | Blob;
|
|
1026
|
-
|
|
1027
1027
|
/**
|
|
1028
1028
|
* Interface for clinic contact information
|
|
1029
1029
|
*/
|
package/dist/index.d.mts
CHANGED
|
@@ -507,6 +507,102 @@ declare enum Currency {
|
|
|
507
507
|
AUD = "AUD"
|
|
508
508
|
}
|
|
509
509
|
|
|
510
|
+
declare class BaseService {
|
|
511
|
+
protected db: Firestore;
|
|
512
|
+
protected auth: Auth;
|
|
513
|
+
protected app: FirebaseApp;
|
|
514
|
+
protected storage: FirebaseStorage;
|
|
515
|
+
constructor(db: Firestore, auth: Auth, app: FirebaseApp);
|
|
516
|
+
/**
|
|
517
|
+
* Generiše jedinstveni ID za dokumente
|
|
518
|
+
* Format: xxxxxxxxxxxx-timestamp
|
|
519
|
+
* Gde je x random karakter (broj ili slovo)
|
|
520
|
+
*/
|
|
521
|
+
protected generateId(): string;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Enum for media access levels
|
|
526
|
+
*/
|
|
527
|
+
declare enum MediaAccessLevel {
|
|
528
|
+
PUBLIC = "public",
|
|
529
|
+
PRIVATE = "private",
|
|
530
|
+
CONFIDENTIAL = "confidential"
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Type that allows a field to be either a URL string or a File object
|
|
534
|
+
*/
|
|
535
|
+
type MediaResource = string | File | Blob;
|
|
536
|
+
/**
|
|
537
|
+
* Media file metadata interface
|
|
538
|
+
*/
|
|
539
|
+
interface MediaMetadata {
|
|
540
|
+
id: string;
|
|
541
|
+
name: string;
|
|
542
|
+
url: string;
|
|
543
|
+
contentType: string;
|
|
544
|
+
size: number;
|
|
545
|
+
createdAt: Timestamp;
|
|
546
|
+
accessLevel: MediaAccessLevel;
|
|
547
|
+
ownerId: string;
|
|
548
|
+
collectionName: string;
|
|
549
|
+
path: string;
|
|
550
|
+
updatedAt?: Timestamp;
|
|
551
|
+
}
|
|
552
|
+
declare const MEDIA_METADATA_COLLECTION = "media_metadata";
|
|
553
|
+
declare class MediaService extends BaseService {
|
|
554
|
+
constructor(db: Firestore, auth: Auth, app: FirebaseApp);
|
|
555
|
+
/**
|
|
556
|
+
* Upload a media file, store its metadata, and return the metadata including the URL.
|
|
557
|
+
* @param file - The file to upload.
|
|
558
|
+
* @param ownerId - ID of the owner (user, patient, clinic, etc.).
|
|
559
|
+
* @param accessLevel - Access level (public, private, confidential).
|
|
560
|
+
* @param collectionName - The logical collection name this media belongs to (e.g., 'patient_profile_pictures', 'clinic_logos').
|
|
561
|
+
* @param originalFileName - Optional: the original name of the file, if not using file.name.
|
|
562
|
+
* @returns Promise with the media metadata.
|
|
563
|
+
*/
|
|
564
|
+
uploadMedia(file: File | Blob, ownerId: string, accessLevel: MediaAccessLevel, collectionName: string, originalFileName?: string): Promise<MediaMetadata>;
|
|
565
|
+
/**
|
|
566
|
+
* Get media metadata from Firestore by its ID.
|
|
567
|
+
* @param mediaId - ID of the media.
|
|
568
|
+
* @returns Promise with the media metadata or null if not found.
|
|
569
|
+
*/
|
|
570
|
+
getMediaMetadata(mediaId: string): Promise<MediaMetadata | null>;
|
|
571
|
+
/**
|
|
572
|
+
* Get media metadata from Firestore by its public URL.
|
|
573
|
+
* @param url - The public URL of the media file.
|
|
574
|
+
* @returns Promise with the media metadata or null if not found.
|
|
575
|
+
*/
|
|
576
|
+
getMediaMetadataByUrl(url: string): Promise<MediaMetadata | null>;
|
|
577
|
+
/**
|
|
578
|
+
* Delete media from storage and remove metadata from Firestore.
|
|
579
|
+
* @param mediaId - ID of the media to delete.
|
|
580
|
+
*/
|
|
581
|
+
deleteMedia(mediaId: string): Promise<void>;
|
|
582
|
+
/**
|
|
583
|
+
* Update media access level. This involves moving the file in Firebase Storage
|
|
584
|
+
* to a new path reflecting the new access level, and updating its metadata.
|
|
585
|
+
* @param mediaId - ID of the media to update.
|
|
586
|
+
* @param newAccessLevel - New access level.
|
|
587
|
+
* @returns Promise with the updated media metadata, or null if metadata not found.
|
|
588
|
+
*/
|
|
589
|
+
updateMediaAccessLevel(mediaId: string, newAccessLevel: MediaAccessLevel): Promise<MediaMetadata | null>;
|
|
590
|
+
/**
|
|
591
|
+
* List all media for an owner, optionally filtered by collection and access level.
|
|
592
|
+
* @param ownerId - ID of the owner.
|
|
593
|
+
* @param collectionName - Optional: Filter by collection name.
|
|
594
|
+
* @param accessLevel - Optional: Filter by access level.
|
|
595
|
+
* @param count - Optional: Number of items to fetch.
|
|
596
|
+
* @param startAfterId - Optional: ID of the document to start after (for pagination).
|
|
597
|
+
*/
|
|
598
|
+
listMedia(ownerId: string, collectionName?: string, accessLevel?: MediaAccessLevel, count?: number, startAfterId?: string): Promise<MediaMetadata[]>;
|
|
599
|
+
/**
|
|
600
|
+
* Get download URL for media. (Convenience, as URL is in metadata)
|
|
601
|
+
* @param mediaId - ID of the media.
|
|
602
|
+
*/
|
|
603
|
+
getMediaDownloadUrl(mediaId: string): Promise<string | null>;
|
|
604
|
+
}
|
|
605
|
+
|
|
510
606
|
/**
|
|
511
607
|
* Procedure represents a specific medical procedure that can be performed by a practitioner in a clinic
|
|
512
608
|
* It inherits properties from technology and adds clinic/practitioner specific details
|
|
@@ -517,7 +613,7 @@ interface Procedure {
|
|
|
517
613
|
/** Name of the procedure */
|
|
518
614
|
name: string;
|
|
519
615
|
/** Photos of the procedure */
|
|
520
|
-
photos?:
|
|
616
|
+
photos?: MediaResource[];
|
|
521
617
|
/** Detailed description of the procedure */
|
|
522
618
|
description: string;
|
|
523
619
|
/** Family of procedures this belongs to (aesthetics/surgery) */
|
|
@@ -586,7 +682,7 @@ interface CreateProcedureData {
|
|
|
586
682
|
duration: number;
|
|
587
683
|
practitionerId: string;
|
|
588
684
|
clinicBranchId: string;
|
|
589
|
-
photos?:
|
|
685
|
+
photos?: MediaResource[];
|
|
590
686
|
}
|
|
591
687
|
/**
|
|
592
688
|
* Data that can be updated for an existing procedure
|
|
@@ -605,7 +701,7 @@ interface UpdateProcedureData {
|
|
|
605
701
|
technologyId?: string;
|
|
606
702
|
productId?: string;
|
|
607
703
|
clinicBranchId?: string;
|
|
608
|
-
photos?:
|
|
704
|
+
photos?: MediaResource[];
|
|
609
705
|
}
|
|
610
706
|
/**
|
|
611
707
|
* Collection name for procedures in Firestore
|
|
@@ -749,102 +845,6 @@ declare enum ClinicPhotoTag {
|
|
|
749
845
|
OTHER = "other"
|
|
750
846
|
}
|
|
751
847
|
|
|
752
|
-
declare class BaseService {
|
|
753
|
-
protected db: Firestore;
|
|
754
|
-
protected auth: Auth;
|
|
755
|
-
protected app: FirebaseApp;
|
|
756
|
-
protected storage: FirebaseStorage;
|
|
757
|
-
constructor(db: Firestore, auth: Auth, app: FirebaseApp);
|
|
758
|
-
/**
|
|
759
|
-
* Generiše jedinstveni ID za dokumente
|
|
760
|
-
* Format: xxxxxxxxxxxx-timestamp
|
|
761
|
-
* Gde je x random karakter (broj ili slovo)
|
|
762
|
-
*/
|
|
763
|
-
protected generateId(): string;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
/**
|
|
767
|
-
* Enum for media access levels
|
|
768
|
-
*/
|
|
769
|
-
declare enum MediaAccessLevel {
|
|
770
|
-
PUBLIC = "public",
|
|
771
|
-
PRIVATE = "private",
|
|
772
|
-
CONFIDENTIAL = "confidential"
|
|
773
|
-
}
|
|
774
|
-
/**
|
|
775
|
-
* Type that allows a field to be either a URL string or a File object
|
|
776
|
-
*/
|
|
777
|
-
type MediaResource = string | File | Blob;
|
|
778
|
-
/**
|
|
779
|
-
* Media file metadata interface
|
|
780
|
-
*/
|
|
781
|
-
interface MediaMetadata {
|
|
782
|
-
id: string;
|
|
783
|
-
name: string;
|
|
784
|
-
url: string;
|
|
785
|
-
contentType: string;
|
|
786
|
-
size: number;
|
|
787
|
-
createdAt: Timestamp;
|
|
788
|
-
accessLevel: MediaAccessLevel;
|
|
789
|
-
ownerId: string;
|
|
790
|
-
collectionName: string;
|
|
791
|
-
path: string;
|
|
792
|
-
updatedAt?: Timestamp;
|
|
793
|
-
}
|
|
794
|
-
declare const MEDIA_METADATA_COLLECTION = "media_metadata";
|
|
795
|
-
declare class MediaService extends BaseService {
|
|
796
|
-
constructor(db: Firestore, auth: Auth, app: FirebaseApp);
|
|
797
|
-
/**
|
|
798
|
-
* Upload a media file, store its metadata, and return the metadata including the URL.
|
|
799
|
-
* @param file - The file to upload.
|
|
800
|
-
* @param ownerId - ID of the owner (user, patient, clinic, etc.).
|
|
801
|
-
* @param accessLevel - Access level (public, private, confidential).
|
|
802
|
-
* @param collectionName - The logical collection name this media belongs to (e.g., 'patient_profile_pictures', 'clinic_logos').
|
|
803
|
-
* @param originalFileName - Optional: the original name of the file, if not using file.name.
|
|
804
|
-
* @returns Promise with the media metadata.
|
|
805
|
-
*/
|
|
806
|
-
uploadMedia(file: File | Blob, ownerId: string, accessLevel: MediaAccessLevel, collectionName: string, originalFileName?: string): Promise<MediaMetadata>;
|
|
807
|
-
/**
|
|
808
|
-
* Get media metadata from Firestore by its ID.
|
|
809
|
-
* @param mediaId - ID of the media.
|
|
810
|
-
* @returns Promise with the media metadata or null if not found.
|
|
811
|
-
*/
|
|
812
|
-
getMediaMetadata(mediaId: string): Promise<MediaMetadata | null>;
|
|
813
|
-
/**
|
|
814
|
-
* Get media metadata from Firestore by its public URL.
|
|
815
|
-
* @param url - The public URL of the media file.
|
|
816
|
-
* @returns Promise with the media metadata or null if not found.
|
|
817
|
-
*/
|
|
818
|
-
getMediaMetadataByUrl(url: string): Promise<MediaMetadata | null>;
|
|
819
|
-
/**
|
|
820
|
-
* Delete media from storage and remove metadata from Firestore.
|
|
821
|
-
* @param mediaId - ID of the media to delete.
|
|
822
|
-
*/
|
|
823
|
-
deleteMedia(mediaId: string): Promise<void>;
|
|
824
|
-
/**
|
|
825
|
-
* Update media access level. This involves moving the file in Firebase Storage
|
|
826
|
-
* to a new path reflecting the new access level, and updating its metadata.
|
|
827
|
-
* @param mediaId - ID of the media to update.
|
|
828
|
-
* @param newAccessLevel - New access level.
|
|
829
|
-
* @returns Promise with the updated media metadata, or null if metadata not found.
|
|
830
|
-
*/
|
|
831
|
-
updateMediaAccessLevel(mediaId: string, newAccessLevel: MediaAccessLevel): Promise<MediaMetadata | null>;
|
|
832
|
-
/**
|
|
833
|
-
* List all media for an owner, optionally filtered by collection and access level.
|
|
834
|
-
* @param ownerId - ID of the owner.
|
|
835
|
-
* @param collectionName - Optional: Filter by collection name.
|
|
836
|
-
* @param accessLevel - Optional: Filter by access level.
|
|
837
|
-
* @param count - Optional: Number of items to fetch.
|
|
838
|
-
* @param startAfterId - Optional: ID of the document to start after (for pagination).
|
|
839
|
-
*/
|
|
840
|
-
listMedia(ownerId: string, collectionName?: string, accessLevel?: MediaAccessLevel, count?: number, startAfterId?: string): Promise<MediaMetadata[]>;
|
|
841
|
-
/**
|
|
842
|
-
* Get download URL for media. (Convenience, as URL is in metadata)
|
|
843
|
-
* @param mediaId - ID of the media.
|
|
844
|
-
*/
|
|
845
|
-
getMediaDownloadUrl(mediaId: string): Promise<string | null>;
|
|
846
|
-
}
|
|
847
|
-
|
|
848
848
|
declare const CLINIC_GROUPS_COLLECTION = "clinic_groups";
|
|
849
849
|
declare const CLINIC_ADMINS_COLLECTION = "clinic_admins";
|
|
850
850
|
declare const CLINICS_COLLECTION = "clinics";
|
|
@@ -4836,8 +4836,8 @@ declare const updateAppointmentSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
|
4836
4836
|
submittedAt: z.ZodOptional<z.ZodEffects<z.ZodAny, any, any>>;
|
|
4837
4837
|
completedAt: z.ZodOptional<z.ZodEffects<z.ZodAny, any, any>>;
|
|
4838
4838
|
}, "strip", z.ZodTypeAny, {
|
|
4839
|
-
status: FilledDocumentStatus;
|
|
4840
4839
|
path: string;
|
|
4840
|
+
status: FilledDocumentStatus;
|
|
4841
4841
|
title: string;
|
|
4842
4842
|
isUserForm: boolean;
|
|
4843
4843
|
templateId: string;
|
|
@@ -4847,8 +4847,8 @@ declare const updateAppointmentSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
|
4847
4847
|
submittedAt?: any;
|
|
4848
4848
|
completedAt?: any;
|
|
4849
4849
|
}, {
|
|
4850
|
-
status: FilledDocumentStatus;
|
|
4851
4850
|
path: string;
|
|
4851
|
+
status: FilledDocumentStatus;
|
|
4852
4852
|
title: string;
|
|
4853
4853
|
isUserForm: boolean;
|
|
4854
4854
|
templateId: string;
|
|
@@ -5103,56 +5103,56 @@ declare const searchAppointmentsSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
|
5103
5103
|
startAfter: z.ZodOptional<z.ZodAny>;
|
|
5104
5104
|
}, "strip", z.ZodTypeAny, {
|
|
5105
5105
|
limit: number;
|
|
5106
|
+
startAfter?: any;
|
|
5106
5107
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5107
5108
|
patientId?: string | undefined;
|
|
5108
5109
|
startDate?: any;
|
|
5109
5110
|
endDate?: any;
|
|
5110
|
-
startAfter?: any;
|
|
5111
5111
|
practitionerId?: string | undefined;
|
|
5112
5112
|
clinicBranchId?: string | undefined;
|
|
5113
5113
|
}, {
|
|
5114
|
+
limit?: number | undefined;
|
|
5115
|
+
startAfter?: any;
|
|
5114
5116
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5115
5117
|
patientId?: string | undefined;
|
|
5116
5118
|
startDate?: any;
|
|
5117
5119
|
endDate?: any;
|
|
5118
|
-
limit?: number | undefined;
|
|
5119
|
-
startAfter?: any;
|
|
5120
5120
|
practitionerId?: string | undefined;
|
|
5121
5121
|
clinicBranchId?: string | undefined;
|
|
5122
5122
|
}>, {
|
|
5123
5123
|
limit: number;
|
|
5124
|
+
startAfter?: any;
|
|
5124
5125
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5125
5126
|
patientId?: string | undefined;
|
|
5126
5127
|
startDate?: any;
|
|
5127
5128
|
endDate?: any;
|
|
5128
|
-
startAfter?: any;
|
|
5129
5129
|
practitionerId?: string | undefined;
|
|
5130
5130
|
clinicBranchId?: string | undefined;
|
|
5131
5131
|
}, {
|
|
5132
|
+
limit?: number | undefined;
|
|
5133
|
+
startAfter?: any;
|
|
5132
5134
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5133
5135
|
patientId?: string | undefined;
|
|
5134
5136
|
startDate?: any;
|
|
5135
5137
|
endDate?: any;
|
|
5136
|
-
limit?: number | undefined;
|
|
5137
|
-
startAfter?: any;
|
|
5138
5138
|
practitionerId?: string | undefined;
|
|
5139
5139
|
clinicBranchId?: string | undefined;
|
|
5140
5140
|
}>, {
|
|
5141
5141
|
limit: number;
|
|
5142
|
+
startAfter?: any;
|
|
5142
5143
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5143
5144
|
patientId?: string | undefined;
|
|
5144
5145
|
startDate?: any;
|
|
5145
5146
|
endDate?: any;
|
|
5146
|
-
startAfter?: any;
|
|
5147
5147
|
practitionerId?: string | undefined;
|
|
5148
5148
|
clinicBranchId?: string | undefined;
|
|
5149
5149
|
}, {
|
|
5150
|
+
limit?: number | undefined;
|
|
5151
|
+
startAfter?: any;
|
|
5150
5152
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5151
5153
|
patientId?: string | undefined;
|
|
5152
5154
|
startDate?: any;
|
|
5153
5155
|
endDate?: any;
|
|
5154
|
-
limit?: number | undefined;
|
|
5155
|
-
startAfter?: any;
|
|
5156
5156
|
practitionerId?: string | undefined;
|
|
5157
5157
|
clinicBranchId?: string | undefined;
|
|
5158
5158
|
}>;
|
|
@@ -6444,7 +6444,24 @@ declare class ProcedureService extends BaseService {
|
|
|
6444
6444
|
private subcategoryService;
|
|
6445
6445
|
private technologyService;
|
|
6446
6446
|
private productService;
|
|
6447
|
-
|
|
6447
|
+
private mediaService;
|
|
6448
|
+
constructor(db: Firestore, auth: Auth, app: FirebaseApp, categoryService: CategoryService, subcategoryService: SubcategoryService, technologyService: TechnologyService, productService: ProductService, mediaService: MediaService);
|
|
6449
|
+
/**
|
|
6450
|
+
* Process media resource (string URL or File object)
|
|
6451
|
+
* @param media String URL or File object
|
|
6452
|
+
* @param ownerId Owner ID for the media (usually procedureId)
|
|
6453
|
+
* @param collectionName Collection name for organizing files
|
|
6454
|
+
* @returns URL string after processing
|
|
6455
|
+
*/
|
|
6456
|
+
private processMedia;
|
|
6457
|
+
/**
|
|
6458
|
+
* Process array of media resources (strings or Files)
|
|
6459
|
+
* @param mediaArray Array of string URLs or File objects
|
|
6460
|
+
* @param ownerId Owner ID for the media
|
|
6461
|
+
* @param collectionName Collection name for organizing files
|
|
6462
|
+
* @returns Array of URL strings after processing
|
|
6463
|
+
*/
|
|
6464
|
+
private processMediaArray;
|
|
6448
6465
|
/**
|
|
6449
6466
|
* Creates a new procedure
|
|
6450
6467
|
* @param data - The data for creating a new procedure
|
|
@@ -14079,6 +14096,7 @@ declare const clinicGroupSchema: z.ZodObject<{
|
|
|
14079
14096
|
updatedAt: Date | Timestamp;
|
|
14080
14097
|
name: string;
|
|
14081
14098
|
isActive: boolean;
|
|
14099
|
+
ownerId: string | null;
|
|
14082
14100
|
clinics: string[];
|
|
14083
14101
|
clinicsInfo: {
|
|
14084
14102
|
id: string;
|
|
@@ -14101,7 +14119,6 @@ declare const clinicGroupSchema: z.ZodObject<{
|
|
|
14101
14119
|
featuredPhoto: string;
|
|
14102
14120
|
description?: string | null | undefined;
|
|
14103
14121
|
}[];
|
|
14104
|
-
ownerId: string | null;
|
|
14105
14122
|
contactInfo: {
|
|
14106
14123
|
email: string;
|
|
14107
14124
|
phoneNumber: string;
|
|
@@ -14157,6 +14174,7 @@ declare const clinicGroupSchema: z.ZodObject<{
|
|
|
14157
14174
|
updatedAt: Date | Timestamp;
|
|
14158
14175
|
name: string;
|
|
14159
14176
|
isActive: boolean;
|
|
14177
|
+
ownerId: string | null;
|
|
14160
14178
|
clinics: string[];
|
|
14161
14179
|
clinicsInfo: {
|
|
14162
14180
|
id: string;
|
|
@@ -14179,7 +14197,6 @@ declare const clinicGroupSchema: z.ZodObject<{
|
|
|
14179
14197
|
featuredPhoto: string;
|
|
14180
14198
|
description?: string | null | undefined;
|
|
14181
14199
|
}[];
|
|
14182
|
-
ownerId: string | null;
|
|
14183
14200
|
contactInfo: {
|
|
14184
14201
|
email: string;
|
|
14185
14202
|
phoneNumber: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -507,6 +507,102 @@ declare enum Currency {
|
|
|
507
507
|
AUD = "AUD"
|
|
508
508
|
}
|
|
509
509
|
|
|
510
|
+
declare class BaseService {
|
|
511
|
+
protected db: Firestore;
|
|
512
|
+
protected auth: Auth;
|
|
513
|
+
protected app: FirebaseApp;
|
|
514
|
+
protected storage: FirebaseStorage;
|
|
515
|
+
constructor(db: Firestore, auth: Auth, app: FirebaseApp);
|
|
516
|
+
/**
|
|
517
|
+
* Generiše jedinstveni ID za dokumente
|
|
518
|
+
* Format: xxxxxxxxxxxx-timestamp
|
|
519
|
+
* Gde je x random karakter (broj ili slovo)
|
|
520
|
+
*/
|
|
521
|
+
protected generateId(): string;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Enum for media access levels
|
|
526
|
+
*/
|
|
527
|
+
declare enum MediaAccessLevel {
|
|
528
|
+
PUBLIC = "public",
|
|
529
|
+
PRIVATE = "private",
|
|
530
|
+
CONFIDENTIAL = "confidential"
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Type that allows a field to be either a URL string or a File object
|
|
534
|
+
*/
|
|
535
|
+
type MediaResource = string | File | Blob;
|
|
536
|
+
/**
|
|
537
|
+
* Media file metadata interface
|
|
538
|
+
*/
|
|
539
|
+
interface MediaMetadata {
|
|
540
|
+
id: string;
|
|
541
|
+
name: string;
|
|
542
|
+
url: string;
|
|
543
|
+
contentType: string;
|
|
544
|
+
size: number;
|
|
545
|
+
createdAt: Timestamp;
|
|
546
|
+
accessLevel: MediaAccessLevel;
|
|
547
|
+
ownerId: string;
|
|
548
|
+
collectionName: string;
|
|
549
|
+
path: string;
|
|
550
|
+
updatedAt?: Timestamp;
|
|
551
|
+
}
|
|
552
|
+
declare const MEDIA_METADATA_COLLECTION = "media_metadata";
|
|
553
|
+
declare class MediaService extends BaseService {
|
|
554
|
+
constructor(db: Firestore, auth: Auth, app: FirebaseApp);
|
|
555
|
+
/**
|
|
556
|
+
* Upload a media file, store its metadata, and return the metadata including the URL.
|
|
557
|
+
* @param file - The file to upload.
|
|
558
|
+
* @param ownerId - ID of the owner (user, patient, clinic, etc.).
|
|
559
|
+
* @param accessLevel - Access level (public, private, confidential).
|
|
560
|
+
* @param collectionName - The logical collection name this media belongs to (e.g., 'patient_profile_pictures', 'clinic_logos').
|
|
561
|
+
* @param originalFileName - Optional: the original name of the file, if not using file.name.
|
|
562
|
+
* @returns Promise with the media metadata.
|
|
563
|
+
*/
|
|
564
|
+
uploadMedia(file: File | Blob, ownerId: string, accessLevel: MediaAccessLevel, collectionName: string, originalFileName?: string): Promise<MediaMetadata>;
|
|
565
|
+
/**
|
|
566
|
+
* Get media metadata from Firestore by its ID.
|
|
567
|
+
* @param mediaId - ID of the media.
|
|
568
|
+
* @returns Promise with the media metadata or null if not found.
|
|
569
|
+
*/
|
|
570
|
+
getMediaMetadata(mediaId: string): Promise<MediaMetadata | null>;
|
|
571
|
+
/**
|
|
572
|
+
* Get media metadata from Firestore by its public URL.
|
|
573
|
+
* @param url - The public URL of the media file.
|
|
574
|
+
* @returns Promise with the media metadata or null if not found.
|
|
575
|
+
*/
|
|
576
|
+
getMediaMetadataByUrl(url: string): Promise<MediaMetadata | null>;
|
|
577
|
+
/**
|
|
578
|
+
* Delete media from storage and remove metadata from Firestore.
|
|
579
|
+
* @param mediaId - ID of the media to delete.
|
|
580
|
+
*/
|
|
581
|
+
deleteMedia(mediaId: string): Promise<void>;
|
|
582
|
+
/**
|
|
583
|
+
* Update media access level. This involves moving the file in Firebase Storage
|
|
584
|
+
* to a new path reflecting the new access level, and updating its metadata.
|
|
585
|
+
* @param mediaId - ID of the media to update.
|
|
586
|
+
* @param newAccessLevel - New access level.
|
|
587
|
+
* @returns Promise with the updated media metadata, or null if metadata not found.
|
|
588
|
+
*/
|
|
589
|
+
updateMediaAccessLevel(mediaId: string, newAccessLevel: MediaAccessLevel): Promise<MediaMetadata | null>;
|
|
590
|
+
/**
|
|
591
|
+
* List all media for an owner, optionally filtered by collection and access level.
|
|
592
|
+
* @param ownerId - ID of the owner.
|
|
593
|
+
* @param collectionName - Optional: Filter by collection name.
|
|
594
|
+
* @param accessLevel - Optional: Filter by access level.
|
|
595
|
+
* @param count - Optional: Number of items to fetch.
|
|
596
|
+
* @param startAfterId - Optional: ID of the document to start after (for pagination).
|
|
597
|
+
*/
|
|
598
|
+
listMedia(ownerId: string, collectionName?: string, accessLevel?: MediaAccessLevel, count?: number, startAfterId?: string): Promise<MediaMetadata[]>;
|
|
599
|
+
/**
|
|
600
|
+
* Get download URL for media. (Convenience, as URL is in metadata)
|
|
601
|
+
* @param mediaId - ID of the media.
|
|
602
|
+
*/
|
|
603
|
+
getMediaDownloadUrl(mediaId: string): Promise<string | null>;
|
|
604
|
+
}
|
|
605
|
+
|
|
510
606
|
/**
|
|
511
607
|
* Procedure represents a specific medical procedure that can be performed by a practitioner in a clinic
|
|
512
608
|
* It inherits properties from technology and adds clinic/practitioner specific details
|
|
@@ -517,7 +613,7 @@ interface Procedure {
|
|
|
517
613
|
/** Name of the procedure */
|
|
518
614
|
name: string;
|
|
519
615
|
/** Photos of the procedure */
|
|
520
|
-
photos?:
|
|
616
|
+
photos?: MediaResource[];
|
|
521
617
|
/** Detailed description of the procedure */
|
|
522
618
|
description: string;
|
|
523
619
|
/** Family of procedures this belongs to (aesthetics/surgery) */
|
|
@@ -586,7 +682,7 @@ interface CreateProcedureData {
|
|
|
586
682
|
duration: number;
|
|
587
683
|
practitionerId: string;
|
|
588
684
|
clinicBranchId: string;
|
|
589
|
-
photos?:
|
|
685
|
+
photos?: MediaResource[];
|
|
590
686
|
}
|
|
591
687
|
/**
|
|
592
688
|
* Data that can be updated for an existing procedure
|
|
@@ -605,7 +701,7 @@ interface UpdateProcedureData {
|
|
|
605
701
|
technologyId?: string;
|
|
606
702
|
productId?: string;
|
|
607
703
|
clinicBranchId?: string;
|
|
608
|
-
photos?:
|
|
704
|
+
photos?: MediaResource[];
|
|
609
705
|
}
|
|
610
706
|
/**
|
|
611
707
|
* Collection name for procedures in Firestore
|
|
@@ -749,102 +845,6 @@ declare enum ClinicPhotoTag {
|
|
|
749
845
|
OTHER = "other"
|
|
750
846
|
}
|
|
751
847
|
|
|
752
|
-
declare class BaseService {
|
|
753
|
-
protected db: Firestore;
|
|
754
|
-
protected auth: Auth;
|
|
755
|
-
protected app: FirebaseApp;
|
|
756
|
-
protected storage: FirebaseStorage;
|
|
757
|
-
constructor(db: Firestore, auth: Auth, app: FirebaseApp);
|
|
758
|
-
/**
|
|
759
|
-
* Generiše jedinstveni ID za dokumente
|
|
760
|
-
* Format: xxxxxxxxxxxx-timestamp
|
|
761
|
-
* Gde je x random karakter (broj ili slovo)
|
|
762
|
-
*/
|
|
763
|
-
protected generateId(): string;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
/**
|
|
767
|
-
* Enum for media access levels
|
|
768
|
-
*/
|
|
769
|
-
declare enum MediaAccessLevel {
|
|
770
|
-
PUBLIC = "public",
|
|
771
|
-
PRIVATE = "private",
|
|
772
|
-
CONFIDENTIAL = "confidential"
|
|
773
|
-
}
|
|
774
|
-
/**
|
|
775
|
-
* Type that allows a field to be either a URL string or a File object
|
|
776
|
-
*/
|
|
777
|
-
type MediaResource = string | File | Blob;
|
|
778
|
-
/**
|
|
779
|
-
* Media file metadata interface
|
|
780
|
-
*/
|
|
781
|
-
interface MediaMetadata {
|
|
782
|
-
id: string;
|
|
783
|
-
name: string;
|
|
784
|
-
url: string;
|
|
785
|
-
contentType: string;
|
|
786
|
-
size: number;
|
|
787
|
-
createdAt: Timestamp;
|
|
788
|
-
accessLevel: MediaAccessLevel;
|
|
789
|
-
ownerId: string;
|
|
790
|
-
collectionName: string;
|
|
791
|
-
path: string;
|
|
792
|
-
updatedAt?: Timestamp;
|
|
793
|
-
}
|
|
794
|
-
declare const MEDIA_METADATA_COLLECTION = "media_metadata";
|
|
795
|
-
declare class MediaService extends BaseService {
|
|
796
|
-
constructor(db: Firestore, auth: Auth, app: FirebaseApp);
|
|
797
|
-
/**
|
|
798
|
-
* Upload a media file, store its metadata, and return the metadata including the URL.
|
|
799
|
-
* @param file - The file to upload.
|
|
800
|
-
* @param ownerId - ID of the owner (user, patient, clinic, etc.).
|
|
801
|
-
* @param accessLevel - Access level (public, private, confidential).
|
|
802
|
-
* @param collectionName - The logical collection name this media belongs to (e.g., 'patient_profile_pictures', 'clinic_logos').
|
|
803
|
-
* @param originalFileName - Optional: the original name of the file, if not using file.name.
|
|
804
|
-
* @returns Promise with the media metadata.
|
|
805
|
-
*/
|
|
806
|
-
uploadMedia(file: File | Blob, ownerId: string, accessLevel: MediaAccessLevel, collectionName: string, originalFileName?: string): Promise<MediaMetadata>;
|
|
807
|
-
/**
|
|
808
|
-
* Get media metadata from Firestore by its ID.
|
|
809
|
-
* @param mediaId - ID of the media.
|
|
810
|
-
* @returns Promise with the media metadata or null if not found.
|
|
811
|
-
*/
|
|
812
|
-
getMediaMetadata(mediaId: string): Promise<MediaMetadata | null>;
|
|
813
|
-
/**
|
|
814
|
-
* Get media metadata from Firestore by its public URL.
|
|
815
|
-
* @param url - The public URL of the media file.
|
|
816
|
-
* @returns Promise with the media metadata or null if not found.
|
|
817
|
-
*/
|
|
818
|
-
getMediaMetadataByUrl(url: string): Promise<MediaMetadata | null>;
|
|
819
|
-
/**
|
|
820
|
-
* Delete media from storage and remove metadata from Firestore.
|
|
821
|
-
* @param mediaId - ID of the media to delete.
|
|
822
|
-
*/
|
|
823
|
-
deleteMedia(mediaId: string): Promise<void>;
|
|
824
|
-
/**
|
|
825
|
-
* Update media access level. This involves moving the file in Firebase Storage
|
|
826
|
-
* to a new path reflecting the new access level, and updating its metadata.
|
|
827
|
-
* @param mediaId - ID of the media to update.
|
|
828
|
-
* @param newAccessLevel - New access level.
|
|
829
|
-
* @returns Promise with the updated media metadata, or null if metadata not found.
|
|
830
|
-
*/
|
|
831
|
-
updateMediaAccessLevel(mediaId: string, newAccessLevel: MediaAccessLevel): Promise<MediaMetadata | null>;
|
|
832
|
-
/**
|
|
833
|
-
* List all media for an owner, optionally filtered by collection and access level.
|
|
834
|
-
* @param ownerId - ID of the owner.
|
|
835
|
-
* @param collectionName - Optional: Filter by collection name.
|
|
836
|
-
* @param accessLevel - Optional: Filter by access level.
|
|
837
|
-
* @param count - Optional: Number of items to fetch.
|
|
838
|
-
* @param startAfterId - Optional: ID of the document to start after (for pagination).
|
|
839
|
-
*/
|
|
840
|
-
listMedia(ownerId: string, collectionName?: string, accessLevel?: MediaAccessLevel, count?: number, startAfterId?: string): Promise<MediaMetadata[]>;
|
|
841
|
-
/**
|
|
842
|
-
* Get download URL for media. (Convenience, as URL is in metadata)
|
|
843
|
-
* @param mediaId - ID of the media.
|
|
844
|
-
*/
|
|
845
|
-
getMediaDownloadUrl(mediaId: string): Promise<string | null>;
|
|
846
|
-
}
|
|
847
|
-
|
|
848
848
|
declare const CLINIC_GROUPS_COLLECTION = "clinic_groups";
|
|
849
849
|
declare const CLINIC_ADMINS_COLLECTION = "clinic_admins";
|
|
850
850
|
declare const CLINICS_COLLECTION = "clinics";
|
|
@@ -4836,8 +4836,8 @@ declare const updateAppointmentSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
|
4836
4836
|
submittedAt: z.ZodOptional<z.ZodEffects<z.ZodAny, any, any>>;
|
|
4837
4837
|
completedAt: z.ZodOptional<z.ZodEffects<z.ZodAny, any, any>>;
|
|
4838
4838
|
}, "strip", z.ZodTypeAny, {
|
|
4839
|
-
status: FilledDocumentStatus;
|
|
4840
4839
|
path: string;
|
|
4840
|
+
status: FilledDocumentStatus;
|
|
4841
4841
|
title: string;
|
|
4842
4842
|
isUserForm: boolean;
|
|
4843
4843
|
templateId: string;
|
|
@@ -4847,8 +4847,8 @@ declare const updateAppointmentSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
|
4847
4847
|
submittedAt?: any;
|
|
4848
4848
|
completedAt?: any;
|
|
4849
4849
|
}, {
|
|
4850
|
-
status: FilledDocumentStatus;
|
|
4851
4850
|
path: string;
|
|
4851
|
+
status: FilledDocumentStatus;
|
|
4852
4852
|
title: string;
|
|
4853
4853
|
isUserForm: boolean;
|
|
4854
4854
|
templateId: string;
|
|
@@ -5103,56 +5103,56 @@ declare const searchAppointmentsSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
|
5103
5103
|
startAfter: z.ZodOptional<z.ZodAny>;
|
|
5104
5104
|
}, "strip", z.ZodTypeAny, {
|
|
5105
5105
|
limit: number;
|
|
5106
|
+
startAfter?: any;
|
|
5106
5107
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5107
5108
|
patientId?: string | undefined;
|
|
5108
5109
|
startDate?: any;
|
|
5109
5110
|
endDate?: any;
|
|
5110
|
-
startAfter?: any;
|
|
5111
5111
|
practitionerId?: string | undefined;
|
|
5112
5112
|
clinicBranchId?: string | undefined;
|
|
5113
5113
|
}, {
|
|
5114
|
+
limit?: number | undefined;
|
|
5115
|
+
startAfter?: any;
|
|
5114
5116
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5115
5117
|
patientId?: string | undefined;
|
|
5116
5118
|
startDate?: any;
|
|
5117
5119
|
endDate?: any;
|
|
5118
|
-
limit?: number | undefined;
|
|
5119
|
-
startAfter?: any;
|
|
5120
5120
|
practitionerId?: string | undefined;
|
|
5121
5121
|
clinicBranchId?: string | undefined;
|
|
5122
5122
|
}>, {
|
|
5123
5123
|
limit: number;
|
|
5124
|
+
startAfter?: any;
|
|
5124
5125
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5125
5126
|
patientId?: string | undefined;
|
|
5126
5127
|
startDate?: any;
|
|
5127
5128
|
endDate?: any;
|
|
5128
|
-
startAfter?: any;
|
|
5129
5129
|
practitionerId?: string | undefined;
|
|
5130
5130
|
clinicBranchId?: string | undefined;
|
|
5131
5131
|
}, {
|
|
5132
|
+
limit?: number | undefined;
|
|
5133
|
+
startAfter?: any;
|
|
5132
5134
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5133
5135
|
patientId?: string | undefined;
|
|
5134
5136
|
startDate?: any;
|
|
5135
5137
|
endDate?: any;
|
|
5136
|
-
limit?: number | undefined;
|
|
5137
|
-
startAfter?: any;
|
|
5138
5138
|
practitionerId?: string | undefined;
|
|
5139
5139
|
clinicBranchId?: string | undefined;
|
|
5140
5140
|
}>, {
|
|
5141
5141
|
limit: number;
|
|
5142
|
+
startAfter?: any;
|
|
5142
5143
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5143
5144
|
patientId?: string | undefined;
|
|
5144
5145
|
startDate?: any;
|
|
5145
5146
|
endDate?: any;
|
|
5146
|
-
startAfter?: any;
|
|
5147
5147
|
practitionerId?: string | undefined;
|
|
5148
5148
|
clinicBranchId?: string | undefined;
|
|
5149
5149
|
}, {
|
|
5150
|
+
limit?: number | undefined;
|
|
5151
|
+
startAfter?: any;
|
|
5150
5152
|
status?: AppointmentStatus | [AppointmentStatus, ...AppointmentStatus[]] | undefined;
|
|
5151
5153
|
patientId?: string | undefined;
|
|
5152
5154
|
startDate?: any;
|
|
5153
5155
|
endDate?: any;
|
|
5154
|
-
limit?: number | undefined;
|
|
5155
|
-
startAfter?: any;
|
|
5156
5156
|
practitionerId?: string | undefined;
|
|
5157
5157
|
clinicBranchId?: string | undefined;
|
|
5158
5158
|
}>;
|
|
@@ -6444,7 +6444,24 @@ declare class ProcedureService extends BaseService {
|
|
|
6444
6444
|
private subcategoryService;
|
|
6445
6445
|
private technologyService;
|
|
6446
6446
|
private productService;
|
|
6447
|
-
|
|
6447
|
+
private mediaService;
|
|
6448
|
+
constructor(db: Firestore, auth: Auth, app: FirebaseApp, categoryService: CategoryService, subcategoryService: SubcategoryService, technologyService: TechnologyService, productService: ProductService, mediaService: MediaService);
|
|
6449
|
+
/**
|
|
6450
|
+
* Process media resource (string URL or File object)
|
|
6451
|
+
* @param media String URL or File object
|
|
6452
|
+
* @param ownerId Owner ID for the media (usually procedureId)
|
|
6453
|
+
* @param collectionName Collection name for organizing files
|
|
6454
|
+
* @returns URL string after processing
|
|
6455
|
+
*/
|
|
6456
|
+
private processMedia;
|
|
6457
|
+
/**
|
|
6458
|
+
* Process array of media resources (strings or Files)
|
|
6459
|
+
* @param mediaArray Array of string URLs or File objects
|
|
6460
|
+
* @param ownerId Owner ID for the media
|
|
6461
|
+
* @param collectionName Collection name for organizing files
|
|
6462
|
+
* @returns Array of URL strings after processing
|
|
6463
|
+
*/
|
|
6464
|
+
private processMediaArray;
|
|
6448
6465
|
/**
|
|
6449
6466
|
* Creates a new procedure
|
|
6450
6467
|
* @param data - The data for creating a new procedure
|
|
@@ -14079,6 +14096,7 @@ declare const clinicGroupSchema: z.ZodObject<{
|
|
|
14079
14096
|
updatedAt: Date | Timestamp;
|
|
14080
14097
|
name: string;
|
|
14081
14098
|
isActive: boolean;
|
|
14099
|
+
ownerId: string | null;
|
|
14082
14100
|
clinics: string[];
|
|
14083
14101
|
clinicsInfo: {
|
|
14084
14102
|
id: string;
|
|
@@ -14101,7 +14119,6 @@ declare const clinicGroupSchema: z.ZodObject<{
|
|
|
14101
14119
|
featuredPhoto: string;
|
|
14102
14120
|
description?: string | null | undefined;
|
|
14103
14121
|
}[];
|
|
14104
|
-
ownerId: string | null;
|
|
14105
14122
|
contactInfo: {
|
|
14106
14123
|
email: string;
|
|
14107
14124
|
phoneNumber: string;
|
|
@@ -14157,6 +14174,7 @@ declare const clinicGroupSchema: z.ZodObject<{
|
|
|
14157
14174
|
updatedAt: Date | Timestamp;
|
|
14158
14175
|
name: string;
|
|
14159
14176
|
isActive: boolean;
|
|
14177
|
+
ownerId: string | null;
|
|
14160
14178
|
clinics: string[];
|
|
14161
14179
|
clinicsInfo: {
|
|
14162
14180
|
id: string;
|
|
@@ -14179,7 +14197,6 @@ declare const clinicGroupSchema: z.ZodObject<{
|
|
|
14179
14197
|
featuredPhoto: string;
|
|
14180
14198
|
description?: string | null | undefined;
|
|
14181
14199
|
}[];
|
|
14182
|
-
ownerId: string | null;
|
|
14183
14200
|
contactInfo: {
|
|
14184
14201
|
email: string;
|
|
14185
14202
|
phoneNumber: string;
|
package/dist/index.js
CHANGED
|
@@ -8353,7 +8353,7 @@ var createProcedureSchema = import_zod21.z.object({
|
|
|
8353
8353
|
// Max 8 hours
|
|
8354
8354
|
practitionerId: import_zod21.z.string().min(1),
|
|
8355
8355
|
clinicBranchId: import_zod21.z.string().min(1),
|
|
8356
|
-
photos: import_zod21.z.array(
|
|
8356
|
+
photos: import_zod21.z.array(mediaResourceSchema).optional()
|
|
8357
8357
|
});
|
|
8358
8358
|
var updateProcedureSchema = import_zod21.z.object({
|
|
8359
8359
|
name: import_zod21.z.string().min(3).max(100).optional(),
|
|
@@ -8369,7 +8369,7 @@ var updateProcedureSchema = import_zod21.z.object({
|
|
|
8369
8369
|
technologyId: import_zod21.z.string().optional(),
|
|
8370
8370
|
productId: import_zod21.z.string().optional(),
|
|
8371
8371
|
clinicBranchId: import_zod21.z.string().optional(),
|
|
8372
|
-
photos: import_zod21.z.array(
|
|
8372
|
+
photos: import_zod21.z.array(mediaResourceSchema).optional()
|
|
8373
8373
|
});
|
|
8374
8374
|
var procedureSchema = createProcedureSchema.extend({
|
|
8375
8375
|
id: import_zod21.z.string().min(1),
|
|
@@ -8409,12 +8409,61 @@ var procedureSchema = createProcedureSchema.extend({
|
|
|
8409
8409
|
// src/services/procedure/procedure.service.ts
|
|
8410
8410
|
var import_geofire_common8 = require("geofire-common");
|
|
8411
8411
|
var ProcedureService = class extends BaseService {
|
|
8412
|
-
constructor(db, auth, app, categoryService, subcategoryService, technologyService, productService) {
|
|
8412
|
+
constructor(db, auth, app, categoryService, subcategoryService, technologyService, productService, mediaService) {
|
|
8413
8413
|
super(db, auth, app);
|
|
8414
8414
|
this.categoryService = categoryService;
|
|
8415
8415
|
this.subcategoryService = subcategoryService;
|
|
8416
8416
|
this.technologyService = technologyService;
|
|
8417
8417
|
this.productService = productService;
|
|
8418
|
+
this.mediaService = mediaService;
|
|
8419
|
+
}
|
|
8420
|
+
/**
|
|
8421
|
+
* Process media resource (string URL or File object)
|
|
8422
|
+
* @param media String URL or File object
|
|
8423
|
+
* @param ownerId Owner ID for the media (usually procedureId)
|
|
8424
|
+
* @param collectionName Collection name for organizing files
|
|
8425
|
+
* @returns URL string after processing
|
|
8426
|
+
*/
|
|
8427
|
+
async processMedia(media, ownerId, collectionName) {
|
|
8428
|
+
if (!media) return null;
|
|
8429
|
+
if (typeof media === "string") {
|
|
8430
|
+
return media;
|
|
8431
|
+
}
|
|
8432
|
+
if (media instanceof File || media instanceof Blob) {
|
|
8433
|
+
console.log(
|
|
8434
|
+
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
8435
|
+
);
|
|
8436
|
+
const metadata = await this.mediaService.uploadMedia(
|
|
8437
|
+
media,
|
|
8438
|
+
ownerId,
|
|
8439
|
+
"public" /* PUBLIC */,
|
|
8440
|
+
collectionName
|
|
8441
|
+
);
|
|
8442
|
+
return metadata.url;
|
|
8443
|
+
}
|
|
8444
|
+
return null;
|
|
8445
|
+
}
|
|
8446
|
+
/**
|
|
8447
|
+
* Process array of media resources (strings or Files)
|
|
8448
|
+
* @param mediaArray Array of string URLs or File objects
|
|
8449
|
+
* @param ownerId Owner ID for the media
|
|
8450
|
+
* @param collectionName Collection name for organizing files
|
|
8451
|
+
* @returns Array of URL strings after processing
|
|
8452
|
+
*/
|
|
8453
|
+
async processMediaArray(mediaArray, ownerId, collectionName) {
|
|
8454
|
+
if (!mediaArray || mediaArray.length === 0) return [];
|
|
8455
|
+
const result = [];
|
|
8456
|
+
for (const media of mediaArray) {
|
|
8457
|
+
const processedUrl = await this.processMedia(
|
|
8458
|
+
media,
|
|
8459
|
+
ownerId,
|
|
8460
|
+
collectionName
|
|
8461
|
+
);
|
|
8462
|
+
if (processedUrl) {
|
|
8463
|
+
result.push(processedUrl);
|
|
8464
|
+
}
|
|
8465
|
+
}
|
|
8466
|
+
return result;
|
|
8418
8467
|
}
|
|
8419
8468
|
/**
|
|
8420
8469
|
* Creates a new procedure
|
|
@@ -8424,6 +8473,7 @@ var ProcedureService = class extends BaseService {
|
|
|
8424
8473
|
async createProcedure(data) {
|
|
8425
8474
|
var _a;
|
|
8426
8475
|
const validatedData = createProcedureSchema.parse(data);
|
|
8476
|
+
const procedureId = this.generateId();
|
|
8427
8477
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
8428
8478
|
this.categoryService.getById(validatedData.categoryId),
|
|
8429
8479
|
this.subcategoryService.getById(
|
|
@@ -8463,6 +8513,14 @@ var ProcedureService = class extends BaseService {
|
|
|
8463
8513
|
);
|
|
8464
8514
|
}
|
|
8465
8515
|
const practitioner = practitionerSnapshot.data();
|
|
8516
|
+
let processedPhotos = [];
|
|
8517
|
+
if (validatedData.photos && validatedData.photos.length > 0) {
|
|
8518
|
+
processedPhotos = await this.processMediaArray(
|
|
8519
|
+
validatedData.photos,
|
|
8520
|
+
procedureId,
|
|
8521
|
+
"procedure-photos"
|
|
8522
|
+
);
|
|
8523
|
+
}
|
|
8466
8524
|
const clinicInfo = {
|
|
8467
8525
|
id: clinicSnapshot.id,
|
|
8468
8526
|
name: clinic.name,
|
|
@@ -8479,10 +8537,10 @@ var ProcedureService = class extends BaseService {
|
|
|
8479
8537
|
rating: ((_a = practitioner.reviewInfo) == null ? void 0 : _a.averageRating) || 0,
|
|
8480
8538
|
services: practitioner.procedures || []
|
|
8481
8539
|
};
|
|
8482
|
-
const procedureId = this.generateId();
|
|
8483
8540
|
const newProcedure = {
|
|
8484
8541
|
id: procedureId,
|
|
8485
8542
|
...validatedData,
|
|
8543
|
+
photos: processedPhotos,
|
|
8486
8544
|
category,
|
|
8487
8545
|
// Embed full objects
|
|
8488
8546
|
subcategory,
|
|
@@ -8585,6 +8643,13 @@ var ProcedureService = class extends BaseService {
|
|
|
8585
8643
|
const oldClinicId = existingProcedure.clinicBranchId;
|
|
8586
8644
|
let newPractitioner = null;
|
|
8587
8645
|
let newClinic = null;
|
|
8646
|
+
if (validatedData.photos !== void 0) {
|
|
8647
|
+
updatedProcedureData.photos = await this.processMediaArray(
|
|
8648
|
+
validatedData.photos,
|
|
8649
|
+
id,
|
|
8650
|
+
"procedure-photos"
|
|
8651
|
+
);
|
|
8652
|
+
}
|
|
8588
8653
|
if (validatedData.practitionerId && validatedData.practitionerId !== oldPractitionerId) {
|
|
8589
8654
|
practitionerChanged = true;
|
|
8590
8655
|
const newPractitionerRef = (0, import_firestore27.doc)(
|
package/dist/index.mjs
CHANGED
|
@@ -8342,7 +8342,7 @@ var createProcedureSchema = z21.object({
|
|
|
8342
8342
|
// Max 8 hours
|
|
8343
8343
|
practitionerId: z21.string().min(1),
|
|
8344
8344
|
clinicBranchId: z21.string().min(1),
|
|
8345
|
-
photos: z21.array(
|
|
8345
|
+
photos: z21.array(mediaResourceSchema).optional()
|
|
8346
8346
|
});
|
|
8347
8347
|
var updateProcedureSchema = z21.object({
|
|
8348
8348
|
name: z21.string().min(3).max(100).optional(),
|
|
@@ -8358,7 +8358,7 @@ var updateProcedureSchema = z21.object({
|
|
|
8358
8358
|
technologyId: z21.string().optional(),
|
|
8359
8359
|
productId: z21.string().optional(),
|
|
8360
8360
|
clinicBranchId: z21.string().optional(),
|
|
8361
|
-
photos: z21.array(
|
|
8361
|
+
photos: z21.array(mediaResourceSchema).optional()
|
|
8362
8362
|
});
|
|
8363
8363
|
var procedureSchema = createProcedureSchema.extend({
|
|
8364
8364
|
id: z21.string().min(1),
|
|
@@ -8398,12 +8398,61 @@ var procedureSchema = createProcedureSchema.extend({
|
|
|
8398
8398
|
// src/services/procedure/procedure.service.ts
|
|
8399
8399
|
import { distanceBetween as distanceBetween6, geohashQueryBounds as geohashQueryBounds5 } from "geofire-common";
|
|
8400
8400
|
var ProcedureService = class extends BaseService {
|
|
8401
|
-
constructor(db, auth, app, categoryService, subcategoryService, technologyService, productService) {
|
|
8401
|
+
constructor(db, auth, app, categoryService, subcategoryService, technologyService, productService, mediaService) {
|
|
8402
8402
|
super(db, auth, app);
|
|
8403
8403
|
this.categoryService = categoryService;
|
|
8404
8404
|
this.subcategoryService = subcategoryService;
|
|
8405
8405
|
this.technologyService = technologyService;
|
|
8406
8406
|
this.productService = productService;
|
|
8407
|
+
this.mediaService = mediaService;
|
|
8408
|
+
}
|
|
8409
|
+
/**
|
|
8410
|
+
* Process media resource (string URL or File object)
|
|
8411
|
+
* @param media String URL or File object
|
|
8412
|
+
* @param ownerId Owner ID for the media (usually procedureId)
|
|
8413
|
+
* @param collectionName Collection name for organizing files
|
|
8414
|
+
* @returns URL string after processing
|
|
8415
|
+
*/
|
|
8416
|
+
async processMedia(media, ownerId, collectionName) {
|
|
8417
|
+
if (!media) return null;
|
|
8418
|
+
if (typeof media === "string") {
|
|
8419
|
+
return media;
|
|
8420
|
+
}
|
|
8421
|
+
if (media instanceof File || media instanceof Blob) {
|
|
8422
|
+
console.log(
|
|
8423
|
+
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
8424
|
+
);
|
|
8425
|
+
const metadata = await this.mediaService.uploadMedia(
|
|
8426
|
+
media,
|
|
8427
|
+
ownerId,
|
|
8428
|
+
"public" /* PUBLIC */,
|
|
8429
|
+
collectionName
|
|
8430
|
+
);
|
|
8431
|
+
return metadata.url;
|
|
8432
|
+
}
|
|
8433
|
+
return null;
|
|
8434
|
+
}
|
|
8435
|
+
/**
|
|
8436
|
+
* Process array of media resources (strings or Files)
|
|
8437
|
+
* @param mediaArray Array of string URLs or File objects
|
|
8438
|
+
* @param ownerId Owner ID for the media
|
|
8439
|
+
* @param collectionName Collection name for organizing files
|
|
8440
|
+
* @returns Array of URL strings after processing
|
|
8441
|
+
*/
|
|
8442
|
+
async processMediaArray(mediaArray, ownerId, collectionName) {
|
|
8443
|
+
if (!mediaArray || mediaArray.length === 0) return [];
|
|
8444
|
+
const result = [];
|
|
8445
|
+
for (const media of mediaArray) {
|
|
8446
|
+
const processedUrl = await this.processMedia(
|
|
8447
|
+
media,
|
|
8448
|
+
ownerId,
|
|
8449
|
+
collectionName
|
|
8450
|
+
);
|
|
8451
|
+
if (processedUrl) {
|
|
8452
|
+
result.push(processedUrl);
|
|
8453
|
+
}
|
|
8454
|
+
}
|
|
8455
|
+
return result;
|
|
8407
8456
|
}
|
|
8408
8457
|
/**
|
|
8409
8458
|
* Creates a new procedure
|
|
@@ -8413,6 +8462,7 @@ var ProcedureService = class extends BaseService {
|
|
|
8413
8462
|
async createProcedure(data) {
|
|
8414
8463
|
var _a;
|
|
8415
8464
|
const validatedData = createProcedureSchema.parse(data);
|
|
8465
|
+
const procedureId = this.generateId();
|
|
8416
8466
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
8417
8467
|
this.categoryService.getById(validatedData.categoryId),
|
|
8418
8468
|
this.subcategoryService.getById(
|
|
@@ -8452,6 +8502,14 @@ var ProcedureService = class extends BaseService {
|
|
|
8452
8502
|
);
|
|
8453
8503
|
}
|
|
8454
8504
|
const practitioner = practitionerSnapshot.data();
|
|
8505
|
+
let processedPhotos = [];
|
|
8506
|
+
if (validatedData.photos && validatedData.photos.length > 0) {
|
|
8507
|
+
processedPhotos = await this.processMediaArray(
|
|
8508
|
+
validatedData.photos,
|
|
8509
|
+
procedureId,
|
|
8510
|
+
"procedure-photos"
|
|
8511
|
+
);
|
|
8512
|
+
}
|
|
8455
8513
|
const clinicInfo = {
|
|
8456
8514
|
id: clinicSnapshot.id,
|
|
8457
8515
|
name: clinic.name,
|
|
@@ -8468,10 +8526,10 @@ var ProcedureService = class extends BaseService {
|
|
|
8468
8526
|
rating: ((_a = practitioner.reviewInfo) == null ? void 0 : _a.averageRating) || 0,
|
|
8469
8527
|
services: practitioner.procedures || []
|
|
8470
8528
|
};
|
|
8471
|
-
const procedureId = this.generateId();
|
|
8472
8529
|
const newProcedure = {
|
|
8473
8530
|
id: procedureId,
|
|
8474
8531
|
...validatedData,
|
|
8532
|
+
photos: processedPhotos,
|
|
8475
8533
|
category,
|
|
8476
8534
|
// Embed full objects
|
|
8477
8535
|
subcategory,
|
|
@@ -8574,6 +8632,13 @@ var ProcedureService = class extends BaseService {
|
|
|
8574
8632
|
const oldClinicId = existingProcedure.clinicBranchId;
|
|
8575
8633
|
let newPractitioner = null;
|
|
8576
8634
|
let newClinic = null;
|
|
8635
|
+
if (validatedData.photos !== void 0) {
|
|
8636
|
+
updatedProcedureData.photos = await this.processMediaArray(
|
|
8637
|
+
validatedData.photos,
|
|
8638
|
+
id,
|
|
8639
|
+
"procedure-photos"
|
|
8640
|
+
);
|
|
8641
|
+
}
|
|
8577
8642
|
if (validatedData.practitionerId && validatedData.practitionerId !== oldPractitionerId) {
|
|
8578
8643
|
practitionerChanged = true;
|
|
8579
8644
|
const newPractitionerRef = doc16(
|
package/package.json
CHANGED
|
@@ -70,12 +70,14 @@ import { Clinic, CLINICS_COLLECTION } from "../../types/clinic";
|
|
|
70
70
|
import { ProcedureReviewInfo } from "../../types/reviews";
|
|
71
71
|
import { distanceBetween, geohashQueryBounds } from "geofire-common";
|
|
72
72
|
import { TreatmentBenefit } from "../../backoffice/types/static/treatment-benefit.types";
|
|
73
|
+
import { MediaService, MediaAccessLevel } from "../media/media.service";
|
|
73
74
|
|
|
74
75
|
export class ProcedureService extends BaseService {
|
|
75
76
|
private categoryService: CategoryService;
|
|
76
77
|
private subcategoryService: SubcategoryService;
|
|
77
78
|
private technologyService: TechnologyService;
|
|
78
79
|
private productService: ProductService;
|
|
80
|
+
private mediaService: MediaService;
|
|
79
81
|
|
|
80
82
|
constructor(
|
|
81
83
|
db: Firestore,
|
|
@@ -84,13 +86,81 @@ export class ProcedureService extends BaseService {
|
|
|
84
86
|
categoryService: CategoryService,
|
|
85
87
|
subcategoryService: SubcategoryService,
|
|
86
88
|
technologyService: TechnologyService,
|
|
87
|
-
productService: ProductService
|
|
89
|
+
productService: ProductService,
|
|
90
|
+
mediaService: MediaService
|
|
88
91
|
) {
|
|
89
92
|
super(db, auth, app);
|
|
90
93
|
this.categoryService = categoryService;
|
|
91
94
|
this.subcategoryService = subcategoryService;
|
|
92
95
|
this.technologyService = technologyService;
|
|
93
96
|
this.productService = productService;
|
|
97
|
+
this.mediaService = mediaService;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Process media resource (string URL or File object)
|
|
102
|
+
* @param media String URL or File object
|
|
103
|
+
* @param ownerId Owner ID for the media (usually procedureId)
|
|
104
|
+
* @param collectionName Collection name for organizing files
|
|
105
|
+
* @returns URL string after processing
|
|
106
|
+
*/
|
|
107
|
+
private async processMedia(
|
|
108
|
+
media: string | File | Blob | null | undefined,
|
|
109
|
+
ownerId: string,
|
|
110
|
+
collectionName: string
|
|
111
|
+
): Promise<string | null> {
|
|
112
|
+
if (!media) return null;
|
|
113
|
+
|
|
114
|
+
// If already a string URL, return it directly
|
|
115
|
+
if (typeof media === "string") {
|
|
116
|
+
return media;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// If it's a File, upload it using MediaService
|
|
120
|
+
if (media instanceof File || media instanceof Blob) {
|
|
121
|
+
console.log(
|
|
122
|
+
`[ProcedureService] Uploading ${collectionName} media for ${ownerId}`
|
|
123
|
+
);
|
|
124
|
+
const metadata = await this.mediaService.uploadMedia(
|
|
125
|
+
media,
|
|
126
|
+
ownerId,
|
|
127
|
+
MediaAccessLevel.PUBLIC,
|
|
128
|
+
collectionName
|
|
129
|
+
);
|
|
130
|
+
return metadata.url;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Process array of media resources (strings or Files)
|
|
138
|
+
* @param mediaArray Array of string URLs or File objects
|
|
139
|
+
* @param ownerId Owner ID for the media
|
|
140
|
+
* @param collectionName Collection name for organizing files
|
|
141
|
+
* @returns Array of URL strings after processing
|
|
142
|
+
*/
|
|
143
|
+
private async processMediaArray(
|
|
144
|
+
mediaArray: (string | File | Blob)[] | undefined,
|
|
145
|
+
ownerId: string,
|
|
146
|
+
collectionName: string
|
|
147
|
+
): Promise<string[]> {
|
|
148
|
+
if (!mediaArray || mediaArray.length === 0) return [];
|
|
149
|
+
|
|
150
|
+
const result: string[] = [];
|
|
151
|
+
|
|
152
|
+
for (const media of mediaArray) {
|
|
153
|
+
const processedUrl = await this.processMedia(
|
|
154
|
+
media,
|
|
155
|
+
ownerId,
|
|
156
|
+
collectionName
|
|
157
|
+
);
|
|
158
|
+
if (processedUrl) {
|
|
159
|
+
result.push(processedUrl);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return result;
|
|
94
164
|
}
|
|
95
165
|
|
|
96
166
|
/**
|
|
@@ -101,6 +171,9 @@ export class ProcedureService extends BaseService {
|
|
|
101
171
|
async createProcedure(data: CreateProcedureData): Promise<Procedure> {
|
|
102
172
|
const validatedData = createProcedureSchema.parse(data);
|
|
103
173
|
|
|
174
|
+
// Generate procedure ID first so we can use it for media uploads
|
|
175
|
+
const procedureId = this.generateId();
|
|
176
|
+
|
|
104
177
|
// Get references to related entities (Category, Subcategory, Technology, Product)
|
|
105
178
|
const [category, subcategory, technology, product] = await Promise.all([
|
|
106
179
|
this.categoryService.getById(validatedData.categoryId),
|
|
@@ -146,6 +219,16 @@ export class ProcedureService extends BaseService {
|
|
|
146
219
|
}
|
|
147
220
|
const practitioner = practitionerSnapshot.data() as Practitioner; // Assert type
|
|
148
221
|
|
|
222
|
+
// Process photos if provided
|
|
223
|
+
let processedPhotos: string[] = [];
|
|
224
|
+
if (validatedData.photos && validatedData.photos.length > 0) {
|
|
225
|
+
processedPhotos = await this.processMediaArray(
|
|
226
|
+
validatedData.photos,
|
|
227
|
+
procedureId,
|
|
228
|
+
"procedure-photos"
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
149
232
|
// Create aggregated clinic info for the procedure document
|
|
150
233
|
const clinicInfo = {
|
|
151
234
|
id: clinicSnapshot.id,
|
|
@@ -174,10 +257,10 @@ export class ProcedureService extends BaseService {
|
|
|
174
257
|
};
|
|
175
258
|
|
|
176
259
|
// Create the procedure object
|
|
177
|
-
const procedureId = this.generateId();
|
|
178
260
|
const newProcedure: Omit<Procedure, "createdAt" | "updatedAt"> = {
|
|
179
261
|
id: procedureId,
|
|
180
262
|
...validatedData,
|
|
263
|
+
photos: processedPhotos,
|
|
181
264
|
category, // Embed full objects
|
|
182
265
|
subcategory,
|
|
183
266
|
technology,
|
|
@@ -296,6 +379,15 @@ export class ProcedureService extends BaseService {
|
|
|
296
379
|
let newPractitioner: Practitioner | null = null;
|
|
297
380
|
let newClinic: Clinic | null = null;
|
|
298
381
|
|
|
382
|
+
// Process photos if provided
|
|
383
|
+
if (validatedData.photos !== undefined) {
|
|
384
|
+
updatedProcedureData.photos = await this.processMediaArray(
|
|
385
|
+
validatedData.photos,
|
|
386
|
+
id,
|
|
387
|
+
"procedure-photos"
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
299
391
|
// --- Prepare updates and fetch new related data if IDs change ---
|
|
300
392
|
|
|
301
393
|
// Handle Practitioner Change
|
|
@@ -20,6 +20,7 @@ import { DoctorInfo } from "../clinic";
|
|
|
20
20
|
import { PRACTITIONERS_COLLECTION } from "../practitioner";
|
|
21
21
|
import { ProcedureReviewInfo } from "../reviews";
|
|
22
22
|
import type { Contraindication } from "../../backoffice/types/static/contraindication.types";
|
|
23
|
+
import { MediaResource } from "../../services/media/media.service";
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* Procedure represents a specific medical procedure that can be performed by a practitioner in a clinic
|
|
@@ -31,7 +32,7 @@ export interface Procedure {
|
|
|
31
32
|
/** Name of the procedure */
|
|
32
33
|
name: string;
|
|
33
34
|
/** Photos of the procedure */
|
|
34
|
-
photos?:
|
|
35
|
+
photos?: MediaResource[];
|
|
35
36
|
/** Detailed description of the procedure */
|
|
36
37
|
description: string;
|
|
37
38
|
/** Family of procedures this belongs to (aesthetics/surgery) */
|
|
@@ -101,7 +102,7 @@ export interface CreateProcedureData {
|
|
|
101
102
|
duration: number;
|
|
102
103
|
practitionerId: string;
|
|
103
104
|
clinicBranchId: string;
|
|
104
|
-
photos?:
|
|
105
|
+
photos?: MediaResource[];
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
/**
|
|
@@ -121,7 +122,7 @@ export interface UpdateProcedureData {
|
|
|
121
122
|
technologyId?: string;
|
|
122
123
|
productId?: string;
|
|
123
124
|
clinicBranchId?: string;
|
|
124
|
-
photos?:
|
|
125
|
+
photos?: MediaResource[];
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
/**
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "../backoffice/types/static/pricing.types";
|
|
7
7
|
import { clinicInfoSchema, doctorInfoSchema } from "./shared.schema";
|
|
8
8
|
import { procedureReviewInfoSchema } from "./reviews.schema";
|
|
9
|
-
|
|
9
|
+
import { mediaResourceSchema } from "./media.schema";
|
|
10
10
|
/**
|
|
11
11
|
* Schema for creating a new procedure
|
|
12
12
|
*/
|
|
@@ -24,7 +24,7 @@ export const createProcedureSchema = z.object({
|
|
|
24
24
|
duration: z.number().min(1).max(480), // Max 8 hours
|
|
25
25
|
practitionerId: z.string().min(1),
|
|
26
26
|
clinicBranchId: z.string().min(1),
|
|
27
|
-
photos: z.array(
|
|
27
|
+
photos: z.array(mediaResourceSchema).optional(),
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
/**
|
|
@@ -44,7 +44,7 @@ export const updateProcedureSchema = z.object({
|
|
|
44
44
|
technologyId: z.string().optional(),
|
|
45
45
|
productId: z.string().optional(),
|
|
46
46
|
clinicBranchId: z.string().optional(),
|
|
47
|
-
photos: z.array(
|
|
47
|
+
photos: z.array(mediaResourceSchema).optional(),
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
/**
|