@blackcode_sa/metaestetics-api 1.14.51 → 1.14.52
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/index.js +176 -11
- package/dist/index.mjs +176 -11
- package/package.json +1 -1
- package/src/services/appointment/utils/form-initialization.utils.ts +267 -12
package/dist/index.js
CHANGED
|
@@ -4957,6 +4957,45 @@ var import_firestore10 = require("firebase/firestore");
|
|
|
4957
4957
|
|
|
4958
4958
|
// src/services/appointment/utils/form-initialization.utils.ts
|
|
4959
4959
|
var import_firestore9 = require("firebase/firestore");
|
|
4960
|
+
function isProcedureSpecificForm(template) {
|
|
4961
|
+
const tags = template.tags || [];
|
|
4962
|
+
const titleLower = template.title.toLowerCase();
|
|
4963
|
+
if (tags.includes("procedure-specific")) {
|
|
4964
|
+
return true;
|
|
4965
|
+
}
|
|
4966
|
+
if (tags.includes("shared")) {
|
|
4967
|
+
return false;
|
|
4968
|
+
}
|
|
4969
|
+
if (tags.some((tag) => {
|
|
4970
|
+
const tagLower = tag.toLowerCase();
|
|
4971
|
+
return tagLower.includes("consent") || tagLower === "consent-form";
|
|
4972
|
+
})) {
|
|
4973
|
+
return true;
|
|
4974
|
+
}
|
|
4975
|
+
if (titleLower.includes("consent")) {
|
|
4976
|
+
return true;
|
|
4977
|
+
}
|
|
4978
|
+
return false;
|
|
4979
|
+
}
|
|
4980
|
+
async function findExistingFormByTemplate(db, appointmentId, templateId, isUserForm) {
|
|
4981
|
+
const formSubcollection = isUserForm ? USER_FORMS_SUBCOLLECTION : DOCTOR_FORMS_SUBCOLLECTION;
|
|
4982
|
+
const appointmentRef = (0, import_firestore9.doc)(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
4983
|
+
const formsCollectionRef = (0, import_firestore9.collection)(appointmentRef, formSubcollection);
|
|
4984
|
+
const q = (0, import_firestore9.query)(
|
|
4985
|
+
formsCollectionRef,
|
|
4986
|
+
(0, import_firestore9.where)("templateId", "==", templateId)
|
|
4987
|
+
);
|
|
4988
|
+
const querySnapshot = await (0, import_firestore9.getDocs)(q);
|
|
4989
|
+
if (querySnapshot.empty) {
|
|
4990
|
+
return null;
|
|
4991
|
+
}
|
|
4992
|
+
const docSnap = querySnapshot.docs[0];
|
|
4993
|
+
const data = docSnap.data();
|
|
4994
|
+
if (!data.id) {
|
|
4995
|
+
data.id = docSnap.id;
|
|
4996
|
+
}
|
|
4997
|
+
return data;
|
|
4998
|
+
}
|
|
4960
4999
|
async function initializeFormsForExtendedProcedure(db, appointmentId, procedureId, technologyTemplates, patientId, practitionerId, clinicId) {
|
|
4961
5000
|
const initializedFormsInfo = [];
|
|
4962
5001
|
const pendingUserFormsIds = [];
|
|
@@ -4999,6 +5038,49 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
4999
5038
|
const isRequired = templateRef.isRequired;
|
|
5000
5039
|
const isUserForm = templateRef.isUserForm || false;
|
|
5001
5040
|
const formSubcollectionPath = isUserForm ? USER_FORMS_SUBCOLLECTION : DOCTOR_FORMS_SUBCOLLECTION;
|
|
5041
|
+
const isProcedureSpecific = isProcedureSpecificForm(template);
|
|
5042
|
+
let existingForm = null;
|
|
5043
|
+
if (!isProcedureSpecific) {
|
|
5044
|
+
try {
|
|
5045
|
+
existingForm = await findExistingFormByTemplate(
|
|
5046
|
+
db,
|
|
5047
|
+
appointmentId,
|
|
5048
|
+
templateRef.templateId,
|
|
5049
|
+
isUserForm
|
|
5050
|
+
);
|
|
5051
|
+
if (existingForm) {
|
|
5052
|
+
console.log(
|
|
5053
|
+
`[FormInit] Found existing shared form ${existingForm.id} (template: ${template.id}) for appointment ${appointmentId}. Reusing instead of creating duplicate.`
|
|
5054
|
+
);
|
|
5055
|
+
const linkedForm = {
|
|
5056
|
+
formId: existingForm.id,
|
|
5057
|
+
templateId: template.id,
|
|
5058
|
+
templateVersion: template.version,
|
|
5059
|
+
title: template.title,
|
|
5060
|
+
isUserForm,
|
|
5061
|
+
isRequired,
|
|
5062
|
+
sortingOrder: templateRef.sortingOrder,
|
|
5063
|
+
status: existingForm.status || "pending" /* PENDING */,
|
|
5064
|
+
path: `${APPOINTMENTS_COLLECTION}/${appointmentId}/${formSubcollectionPath}/${existingForm.id}`
|
|
5065
|
+
};
|
|
5066
|
+
initializedFormsInfo.push(linkedForm);
|
|
5067
|
+
if (!allLinkedFormIds.includes(existingForm.id)) {
|
|
5068
|
+
allLinkedFormIds.push(existingForm.id);
|
|
5069
|
+
}
|
|
5070
|
+
if (isUserForm && isRequired && existingForm.status === "pending" /* PENDING */) {
|
|
5071
|
+
if (!pendingUserFormsIds.includes(existingForm.id)) {
|
|
5072
|
+
pendingUserFormsIds.push(existingForm.id);
|
|
5073
|
+
}
|
|
5074
|
+
}
|
|
5075
|
+
continue;
|
|
5076
|
+
}
|
|
5077
|
+
} catch (error) {
|
|
5078
|
+
console.warn(
|
|
5079
|
+
`[FormInit] Error checking for existing form (template: ${templateRef.templateId}):`,
|
|
5080
|
+
error
|
|
5081
|
+
);
|
|
5082
|
+
}
|
|
5083
|
+
}
|
|
5002
5084
|
const appointmentRef = (0, import_firestore9.doc)(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
5003
5085
|
const formsCollectionRef = (0, import_firestore9.collection)(appointmentRef, formSubcollectionPath);
|
|
5004
5086
|
const filledDocumentData = {
|
|
@@ -5036,8 +5118,9 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
5036
5118
|
path: docRef.path
|
|
5037
5119
|
};
|
|
5038
5120
|
initializedFormsInfo.push(linkedForm);
|
|
5121
|
+
const formType = isProcedureSpecific ? "procedure-specific" : "general/shared";
|
|
5039
5122
|
console.log(
|
|
5040
|
-
`[FormInit] Created FilledDocument ${filledDocumentId} (template: ${template.id}, isUserForm: ${isUserForm}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
5123
|
+
`[FormInit] Created ${formType} FilledDocument ${filledDocumentId} (template: ${template.id}, isUserForm: ${isUserForm}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
5041
5124
|
);
|
|
5042
5125
|
} catch (error) {
|
|
5043
5126
|
console.error(
|
|
@@ -5049,8 +5132,28 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
5049
5132
|
return { initializedFormsInfo, pendingUserFormsIds, allLinkedFormIds };
|
|
5050
5133
|
}
|
|
5051
5134
|
async function removeFormsForExtendedProcedure(db, appointmentId, procedureId) {
|
|
5135
|
+
var _a, _b;
|
|
5052
5136
|
const removedFormIds = [];
|
|
5053
5137
|
const appointmentRef = (0, import_firestore9.doc)(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
5138
|
+
const appointmentSnap = await (0, import_firestore9.getDoc)(appointmentRef);
|
|
5139
|
+
if (!appointmentSnap.exists()) {
|
|
5140
|
+
console.warn(
|
|
5141
|
+
`[FormInit] Appointment ${appointmentId} not found when removing forms for procedure ${procedureId}.`
|
|
5142
|
+
);
|
|
5143
|
+
return removedFormIds;
|
|
5144
|
+
}
|
|
5145
|
+
const appointment = appointmentSnap.data();
|
|
5146
|
+
const linkedForms = appointment.linkedForms || [];
|
|
5147
|
+
const mainProcedureId = appointment.procedureId;
|
|
5148
|
+
const extendedProcedureIds = ((_b = (_a = appointment.metadata) == null ? void 0 : _a.extendedProcedures) == null ? void 0 : _b.map(
|
|
5149
|
+
(ep) => ep.procedureId
|
|
5150
|
+
)) || [];
|
|
5151
|
+
const allProcedureIds = [mainProcedureId, ...extendedProcedureIds].filter(Boolean);
|
|
5152
|
+
const remainingProcedureIds = allProcedureIds.filter((id) => id !== procedureId);
|
|
5153
|
+
const isFormSharedAndReferenced = (formId) => {
|
|
5154
|
+
const formEntries = linkedForms.filter((form) => form.formId === formId);
|
|
5155
|
+
return formEntries.length > 1;
|
|
5156
|
+
};
|
|
5054
5157
|
const doctorFormsRef = (0, import_firestore9.collection)(appointmentRef, DOCTOR_FORMS_SUBCOLLECTION);
|
|
5055
5158
|
const doctorFormsQuery = (0, import_firestore9.query)(
|
|
5056
5159
|
doctorFormsRef,
|
|
@@ -5059,11 +5162,42 @@ async function removeFormsForExtendedProcedure(db, appointmentId, procedureId) {
|
|
|
5059
5162
|
const doctorFormsSnap = await (0, import_firestore9.getDocs)(doctorFormsQuery);
|
|
5060
5163
|
for (const formDoc of doctorFormsSnap.docs) {
|
|
5061
5164
|
try {
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5165
|
+
const formData = formDoc.data();
|
|
5166
|
+
let isShared = false;
|
|
5167
|
+
if (formData.templateId) {
|
|
5168
|
+
try {
|
|
5169
|
+
const templateDoc = (0, import_firestore9.doc)(db, DOCUMENTATION_TEMPLATES_COLLECTION, formData.templateId);
|
|
5170
|
+
const templateSnap = await (0, import_firestore9.getDoc)(templateDoc);
|
|
5171
|
+
if (templateSnap.exists()) {
|
|
5172
|
+
const template = templateSnap.data();
|
|
5173
|
+
isShared = !isProcedureSpecificForm(template);
|
|
5174
|
+
}
|
|
5175
|
+
} catch (error) {
|
|
5176
|
+
console.warn(
|
|
5177
|
+
`[FormInit] Could not check template for form ${formDoc.id}, assuming procedure-specific:`,
|
|
5178
|
+
error
|
|
5179
|
+
);
|
|
5180
|
+
}
|
|
5181
|
+
}
|
|
5182
|
+
if (!isShared) {
|
|
5183
|
+
await (0, import_firestore9.deleteDoc)(formDoc.ref);
|
|
5184
|
+
removedFormIds.push(formDoc.id);
|
|
5185
|
+
console.log(
|
|
5186
|
+
`[FormInit] Removed procedure-specific doctor form ${formDoc.id} for extended procedure ${procedureId} from appointment ${appointmentId}.`
|
|
5187
|
+
);
|
|
5188
|
+
} else {
|
|
5189
|
+
if (isFormSharedAndReferenced(formDoc.id)) {
|
|
5190
|
+
console.log(
|
|
5191
|
+
`[FormInit] Skipped deletion of shared doctor form ${formDoc.id} - still referenced by other procedures.`
|
|
5192
|
+
);
|
|
5193
|
+
} else {
|
|
5194
|
+
await (0, import_firestore9.deleteDoc)(formDoc.ref);
|
|
5195
|
+
removedFormIds.push(formDoc.id);
|
|
5196
|
+
console.log(
|
|
5197
|
+
`[FormInit] Removed shared doctor form ${formDoc.id} - no longer referenced by other procedures.`
|
|
5198
|
+
);
|
|
5199
|
+
}
|
|
5200
|
+
}
|
|
5067
5201
|
} catch (error) {
|
|
5068
5202
|
console.error(
|
|
5069
5203
|
`[FormInit] Error removing doctor form ${formDoc.id}:`,
|
|
@@ -5079,11 +5213,42 @@ async function removeFormsForExtendedProcedure(db, appointmentId, procedureId) {
|
|
|
5079
5213
|
const userFormsSnap = await (0, import_firestore9.getDocs)(userFormsQuery);
|
|
5080
5214
|
for (const formDoc of userFormsSnap.docs) {
|
|
5081
5215
|
try {
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5216
|
+
const formData = formDoc.data();
|
|
5217
|
+
let isShared = false;
|
|
5218
|
+
if (formData.templateId) {
|
|
5219
|
+
try {
|
|
5220
|
+
const templateDoc = (0, import_firestore9.doc)(db, DOCUMENTATION_TEMPLATES_COLLECTION, formData.templateId);
|
|
5221
|
+
const templateSnap = await (0, import_firestore9.getDoc)(templateDoc);
|
|
5222
|
+
if (templateSnap.exists()) {
|
|
5223
|
+
const template = templateSnap.data();
|
|
5224
|
+
isShared = !isProcedureSpecificForm(template);
|
|
5225
|
+
}
|
|
5226
|
+
} catch (error) {
|
|
5227
|
+
console.warn(
|
|
5228
|
+
`[FormInit] Could not check template for form ${formDoc.id}, assuming procedure-specific:`,
|
|
5229
|
+
error
|
|
5230
|
+
);
|
|
5231
|
+
}
|
|
5232
|
+
}
|
|
5233
|
+
if (!isShared) {
|
|
5234
|
+
await (0, import_firestore9.deleteDoc)(formDoc.ref);
|
|
5235
|
+
removedFormIds.push(formDoc.id);
|
|
5236
|
+
console.log(
|
|
5237
|
+
`[FormInit] Removed procedure-specific user form ${formDoc.id} for extended procedure ${procedureId} from appointment ${appointmentId}.`
|
|
5238
|
+
);
|
|
5239
|
+
} else {
|
|
5240
|
+
if (isFormSharedAndReferenced(formDoc.id)) {
|
|
5241
|
+
console.log(
|
|
5242
|
+
`[FormInit] Skipped deletion of shared user form ${formDoc.id} - still referenced by other procedures.`
|
|
5243
|
+
);
|
|
5244
|
+
} else {
|
|
5245
|
+
await (0, import_firestore9.deleteDoc)(formDoc.ref);
|
|
5246
|
+
removedFormIds.push(formDoc.id);
|
|
5247
|
+
console.log(
|
|
5248
|
+
`[FormInit] Removed shared user form ${formDoc.id} - no longer referenced by other procedures.`
|
|
5249
|
+
);
|
|
5250
|
+
}
|
|
5251
|
+
}
|
|
5087
5252
|
} catch (error) {
|
|
5088
5253
|
console.error(
|
|
5089
5254
|
`[FormInit] Error removing user form ${formDoc.id}:`,
|
package/dist/index.mjs
CHANGED
|
@@ -4843,6 +4843,45 @@ import { updateDoc as updateDoc5, serverTimestamp as serverTimestamp4, doc as do
|
|
|
4843
4843
|
|
|
4844
4844
|
// src/services/appointment/utils/form-initialization.utils.ts
|
|
4845
4845
|
import { collection as collection5, doc as doc6, addDoc, deleteDoc as deleteDoc2, getDocs as getDocs5, query as query5, where as where5, serverTimestamp as serverTimestamp3, getDoc as getDoc6, updateDoc as updateDoc4 } from "firebase/firestore";
|
|
4846
|
+
function isProcedureSpecificForm(template) {
|
|
4847
|
+
const tags = template.tags || [];
|
|
4848
|
+
const titleLower = template.title.toLowerCase();
|
|
4849
|
+
if (tags.includes("procedure-specific")) {
|
|
4850
|
+
return true;
|
|
4851
|
+
}
|
|
4852
|
+
if (tags.includes("shared")) {
|
|
4853
|
+
return false;
|
|
4854
|
+
}
|
|
4855
|
+
if (tags.some((tag) => {
|
|
4856
|
+
const tagLower = tag.toLowerCase();
|
|
4857
|
+
return tagLower.includes("consent") || tagLower === "consent-form";
|
|
4858
|
+
})) {
|
|
4859
|
+
return true;
|
|
4860
|
+
}
|
|
4861
|
+
if (titleLower.includes("consent")) {
|
|
4862
|
+
return true;
|
|
4863
|
+
}
|
|
4864
|
+
return false;
|
|
4865
|
+
}
|
|
4866
|
+
async function findExistingFormByTemplate(db, appointmentId, templateId, isUserForm) {
|
|
4867
|
+
const formSubcollection = isUserForm ? USER_FORMS_SUBCOLLECTION : DOCTOR_FORMS_SUBCOLLECTION;
|
|
4868
|
+
const appointmentRef = doc6(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
4869
|
+
const formsCollectionRef = collection5(appointmentRef, formSubcollection);
|
|
4870
|
+
const q = query5(
|
|
4871
|
+
formsCollectionRef,
|
|
4872
|
+
where5("templateId", "==", templateId)
|
|
4873
|
+
);
|
|
4874
|
+
const querySnapshot = await getDocs5(q);
|
|
4875
|
+
if (querySnapshot.empty) {
|
|
4876
|
+
return null;
|
|
4877
|
+
}
|
|
4878
|
+
const docSnap = querySnapshot.docs[0];
|
|
4879
|
+
const data = docSnap.data();
|
|
4880
|
+
if (!data.id) {
|
|
4881
|
+
data.id = docSnap.id;
|
|
4882
|
+
}
|
|
4883
|
+
return data;
|
|
4884
|
+
}
|
|
4846
4885
|
async function initializeFormsForExtendedProcedure(db, appointmentId, procedureId, technologyTemplates, patientId, practitionerId, clinicId) {
|
|
4847
4886
|
const initializedFormsInfo = [];
|
|
4848
4887
|
const pendingUserFormsIds = [];
|
|
@@ -4885,6 +4924,49 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
4885
4924
|
const isRequired = templateRef.isRequired;
|
|
4886
4925
|
const isUserForm = templateRef.isUserForm || false;
|
|
4887
4926
|
const formSubcollectionPath = isUserForm ? USER_FORMS_SUBCOLLECTION : DOCTOR_FORMS_SUBCOLLECTION;
|
|
4927
|
+
const isProcedureSpecific = isProcedureSpecificForm(template);
|
|
4928
|
+
let existingForm = null;
|
|
4929
|
+
if (!isProcedureSpecific) {
|
|
4930
|
+
try {
|
|
4931
|
+
existingForm = await findExistingFormByTemplate(
|
|
4932
|
+
db,
|
|
4933
|
+
appointmentId,
|
|
4934
|
+
templateRef.templateId,
|
|
4935
|
+
isUserForm
|
|
4936
|
+
);
|
|
4937
|
+
if (existingForm) {
|
|
4938
|
+
console.log(
|
|
4939
|
+
`[FormInit] Found existing shared form ${existingForm.id} (template: ${template.id}) for appointment ${appointmentId}. Reusing instead of creating duplicate.`
|
|
4940
|
+
);
|
|
4941
|
+
const linkedForm = {
|
|
4942
|
+
formId: existingForm.id,
|
|
4943
|
+
templateId: template.id,
|
|
4944
|
+
templateVersion: template.version,
|
|
4945
|
+
title: template.title,
|
|
4946
|
+
isUserForm,
|
|
4947
|
+
isRequired,
|
|
4948
|
+
sortingOrder: templateRef.sortingOrder,
|
|
4949
|
+
status: existingForm.status || "pending" /* PENDING */,
|
|
4950
|
+
path: `${APPOINTMENTS_COLLECTION}/${appointmentId}/${formSubcollectionPath}/${existingForm.id}`
|
|
4951
|
+
};
|
|
4952
|
+
initializedFormsInfo.push(linkedForm);
|
|
4953
|
+
if (!allLinkedFormIds.includes(existingForm.id)) {
|
|
4954
|
+
allLinkedFormIds.push(existingForm.id);
|
|
4955
|
+
}
|
|
4956
|
+
if (isUserForm && isRequired && existingForm.status === "pending" /* PENDING */) {
|
|
4957
|
+
if (!pendingUserFormsIds.includes(existingForm.id)) {
|
|
4958
|
+
pendingUserFormsIds.push(existingForm.id);
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4961
|
+
continue;
|
|
4962
|
+
}
|
|
4963
|
+
} catch (error) {
|
|
4964
|
+
console.warn(
|
|
4965
|
+
`[FormInit] Error checking for existing form (template: ${templateRef.templateId}):`,
|
|
4966
|
+
error
|
|
4967
|
+
);
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4888
4970
|
const appointmentRef = doc6(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
4889
4971
|
const formsCollectionRef = collection5(appointmentRef, formSubcollectionPath);
|
|
4890
4972
|
const filledDocumentData = {
|
|
@@ -4922,8 +5004,9 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
4922
5004
|
path: docRef.path
|
|
4923
5005
|
};
|
|
4924
5006
|
initializedFormsInfo.push(linkedForm);
|
|
5007
|
+
const formType = isProcedureSpecific ? "procedure-specific" : "general/shared";
|
|
4925
5008
|
console.log(
|
|
4926
|
-
`[FormInit] Created FilledDocument ${filledDocumentId} (template: ${template.id}, isUserForm: ${isUserForm}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
5009
|
+
`[FormInit] Created ${formType} FilledDocument ${filledDocumentId} (template: ${template.id}, isUserForm: ${isUserForm}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
4927
5010
|
);
|
|
4928
5011
|
} catch (error) {
|
|
4929
5012
|
console.error(
|
|
@@ -4935,8 +5018,28 @@ async function initializeFormsForExtendedProcedure(db, appointmentId, procedureI
|
|
|
4935
5018
|
return { initializedFormsInfo, pendingUserFormsIds, allLinkedFormIds };
|
|
4936
5019
|
}
|
|
4937
5020
|
async function removeFormsForExtendedProcedure(db, appointmentId, procedureId) {
|
|
5021
|
+
var _a, _b;
|
|
4938
5022
|
const removedFormIds = [];
|
|
4939
5023
|
const appointmentRef = doc6(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
5024
|
+
const appointmentSnap = await getDoc6(appointmentRef);
|
|
5025
|
+
if (!appointmentSnap.exists()) {
|
|
5026
|
+
console.warn(
|
|
5027
|
+
`[FormInit] Appointment ${appointmentId} not found when removing forms for procedure ${procedureId}.`
|
|
5028
|
+
);
|
|
5029
|
+
return removedFormIds;
|
|
5030
|
+
}
|
|
5031
|
+
const appointment = appointmentSnap.data();
|
|
5032
|
+
const linkedForms = appointment.linkedForms || [];
|
|
5033
|
+
const mainProcedureId = appointment.procedureId;
|
|
5034
|
+
const extendedProcedureIds = ((_b = (_a = appointment.metadata) == null ? void 0 : _a.extendedProcedures) == null ? void 0 : _b.map(
|
|
5035
|
+
(ep) => ep.procedureId
|
|
5036
|
+
)) || [];
|
|
5037
|
+
const allProcedureIds = [mainProcedureId, ...extendedProcedureIds].filter(Boolean);
|
|
5038
|
+
const remainingProcedureIds = allProcedureIds.filter((id) => id !== procedureId);
|
|
5039
|
+
const isFormSharedAndReferenced = (formId) => {
|
|
5040
|
+
const formEntries = linkedForms.filter((form) => form.formId === formId);
|
|
5041
|
+
return formEntries.length > 1;
|
|
5042
|
+
};
|
|
4940
5043
|
const doctorFormsRef = collection5(appointmentRef, DOCTOR_FORMS_SUBCOLLECTION);
|
|
4941
5044
|
const doctorFormsQuery = query5(
|
|
4942
5045
|
doctorFormsRef,
|
|
@@ -4945,11 +5048,42 @@ async function removeFormsForExtendedProcedure(db, appointmentId, procedureId) {
|
|
|
4945
5048
|
const doctorFormsSnap = await getDocs5(doctorFormsQuery);
|
|
4946
5049
|
for (const formDoc of doctorFormsSnap.docs) {
|
|
4947
5050
|
try {
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
5051
|
+
const formData = formDoc.data();
|
|
5052
|
+
let isShared = false;
|
|
5053
|
+
if (formData.templateId) {
|
|
5054
|
+
try {
|
|
5055
|
+
const templateDoc = doc6(db, DOCUMENTATION_TEMPLATES_COLLECTION, formData.templateId);
|
|
5056
|
+
const templateSnap = await getDoc6(templateDoc);
|
|
5057
|
+
if (templateSnap.exists()) {
|
|
5058
|
+
const template = templateSnap.data();
|
|
5059
|
+
isShared = !isProcedureSpecificForm(template);
|
|
5060
|
+
}
|
|
5061
|
+
} catch (error) {
|
|
5062
|
+
console.warn(
|
|
5063
|
+
`[FormInit] Could not check template for form ${formDoc.id}, assuming procedure-specific:`,
|
|
5064
|
+
error
|
|
5065
|
+
);
|
|
5066
|
+
}
|
|
5067
|
+
}
|
|
5068
|
+
if (!isShared) {
|
|
5069
|
+
await deleteDoc2(formDoc.ref);
|
|
5070
|
+
removedFormIds.push(formDoc.id);
|
|
5071
|
+
console.log(
|
|
5072
|
+
`[FormInit] Removed procedure-specific doctor form ${formDoc.id} for extended procedure ${procedureId} from appointment ${appointmentId}.`
|
|
5073
|
+
);
|
|
5074
|
+
} else {
|
|
5075
|
+
if (isFormSharedAndReferenced(formDoc.id)) {
|
|
5076
|
+
console.log(
|
|
5077
|
+
`[FormInit] Skipped deletion of shared doctor form ${formDoc.id} - still referenced by other procedures.`
|
|
5078
|
+
);
|
|
5079
|
+
} else {
|
|
5080
|
+
await deleteDoc2(formDoc.ref);
|
|
5081
|
+
removedFormIds.push(formDoc.id);
|
|
5082
|
+
console.log(
|
|
5083
|
+
`[FormInit] Removed shared doctor form ${formDoc.id} - no longer referenced by other procedures.`
|
|
5084
|
+
);
|
|
5085
|
+
}
|
|
5086
|
+
}
|
|
4953
5087
|
} catch (error) {
|
|
4954
5088
|
console.error(
|
|
4955
5089
|
`[FormInit] Error removing doctor form ${formDoc.id}:`,
|
|
@@ -4965,11 +5099,42 @@ async function removeFormsForExtendedProcedure(db, appointmentId, procedureId) {
|
|
|
4965
5099
|
const userFormsSnap = await getDocs5(userFormsQuery);
|
|
4966
5100
|
for (const formDoc of userFormsSnap.docs) {
|
|
4967
5101
|
try {
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
5102
|
+
const formData = formDoc.data();
|
|
5103
|
+
let isShared = false;
|
|
5104
|
+
if (formData.templateId) {
|
|
5105
|
+
try {
|
|
5106
|
+
const templateDoc = doc6(db, DOCUMENTATION_TEMPLATES_COLLECTION, formData.templateId);
|
|
5107
|
+
const templateSnap = await getDoc6(templateDoc);
|
|
5108
|
+
if (templateSnap.exists()) {
|
|
5109
|
+
const template = templateSnap.data();
|
|
5110
|
+
isShared = !isProcedureSpecificForm(template);
|
|
5111
|
+
}
|
|
5112
|
+
} catch (error) {
|
|
5113
|
+
console.warn(
|
|
5114
|
+
`[FormInit] Could not check template for form ${formDoc.id}, assuming procedure-specific:`,
|
|
5115
|
+
error
|
|
5116
|
+
);
|
|
5117
|
+
}
|
|
5118
|
+
}
|
|
5119
|
+
if (!isShared) {
|
|
5120
|
+
await deleteDoc2(formDoc.ref);
|
|
5121
|
+
removedFormIds.push(formDoc.id);
|
|
5122
|
+
console.log(
|
|
5123
|
+
`[FormInit] Removed procedure-specific user form ${formDoc.id} for extended procedure ${procedureId} from appointment ${appointmentId}.`
|
|
5124
|
+
);
|
|
5125
|
+
} else {
|
|
5126
|
+
if (isFormSharedAndReferenced(formDoc.id)) {
|
|
5127
|
+
console.log(
|
|
5128
|
+
`[FormInit] Skipped deletion of shared user form ${formDoc.id} - still referenced by other procedures.`
|
|
5129
|
+
);
|
|
5130
|
+
} else {
|
|
5131
|
+
await deleteDoc2(formDoc.ref);
|
|
5132
|
+
removedFormIds.push(formDoc.id);
|
|
5133
|
+
console.log(
|
|
5134
|
+
`[FormInit] Removed shared user form ${formDoc.id} - no longer referenced by other procedures.`
|
|
5135
|
+
);
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
4973
5138
|
} catch (error) {
|
|
4974
5139
|
console.error(
|
|
4975
5140
|
`[FormInit] Error removing user form ${formDoc.id}:`,
|
package/package.json
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
DOCTOR_FORMS_SUBCOLLECTION,
|
|
6
6
|
USER_FORMS_SUBCOLLECTION,
|
|
7
7
|
DOCUMENTATION_TEMPLATES_COLLECTION,
|
|
8
|
+
FilledDocument,
|
|
8
9
|
} from '../../../types/documentation-templates';
|
|
9
10
|
import {
|
|
10
11
|
APPOINTMENTS_COLLECTION,
|
|
@@ -18,6 +19,95 @@ export interface InitializeExtendedProcedureFormsResult {
|
|
|
18
19
|
allLinkedFormIds: string[];
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Determines if a form template is procedure-specific or general/shared
|
|
24
|
+
* Uses explicit tags first, then falls back to heuristics
|
|
25
|
+
*
|
|
26
|
+
* Priority order:
|
|
27
|
+
* 1. "procedure-specific" tag → always procedure-specific
|
|
28
|
+
* 2. "shared" tag → always shared
|
|
29
|
+
* 3. Consent-related tags ("consent", "consent-form") → procedure-specific
|
|
30
|
+
* 4. Title contains "consent" → procedure-specific
|
|
31
|
+
* 5. Default → shared (general forms)
|
|
32
|
+
*
|
|
33
|
+
* @param template DocumentTemplate to check
|
|
34
|
+
* @returns true if procedure-specific, false if general/shared
|
|
35
|
+
*/
|
|
36
|
+
function isProcedureSpecificForm(template: DocumentTemplate): boolean {
|
|
37
|
+
const tags = template.tags || [];
|
|
38
|
+
const titleLower = template.title.toLowerCase();
|
|
39
|
+
|
|
40
|
+
// Priority 1: Explicit "procedure-specific" tag → always procedure-specific
|
|
41
|
+
if (tags.includes('procedure-specific')) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Priority 2: Explicit "shared" tag → always shared
|
|
46
|
+
if (tags.includes('shared')) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Priority 3: Consent-related tags → procedure-specific
|
|
51
|
+
if (tags.some(tag => {
|
|
52
|
+
const tagLower = tag.toLowerCase();
|
|
53
|
+
return tagLower.includes('consent') || tagLower === 'consent-form';
|
|
54
|
+
})) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Priority 4: Check title for "consent" → procedure-specific
|
|
59
|
+
if (titleLower.includes('consent')) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Priority 5: Default → shared (general forms)
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Checks if a form with the given templateId already exists in the appointment
|
|
69
|
+
* @param db Firestore instance
|
|
70
|
+
* @param appointmentId Appointment ID
|
|
71
|
+
* @param templateId Template ID to check
|
|
72
|
+
* @param isUserForm Whether to check user-forms or doctor-forms subcollection
|
|
73
|
+
* @returns Existing FilledDocument or null if not found
|
|
74
|
+
*/
|
|
75
|
+
async function findExistingFormByTemplate(
|
|
76
|
+
db: Firestore,
|
|
77
|
+
appointmentId: string,
|
|
78
|
+
templateId: string,
|
|
79
|
+
isUserForm: boolean
|
|
80
|
+
): Promise<FilledDocument | null> {
|
|
81
|
+
const formSubcollection = isUserForm
|
|
82
|
+
? USER_FORMS_SUBCOLLECTION
|
|
83
|
+
: DOCTOR_FORMS_SUBCOLLECTION;
|
|
84
|
+
|
|
85
|
+
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
86
|
+
const formsCollectionRef = collection(appointmentRef, formSubcollection);
|
|
87
|
+
|
|
88
|
+
const q = query(
|
|
89
|
+
formsCollectionRef,
|
|
90
|
+
where('templateId', '==', templateId)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const querySnapshot = await getDocs(q);
|
|
94
|
+
|
|
95
|
+
if (querySnapshot.empty) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Return the first matching form (should only be one for general forms)
|
|
100
|
+
const docSnap = querySnapshot.docs[0];
|
|
101
|
+
const data = docSnap.data() as FilledDocument;
|
|
102
|
+
|
|
103
|
+
// Ensure id is populated from Firestore document ID if not in data
|
|
104
|
+
if (!data.id) {
|
|
105
|
+
data.id = docSnap.id;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return data;
|
|
109
|
+
}
|
|
110
|
+
|
|
21
111
|
/**
|
|
22
112
|
* Initializes forms for an extended procedure using client-side Firestore
|
|
23
113
|
* Similar to DocumentManagerAdminService but for client-side usage
|
|
@@ -94,7 +184,67 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
94
184
|
? USER_FORMS_SUBCOLLECTION
|
|
95
185
|
: DOCTOR_FORMS_SUBCOLLECTION;
|
|
96
186
|
|
|
97
|
-
//
|
|
187
|
+
// Check if form is procedure-specific or general/shared
|
|
188
|
+
const isProcedureSpecific = isProcedureSpecificForm(template);
|
|
189
|
+
|
|
190
|
+
// For general/shared forms, check if form already exists in appointment
|
|
191
|
+
let existingForm: FilledDocument | null = null;
|
|
192
|
+
if (!isProcedureSpecific) {
|
|
193
|
+
try {
|
|
194
|
+
existingForm = await findExistingFormByTemplate(
|
|
195
|
+
db,
|
|
196
|
+
appointmentId,
|
|
197
|
+
templateRef.templateId,
|
|
198
|
+
isUserForm
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
if (existingForm) {
|
|
202
|
+
console.log(
|
|
203
|
+
`[FormInit] Found existing shared form ${existingForm.id} (template: ${template.id}) for appointment ${appointmentId}. Reusing instead of creating duplicate.`
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
// Reuse existing form - add to linkedForms but don't create new document
|
|
207
|
+
// Note: We still add it to allLinkedFormIds to ensure it's tracked,
|
|
208
|
+
// but we don't add it again if it's already in the appointment's linkedForms
|
|
209
|
+
// (This will be handled by the caller merging the arrays)
|
|
210
|
+
|
|
211
|
+
const linkedForm: LinkedFormInfo = {
|
|
212
|
+
formId: existingForm.id,
|
|
213
|
+
templateId: template.id,
|
|
214
|
+
templateVersion: template.version,
|
|
215
|
+
title: template.title,
|
|
216
|
+
isUserForm: isUserForm,
|
|
217
|
+
isRequired: isRequired,
|
|
218
|
+
sortingOrder: templateRef.sortingOrder,
|
|
219
|
+
status: existingForm.status || FilledDocumentStatus.PENDING,
|
|
220
|
+
path: `${APPOINTMENTS_COLLECTION}/${appointmentId}/${formSubcollectionPath}/${existingForm.id}`,
|
|
221
|
+
};
|
|
222
|
+
initializedFormsInfo.push(linkedForm);
|
|
223
|
+
|
|
224
|
+
// Add to allLinkedFormIds if not already present (to avoid duplicates)
|
|
225
|
+
if (!allLinkedFormIds.includes(existingForm.id)) {
|
|
226
|
+
allLinkedFormIds.push(existingForm.id);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Add to pendingUserFormsIds if it's a required user form and not already completed
|
|
230
|
+
if (isUserForm && isRequired && existingForm.status === FilledDocumentStatus.PENDING) {
|
|
231
|
+
if (!pendingUserFormsIds.includes(existingForm.id)) {
|
|
232
|
+
pendingUserFormsIds.push(existingForm.id);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
continue; // Skip creating new form, reuse existing one
|
|
237
|
+
}
|
|
238
|
+
} catch (error) {
|
|
239
|
+
console.warn(
|
|
240
|
+
`[FormInit] Error checking for existing form (template: ${templateRef.templateId}):`,
|
|
241
|
+
error
|
|
242
|
+
);
|
|
243
|
+
// Continue to create new form if check fails
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Create new form document (either procedure-specific or general form not found)
|
|
98
248
|
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
99
249
|
const formsCollectionRef = collection(appointmentRef, formSubcollectionPath);
|
|
100
250
|
|
|
@@ -141,8 +291,9 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
141
291
|
};
|
|
142
292
|
initializedFormsInfo.push(linkedForm);
|
|
143
293
|
|
|
294
|
+
const formType = isProcedureSpecific ? 'procedure-specific' : 'general/shared';
|
|
144
295
|
console.log(
|
|
145
|
-
`[FormInit] Created FilledDocument ${filledDocumentId} (template: ${template.id}, isUserForm: ${isUserForm}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
296
|
+
`[FormInit] Created ${formType} FilledDocument ${filledDocumentId} (template: ${template.id}, isUserForm: ${isUserForm}) for extended procedure ${procedureId} in appointment ${appointmentId}.`
|
|
146
297
|
);
|
|
147
298
|
} catch (error) {
|
|
148
299
|
console.error(
|
|
@@ -157,6 +308,7 @@ export async function initializeFormsForExtendedProcedure(
|
|
|
157
308
|
|
|
158
309
|
/**
|
|
159
310
|
* Removes all forms associated with a specific procedure from an appointment
|
|
311
|
+
* Only removes procedure-specific forms. Shared forms are kept if still referenced by other procedures.
|
|
160
312
|
* Removes both user forms and doctor forms
|
|
161
313
|
* @param db Firestore instance
|
|
162
314
|
* @param appointmentId Appointment ID
|
|
@@ -170,7 +322,34 @@ export async function removeFormsForExtendedProcedure(
|
|
|
170
322
|
): Promise<string[]> {
|
|
171
323
|
const removedFormIds: string[] = [];
|
|
172
324
|
|
|
325
|
+
// Get appointment to check linkedForms
|
|
173
326
|
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
327
|
+
const appointmentSnap = await getDoc(appointmentRef);
|
|
328
|
+
|
|
329
|
+
if (!appointmentSnap.exists()) {
|
|
330
|
+
console.warn(
|
|
331
|
+
`[FormInit] Appointment ${appointmentId} not found when removing forms for procedure ${procedureId}.`
|
|
332
|
+
);
|
|
333
|
+
return removedFormIds;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const appointment = appointmentSnap.data() as any;
|
|
337
|
+
const linkedForms = appointment.linkedForms || [];
|
|
338
|
+
|
|
339
|
+
// Get all procedure IDs (main + extended) to check if shared forms are still referenced
|
|
340
|
+
const mainProcedureId = appointment.procedureId;
|
|
341
|
+
const extendedProcedureIds = appointment.metadata?.extendedProcedures?.map(
|
|
342
|
+
(ep: any) => ep.procedureId
|
|
343
|
+
) || [];
|
|
344
|
+
const allProcedureIds = [mainProcedureId, ...extendedProcedureIds].filter(Boolean);
|
|
345
|
+
const remainingProcedureIds = allProcedureIds.filter((id: string) => id !== procedureId);
|
|
346
|
+
|
|
347
|
+
// Helper function to check if form appears multiple times in linkedForms (indicating it's shared)
|
|
348
|
+
const isFormSharedAndReferenced = (formId: string): boolean => {
|
|
349
|
+
const formEntries = linkedForms.filter((form: LinkedFormInfo) => form.formId === formId);
|
|
350
|
+
// If form appears multiple times in linkedForms, it's shared across procedures
|
|
351
|
+
return formEntries.length > 1;
|
|
352
|
+
};
|
|
174
353
|
|
|
175
354
|
// Remove from doctor forms subcollection
|
|
176
355
|
const doctorFormsRef = collection(appointmentRef, DOCTOR_FORMS_SUBCOLLECTION);
|
|
@@ -182,11 +361,49 @@ export async function removeFormsForExtendedProcedure(
|
|
|
182
361
|
|
|
183
362
|
for (const formDoc of doctorFormsSnap.docs) {
|
|
184
363
|
try {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
)
|
|
364
|
+
const formData = formDoc.data() as FilledDocument;
|
|
365
|
+
|
|
366
|
+
// Fetch template to check if form is shared
|
|
367
|
+
let isShared = false;
|
|
368
|
+
if (formData.templateId) {
|
|
369
|
+
try {
|
|
370
|
+
const templateDoc = doc(db, DOCUMENTATION_TEMPLATES_COLLECTION, formData.templateId);
|
|
371
|
+
const templateSnap = await getDoc(templateDoc);
|
|
372
|
+
if (templateSnap.exists()) {
|
|
373
|
+
const template = templateSnap.data() as DocumentTemplate;
|
|
374
|
+
isShared = !isProcedureSpecificForm(template);
|
|
375
|
+
}
|
|
376
|
+
} catch (error) {
|
|
377
|
+
console.warn(
|
|
378
|
+
`[FormInit] Could not check template for form ${formDoc.id}, assuming procedure-specific:`,
|
|
379
|
+
error
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Only delete procedure-specific forms
|
|
385
|
+
// Shared forms are kept even if procedureId matches, as they may be used by other procedures
|
|
386
|
+
if (!isShared) {
|
|
387
|
+
await deleteDoc(formDoc.ref);
|
|
388
|
+
removedFormIds.push(formDoc.id);
|
|
389
|
+
console.log(
|
|
390
|
+
`[FormInit] Removed procedure-specific doctor form ${formDoc.id} for extended procedure ${procedureId} from appointment ${appointmentId}.`
|
|
391
|
+
);
|
|
392
|
+
} else {
|
|
393
|
+
// Check if form is still referenced by other procedures (appears multiple times in linkedForms)
|
|
394
|
+
if (isFormSharedAndReferenced(formDoc.id)) {
|
|
395
|
+
console.log(
|
|
396
|
+
`[FormInit] Skipped deletion of shared doctor form ${formDoc.id} - still referenced by other procedures.`
|
|
397
|
+
);
|
|
398
|
+
} else {
|
|
399
|
+
// Shared form but only referenced by this procedure (shouldn't happen, but handle it)
|
|
400
|
+
await deleteDoc(formDoc.ref);
|
|
401
|
+
removedFormIds.push(formDoc.id);
|
|
402
|
+
console.log(
|
|
403
|
+
`[FormInit] Removed shared doctor form ${formDoc.id} - no longer referenced by other procedures.`
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
190
407
|
} catch (error) {
|
|
191
408
|
console.error(
|
|
192
409
|
`[FormInit] Error removing doctor form ${formDoc.id}:`,
|
|
@@ -205,11 +422,49 @@ export async function removeFormsForExtendedProcedure(
|
|
|
205
422
|
|
|
206
423
|
for (const formDoc of userFormsSnap.docs) {
|
|
207
424
|
try {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
)
|
|
425
|
+
const formData = formDoc.data() as FilledDocument;
|
|
426
|
+
|
|
427
|
+
// Fetch template to check if form is shared
|
|
428
|
+
let isShared = false;
|
|
429
|
+
if (formData.templateId) {
|
|
430
|
+
try {
|
|
431
|
+
const templateDoc = doc(db, DOCUMENTATION_TEMPLATES_COLLECTION, formData.templateId);
|
|
432
|
+
const templateSnap = await getDoc(templateDoc);
|
|
433
|
+
if (templateSnap.exists()) {
|
|
434
|
+
const template = templateSnap.data() as DocumentTemplate;
|
|
435
|
+
isShared = !isProcedureSpecificForm(template);
|
|
436
|
+
}
|
|
437
|
+
} catch (error) {
|
|
438
|
+
console.warn(
|
|
439
|
+
`[FormInit] Could not check template for form ${formDoc.id}, assuming procedure-specific:`,
|
|
440
|
+
error
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Only delete procedure-specific forms
|
|
446
|
+
// Shared forms are kept even if procedureId matches, as they may be used by other procedures
|
|
447
|
+
if (!isShared) {
|
|
448
|
+
await deleteDoc(formDoc.ref);
|
|
449
|
+
removedFormIds.push(formDoc.id);
|
|
450
|
+
console.log(
|
|
451
|
+
`[FormInit] Removed procedure-specific user form ${formDoc.id} for extended procedure ${procedureId} from appointment ${appointmentId}.`
|
|
452
|
+
);
|
|
453
|
+
} else {
|
|
454
|
+
// Check if form is still referenced by other procedures (appears multiple times in linkedForms)
|
|
455
|
+
if (isFormSharedAndReferenced(formDoc.id)) {
|
|
456
|
+
console.log(
|
|
457
|
+
`[FormInit] Skipped deletion of shared user form ${formDoc.id} - still referenced by other procedures.`
|
|
458
|
+
);
|
|
459
|
+
} else {
|
|
460
|
+
// Shared form but only referenced by this procedure (shouldn't happen, but handle it)
|
|
461
|
+
await deleteDoc(formDoc.ref);
|
|
462
|
+
removedFormIds.push(formDoc.id);
|
|
463
|
+
console.log(
|
|
464
|
+
`[FormInit] Removed shared user form ${formDoc.id} - no longer referenced by other procedures.`
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
213
468
|
} catch (error) {
|
|
214
469
|
console.error(
|
|
215
470
|
`[FormInit] Error removing user form ${formDoc.id}:`,
|