@blackcode_sa/metaestetics-api 1.13.5 → 1.13.8
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 +20 -1
- package/dist/admin/index.d.ts +20 -1
- package/dist/admin/index.js +217 -1
- package/dist/admin/index.mjs +217 -1
- package/dist/index.d.mts +26 -3
- package/dist/index.d.ts +26 -3
- package/dist/index.js +168 -6
- package/dist/index.mjs +168 -6
- package/package.json +121 -121
- package/src/__mocks__/firstore.ts +10 -10
- package/src/admin/aggregation/README.md +79 -79
- package/src/admin/aggregation/appointment/README.md +128 -128
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +1984 -1984
- package/src/admin/aggregation/appointment/index.ts +1 -1
- package/src/admin/aggregation/clinic/README.md +52 -52
- package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +966 -703
- package/src/admin/aggregation/clinic/index.ts +1 -1
- package/src/admin/aggregation/forms/README.md +13 -13
- package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +322 -322
- package/src/admin/aggregation/forms/index.ts +1 -1
- package/src/admin/aggregation/index.ts +8 -8
- package/src/admin/aggregation/patient/README.md +27 -27
- package/src/admin/aggregation/patient/index.ts +1 -1
- package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -141
- package/src/admin/aggregation/practitioner/README.md +42 -42
- package/src/admin/aggregation/practitioner/index.ts +1 -1
- package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -433
- package/src/admin/aggregation/practitioner-invite/index.ts +1 -1
- package/src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts +961 -961
- package/src/admin/aggregation/procedure/README.md +43 -43
- package/src/admin/aggregation/procedure/index.ts +1 -1
- package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +702 -702
- package/src/admin/aggregation/reviews/index.ts +1 -1
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +689 -689
- package/src/admin/analytics/analytics.admin.service.ts +278 -278
- package/src/admin/analytics/index.ts +2 -2
- package/src/admin/booking/README.md +125 -125
- package/src/admin/booking/booking.admin.ts +1037 -1037
- package/src/admin/booking/booking.calculator.ts +712 -712
- package/src/admin/booking/booking.types.ts +59 -59
- package/src/admin/booking/index.ts +3 -3
- package/src/admin/booking/timezones-problem.md +185 -185
- package/src/admin/calendar/README.md +7 -7
- package/src/admin/calendar/calendar.admin.service.ts +345 -345
- package/src/admin/calendar/index.ts +1 -1
- package/src/admin/documentation-templates/document-manager.admin.ts +260 -260
- package/src/admin/documentation-templates/index.ts +1 -1
- package/src/admin/free-consultation/free-consultation-utils.admin.ts +148 -148
- package/src/admin/free-consultation/index.ts +1 -1
- package/src/admin/index.ts +81 -81
- package/src/admin/logger/index.ts +78 -78
- package/src/admin/mailing/README.md +95 -95
- package/src/admin/mailing/appointment/appointment.mailing.service.ts +732 -732
- package/src/admin/mailing/appointment/index.ts +1 -1
- package/src/admin/mailing/appointment/templates/patient/appointment-confirmed.html +40 -40
- package/src/admin/mailing/base.mailing.service.ts +208 -208
- package/src/admin/mailing/index.ts +3 -3
- package/src/admin/mailing/practitionerInvite/existing-practitioner-invite.mailing.ts +611 -611
- package/src/admin/mailing/practitionerInvite/index.ts +2 -2
- package/src/admin/mailing/practitionerInvite/practitionerInvite.mailing.ts +395 -395
- package/src/admin/mailing/practitionerInvite/templates/existing-practitioner-invitation.template.ts +155 -155
- package/src/admin/mailing/practitionerInvite/templates/invitation.template.ts +101 -101
- package/src/admin/mailing/practitionerInvite/templates/invite-accepted-notification.template.ts +228 -228
- package/src/admin/mailing/practitionerInvite/templates/invite-rejected-notification.template.ts +242 -242
- package/src/admin/notifications/index.ts +1 -1
- package/src/admin/notifications/notifications.admin.ts +710 -710
- package/src/admin/requirements/README.md +128 -128
- package/src/admin/requirements/index.ts +1 -1
- package/src/admin/requirements/patient-requirements.admin.service.ts +475 -475
- package/src/admin/users/index.ts +1 -1
- package/src/admin/users/user-profile.admin.ts +405 -405
- package/src/backoffice/constants/certification.constants.ts +13 -13
- package/src/backoffice/constants/index.ts +1 -1
- package/src/backoffice/errors/backoffice.errors.ts +181 -181
- package/src/backoffice/errors/index.ts +1 -1
- package/src/backoffice/expo-safe/README.md +26 -26
- package/src/backoffice/expo-safe/index.ts +41 -41
- package/src/backoffice/index.ts +5 -5
- package/src/backoffice/services/FIXES_README.md +102 -102
- package/src/backoffice/services/README.md +57 -57
- package/src/backoffice/services/analytics.service.proposal.md +863 -863
- package/src/backoffice/services/analytics.service.summary.md +143 -143
- package/src/backoffice/services/brand.service.ts +256 -256
- package/src/backoffice/services/category.service.ts +384 -384
- package/src/backoffice/services/constants.service.ts +385 -385
- package/src/backoffice/services/documentation-template.service.ts +202 -202
- package/src/backoffice/services/index.ts +10 -10
- package/src/backoffice/services/migrate-products.ts +116 -116
- package/src/backoffice/services/product.service.ts +553 -553
- package/src/backoffice/services/requirement.service.ts +235 -235
- package/src/backoffice/services/subcategory.service.ts +461 -461
- package/src/backoffice/services/technology.service.ts +1151 -1151
- package/src/backoffice/types/README.md +12 -12
- package/src/backoffice/types/admin-constants.types.ts +69 -69
- package/src/backoffice/types/brand.types.ts +29 -29
- package/src/backoffice/types/category.types.ts +67 -67
- package/src/backoffice/types/documentation-templates.types.ts +28 -28
- package/src/backoffice/types/index.ts +10 -10
- package/src/backoffice/types/procedure-product.types.ts +38 -38
- package/src/backoffice/types/product.types.ts +240 -240
- package/src/backoffice/types/requirement.types.ts +63 -63
- package/src/backoffice/types/static/README.md +18 -18
- package/src/backoffice/types/static/blocking-condition.types.ts +21 -21
- package/src/backoffice/types/static/certification.types.ts +37 -37
- package/src/backoffice/types/static/contraindication.types.ts +19 -19
- package/src/backoffice/types/static/index.ts +6 -6
- package/src/backoffice/types/static/pricing.types.ts +16 -16
- package/src/backoffice/types/static/procedure-family.types.ts +14 -14
- package/src/backoffice/types/static/treatment-benefit.types.ts +22 -22
- package/src/backoffice/types/subcategory.types.ts +34 -34
- package/src/backoffice/types/technology.types.ts +168 -168
- package/src/backoffice/validations/index.ts +1 -1
- package/src/backoffice/validations/schemas.ts +164 -164
- package/src/config/__mocks__/firebase.ts +99 -99
- package/src/config/firebase.ts +78 -78
- package/src/config/index.ts +9 -9
- package/src/errors/auth.error.ts +6 -6
- package/src/errors/auth.errors.ts +211 -200
- package/src/errors/clinic.errors.ts +32 -32
- package/src/errors/firebase.errors.ts +47 -47
- package/src/errors/user.errors.ts +99 -99
- package/src/index.backup.ts +407 -407
- package/src/index.ts +6 -6
- package/src/locales/en.ts +31 -31
- package/src/recommender/admin/index.ts +1 -1
- package/src/recommender/admin/services/recommender.service.admin.ts +5 -5
- package/src/recommender/front/index.ts +1 -1
- package/src/recommender/front/services/onboarding.service.ts +5 -5
- package/src/recommender/front/services/recommender.service.ts +3 -3
- package/src/recommender/index.ts +1 -1
- package/src/services/PATIENTAUTH.MD +197 -197
- package/src/services/README.md +106 -106
- package/src/services/__tests__/auth/auth.mock.test.ts +17 -17
- package/src/services/__tests__/auth/auth.setup.ts +293 -293
- package/src/services/__tests__/auth.service.test.ts +346 -346
- package/src/services/__tests__/base.service.test.ts +77 -77
- package/src/services/__tests__/user.service.test.ts +528 -528
- package/src/services/analytics/ARCHITECTURE.md +199 -199
- package/src/services/analytics/CLOUD_FUNCTIONS.md +225 -225
- package/src/services/analytics/GROUPED_ANALYTICS.md +501 -501
- package/src/services/analytics/QUICK_START.md +393 -393
- package/src/services/analytics/README.md +304 -304
- package/src/services/analytics/SUMMARY.md +141 -141
- package/src/services/analytics/TRENDS.md +380 -380
- package/src/services/analytics/USAGE_GUIDE.md +518 -518
- package/src/services/analytics/analytics-cloud.service.ts +222 -222
- package/src/services/analytics/analytics.service.ts +2142 -2142
- package/src/services/analytics/index.ts +4 -4
- package/src/services/analytics/review-analytics.service.ts +941 -941
- package/src/services/analytics/utils/appointment-filtering.utils.ts +138 -138
- package/src/services/analytics/utils/cost-calculation.utils.ts +182 -182
- package/src/services/analytics/utils/grouping.utils.ts +434 -434
- package/src/services/analytics/utils/stored-analytics.utils.ts +347 -347
- package/src/services/analytics/utils/time-calculation.utils.ts +186 -186
- package/src/services/analytics/utils/trend-calculation.utils.ts +200 -200
- package/src/services/appointment/README.md +17 -17
- package/src/services/appointment/appointment.service.ts +2558 -2558
- package/src/services/appointment/index.ts +1 -1
- package/src/services/appointment/utils/appointment.utils.ts +552 -552
- package/src/services/appointment/utils/extended-procedure.utils.ts +314 -314
- package/src/services/appointment/utils/form-initialization.utils.ts +225 -225
- package/src/services/appointment/utils/recommended-procedure.utils.ts +195 -195
- package/src/services/appointment/utils/zone-management.utils.ts +353 -353
- package/src/services/appointment/utils/zone-photo.utils.ts +152 -152
- package/src/services/auth/auth.service.ts +1043 -989
- package/src/services/auth/auth.v2.service.ts +961 -961
- package/src/services/auth/index.ts +7 -7
- package/src/services/auth/utils/error.utils.ts +90 -90
- package/src/services/auth/utils/firebase.utils.ts +49 -49
- package/src/services/auth/utils/index.ts +21 -21
- package/src/services/auth/utils/practitioner.utils.ts +125 -125
- package/src/services/base.service.ts +41 -41
- package/src/services/calendar/calendar.service.ts +1077 -1077
- package/src/services/calendar/calendar.v2.service.ts +1683 -1683
- package/src/services/calendar/calendar.v3.service.ts +313 -313
- package/src/services/calendar/externalCalendar.service.ts +178 -178
- package/src/services/calendar/index.ts +5 -5
- package/src/services/calendar/synced-calendars.service.ts +743 -743
- package/src/services/calendar/utils/appointment.utils.ts +265 -265
- package/src/services/calendar/utils/calendar-event.utils.ts +646 -646
- package/src/services/calendar/utils/clinic.utils.ts +237 -237
- package/src/services/calendar/utils/docs.utils.ts +157 -157
- package/src/services/calendar/utils/google-calendar.utils.ts +697 -697
- package/src/services/calendar/utils/index.ts +8 -8
- package/src/services/calendar/utils/patient.utils.ts +198 -198
- package/src/services/calendar/utils/practitioner.utils.ts +221 -221
- package/src/services/calendar/utils/synced-calendar.utils.ts +472 -472
- package/src/services/clinic/README.md +204 -204
- package/src/services/clinic/__tests__/clinic-admin.service.test.ts +287 -287
- package/src/services/clinic/__tests__/clinic-group.service.test.ts +352 -352
- package/src/services/clinic/__tests__/clinic.service.test.ts +354 -354
- package/src/services/clinic/billing-transactions.service.ts +217 -217
- package/src/services/clinic/clinic-admin.service.ts +202 -202
- package/src/services/clinic/clinic-group.service.ts +310 -310
- package/src/services/clinic/clinic.service.ts +708 -708
- package/src/services/clinic/index.ts +5 -5
- package/src/services/clinic/practitioner-invite.service.ts +519 -519
- package/src/services/clinic/utils/admin.utils.ts +551 -551
- package/src/services/clinic/utils/clinic-group.utils.ts +646 -646
- package/src/services/clinic/utils/clinic.utils.ts +949 -949
- package/src/services/clinic/utils/filter.utils.d.ts +23 -23
- package/src/services/clinic/utils/filter.utils.ts +446 -446
- package/src/services/clinic/utils/index.ts +11 -11
- package/src/services/clinic/utils/photos.utils.ts +188 -188
- package/src/services/clinic/utils/search.utils.ts +84 -84
- package/src/services/clinic/utils/tag.utils.ts +124 -124
- package/src/services/documentation-templates/documentation-template.service.ts +537 -537
- package/src/services/documentation-templates/filled-document.service.ts +587 -587
- package/src/services/documentation-templates/index.ts +2 -2
- package/src/services/index.ts +14 -14
- package/src/services/media/index.ts +1 -1
- package/src/services/media/media.service.ts +418 -418
- package/src/services/notifications/__tests__/notification.service.test.ts +242 -242
- package/src/services/notifications/index.ts +1 -1
- package/src/services/notifications/notification.service.ts +215 -215
- package/src/services/patient/README.md +48 -48
- package/src/services/patient/To-Do.md +43 -43
- package/src/services/patient/__tests__/patient.service.test.ts +294 -294
- package/src/services/patient/index.ts +2 -2
- package/src/services/patient/patient.service.ts +883 -883
- package/src/services/patient/patientRequirements.service.ts +285 -285
- package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -176
- package/src/services/patient/utils/clinic.utils.ts +80 -80
- package/src/services/patient/utils/docs.utils.ts +142 -142
- package/src/services/patient/utils/index.ts +9 -9
- package/src/services/patient/utils/location.utils.ts +126 -126
- package/src/services/patient/utils/medical-stuff.utils.ts +143 -143
- package/src/services/patient/utils/medical.utils.ts +458 -458
- package/src/services/patient/utils/practitioner.utils.ts +260 -260
- package/src/services/patient/utils/profile.utils.ts +510 -510
- package/src/services/patient/utils/sensitive.utils.ts +260 -260
- package/src/services/patient/utils/token.utils.ts +211 -211
- package/src/services/practitioner/README.md +145 -145
- package/src/services/practitioner/index.ts +1 -1
- package/src/services/practitioner/practitioner.service.ts +1799 -1742
- package/src/services/procedure/README.md +163 -163
- package/src/services/procedure/index.ts +1 -1
- package/src/services/procedure/procedure.service.ts +2307 -2200
- package/src/services/reviews/index.ts +1 -1
- package/src/services/reviews/reviews.service.ts +734 -734
- package/src/services/user/index.ts +1 -1
- package/src/services/user/user.service.ts +489 -489
- package/src/services/user/user.v2.service.ts +466 -466
- package/src/types/analytics/analytics.types.ts +597 -597
- package/src/types/analytics/grouped-analytics.types.ts +173 -173
- package/src/types/analytics/index.ts +4 -4
- package/src/types/analytics/stored-analytics.types.ts +137 -137
- package/src/types/appointment/index.ts +480 -480
- package/src/types/calendar/index.ts +258 -258
- package/src/types/calendar/synced-calendar.types.ts +66 -66
- package/src/types/clinic/index.ts +498 -498
- package/src/types/clinic/practitioner-invite.types.ts +91 -91
- package/src/types/clinic/preferences.types.ts +159 -159
- package/src/types/clinic/to-do +3 -3
- package/src/types/documentation-templates/index.ts +308 -308
- package/src/types/index.ts +47 -47
- package/src/types/notifications/README.md +77 -77
- package/src/types/notifications/index.ts +286 -286
- package/src/types/patient/aesthetic-analysis.types.ts +66 -66
- package/src/types/patient/allergies.ts +58 -58
- package/src/types/patient/index.ts +275 -275
- package/src/types/patient/medical-info.types.ts +152 -152
- package/src/types/patient/patient-requirements.ts +92 -92
- package/src/types/patient/token.types.ts +61 -61
- package/src/types/practitioner/index.ts +206 -206
- package/src/types/procedure/index.ts +181 -181
- package/src/types/profile/index.ts +39 -39
- package/src/types/reviews/index.ts +132 -132
- package/src/types/tz-lookup.d.ts +4 -4
- package/src/types/user/index.ts +38 -38
- package/src/utils/TIMESTAMPS.md +176 -176
- package/src/utils/TimestampUtils.ts +241 -241
- package/src/utils/index.ts +1 -1
- package/src/validations/appointment.schema.ts +574 -574
- package/src/validations/calendar.schema.ts +225 -225
- package/src/validations/clinic.schema.ts +494 -494
- package/src/validations/common.schema.ts +25 -25
- package/src/validations/documentation-templates/index.ts +1 -1
- package/src/validations/documentation-templates/template.schema.ts +220 -220
- package/src/validations/documentation-templates.schema.ts +10 -10
- package/src/validations/index.ts +20 -20
- package/src/validations/media.schema.ts +10 -10
- package/src/validations/notification.schema.ts +90 -90
- package/src/validations/patient/aesthetic-analysis.schema.ts +55 -55
- package/src/validations/patient/medical-info.schema.ts +125 -125
- package/src/validations/patient/patient-requirements.schema.ts +84 -84
- package/src/validations/patient/token.schema.ts +29 -29
- package/src/validations/patient.schema.ts +217 -217
- package/src/validations/practitioner.schema.ts +222 -222
- package/src/validations/procedure-product.schema.ts +41 -41
- package/src/validations/procedure.schema.ts +124 -124
- package/src/validations/profile-info.schema.ts +41 -41
- package/src/validations/reviews.schema.ts +195 -195
- package/src/validations/schemas.ts +104 -104
- package/src/validations/shared.schema.ts +78 -78
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility functions index
|
|
3
|
-
* Centralized exports for all utility modules
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// export * from "./utils";
|
|
7
|
-
export * from "./auth.service";
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions index
|
|
3
|
+
* Centralized exports for all utility modules
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// export * from "./utils";
|
|
7
|
+
export * from "./auth.service";
|
|
@@ -1,90 +1,90 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import {
|
|
3
|
-
FirebaseError,
|
|
4
|
-
FirebaseErrorCode,
|
|
5
|
-
} from "../../../errors/firebase.errors";
|
|
6
|
-
import { AUTH_ERRORS } from "../../../errors/auth.errors";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Error handling utility functions
|
|
10
|
-
* Contains common error handling and transformation logic
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Handle Firebase-specific errors and transform them to user-friendly messages
|
|
15
|
-
* @param error - Firebase error object
|
|
16
|
-
* @returns Error with user-friendly message
|
|
17
|
-
*/
|
|
18
|
-
export const handleFirebaseError = (error: any): Error => {
|
|
19
|
-
const firebaseError = error as FirebaseError;
|
|
20
|
-
|
|
21
|
-
switch (firebaseError.code) {
|
|
22
|
-
case FirebaseErrorCode.EMAIL_ALREADY_IN_USE:
|
|
23
|
-
return AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
|
|
24
|
-
case "auth/weak-password":
|
|
25
|
-
return new Error(
|
|
26
|
-
"Password is too weak. Please choose a stronger password."
|
|
27
|
-
);
|
|
28
|
-
case "auth/invalid-email":
|
|
29
|
-
return new Error("Please enter a valid email address.");
|
|
30
|
-
case "auth/network-request-failed":
|
|
31
|
-
return new Error(
|
|
32
|
-
"Network error. Please check your internet connection and try again."
|
|
33
|
-
);
|
|
34
|
-
default:
|
|
35
|
-
return new Error(
|
|
36
|
-
`Account creation failed: ${firebaseError.message || "Unknown error"}`
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Handle signup errors with specific messaging
|
|
43
|
-
* @param error - Error object from signup process
|
|
44
|
-
* @returns Error with specific user-friendly message
|
|
45
|
-
*/
|
|
46
|
-
export const handleSignupError = (error: any): Error => {
|
|
47
|
-
if (error instanceof z.ZodError) {
|
|
48
|
-
const errorMessages = error.errors
|
|
49
|
-
.map((e) => `${e.path.join(".")}: ${e.message}`)
|
|
50
|
-
.join(", ");
|
|
51
|
-
return new Error(`Validation failed: ${errorMessages}`);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (error.code && error.code.startsWith("auth/")) {
|
|
55
|
-
return handleFirebaseError(error);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (error.message && error.message.includes("token")) {
|
|
59
|
-
return new Error("Invalid or expired invitation token");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (error.message && error.message.includes("validation")) {
|
|
63
|
-
return new Error(`Invalid practitioner data: ${error.message}`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return new Error(
|
|
67
|
-
`Registration failed: ${error.message || "Unknown error occurred"}`
|
|
68
|
-
);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Extract meaningful error message from various error types
|
|
73
|
-
* @param error - Error object of unknown type
|
|
74
|
-
* @returns String containing the error message
|
|
75
|
-
*/
|
|
76
|
-
export const extractErrorMessage = (error: any): string => {
|
|
77
|
-
if (error instanceof Error) {
|
|
78
|
-
return error.message;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (typeof error === "string") {
|
|
82
|
-
return error;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (error?.message) {
|
|
86
|
-
return error.message;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return "Unknown error occurred";
|
|
90
|
-
};
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import {
|
|
3
|
+
FirebaseError,
|
|
4
|
+
FirebaseErrorCode,
|
|
5
|
+
} from "../../../errors/firebase.errors";
|
|
6
|
+
import { AUTH_ERRORS } from "../../../errors/auth.errors";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Error handling utility functions
|
|
10
|
+
* Contains common error handling and transformation logic
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Handle Firebase-specific errors and transform them to user-friendly messages
|
|
15
|
+
* @param error - Firebase error object
|
|
16
|
+
* @returns Error with user-friendly message
|
|
17
|
+
*/
|
|
18
|
+
export const handleFirebaseError = (error: any): Error => {
|
|
19
|
+
const firebaseError = error as FirebaseError;
|
|
20
|
+
|
|
21
|
+
switch (firebaseError.code) {
|
|
22
|
+
case FirebaseErrorCode.EMAIL_ALREADY_IN_USE:
|
|
23
|
+
return AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
|
|
24
|
+
case "auth/weak-password":
|
|
25
|
+
return new Error(
|
|
26
|
+
"Password is too weak. Please choose a stronger password."
|
|
27
|
+
);
|
|
28
|
+
case "auth/invalid-email":
|
|
29
|
+
return new Error("Please enter a valid email address.");
|
|
30
|
+
case "auth/network-request-failed":
|
|
31
|
+
return new Error(
|
|
32
|
+
"Network error. Please check your internet connection and try again."
|
|
33
|
+
);
|
|
34
|
+
default:
|
|
35
|
+
return new Error(
|
|
36
|
+
`Account creation failed: ${firebaseError.message || "Unknown error"}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Handle signup errors with specific messaging
|
|
43
|
+
* @param error - Error object from signup process
|
|
44
|
+
* @returns Error with specific user-friendly message
|
|
45
|
+
*/
|
|
46
|
+
export const handleSignupError = (error: any): Error => {
|
|
47
|
+
if (error instanceof z.ZodError) {
|
|
48
|
+
const errorMessages = error.errors
|
|
49
|
+
.map((e) => `${e.path.join(".")}: ${e.message}`)
|
|
50
|
+
.join(", ");
|
|
51
|
+
return new Error(`Validation failed: ${errorMessages}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (error.code && error.code.startsWith("auth/")) {
|
|
55
|
+
return handleFirebaseError(error);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (error.message && error.message.includes("token")) {
|
|
59
|
+
return new Error("Invalid or expired invitation token");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (error.message && error.message.includes("validation")) {
|
|
63
|
+
return new Error(`Invalid practitioner data: ${error.message}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return new Error(
|
|
67
|
+
`Registration failed: ${error.message || "Unknown error occurred"}`
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Extract meaningful error message from various error types
|
|
73
|
+
* @param error - Error object of unknown type
|
|
74
|
+
* @returns String containing the error message
|
|
75
|
+
*/
|
|
76
|
+
export const extractErrorMessage = (error: any): string => {
|
|
77
|
+
if (error instanceof Error) {
|
|
78
|
+
return error.message;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (typeof error === "string") {
|
|
82
|
+
return error;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (error?.message) {
|
|
86
|
+
return error.message;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return "Unknown error occurred";
|
|
90
|
+
};
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { fetchSignInMethodsForEmail, Auth } from "firebase/auth";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Firebase utility functions
|
|
5
|
-
* Contains Firebase-specific helper functions
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Checks if an email address is already registered in Firebase Auth
|
|
10
|
-
* @param auth - Firebase Auth instance
|
|
11
|
-
* @param email - Email address to check
|
|
12
|
-
* @returns Promise<boolean> - True if email exists, false otherwise
|
|
13
|
-
*/
|
|
14
|
-
export const checkEmailExists = async (
|
|
15
|
-
auth: Auth,
|
|
16
|
-
email: string
|
|
17
|
-
): Promise<boolean> => {
|
|
18
|
-
try {
|
|
19
|
-
// Use Firebase Auth to check if email exists
|
|
20
|
-
const methods = await fetchSignInMethodsForEmail(auth, email);
|
|
21
|
-
return methods.length > 0;
|
|
22
|
-
} catch (error) {
|
|
23
|
-
console.warn(
|
|
24
|
-
"[FIREBASE] Could not check email existence, allowing signup to proceed:",
|
|
25
|
-
error
|
|
26
|
-
);
|
|
27
|
-
// If error checking, assume it doesn't exist to allow process to continue
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Cleanup Firebase user if signup transaction fails
|
|
34
|
-
* @param firebaseUser - Firebase user object to delete
|
|
35
|
-
* @returns Promise<void>
|
|
36
|
-
*/
|
|
37
|
-
export const cleanupFirebaseUser = async (firebaseUser: any): Promise<void> => {
|
|
38
|
-
try {
|
|
39
|
-
console.log("[FIREBASE] Cleaning up Firebase user", {
|
|
40
|
-
uid: firebaseUser.uid,
|
|
41
|
-
});
|
|
42
|
-
await firebaseUser.delete();
|
|
43
|
-
console.log("[FIREBASE] Firebase user cleanup successful");
|
|
44
|
-
} catch (cleanupError) {
|
|
45
|
-
console.error("[FIREBASE] Failed to cleanup Firebase user:", cleanupError);
|
|
46
|
-
// Log this for manual cleanup - don't throw as it would mask original error
|
|
47
|
-
// You might want to send this to a monitoring service for manual cleanup
|
|
48
|
-
}
|
|
49
|
-
};
|
|
1
|
+
import { fetchSignInMethodsForEmail, Auth } from "firebase/auth";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Firebase utility functions
|
|
5
|
+
* Contains Firebase-specific helper functions
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Checks if an email address is already registered in Firebase Auth
|
|
10
|
+
* @param auth - Firebase Auth instance
|
|
11
|
+
* @param email - Email address to check
|
|
12
|
+
* @returns Promise<boolean> - True if email exists, false otherwise
|
|
13
|
+
*/
|
|
14
|
+
export const checkEmailExists = async (
|
|
15
|
+
auth: Auth,
|
|
16
|
+
email: string
|
|
17
|
+
): Promise<boolean> => {
|
|
18
|
+
try {
|
|
19
|
+
// Use Firebase Auth to check if email exists
|
|
20
|
+
const methods = await fetchSignInMethodsForEmail(auth, email);
|
|
21
|
+
return methods.length > 0;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.warn(
|
|
24
|
+
"[FIREBASE] Could not check email existence, allowing signup to proceed:",
|
|
25
|
+
error
|
|
26
|
+
);
|
|
27
|
+
// If error checking, assume it doesn't exist to allow process to continue
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Cleanup Firebase user if signup transaction fails
|
|
34
|
+
* @param firebaseUser - Firebase user object to delete
|
|
35
|
+
* @returns Promise<void>
|
|
36
|
+
*/
|
|
37
|
+
export const cleanupFirebaseUser = async (firebaseUser: any): Promise<void> => {
|
|
38
|
+
try {
|
|
39
|
+
console.log("[FIREBASE] Cleaning up Firebase user", {
|
|
40
|
+
uid: firebaseUser.uid,
|
|
41
|
+
});
|
|
42
|
+
await firebaseUser.delete();
|
|
43
|
+
console.log("[FIREBASE] Firebase user cleanup successful");
|
|
44
|
+
} catch (cleanupError) {
|
|
45
|
+
console.error("[FIREBASE] Failed to cleanup Firebase user:", cleanupError);
|
|
46
|
+
// Log this for manual cleanup - don't throw as it would mask original error
|
|
47
|
+
// You might want to send this to a monitoring service for manual cleanup
|
|
48
|
+
}
|
|
49
|
+
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility functions index
|
|
3
|
-
* Centralized exports for all utility modules
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Firebase utilities
|
|
7
|
-
export { checkEmailExists, cleanupFirebaseUser } from "./firebase.utils";
|
|
8
|
-
|
|
9
|
-
// Error handling utilities
|
|
10
|
-
export {
|
|
11
|
-
handleFirebaseError,
|
|
12
|
-
handleSignupError,
|
|
13
|
-
extractErrorMessage,
|
|
14
|
-
} from "./error.utils";
|
|
15
|
-
|
|
16
|
-
// Practitioner utilities
|
|
17
|
-
export {
|
|
18
|
-
buildPractitionerData,
|
|
19
|
-
validatePractitionerProfileData,
|
|
20
|
-
isPractitionerDataComplete,
|
|
21
|
-
} from "./practitioner.utils";
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions index
|
|
3
|
+
* Centralized exports for all utility modules
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Firebase utilities
|
|
7
|
+
export { checkEmailExists, cleanupFirebaseUser } from "./firebase.utils";
|
|
8
|
+
|
|
9
|
+
// Error handling utilities
|
|
10
|
+
export {
|
|
11
|
+
handleFirebaseError,
|
|
12
|
+
handleSignupError,
|
|
13
|
+
extractErrorMessage,
|
|
14
|
+
} from "./error.utils";
|
|
15
|
+
|
|
16
|
+
// Practitioner utilities
|
|
17
|
+
export {
|
|
18
|
+
buildPractitionerData,
|
|
19
|
+
validatePractitionerProfileData,
|
|
20
|
+
isPractitionerDataComplete,
|
|
21
|
+
} from "./practitioner.utils";
|
|
@@ -1,125 +1,125 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CreatePractitionerData,
|
|
3
|
-
PractitionerBasicInfo,
|
|
4
|
-
PractitionerCertification,
|
|
5
|
-
PractitionerStatus,
|
|
6
|
-
} from "../../../types/practitioner";
|
|
7
|
-
import { CertificationLevel } from "../../../backoffice/types/static/certification.types";
|
|
8
|
-
import { z } from "zod";
|
|
9
|
-
import {
|
|
10
|
-
practitionerBasicInfoSchema,
|
|
11
|
-
practitionerCertificationSchema,
|
|
12
|
-
} from "../../../validations/practitioner.schema";
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Practitioner utility functions
|
|
16
|
-
* Contains practitioner-specific helper functions
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
// Partial schemas for profile data validation using existing schemas
|
|
20
|
-
const profileDataSchema = z
|
|
21
|
-
.object({
|
|
22
|
-
basicInfo: practitionerBasicInfoSchema.partial().optional(),
|
|
23
|
-
certification: practitionerCertificationSchema.partial().optional(),
|
|
24
|
-
})
|
|
25
|
-
.partial();
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Build practitioner data from signup input
|
|
29
|
-
* @param data - Signup data containing practitioner information
|
|
30
|
-
* @param userRef - Firebase user reference ID
|
|
31
|
-
* @returns Complete practitioner data object ready for creation
|
|
32
|
-
*/
|
|
33
|
-
export const buildPractitionerData = (
|
|
34
|
-
data: {
|
|
35
|
-
email: string;
|
|
36
|
-
firstName?: string;
|
|
37
|
-
lastName?: string;
|
|
38
|
-
profileData?: Partial<CreatePractitionerData>;
|
|
39
|
-
},
|
|
40
|
-
userRef: string
|
|
41
|
-
): CreatePractitionerData => {
|
|
42
|
-
// Build complete PractitionerBasicInfo object
|
|
43
|
-
const basicInfo: PractitionerBasicInfo = {
|
|
44
|
-
firstName: data.firstName || "Name",
|
|
45
|
-
lastName: data.lastName || "Surname",
|
|
46
|
-
email: data.email,
|
|
47
|
-
phoneNumber: data.profileData?.basicInfo?.phoneNumber || null,
|
|
48
|
-
profileImageUrl: data.profileData?.basicInfo?.profileImageUrl || "",
|
|
49
|
-
gender: data.profileData?.basicInfo?.gender || "other",
|
|
50
|
-
bio: data.profileData?.basicInfo?.bio || "",
|
|
51
|
-
title: "Practitioner",
|
|
52
|
-
dateOfBirth: data.profileData?.basicInfo?.dateOfBirth || new Date(),
|
|
53
|
-
languages: data.profileData?.basicInfo?.languages || ["English"],
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
// Basic certification information with placeholders
|
|
57
|
-
const certification: PractitionerCertification = data.profileData
|
|
58
|
-
?.certification || {
|
|
59
|
-
level: CertificationLevel.AESTHETICIAN,
|
|
60
|
-
specialties: [],
|
|
61
|
-
licenseNumber: "Pending",
|
|
62
|
-
issuingAuthority: "Pending",
|
|
63
|
-
issueDate: new Date(),
|
|
64
|
-
verificationStatus: "pending",
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
userRef,
|
|
69
|
-
basicInfo,
|
|
70
|
-
certification,
|
|
71
|
-
status: PractitionerStatus.ACTIVE,
|
|
72
|
-
isActive: true,
|
|
73
|
-
isVerified: false,
|
|
74
|
-
};
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Validate practitioner profile data structure using existing Zod schemas
|
|
79
|
-
* @param profileData - Partial practitioner data to validate
|
|
80
|
-
* @throws Error if validation fails
|
|
81
|
-
*/
|
|
82
|
-
export const validatePractitionerProfileData = async (
|
|
83
|
-
profileData: Partial<CreatePractitionerData>
|
|
84
|
-
): Promise<void> => {
|
|
85
|
-
try {
|
|
86
|
-
await profileDataSchema.parseAsync(profileData);
|
|
87
|
-
} catch (error) {
|
|
88
|
-
if (error instanceof z.ZodError) {
|
|
89
|
-
const errorMessages = error.errors
|
|
90
|
-
.map((e) => `${e.path.join(".")}: ${e.message}`)
|
|
91
|
-
.join(", ");
|
|
92
|
-
throw new Error(
|
|
93
|
-
`Practitioner profile validation failed: ${errorMessages}`
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Check if practitioner data is complete for verification
|
|
102
|
-
* @param practitioner - Practitioner object to check
|
|
103
|
-
* @returns boolean indicating if data is complete
|
|
104
|
-
*/
|
|
105
|
-
export const isPractitionerDataComplete = (
|
|
106
|
-
practitioner: CreatePractitionerData
|
|
107
|
-
): boolean => {
|
|
108
|
-
const { basicInfo, certification } = practitioner;
|
|
109
|
-
|
|
110
|
-
// Check required basic info fields
|
|
111
|
-
const hasRequiredBasicInfo =
|
|
112
|
-
basicInfo.firstName &&
|
|
113
|
-
basicInfo.lastName &&
|
|
114
|
-
basicInfo.email &&
|
|
115
|
-
basicInfo.phoneNumber;
|
|
116
|
-
|
|
117
|
-
// Check required certification fields
|
|
118
|
-
const hasRequiredCertification =
|
|
119
|
-
certification.licenseNumber &&
|
|
120
|
-
certification.licenseNumber !== "Pending" &&
|
|
121
|
-
certification.issuingAuthority &&
|
|
122
|
-
certification.issuingAuthority !== "Pending";
|
|
123
|
-
|
|
124
|
-
return !!(hasRequiredBasicInfo && hasRequiredCertification);
|
|
125
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
CreatePractitionerData,
|
|
3
|
+
PractitionerBasicInfo,
|
|
4
|
+
PractitionerCertification,
|
|
5
|
+
PractitionerStatus,
|
|
6
|
+
} from "../../../types/practitioner";
|
|
7
|
+
import { CertificationLevel } from "../../../backoffice/types/static/certification.types";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import {
|
|
10
|
+
practitionerBasicInfoSchema,
|
|
11
|
+
practitionerCertificationSchema,
|
|
12
|
+
} from "../../../validations/practitioner.schema";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Practitioner utility functions
|
|
16
|
+
* Contains practitioner-specific helper functions
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Partial schemas for profile data validation using existing schemas
|
|
20
|
+
const profileDataSchema = z
|
|
21
|
+
.object({
|
|
22
|
+
basicInfo: practitionerBasicInfoSchema.partial().optional(),
|
|
23
|
+
certification: practitionerCertificationSchema.partial().optional(),
|
|
24
|
+
})
|
|
25
|
+
.partial();
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Build practitioner data from signup input
|
|
29
|
+
* @param data - Signup data containing practitioner information
|
|
30
|
+
* @param userRef - Firebase user reference ID
|
|
31
|
+
* @returns Complete practitioner data object ready for creation
|
|
32
|
+
*/
|
|
33
|
+
export const buildPractitionerData = (
|
|
34
|
+
data: {
|
|
35
|
+
email: string;
|
|
36
|
+
firstName?: string;
|
|
37
|
+
lastName?: string;
|
|
38
|
+
profileData?: Partial<CreatePractitionerData>;
|
|
39
|
+
},
|
|
40
|
+
userRef: string
|
|
41
|
+
): CreatePractitionerData => {
|
|
42
|
+
// Build complete PractitionerBasicInfo object
|
|
43
|
+
const basicInfo: PractitionerBasicInfo = {
|
|
44
|
+
firstName: data.firstName || "Name",
|
|
45
|
+
lastName: data.lastName || "Surname",
|
|
46
|
+
email: data.email,
|
|
47
|
+
phoneNumber: data.profileData?.basicInfo?.phoneNumber || null,
|
|
48
|
+
profileImageUrl: data.profileData?.basicInfo?.profileImageUrl || "",
|
|
49
|
+
gender: data.profileData?.basicInfo?.gender || "other",
|
|
50
|
+
bio: data.profileData?.basicInfo?.bio || "",
|
|
51
|
+
title: "Practitioner",
|
|
52
|
+
dateOfBirth: data.profileData?.basicInfo?.dateOfBirth || new Date(),
|
|
53
|
+
languages: data.profileData?.basicInfo?.languages || ["English"],
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Basic certification information with placeholders
|
|
57
|
+
const certification: PractitionerCertification = data.profileData
|
|
58
|
+
?.certification || {
|
|
59
|
+
level: CertificationLevel.AESTHETICIAN,
|
|
60
|
+
specialties: [],
|
|
61
|
+
licenseNumber: "Pending",
|
|
62
|
+
issuingAuthority: "Pending",
|
|
63
|
+
issueDate: new Date(),
|
|
64
|
+
verificationStatus: "pending",
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
userRef,
|
|
69
|
+
basicInfo,
|
|
70
|
+
certification,
|
|
71
|
+
status: PractitionerStatus.ACTIVE,
|
|
72
|
+
isActive: true,
|
|
73
|
+
isVerified: false,
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Validate practitioner profile data structure using existing Zod schemas
|
|
79
|
+
* @param profileData - Partial practitioner data to validate
|
|
80
|
+
* @throws Error if validation fails
|
|
81
|
+
*/
|
|
82
|
+
export const validatePractitionerProfileData = async (
|
|
83
|
+
profileData: Partial<CreatePractitionerData>
|
|
84
|
+
): Promise<void> => {
|
|
85
|
+
try {
|
|
86
|
+
await profileDataSchema.parseAsync(profileData);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (error instanceof z.ZodError) {
|
|
89
|
+
const errorMessages = error.errors
|
|
90
|
+
.map((e) => `${e.path.join(".")}: ${e.message}`)
|
|
91
|
+
.join(", ");
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Practitioner profile validation failed: ${errorMessages}`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Check if practitioner data is complete for verification
|
|
102
|
+
* @param practitioner - Practitioner object to check
|
|
103
|
+
* @returns boolean indicating if data is complete
|
|
104
|
+
*/
|
|
105
|
+
export const isPractitionerDataComplete = (
|
|
106
|
+
practitioner: CreatePractitionerData
|
|
107
|
+
): boolean => {
|
|
108
|
+
const { basicInfo, certification } = practitioner;
|
|
109
|
+
|
|
110
|
+
// Check required basic info fields
|
|
111
|
+
const hasRequiredBasicInfo =
|
|
112
|
+
basicInfo.firstName &&
|
|
113
|
+
basicInfo.lastName &&
|
|
114
|
+
basicInfo.email &&
|
|
115
|
+
basicInfo.phoneNumber;
|
|
116
|
+
|
|
117
|
+
// Check required certification fields
|
|
118
|
+
const hasRequiredCertification =
|
|
119
|
+
certification.licenseNumber &&
|
|
120
|
+
certification.licenseNumber !== "Pending" &&
|
|
121
|
+
certification.issuingAuthority &&
|
|
122
|
+
certification.issuingAuthority !== "Pending";
|
|
123
|
+
|
|
124
|
+
return !!(hasRequiredBasicInfo && hasRequiredCertification);
|
|
125
|
+
};
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { Auth } from "firebase/auth";
|
|
2
|
-
import { Firestore } from "firebase/firestore";
|
|
3
|
-
import { FirebaseApp } from "firebase/app";
|
|
4
|
-
import { getStorage, FirebaseStorage } from "firebase/storage";
|
|
5
|
-
|
|
6
|
-
export class BaseService {
|
|
7
|
-
protected db: Firestore;
|
|
8
|
-
protected auth: Auth;
|
|
9
|
-
protected app: FirebaseApp;
|
|
10
|
-
protected storage!: FirebaseStorage;
|
|
11
|
-
|
|
12
|
-
constructor(
|
|
13
|
-
db: Firestore,
|
|
14
|
-
auth: Auth,
|
|
15
|
-
app: FirebaseApp,
|
|
16
|
-
storage?: FirebaseStorage
|
|
17
|
-
) {
|
|
18
|
-
this.db = db;
|
|
19
|
-
this.auth = auth;
|
|
20
|
-
this.app = app;
|
|
21
|
-
if (app) {
|
|
22
|
-
this.storage = storage || getStorage(app);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Generiše jedinstveni ID za dokumente
|
|
28
|
-
* Format: xxxxxxxxxxxx-timestamp
|
|
29
|
-
* Gde je x random karakter (broj ili slovo)
|
|
30
|
-
*/
|
|
31
|
-
protected generateId(): string {
|
|
32
|
-
const chars =
|
|
33
|
-
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
34
|
-
const timestamp = Date.now().toString(36);
|
|
35
|
-
const randomPart = Array.from({ length: 12 }, () =>
|
|
36
|
-
chars.charAt(Math.floor(Math.random() * chars.length))
|
|
37
|
-
).join("");
|
|
38
|
-
|
|
39
|
-
return `${randomPart}-${timestamp}`;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
1
|
+
import { Auth } from "firebase/auth";
|
|
2
|
+
import { Firestore } from "firebase/firestore";
|
|
3
|
+
import { FirebaseApp } from "firebase/app";
|
|
4
|
+
import { getStorage, FirebaseStorage } from "firebase/storage";
|
|
5
|
+
|
|
6
|
+
export class BaseService {
|
|
7
|
+
protected db: Firestore;
|
|
8
|
+
protected auth: Auth;
|
|
9
|
+
protected app: FirebaseApp;
|
|
10
|
+
protected storage!: FirebaseStorage;
|
|
11
|
+
|
|
12
|
+
constructor(
|
|
13
|
+
db: Firestore,
|
|
14
|
+
auth: Auth,
|
|
15
|
+
app: FirebaseApp,
|
|
16
|
+
storage?: FirebaseStorage
|
|
17
|
+
) {
|
|
18
|
+
this.db = db;
|
|
19
|
+
this.auth = auth;
|
|
20
|
+
this.app = app;
|
|
21
|
+
if (app) {
|
|
22
|
+
this.storage = storage || getStorage(app);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Generiše jedinstveni ID za dokumente
|
|
28
|
+
* Format: xxxxxxxxxxxx-timestamp
|
|
29
|
+
* Gde je x random karakter (broj ili slovo)
|
|
30
|
+
*/
|
|
31
|
+
protected generateId(): string {
|
|
32
|
+
const chars =
|
|
33
|
+
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
34
|
+
const timestamp = Date.now().toString(36);
|
|
35
|
+
const randomPart = Array.from({ length: 12 }, () =>
|
|
36
|
+
chars.charAt(Math.floor(Math.random() * chars.length))
|
|
37
|
+
).join("");
|
|
38
|
+
|
|
39
|
+
return `${randomPart}-${timestamp}`;
|
|
40
|
+
}
|
|
41
|
+
}
|