@blackcode_sa/metaestetics-api 1.6.23 → 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 +82 -55
- package/dist/backoffice/index.d.ts +82 -55
- package/dist/backoffice/index.js +85 -4
- package/dist/backoffice/index.mjs +85 -4
- package/dist/index.d.mts +419 -392
- package/dist/index.d.ts +419 -392
- package/dist/index.js +65 -2
- package/dist/index.mjs +65 -2
- 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/services/documentation-template.service.ts +28 -2
- package/src/backoffice/types/technology.types.ts +16 -2
- package/src/services/documentation-templates/documentation-template.service.ts +100 -3
- package/src/types/procedure/index.ts +5 -2
package/dist/index.js
CHANGED
|
@@ -8426,15 +8426,34 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
8426
8426
|
/**
|
|
8427
8427
|
* Get a document template by ID
|
|
8428
8428
|
* @param templateId - ID of the template to retrieve
|
|
8429
|
+
* @param version - Optional version number to retrieve (defaults to latest version)
|
|
8429
8430
|
* @returns The template or null if not found
|
|
8430
8431
|
*/
|
|
8431
|
-
async getTemplateById(templateId) {
|
|
8432
|
+
async getTemplateById(templateId, version) {
|
|
8432
8433
|
const docRef = (0, import_firestore25.doc)(this.collectionRef, templateId);
|
|
8433
8434
|
const docSnap = await (0, import_firestore25.getDoc)(docRef);
|
|
8434
8435
|
if (!docSnap.exists()) {
|
|
8435
8436
|
return null;
|
|
8436
8437
|
}
|
|
8437
|
-
|
|
8438
|
+
const currentTemplate = docSnap.data();
|
|
8439
|
+
if (version === void 0) {
|
|
8440
|
+
return currentTemplate;
|
|
8441
|
+
}
|
|
8442
|
+
if (currentTemplate.version === version) {
|
|
8443
|
+
return currentTemplate;
|
|
8444
|
+
}
|
|
8445
|
+
try {
|
|
8446
|
+
const versionTemplate = await this.getTemplateVersion(
|
|
8447
|
+
templateId,
|
|
8448
|
+
version
|
|
8449
|
+
);
|
|
8450
|
+
if (versionTemplate) {
|
|
8451
|
+
return versionTemplate;
|
|
8452
|
+
}
|
|
8453
|
+
} catch (error) {
|
|
8454
|
+
console.error(`Error getting template version ${version}:`, error);
|
|
8455
|
+
}
|
|
8456
|
+
return null;
|
|
8438
8457
|
}
|
|
8439
8458
|
/**
|
|
8440
8459
|
* Update an existing document template
|
|
@@ -8450,6 +8469,15 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
8450
8469
|
if (!template) {
|
|
8451
8470
|
throw new Error(`Template with ID ${templateId} not found`);
|
|
8452
8471
|
}
|
|
8472
|
+
const versionsCollectionRef = (0, import_firestore25.collection)(
|
|
8473
|
+
this.db,
|
|
8474
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
8475
|
+
);
|
|
8476
|
+
const versionDocRef = (0, import_firestore25.doc)(
|
|
8477
|
+
versionsCollectionRef,
|
|
8478
|
+
template.version.toString()
|
|
8479
|
+
);
|
|
8480
|
+
await (0, import_firestore25.setDoc)(versionDocRef, template);
|
|
8453
8481
|
let updatedElements = template.elements;
|
|
8454
8482
|
if (validatedData.elements) {
|
|
8455
8483
|
updatedElements = validatedData.elements.map((element) => ({
|
|
@@ -8478,6 +8506,41 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
8478
8506
|
await (0, import_firestore25.updateDoc)(docRef, updatePayload);
|
|
8479
8507
|
return { ...template, ...updatePayload };
|
|
8480
8508
|
}
|
|
8509
|
+
/**
|
|
8510
|
+
* Get a specific version of a template
|
|
8511
|
+
* @param templateId - ID of the template
|
|
8512
|
+
* @param versionNumber - Version number to retrieve
|
|
8513
|
+
* @returns The template version or null if not found
|
|
8514
|
+
*/
|
|
8515
|
+
async getTemplateVersion(templateId, versionNumber) {
|
|
8516
|
+
const versionDocRef = (0, import_firestore25.doc)(
|
|
8517
|
+
this.db,
|
|
8518
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions/${versionNumber}`
|
|
8519
|
+
);
|
|
8520
|
+
const versionDocSnap = await (0, import_firestore25.getDoc)(versionDocRef);
|
|
8521
|
+
if (!versionDocSnap.exists()) {
|
|
8522
|
+
return null;
|
|
8523
|
+
}
|
|
8524
|
+
return versionDocSnap.data();
|
|
8525
|
+
}
|
|
8526
|
+
/**
|
|
8527
|
+
* Get all versions of a template
|
|
8528
|
+
* @param templateId - ID of the template
|
|
8529
|
+
* @returns Array of template versions
|
|
8530
|
+
*/
|
|
8531
|
+
async getTemplateOldVersions(templateId) {
|
|
8532
|
+
const versionsCollectionRef = (0, import_firestore25.collection)(
|
|
8533
|
+
this.db,
|
|
8534
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
8535
|
+
);
|
|
8536
|
+
const q = (0, import_firestore25.query)(versionsCollectionRef, (0, import_firestore25.orderBy)("version", "desc"));
|
|
8537
|
+
const querySnapshot = await (0, import_firestore25.getDocs)(q);
|
|
8538
|
+
const versions = [];
|
|
8539
|
+
querySnapshot.forEach((doc33) => {
|
|
8540
|
+
versions.push(doc33.data());
|
|
8541
|
+
});
|
|
8542
|
+
return versions;
|
|
8543
|
+
}
|
|
8481
8544
|
/**
|
|
8482
8545
|
* Delete a document template
|
|
8483
8546
|
* @param templateId - ID of the template to delete
|
package/dist/index.mjs
CHANGED
|
@@ -8414,15 +8414,34 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
8414
8414
|
/**
|
|
8415
8415
|
* Get a document template by ID
|
|
8416
8416
|
* @param templateId - ID of the template to retrieve
|
|
8417
|
+
* @param version - Optional version number to retrieve (defaults to latest version)
|
|
8417
8418
|
* @returns The template or null if not found
|
|
8418
8419
|
*/
|
|
8419
|
-
async getTemplateById(templateId) {
|
|
8420
|
+
async getTemplateById(templateId, version) {
|
|
8420
8421
|
const docRef = doc16(this.collectionRef, templateId);
|
|
8421
8422
|
const docSnap = await getDoc19(docRef);
|
|
8422
8423
|
if (!docSnap.exists()) {
|
|
8423
8424
|
return null;
|
|
8424
8425
|
}
|
|
8425
|
-
|
|
8426
|
+
const currentTemplate = docSnap.data();
|
|
8427
|
+
if (version === void 0) {
|
|
8428
|
+
return currentTemplate;
|
|
8429
|
+
}
|
|
8430
|
+
if (currentTemplate.version === version) {
|
|
8431
|
+
return currentTemplate;
|
|
8432
|
+
}
|
|
8433
|
+
try {
|
|
8434
|
+
const versionTemplate = await this.getTemplateVersion(
|
|
8435
|
+
templateId,
|
|
8436
|
+
version
|
|
8437
|
+
);
|
|
8438
|
+
if (versionTemplate) {
|
|
8439
|
+
return versionTemplate;
|
|
8440
|
+
}
|
|
8441
|
+
} catch (error) {
|
|
8442
|
+
console.error(`Error getting template version ${version}:`, error);
|
|
8443
|
+
}
|
|
8444
|
+
return null;
|
|
8426
8445
|
}
|
|
8427
8446
|
/**
|
|
8428
8447
|
* Update an existing document template
|
|
@@ -8438,6 +8457,15 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
8438
8457
|
if (!template) {
|
|
8439
8458
|
throw new Error(`Template with ID ${templateId} not found`);
|
|
8440
8459
|
}
|
|
8460
|
+
const versionsCollectionRef = collection16(
|
|
8461
|
+
this.db,
|
|
8462
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
8463
|
+
);
|
|
8464
|
+
const versionDocRef = doc16(
|
|
8465
|
+
versionsCollectionRef,
|
|
8466
|
+
template.version.toString()
|
|
8467
|
+
);
|
|
8468
|
+
await setDoc14(versionDocRef, template);
|
|
8441
8469
|
let updatedElements = template.elements;
|
|
8442
8470
|
if (validatedData.elements) {
|
|
8443
8471
|
updatedElements = validatedData.elements.map((element) => ({
|
|
@@ -8466,6 +8494,41 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
8466
8494
|
await updateDoc16(docRef, updatePayload);
|
|
8467
8495
|
return { ...template, ...updatePayload };
|
|
8468
8496
|
}
|
|
8497
|
+
/**
|
|
8498
|
+
* Get a specific version of a template
|
|
8499
|
+
* @param templateId - ID of the template
|
|
8500
|
+
* @param versionNumber - Version number to retrieve
|
|
8501
|
+
* @returns The template version or null if not found
|
|
8502
|
+
*/
|
|
8503
|
+
async getTemplateVersion(templateId, versionNumber) {
|
|
8504
|
+
const versionDocRef = doc16(
|
|
8505
|
+
this.db,
|
|
8506
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions/${versionNumber}`
|
|
8507
|
+
);
|
|
8508
|
+
const versionDocSnap = await getDoc19(versionDocRef);
|
|
8509
|
+
if (!versionDocSnap.exists()) {
|
|
8510
|
+
return null;
|
|
8511
|
+
}
|
|
8512
|
+
return versionDocSnap.data();
|
|
8513
|
+
}
|
|
8514
|
+
/**
|
|
8515
|
+
* Get all versions of a template
|
|
8516
|
+
* @param templateId - ID of the template
|
|
8517
|
+
* @returns Array of template versions
|
|
8518
|
+
*/
|
|
8519
|
+
async getTemplateOldVersions(templateId) {
|
|
8520
|
+
const versionsCollectionRef = collection16(
|
|
8521
|
+
this.db,
|
|
8522
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
8523
|
+
);
|
|
8524
|
+
const q = query16(versionsCollectionRef, orderBy5("version", "desc"));
|
|
8525
|
+
const querySnapshot = await getDocs16(q);
|
|
8526
|
+
const versions = [];
|
|
8527
|
+
querySnapshot.forEach((doc33) => {
|
|
8528
|
+
versions.push(doc33.data());
|
|
8529
|
+
});
|
|
8530
|
+
return versions;
|
|
8531
|
+
}
|
|
8469
8532
|
/**
|
|
8470
8533
|
* Delete a document template
|
|
8471
8534
|
* @param templateId - ID of the template to delete
|
package/package.json
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
USER_FORMS_SUBCOLLECTION,
|
|
45
45
|
DOCTOR_FORMS_SUBCOLLECTION,
|
|
46
46
|
} from "../../types/documentation-templates";
|
|
47
|
+
import { TechnologyDocumentationTemplate } from "../../backoffice/types/technology.types";
|
|
47
48
|
import {
|
|
48
49
|
ClinicInfo,
|
|
49
50
|
PractitionerProfileInfo,
|
|
@@ -539,12 +540,14 @@ export class BookingAdmin {
|
|
|
539
540
|
) {
|
|
540
541
|
pendingUserFormsIds = procedure.documentationTemplates
|
|
541
542
|
.filter(
|
|
542
|
-
(template:
|
|
543
|
+
(template: TechnologyDocumentationTemplate) =>
|
|
543
544
|
template.isUserForm && template.isRequired
|
|
544
545
|
)
|
|
545
|
-
.map(
|
|
546
|
+
.map(
|
|
547
|
+
(template: TechnologyDocumentationTemplate) => template.templateId
|
|
548
|
+
);
|
|
546
549
|
linkedFormIds = procedure.documentationTemplates.map(
|
|
547
|
-
(template:
|
|
550
|
+
(template: TechnologyDocumentationTemplate) => template.templateId
|
|
548
551
|
);
|
|
549
552
|
}
|
|
550
553
|
|
|
@@ -675,11 +678,11 @@ export class BookingAdmin {
|
|
|
675
678
|
procedure.documentationTemplates.length > 0
|
|
676
679
|
) {
|
|
677
680
|
const formInitResult =
|
|
678
|
-
this.documentManagerAdmin.
|
|
681
|
+
await this.documentManagerAdmin.batchInitializeAppointmentFormsFromTechnologyTemplates(
|
|
679
682
|
batch,
|
|
680
683
|
newAppointmentId,
|
|
681
684
|
procedure.id, // Pass the actual procedureId for the forms
|
|
682
|
-
procedure.documentationTemplates
|
|
685
|
+
procedure.documentationTemplates,
|
|
683
686
|
data.patientId,
|
|
684
687
|
procedure.practitionerId,
|
|
685
688
|
procedure.clinicBranchId,
|
|
@@ -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
|
}
|
|
@@ -41,10 +41,14 @@ export class DocumentationTemplateService {
|
|
|
41
41
|
/**
|
|
42
42
|
* Get a document template by ID
|
|
43
43
|
* @param templateId - ID of the template to retrieve
|
|
44
|
+
* @param version - Optional version number to retrieve (defaults to latest version)
|
|
44
45
|
* @returns The template or null if not found
|
|
45
46
|
*/
|
|
46
|
-
async getTemplateById(
|
|
47
|
-
|
|
47
|
+
async getTemplateById(
|
|
48
|
+
templateId: string,
|
|
49
|
+
version?: number
|
|
50
|
+
): Promise<DocumentTemplate | null> {
|
|
51
|
+
return this.apiService.getTemplateById(templateId, version);
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
/**
|
|
@@ -119,4 +123,26 @@ export class DocumentationTemplateService {
|
|
|
119
123
|
}> {
|
|
120
124
|
return this.apiService.getTemplatesByCreator(userId, pageSize, lastDoc);
|
|
121
125
|
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get a specific version of a template
|
|
129
|
+
* @param templateId - ID of the template
|
|
130
|
+
* @param versionNumber - Version number to retrieve
|
|
131
|
+
* @returns The template version or null if not found
|
|
132
|
+
*/
|
|
133
|
+
async getTemplateVersion(
|
|
134
|
+
templateId: string,
|
|
135
|
+
versionNumber: number
|
|
136
|
+
): Promise<DocumentTemplate | null> {
|
|
137
|
+
return this.apiService.getTemplateVersion(templateId, versionNumber);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get all versions of a template
|
|
142
|
+
* @param templateId - ID of the template
|
|
143
|
+
* @returns Array of template versions
|
|
144
|
+
*/
|
|
145
|
+
async getTemplateVersions(templateId: string): Promise<DocumentTemplate[]> {
|
|
146
|
+
return this.apiService.getTemplateOldVersions(templateId);
|
|
147
|
+
}
|
|
122
148
|
}
|
|
@@ -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;
|
|
@@ -88,17 +88,56 @@ export class DocumentationTemplateService extends BaseService {
|
|
|
88
88
|
/**
|
|
89
89
|
* Get a document template by ID
|
|
90
90
|
* @param templateId - ID of the template to retrieve
|
|
91
|
+
* @param version - Optional version number to retrieve (defaults to latest version)
|
|
91
92
|
* @returns The template or null if not found
|
|
92
93
|
*/
|
|
93
|
-
async getTemplateById(
|
|
94
|
+
async getTemplateById(
|
|
95
|
+
templateId: string,
|
|
96
|
+
version?: number
|
|
97
|
+
): Promise<DocumentTemplate | null> {
|
|
98
|
+
// First, check if the template exists at all
|
|
94
99
|
const docRef = doc(this.collectionRef, templateId);
|
|
95
100
|
const docSnap = await getDoc(docRef);
|
|
96
101
|
|
|
97
102
|
if (!docSnap.exists()) {
|
|
98
|
-
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;
|
|
111
|
+
}
|
|
112
|
+
|
|
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);
|
|
99
129
|
}
|
|
100
130
|
|
|
101
|
-
|
|
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;
|
|
102
141
|
}
|
|
103
142
|
|
|
104
143
|
/**
|
|
@@ -121,6 +160,17 @@ export class DocumentationTemplateService extends BaseService {
|
|
|
121
160
|
throw new Error(`Template with ID ${templateId} not found`);
|
|
122
161
|
}
|
|
123
162
|
|
|
163
|
+
// Store the current version in the versions subcollection
|
|
164
|
+
const versionsCollectionRef = collection(
|
|
165
|
+
this.db,
|
|
166
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
167
|
+
);
|
|
168
|
+
const versionDocRef = doc(
|
|
169
|
+
versionsCollectionRef,
|
|
170
|
+
template.version.toString()
|
|
171
|
+
);
|
|
172
|
+
await setDoc(versionDocRef, template);
|
|
173
|
+
|
|
124
174
|
// Process elements if provided
|
|
125
175
|
let updatedElements = template.elements;
|
|
126
176
|
if (validatedData.elements) {
|
|
@@ -158,6 +208,53 @@ export class DocumentationTemplateService extends BaseService {
|
|
|
158
208
|
return { ...template, ...updatePayload } as DocumentTemplate;
|
|
159
209
|
}
|
|
160
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Get a specific version of a template
|
|
213
|
+
* @param templateId - ID of the template
|
|
214
|
+
* @param versionNumber - Version number to retrieve
|
|
215
|
+
* @returns The template version or null if not found
|
|
216
|
+
*/
|
|
217
|
+
async getTemplateVersion(
|
|
218
|
+
templateId: string,
|
|
219
|
+
versionNumber: number
|
|
220
|
+
): Promise<DocumentTemplate | null> {
|
|
221
|
+
const versionDocRef = doc(
|
|
222
|
+
this.db,
|
|
223
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions/${versionNumber}`
|
|
224
|
+
);
|
|
225
|
+
const versionDocSnap = await getDoc(versionDocRef);
|
|
226
|
+
|
|
227
|
+
if (!versionDocSnap.exists()) {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return versionDocSnap.data() as DocumentTemplate;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Get all versions of a template
|
|
236
|
+
* @param templateId - ID of the template
|
|
237
|
+
* @returns Array of template versions
|
|
238
|
+
*/
|
|
239
|
+
async getTemplateOldVersions(
|
|
240
|
+
templateId: string
|
|
241
|
+
): Promise<DocumentTemplate[]> {
|
|
242
|
+
const versionsCollectionRef = collection(
|
|
243
|
+
this.db,
|
|
244
|
+
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
245
|
+
);
|
|
246
|
+
const q = query(versionsCollectionRef, orderBy("version", "desc"));
|
|
247
|
+
|
|
248
|
+
const querySnapshot = await getDocs(q);
|
|
249
|
+
const versions: DocumentTemplate[] = [];
|
|
250
|
+
|
|
251
|
+
querySnapshot.forEach((doc) => {
|
|
252
|
+
versions.push(doc.data() as DocumentTemplate);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
return versions;
|
|
256
|
+
}
|
|
257
|
+
|
|
161
258
|
/**
|
|
162
259
|
* Delete a document template
|
|
163
260
|
* @param templateId - ID of the template to delete
|
|
@@ -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 */
|