@blackcode_sa/metaestetics-api 1.6.24 → 1.6.25
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 +31 -3
- package/dist/admin/index.d.ts +31 -3
- package/dist/admin/index.js +126 -36
- package/dist/admin/index.mjs +126 -36
- package/dist/backoffice/index.d.mts +67 -54
- package/dist/backoffice/index.d.ts +67 -54
- package/dist/backoffice/index.js +19 -14
- package/dist/backoffice/index.mjs +19 -14
- package/dist/index.d.mts +271 -258
- package/dist/index.d.ts +271 -258
- package/dist/index.js +19 -14
- package/dist/index.mjs +19 -14
- package/package.json +1 -1
- package/src/admin/booking/booking.admin.ts +8 -5
- package/src/admin/documentation-templates/document-manager.admin.ts +128 -0
- package/src/backoffice/types/technology.types.ts +16 -2
- package/src/services/documentation-templates/documentation-template.service.ts +37 -21
- package/src/types/procedure/index.ts +5 -2
|
@@ -5,11 +5,13 @@ import {
|
|
|
5
5
|
FilledDocumentStatus,
|
|
6
6
|
USER_FORMS_SUBCOLLECTION,
|
|
7
7
|
DOCTOR_FORMS_SUBCOLLECTION,
|
|
8
|
+
DOCUMENTATION_TEMPLATES_COLLECTION,
|
|
8
9
|
} from "../../types/documentation-templates";
|
|
9
10
|
import {
|
|
10
11
|
APPOINTMENTS_COLLECTION,
|
|
11
12
|
LinkedFormInfo,
|
|
12
13
|
} from "../../types/appointment";
|
|
14
|
+
import { TechnologyDocumentationTemplate } from "../../backoffice/types/technology.types";
|
|
13
15
|
|
|
14
16
|
export interface InitializeAppointmentFormsResult {
|
|
15
17
|
initializedFormsInfo: LinkedFormInfo[];
|
|
@@ -128,4 +130,130 @@ export class DocumentManagerAdminService {
|
|
|
128
130
|
}
|
|
129
131
|
return { initializedFormsInfo, pendingUserFormsIds, allLinkedTemplateIds };
|
|
130
132
|
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Adds operations to a Firestore batch to initialize all linked forms for a new appointment
|
|
136
|
+
* using the TechnologyDocumentationTemplate references.
|
|
137
|
+
*
|
|
138
|
+
* @param dbBatch - The Firestore batch to add operations to.
|
|
139
|
+
* @param appointmentId - The ID of the newly created appointment.
|
|
140
|
+
* @param procedureIdForForms - The ID of the procedure associated with this appointment.
|
|
141
|
+
* @param technologyTemplates - Array of technology documentation template references.
|
|
142
|
+
* @param patientId - ID of the patient.
|
|
143
|
+
* @param practitionerId - ID of the practitioner associated with the procedure.
|
|
144
|
+
* @param clinicId - ID of the clinic where the procedure is performed.
|
|
145
|
+
* @param nowMillis - Current timestamp in milliseconds for createdAt/updatedAt.
|
|
146
|
+
* @returns An object containing initializedFormsInfo, pendingUserFormsIds, and allLinkedTemplateIds.
|
|
147
|
+
*/
|
|
148
|
+
async batchInitializeAppointmentFormsFromTechnologyTemplates(
|
|
149
|
+
dbBatch: admin.firestore.WriteBatch,
|
|
150
|
+
appointmentId: string,
|
|
151
|
+
procedureIdForForms: string,
|
|
152
|
+
technologyTemplates: TechnologyDocumentationTemplate[],
|
|
153
|
+
patientId: string,
|
|
154
|
+
practitionerId: string,
|
|
155
|
+
clinicId: string,
|
|
156
|
+
nowMillis: number
|
|
157
|
+
): Promise<InitializeAppointmentFormsResult> {
|
|
158
|
+
const initializedFormsInfo: LinkedFormInfo[] = [];
|
|
159
|
+
const pendingUserFormsIds: string[] = [];
|
|
160
|
+
const allLinkedTemplateIds: string[] = [];
|
|
161
|
+
|
|
162
|
+
if (!technologyTemplates || technologyTemplates.length === 0) {
|
|
163
|
+
console.log(
|
|
164
|
+
`[DocManagerAdmin] No document templates to initialize for appointment ${appointmentId}.`
|
|
165
|
+
);
|
|
166
|
+
return {
|
|
167
|
+
initializedFormsInfo,
|
|
168
|
+
pendingUserFormsIds,
|
|
169
|
+
allLinkedTemplateIds,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Fetch all template documents in one batch
|
|
174
|
+
const templateIds = technologyTemplates.map((t) => t.templateId);
|
|
175
|
+
const templatesSnapshot = await this.db
|
|
176
|
+
.collection(DOCUMENTATION_TEMPLATES_COLLECTION)
|
|
177
|
+
.where(admin.firestore.FieldPath.documentId(), "in", templateIds)
|
|
178
|
+
.get();
|
|
179
|
+
|
|
180
|
+
const templatesMap = new Map<string, DocumentTemplate>();
|
|
181
|
+
templatesSnapshot.forEach((doc) => {
|
|
182
|
+
templatesMap.set(doc.id, doc.data() as DocumentTemplate);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
for (const templateRef of technologyTemplates) {
|
|
186
|
+
const template = templatesMap.get(templateRef.templateId);
|
|
187
|
+
if (!template) {
|
|
188
|
+
console.warn(
|
|
189
|
+
`[DocManagerAdmin] Template ${templateRef.templateId} not found in Firestore.`
|
|
190
|
+
);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const isUserForm = templateRef.isUserForm;
|
|
195
|
+
const isRequired = templateRef.isRequired;
|
|
196
|
+
|
|
197
|
+
const formSubcollectionPath = isUserForm
|
|
198
|
+
? USER_FORMS_SUBCOLLECTION
|
|
199
|
+
: DOCTOR_FORMS_SUBCOLLECTION;
|
|
200
|
+
|
|
201
|
+
const filledDocumentId = this.db
|
|
202
|
+
.collection(APPOINTMENTS_COLLECTION)
|
|
203
|
+
.doc(appointmentId)
|
|
204
|
+
.collection(formSubcollectionPath)
|
|
205
|
+
.doc().id;
|
|
206
|
+
|
|
207
|
+
if (isUserForm && isRequired) {
|
|
208
|
+
pendingUserFormsIds.push(filledDocumentId);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
allLinkedTemplateIds.push(filledDocumentId);
|
|
212
|
+
// Always initialize with PENDING status regardless of whether the form is required
|
|
213
|
+
// PENDING is the starting state, DRAFT is when a form is saved but not submitted
|
|
214
|
+
const initialStatus = FilledDocumentStatus.PENDING;
|
|
215
|
+
|
|
216
|
+
const filledDocumentData: FilledDocument = {
|
|
217
|
+
id: filledDocumentId,
|
|
218
|
+
templateId: templateRef.templateId,
|
|
219
|
+
templateVersion: template.version,
|
|
220
|
+
isUserForm: isUserForm,
|
|
221
|
+
isRequired: isRequired,
|
|
222
|
+
appointmentId: appointmentId,
|
|
223
|
+
procedureId: procedureIdForForms,
|
|
224
|
+
patientId: patientId,
|
|
225
|
+
practitionerId: practitionerId,
|
|
226
|
+
clinicId: clinicId,
|
|
227
|
+
createdAt: nowMillis,
|
|
228
|
+
updatedAt: nowMillis,
|
|
229
|
+
values: {},
|
|
230
|
+
status: initialStatus,
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const docRef = this.db
|
|
234
|
+
.collection(APPOINTMENTS_COLLECTION)
|
|
235
|
+
.doc(appointmentId)
|
|
236
|
+
.collection(formSubcollectionPath)
|
|
237
|
+
.doc(filledDocumentId);
|
|
238
|
+
|
|
239
|
+
dbBatch.set(docRef, filledDocumentData);
|
|
240
|
+
|
|
241
|
+
const linkedForm: LinkedFormInfo = {
|
|
242
|
+
formId: filledDocumentData.id,
|
|
243
|
+
templateId: template.id,
|
|
244
|
+
templateVersion: template.version,
|
|
245
|
+
title: template.title,
|
|
246
|
+
isUserForm: filledDocumentData.isUserForm,
|
|
247
|
+
isRequired: filledDocumentData.isRequired,
|
|
248
|
+
status: filledDocumentData.status,
|
|
249
|
+
path: docRef.path,
|
|
250
|
+
};
|
|
251
|
+
initializedFormsInfo.push(linkedForm);
|
|
252
|
+
|
|
253
|
+
console.log(
|
|
254
|
+
`[DocManagerAdmin] Added FilledDocument ${filledDocumentId} (template: ${template.id}) and its LinkedFormInfo to batch for appointment ${appointmentId}.`
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
return { initializedFormsInfo, pendingUserFormsIds, allLinkedTemplateIds };
|
|
258
|
+
}
|
|
131
259
|
}
|
|
@@ -6,6 +6,20 @@ import { CertificationRequirement } from "./static/certification.types";
|
|
|
6
6
|
import { DocumentTemplate } from "../../types/documentation-templates";
|
|
7
7
|
import { ProcedureFamily } from "./static/procedure-family.types";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Reference to a documentation template with metadata
|
|
11
|
+
* @property templateId - ID of the documentation template
|
|
12
|
+
* @property isUserForm - Whether this template is filled by users
|
|
13
|
+
* @property isRequired - Whether this template is required
|
|
14
|
+
* @property sortingOrder - The display order of this template
|
|
15
|
+
*/
|
|
16
|
+
export interface TechnologyDocumentationTemplate {
|
|
17
|
+
templateId: string;
|
|
18
|
+
isUserForm: boolean;
|
|
19
|
+
isRequired: boolean;
|
|
20
|
+
sortingOrder: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
9
23
|
/**
|
|
10
24
|
* Zahtevi koji su povezani sa tehnologijom
|
|
11
25
|
* @property pre - Lista zahteva koji se moraju ispuniti pre procedure
|
|
@@ -33,7 +47,7 @@ export interface TechnologyRequirements {
|
|
|
33
47
|
* @property contraindications - List of conditions requiring special attention
|
|
34
48
|
* @property benefits - List of expected benefits from the procedure
|
|
35
49
|
* @property certificationRequirement - Required certification level and specialties
|
|
36
|
-
* @property documentationTemplates - List of documentation
|
|
50
|
+
* @property documentationTemplates - List of documentation template references
|
|
37
51
|
* @property isActive - Whether the technology is active in the system
|
|
38
52
|
* @property createdAt - Creation date
|
|
39
53
|
* @property updatedAt - Last update date
|
|
@@ -54,7 +68,7 @@ export interface Technology {
|
|
|
54
68
|
contraindications: Contraindication[];
|
|
55
69
|
benefits: TreatmentBenefit[];
|
|
56
70
|
certificationRequirement: CertificationRequirement;
|
|
57
|
-
documentationTemplates?:
|
|
71
|
+
documentationTemplates?: TechnologyDocumentationTemplate[];
|
|
58
72
|
isActive: boolean;
|
|
59
73
|
createdAt: Date;
|
|
60
74
|
updatedAt: Date;
|
|
@@ -95,33 +95,49 @@ export class DocumentationTemplateService extends BaseService {
|
|
|
95
95
|
templateId: string,
|
|
96
96
|
version?: number
|
|
97
97
|
): Promise<DocumentTemplate | null> {
|
|
98
|
-
//
|
|
99
|
-
if (version !== undefined) {
|
|
100
|
-
try {
|
|
101
|
-
const versionTemplate = await this.getTemplateVersion(
|
|
102
|
-
templateId,
|
|
103
|
-
version
|
|
104
|
-
);
|
|
105
|
-
// If the version exists, return it
|
|
106
|
-
if (versionTemplate) {
|
|
107
|
-
return versionTemplate;
|
|
108
|
-
}
|
|
109
|
-
// If version doesn't exist, fall back to latest version (continue with code below)
|
|
110
|
-
} catch (error) {
|
|
111
|
-
console.error(`Error getting template version ${version}:`, error);
|
|
112
|
-
// Fall back to latest version if error occurs
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Get the latest version (default behavior)
|
|
98
|
+
// First, check if the template exists at all
|
|
117
99
|
const docRef = doc(this.collectionRef, templateId);
|
|
118
100
|
const docSnap = await getDoc(docRef);
|
|
119
101
|
|
|
120
102
|
if (!docSnap.exists()) {
|
|
121
|
-
return null;
|
|
103
|
+
return null; // Template doesn't exist
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const currentTemplate = docSnap.data() as DocumentTemplate;
|
|
107
|
+
|
|
108
|
+
// If no specific version is requested, simply return the current template
|
|
109
|
+
if (version === undefined) {
|
|
110
|
+
return currentTemplate;
|
|
122
111
|
}
|
|
123
112
|
|
|
124
|
-
|
|
113
|
+
// If the requested version matches the current version, return it
|
|
114
|
+
if (currentTemplate.version === version) {
|
|
115
|
+
return currentTemplate;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Otherwise, try to find the requested version in the versions subcollection
|
|
119
|
+
try {
|
|
120
|
+
const versionTemplate = await this.getTemplateVersion(
|
|
121
|
+
templateId,
|
|
122
|
+
version
|
|
123
|
+
);
|
|
124
|
+
if (versionTemplate) {
|
|
125
|
+
return versionTemplate;
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error(`Error getting template version ${version}:`, error);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// If we get here, the requested version doesn't exist
|
|
132
|
+
// Option 1: Return null (strict approach)
|
|
133
|
+
return null;
|
|
134
|
+
|
|
135
|
+
// Option 2: Return current version but indicate it's not the requested version (uncomment to use)
|
|
136
|
+
// return {
|
|
137
|
+
// ...currentTemplate,
|
|
138
|
+
// _versionRequested: version,
|
|
139
|
+
// _versionNotFound: true
|
|
140
|
+
// } as DocumentTemplate;
|
|
125
141
|
}
|
|
126
142
|
|
|
127
143
|
/**
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { ProcedureFamily } from "../../backoffice/types/static/procedure-family.types";
|
|
2
2
|
import { Category } from "../../backoffice/types/category.types";
|
|
3
3
|
import { Subcategory } from "../../backoffice/types/subcategory.types";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Technology,
|
|
6
|
+
type TechnologyDocumentationTemplate,
|
|
7
|
+
} from "../../backoffice/types/technology.types";
|
|
5
8
|
import { Product } from "../../backoffice/types/product.types";
|
|
6
9
|
import {
|
|
7
10
|
PricingMeasure,
|
|
@@ -62,7 +65,7 @@ export interface Procedure {
|
|
|
62
65
|
/** Certification requirements for performing this procedure */
|
|
63
66
|
certificationRequirement: CertificationRequirement;
|
|
64
67
|
/** Documentation templates required for this procedure */
|
|
65
|
-
documentationTemplates:
|
|
68
|
+
documentationTemplates: TechnologyDocumentationTemplate[];
|
|
66
69
|
/** ID of the practitioner who performs this procedure */
|
|
67
70
|
practitionerId: string;
|
|
68
71
|
/** ID of the clinic branch where this procedure is performed */
|