@blackcode_sa/metaestetics-api 1.7.45 → 1.8.0

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.
Files changed (55) hide show
  1. package/dist/admin/index.d.mts +999 -959
  2. package/dist/admin/index.d.ts +999 -959
  3. package/dist/admin/index.js +69 -69
  4. package/dist/admin/index.mjs +67 -69
  5. package/dist/index.d.mts +14675 -13040
  6. package/dist/index.d.ts +14675 -13040
  7. package/dist/index.js +12224 -14615
  8. package/dist/index.mjs +12452 -14968
  9. package/package.json +5 -5
  10. package/src/admin/index.ts +8 -1
  11. package/src/index.backup.ts +407 -0
  12. package/src/index.ts +5 -406
  13. package/src/services/PATIENTAUTH.MD +197 -0
  14. package/src/services/__tests__/auth/auth.setup.ts +2 -2
  15. package/src/services/__tests__/auth.service.test.ts +1 -1
  16. package/src/services/__tests__/user.service.test.ts +1 -1
  17. package/src/services/appointment/index.ts +1 -2
  18. package/src/services/{auth.service.ts → auth/auth.service.ts} +36 -22
  19. package/src/services/{auth.v2.service.ts → auth/auth.v2.service.ts} +17 -17
  20. package/src/services/auth/index.ts +2 -16
  21. package/src/services/calendar/calendar-refactored.service.ts +1 -1
  22. package/src/services/calendar/externalCalendar.service.ts +178 -0
  23. package/src/services/calendar/index.ts +5 -0
  24. package/src/services/clinic/index.ts +4 -0
  25. package/src/services/index.ts +14 -0
  26. package/src/services/media/index.ts +1 -0
  27. package/src/services/notifications/index.ts +1 -0
  28. package/src/services/patient/README.md +48 -0
  29. package/src/services/patient/To-Do.md +43 -0
  30. package/src/services/patient/index.ts +2 -0
  31. package/src/services/patient/patient.service.ts +289 -34
  32. package/src/services/patient/utils/index.ts +9 -0
  33. package/src/services/patient/utils/medical.utils.ts +114 -157
  34. package/src/services/patient/utils/profile.utils.ts +9 -0
  35. package/src/services/patient/utils/sensitive.utils.ts +79 -14
  36. package/src/services/patient/utils/token.utils.ts +211 -0
  37. package/src/services/practitioner/index.ts +1 -0
  38. package/src/services/procedure/index.ts +1 -0
  39. package/src/services/reviews/index.ts +1 -0
  40. package/src/services/user/index.ts +1 -0
  41. package/src/services/{user.service.ts → user/user.service.ts} +61 -12
  42. package/src/services/{user.v2.service.ts → user/user.v2.service.ts} +12 -12
  43. package/src/types/index.ts +42 -42
  44. package/src/types/patient/index.ts +33 -6
  45. package/src/types/patient/token.types.ts +61 -0
  46. package/src/types/user/index.ts +38 -0
  47. package/src/utils/index.ts +1 -0
  48. package/src/validations/calendar.schema.ts +6 -45
  49. package/src/validations/documentation-templates/index.ts +1 -0
  50. package/src/validations/documentation-templates.schema.ts +1 -1
  51. package/src/validations/index.ts +20 -0
  52. package/src/validations/patient/token.schema.ts +29 -0
  53. package/src/validations/patient.schema.ts +23 -6
  54. package/src/validations/profile-info.schema.ts +1 -1
  55. package/src/validations/schemas.ts +24 -24
@@ -0,0 +1,61 @@
1
+ import { Timestamp } from "firebase/firestore";
2
+
3
+ export const INVITE_TOKENS_COLLECTION = "inviteTokens";
4
+
5
+ /**
6
+ * @enum PatientTokenStatus
7
+ * @description Represents the status of a patient registration token.
8
+ * @property {string} ACTIVE - The token is active and can be used for registration.
9
+ * @property {string} USED - The token has been used and is no longer valid.
10
+ * @property {string} EXPIRED - The token has expired and is no longer valid.
11
+ */
12
+ export enum PatientTokenStatus {
13
+ ACTIVE = "active",
14
+ USED = "used",
15
+ EXPIRED = "expired",
16
+ }
17
+
18
+ /**
19
+ * @interface PatientToken
20
+ * @description Represents a registration token for a patient to claim their profile.
21
+ * These tokens are stored in a subcollection under the patient's profile.
22
+ * @property {string} id - The unique identifier for the token document.
23
+ * @property {string} token - The unique token string (e.g., a 6-character code).
24
+ * @property {string} patientId - The ID of the patient profile this token is for.
25
+ * @property {string} email - The email address the invitation was sent to.
26
+ * @property {string} clinicId - The ID of the clinic that created the invitation.
27
+ * @property {PatientTokenStatus} status - The current status of the token.
28
+ * @property {string} createdBy - The ID of the admin user who created the token.
29
+ * @property {Timestamp} createdAt - The timestamp when the token was created.
30
+ * @property {Timestamp} expiresAt - The timestamp when the token expires.
31
+ * @property {string} [usedBy] - The ID of the user who used the token (optional).
32
+ * @property {Timestamp} [usedAt] - The timestamp when the token was used (optional).
33
+ */
34
+ export interface PatientToken {
35
+ id: string;
36
+ token: string;
37
+ patientId: string;
38
+ email: string;
39
+ clinicId: string;
40
+ status: PatientTokenStatus;
41
+ createdBy: string;
42
+ createdAt: Timestamp;
43
+ expiresAt: Timestamp;
44
+ usedBy?: string;
45
+ usedAt?: Timestamp;
46
+ }
47
+
48
+ /**
49
+ * @interface CreatePatientTokenData
50
+ * @description Represents the data required to create a new patient registration token.
51
+ * @property {string} patientId - The ID of the patient to generate the token for.
52
+ * @property {string} clinicId - The ID of the clinic creating the token.
53
+ * @property {string} email - The email to associate with the token.
54
+ * @property {Date} [expiresAt] - The optional expiration date for the token. Defaults to 7 days from creation.
55
+ */
56
+ export interface CreatePatientTokenData {
57
+ patientId: string;
58
+ clinicId: string;
59
+ email: string;
60
+ expiresAt?: Date;
61
+ }
@@ -0,0 +1,38 @@
1
+ import { User as FirebaseAuthUser } from "firebase/auth";
2
+ import { Timestamp, FieldValue } from "firebase/firestore";
3
+
4
+ // User tipovi
5
+ export enum UserRole {
6
+ PATIENT = "patient",
7
+ PRACTITIONER = "practitioner",
8
+ APP_ADMIN = "app_admin",
9
+ CLINIC_ADMIN = "clinic_admin",
10
+ }
11
+
12
+ export interface User {
13
+ uid: string;
14
+ email: string | null;
15
+ roles: UserRole[];
16
+ isAnonymous: boolean;
17
+ createdAt: any;
18
+ updatedAt: any;
19
+ lastLoginAt: any;
20
+ patientProfile?: string;
21
+ practitionerProfile?: string;
22
+ adminProfile?: string;
23
+ }
24
+
25
+ export interface CreateUserData {
26
+ uid: string;
27
+ email: string | null;
28
+ roles: UserRole[];
29
+ isAnonymous: boolean;
30
+ createdAt: FieldValue;
31
+ updatedAt: FieldValue;
32
+ lastLoginAt: FieldValue;
33
+ }
34
+
35
+ export const USERS_COLLECTION = "users";
36
+
37
+ // Firebase tipovi
38
+ export type FirebaseUser = FirebaseAuthUser;
@@ -0,0 +1 @@
1
+ export * from "./TimestampUtils";
@@ -14,7 +14,7 @@ import {
14
14
  } from "../backoffice/types/static/pricing.types";
15
15
  import { clinicLocationSchema } from "./clinic.schema";
16
16
  import {
17
- clinicInfoSchema,
17
+ clinicBranchInfoSchema,
18
18
  patientProfileInfoSchema,
19
19
  practitionerProfileInfoSchema,
20
20
  } from "./profile-info.schema";
@@ -108,64 +108,26 @@ export const procedureCategorizationSchema = z.object({
108
108
  procedureProduct: z.string(), // Replace with proper enum when available
109
109
  });
110
110
 
111
- /**
112
- * Validation schema for creating an appointment
113
- */
114
- export const createAppointmentSchema = z
115
- .object({
116
- clinicId: z.string().min(1, "Clinic ID is required"),
117
- doctorId: z.string().min(1, "Doctor ID is required"),
118
- patientId: z.string().min(1, "Patient ID is required"),
119
- procedureId: z.string().min(1, "Procedure ID is required"),
120
- eventLocation: clinicLocationSchema,
121
- eventTime: calendarEventTimeSchema,
122
- description: z.string().optional(),
123
- })
124
- .refine(
125
- (data) => {
126
- // If we have access to the actual data, we could validate:
127
- // - Doctor works at the clinic
128
- // - Procedure is available at the clinic
129
- // - Patient is eligible for the procedure
130
- // These validations will be handled in the service layer
131
- return true;
132
- },
133
- {
134
- message: "Invalid appointment parameters",
135
- }
136
- );
137
-
138
- /**
139
- * Validation schema for updating an appointment
140
- */
141
- export const updateAppointmentSchema = z.object({
142
- appointmentId: z.string().min(1, "Appointment ID is required"),
143
- clinicId: z.string().min(1, "Clinic ID is required"),
144
- doctorId: z.string().min(1, "Doctor ID is required"),
145
- patientId: z.string().min(1, "Patient ID is required"),
146
- eventTime: calendarEventTimeSchema.optional(),
147
- description: z.string().optional(),
148
- status: z.nativeEnum(CalendarEventStatus).optional(),
149
- });
150
-
151
111
  /**
152
112
  * Validation schema for creating a calendar event
153
113
  */
154
114
  export const createCalendarEventSchema = z.object({
155
115
  id: z.string(),
156
116
  clinicBranchId: z.string().nullable().optional(),
157
- clinicBranchInfo: z.any().nullable().optional(),
117
+ clinicBranchInfo: clinicBranchInfoSchema.nullable().optional(),
158
118
  practitionerProfileId: z.string().nullable().optional(),
159
119
  practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
160
120
  patientProfileId: z.string().nullable().optional(),
161
121
  patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
162
122
  procedureId: z.string().nullable().optional(),
123
+ procedureInfo: procedureInfoSchema.nullable().optional(),
124
+ procedureCategorization: procedureCategorizationSchema.nullable().optional(),
163
125
  appointmentId: z.string().nullable().optional(),
164
126
  syncedCalendarEventId: z
165
127
  .array(syncedCalendarEventSchema)
166
128
  .nullable()
167
129
  .optional(),
168
- eventName: z.string().min(1, "Event name is required"),
130
+ eventName: z.string(),
169
131
  eventLocation: clinicLocationSchema.optional(),
170
132
  eventTime: calendarEventTimeSchema,
171
133
  description: z.string().optional(),
@@ -200,7 +162,7 @@ export const updateCalendarEventSchema = z.object({
200
162
  export const calendarEventSchema = z.object({
201
163
  id: z.string(),
202
164
  clinicBranchId: z.string().nullable().optional(),
203
- clinicBranchInfo: z.any().nullable().optional(), // Will be replaced with proper clinic info schema
165
+ clinicBranchInfo: clinicBranchInfoSchema.nullable().optional(), // Will be replaced with proper clinic info schema
204
166
  practitionerProfileId: z.string().nullable().optional(),
205
167
  practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
206
168
  patientProfileId: z.string().nullable().optional(),
@@ -260,5 +222,4 @@ export const updateBlockingEventSchema = z.object({
260
222
  .optional(),
261
223
  eventTime: calendarEventTimeSchema.optional(),
262
224
  description: z.string().max(1000, "Description too long").optional(),
263
- status: z.nativeEnum(CalendarEventStatus).optional(),
264
225
  });
@@ -0,0 +1 @@
1
+ export * from "./template.schema";
@@ -7,4 +7,4 @@
7
7
  // documentTemplateSchema, createDocumentTemplateSchema, updateDocumentTemplateSchema,
8
8
  // filledDocumentSchema, createFilledDocumentDataSchema, updateFilledDocumentDataSchema etc.,
9
9
  // are defined and exported from './documentation-templates/template.schema.ts'
10
- export * from "./documentation-templates/template.schema";
10
+ export * from "./documentation-templates/";
@@ -0,0 +1,20 @@
1
+ // This barrel file consolidates all Zod validation schemas for easy importing.
2
+
3
+ export * from "./appointment.schema";
4
+ export * from "./calendar.schema";
5
+ export * from "./clinic.schema";
6
+ export * from "./common.schema";
7
+ export * from "./documentation-templates.schema";
8
+ export * from "./media.schema";
9
+ export * from "./notification.schema";
10
+ export * from "./patient.schema";
11
+ export * from "./patient/medical-info.schema";
12
+ export * from "./patient/patient-requirements.schema";
13
+ export * from "./patient/medical-info.schema";
14
+ export * from "./patient/token.schema";
15
+ export * from "./practitioner.schema";
16
+ export * from "./procedure.schema";
17
+ export * from "./profile-info.schema";
18
+ export * from "./reviews.schema";
19
+ export * from "./schemas";
20
+ export * from "./shared.schema";
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ import { PatientTokenStatus } from "../../types/patient/token.types";
3
+
4
+ /**
5
+ * @description Zod schema for validating a PatientToken object.
6
+ */
7
+ export const patientTokenSchema = z.object({
8
+ id: z.string().min(1, "Token ID is required"),
9
+ token: z.string().min(1, "Token string is required"),
10
+ patientId: z.string().min(1, "Patient ID is required"),
11
+ email: z.string().email("Invalid email format"),
12
+ clinicId: z.string().min(1, "Clinic ID is required"),
13
+ status: z.nativeEnum(PatientTokenStatus),
14
+ createdBy: z.string().min(1, "Creator ID is required"),
15
+ createdAt: z.any(), // Assuming Timestamp validated elsewhere
16
+ expiresAt: z.any(), // Assuming Timestamp validated elsewhere
17
+ usedBy: z.string().optional(),
18
+ usedAt: z.any().optional(), // Assuming Timestamp validated elsewhere
19
+ });
20
+
21
+ /**
22
+ * @description Zod schema for validating the data required to create a PatientToken.
23
+ */
24
+ export const createPatientTokenSchema = z.object({
25
+ patientId: z.string().min(1, "Patient ID is required"),
26
+ clinicId: z.string().min(1, "Clinic ID is required"),
27
+ email: z.string().email("Invalid email format"),
28
+ expiresAt: z.date().optional(),
29
+ });
@@ -45,7 +45,7 @@ export const gamificationSchema = z.object({
45
45
  */
46
46
  export const patientLocationInfoSchema = z.object({
47
47
  patientId: z.string(),
48
- userRef: z.string(),
48
+ userRef: z.string().optional(),
49
49
  locationData: locationDataSchema,
50
50
  createdAt: z.instanceof(Timestamp),
51
51
  updatedAt: z.instanceof(Timestamp),
@@ -56,7 +56,7 @@ export const patientLocationInfoSchema = z.object({
56
56
  */
57
57
  export const createPatientLocationInfoSchema = z.object({
58
58
  patientId: z.string(),
59
- userRef: z.string(),
59
+ userRef: z.string().optional(),
60
60
  locationData: locationDataSchema,
61
61
  });
62
62
 
@@ -65,7 +65,7 @@ export const createPatientLocationInfoSchema = z.object({
65
65
  */
66
66
  export const patientSensitiveInfoSchema = z.object({
67
67
  patientId: z.string(),
68
- userRef: z.string(),
68
+ userRef: z.string().optional(),
69
69
  photoUrl: z.string().nullable().optional(),
70
70
  firstName: z.string().min(2),
71
71
  lastName: z.string().min(2),
@@ -107,12 +107,13 @@ export const patientClinicSchema = z.object({
107
107
  */
108
108
  export const patientProfileSchema = z.object({
109
109
  id: z.string(),
110
- userRef: z.string(),
110
+ userRef: z.string().optional(),
111
111
  displayName: z.string(),
112
112
  gamification: gamificationSchema,
113
113
  expoTokens: z.array(z.string()),
114
114
  isActive: z.boolean(),
115
115
  isVerified: z.boolean(),
116
+ isManual: z.boolean().default(false), // Default to false if missing
116
117
  phoneNumber: z.string().nullable().optional(),
117
118
  dateOfBirth: z.instanceof(Timestamp).nullable().optional(),
118
119
  doctors: z.array(patientDoctorSchema),
@@ -127,12 +128,13 @@ export const patientProfileSchema = z.object({
127
128
  * Šema za validaciju podataka pri kreiranju profila
128
129
  */
129
130
  export const createPatientProfileSchema = z.object({
130
- userRef: z.string(),
131
+ userRef: z.string().optional(),
131
132
  displayName: z.string(),
132
133
  expoTokens: z.array(z.string()),
133
134
  gamification: gamificationSchema.optional(),
134
135
  isActive: z.boolean(),
135
136
  isVerified: z.boolean(),
137
+ isManual: z.boolean().default(false),
136
138
  doctors: z.array(patientDoctorSchema).optional(),
137
139
  clinics: z.array(patientClinicSchema).optional(),
138
140
  doctorIds: z.array(z.string()).optional(),
@@ -144,7 +146,7 @@ export const createPatientProfileSchema = z.object({
144
146
  */
145
147
  export const createPatientSensitiveInfoSchema = z.object({
146
148
  patientId: z.string(),
147
- userRef: z.string(),
149
+ userRef: z.string().optional(),
148
150
  photoUrl: mediaResourceSchema.nullable().optional(),
149
151
  firstName: z.string().min(2),
150
152
  lastName: z.string().min(2),
@@ -157,6 +159,21 @@ export const createPatientSensitiveInfoSchema = z.object({
157
159
  emergencyContacts: z.array(emergencyContactSchema).optional(),
158
160
  });
159
161
 
162
+ /**
163
+ * Schema for validating the data when a clinic admin manually creates a patient.
164
+ */
165
+ export const createManualPatientSchema = z.object({
166
+ clinicId: z.string().min(1, "Clinic ID is required"),
167
+ firstName: z.string().min(2, "First name is required"),
168
+ lastName: z.string().min(2, "Last name is required"),
169
+ dateOfBirth: z.instanceof(Timestamp).nullable(),
170
+ gender: z.nativeEnum(Gender),
171
+ phoneNumber: z.string().optional(),
172
+ email: z.string().email().optional(),
173
+ addressData: addressDataSchema.optional(),
174
+ notes: z.string().optional(),
175
+ });
176
+
160
177
  /**
161
178
  * Schema for validating patient search parameters.
162
179
  */
@@ -7,7 +7,7 @@ import { Gender } from "../types/patient";
7
7
  /**
8
8
  * Validation schema for clinic info
9
9
  */
10
- export const clinicInfoSchema = z.object({
10
+ export const clinicBranchInfoSchema = z.object({
11
11
  id: z.string(),
12
12
  featuredPhoto: z.string(),
13
13
  name: z.string(),
@@ -24,33 +24,33 @@ export const userRolesSchema = z
24
24
  .min(1, "User must have at least one role")
25
25
  .max(3, "User cannot have more than 3 roles");
26
26
 
27
- export const timestampSchema = z.custom<Timestamp | FieldValue | Date>(
28
- (data) => {
29
- // If it's a serverTimestamp (FieldValue), it's valid
30
- if (data && typeof data === "object" && "isEqual" in data) {
31
- return true;
32
- }
27
+ // export const timestampSchema = z.custom<Timestamp | FieldValue | Date>(
28
+ // (data) => {
29
+ // // If it's a serverTimestamp (FieldValue), it's valid
30
+ // if (data && typeof data === "object" && "isEqual" in data) {
31
+ // return true;
32
+ // }
33
33
 
34
- // If it's a Timestamp object, validate its structure
35
- if (
36
- data &&
37
- typeof data === "object" &&
38
- "toDate" in data &&
39
- "seconds" in data &&
40
- "nanoseconds" in data
41
- ) {
42
- return true;
43
- }
34
+ // // If it's a Timestamp object, validate its structure
35
+ // if (
36
+ // data &&
37
+ // typeof data === "object" &&
38
+ // "toDate" in data &&
39
+ // "seconds" in data &&
40
+ // "nanoseconds" in data
41
+ // ) {
42
+ // return true;
43
+ // }
44
44
 
45
- // If it's a JavaScript Date object (what Firestore returns on client), it's valid
46
- if (data instanceof Date) {
47
- return true;
48
- }
45
+ // // If it's a JavaScript Date object (what Firestore returns on client), it's valid
46
+ // if (data instanceof Date) {
47
+ // return true;
48
+ // }
49
49
 
50
- return false;
51
- },
52
- "Must be a Timestamp object, Date object, or serverTimestamp"
53
- );
50
+ // return false;
51
+ // },
52
+ // "Must be a Timestamp object, Date object, or serverTimestamp"
53
+ // );
54
54
 
55
55
  /**
56
56
  * Validaciona šema za clinic admin opcije pri kreiranju