Enhance document template schema and service with referenced templates functionality
All checks were successful
farmcontrol/farmcontrol-api/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-api/pipeline/head This commit looks good
This commit introduces a new field, `referencedTemplates`, to the document template schema, allowing for the association of other document templates. It also adds utility functions for extracting references from template content and converting filter values to ObjectIds. The document template service is updated to recalculate and populate referenced templates when editing a document template. Additionally, route handlers are modified to support the new referenced templates in their population logic, improving the management of document templates.
This commit is contained in:
parent
827f3b7c8c
commit
b0943f3fa0
@ -2,6 +2,53 @@ import mongoose from 'mongoose';
|
||||
import { generateId } from '../../utils.js';
|
||||
const { Schema } = mongoose;
|
||||
|
||||
const RENDER_DOCUMENT_TEMPLATE_CALL =
|
||||
/fc\.renderDocumentTemplate\s*\(\s*(['"])([^'"]+)\1/g;
|
||||
|
||||
function extractRenderDocumentTemplateReferences(content) {
|
||||
if (content == null || typeof content !== 'string' || content === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
const references = [];
|
||||
const seen = new Set();
|
||||
const regex = new RegExp(RENDER_DOCUMENT_TEMPLATE_CALL.source, 'g');
|
||||
let match;
|
||||
while ((match = regex.exec(content)) !== null) {
|
||||
const reference = match[2]?.trim();
|
||||
if (!reference || seen.has(reference)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(reference);
|
||||
references.push(reference);
|
||||
}
|
||||
return references;
|
||||
}
|
||||
|
||||
function objectIdsFromFilterValue(value) {
|
||||
if (value == null) {
|
||||
return [];
|
||||
}
|
||||
if (value instanceof mongoose.Types.ObjectId) {
|
||||
return [value];
|
||||
}
|
||||
if (typeof value === 'string' && /^[a-f\d]{24}$/i.test(value)) {
|
||||
return [new mongoose.Types.ObjectId(value)];
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.flatMap(objectIdsFromFilterValue);
|
||||
}
|
||||
if (typeof value === 'object') {
|
||||
if (Array.isArray(value.$in)) {
|
||||
return objectIdsFromFilterValue(value.$in);
|
||||
}
|
||||
if (value._id != null) {
|
||||
return objectIdsFromFilterValue(value._id);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
const documentTemplateSchema = new Schema(
|
||||
{
|
||||
_reference: { type: String, default: () => generateId()() },
|
||||
@ -39,6 +86,13 @@ const documentTemplateSchema = new Schema(
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
referencedTemplates: [
|
||||
{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'documentTemplate',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
content: {
|
||||
type: String,
|
||||
required: false,
|
||||
@ -63,4 +117,50 @@ documentTemplateSchema.virtual('id').get(function () {
|
||||
// Configure JSON serialization to include virtuals
|
||||
documentTemplateSchema.set('toJSON', { virtuals: true });
|
||||
|
||||
documentTemplateSchema.statics.recalculate = async function (documentTemplate, user) {
|
||||
const documentTemplateId = documentTemplate?._id || documentTemplate;
|
||||
if (!documentTemplateId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stillExists = await this.exists({ _id: documentTemplateId });
|
||||
if (!stillExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { getFilter } = await import('../../../utils.js');
|
||||
const references = extractRenderDocumentTemplateReferences(documentTemplate?.content);
|
||||
const referencedTemplateIds = [];
|
||||
const seenIds = new Set();
|
||||
|
||||
for (const reference of references) {
|
||||
const filter = await getFilter({ parent: reference }, ['parent'], true, this);
|
||||
const ids = objectIdsFromFilterValue(filter.parent);
|
||||
for (const id of ids) {
|
||||
const idString = String(id);
|
||||
if (!idString || seenIds.has(idString)) {
|
||||
continue;
|
||||
}
|
||||
seenIds.add(idString);
|
||||
referencedTemplateIds.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (documentTemplate && typeof documentTemplate === 'object' && !documentTemplate._bsontype) {
|
||||
documentTemplate.referencedTemplates = referencedTemplateIds.map((id) => ({
|
||||
_id: String(id),
|
||||
}));
|
||||
}
|
||||
|
||||
const { editObject } = await import('../../database.js');
|
||||
await editObject({
|
||||
model: this,
|
||||
id: documentTemplateId,
|
||||
updateData: { referencedTemplates: referencedTemplateIds },
|
||||
user,
|
||||
populate: [{ path: 'referencedTemplates', strictPopulate: false }],
|
||||
recalculate: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const documentTemplateModel = mongoose.model('documentTemplate', documentTemplateSchema);
|
||||
|
||||
@ -14,6 +14,8 @@ const listAllowedFilters = [
|
||||
'parent._id',
|
||||
'documentSize',
|
||||
'documentSize._id',
|
||||
'referencedTemplates',
|
||||
'referencedTemplates._id',
|
||||
'objectType',
|
||||
'createdAt',
|
||||
'updatedAt',
|
||||
|
||||
@ -71,6 +71,7 @@ export const listDocumentTemplatesRouteHandler = async (
|
||||
{ path: 'documentSize' },
|
||||
{ path: 'parent' },
|
||||
{ path: 'documentPrinters', strictPopulate: false },
|
||||
{ path: 'referencedTemplates', strictPopulate: false },
|
||||
],
|
||||
});
|
||||
|
||||
@ -136,6 +137,7 @@ export const getDocumentTemplateRouteHandler = async (req, res) => {
|
||||
{ path: 'documentSize' },
|
||||
{ path: 'parent', strictPopulate: false },
|
||||
{ path: 'documentPrinters', strictPopulate: false },
|
||||
{ path: 'referencedTemplates', strictPopulate: false },
|
||||
{ path: 'testObject', strictPopulate: false },
|
||||
],
|
||||
});
|
||||
@ -186,6 +188,7 @@ export const editDocumentTemplateRouteHandler = async (req, res) => {
|
||||
{ path: 'documentSize' },
|
||||
{ path: 'parent', strictPopulate: false },
|
||||
{ path: 'documentPrinters', strictPopulate: false },
|
||||
{ path: 'referencedTemplates', strictPopulate: false },
|
||||
{ path: 'testObject', strictPopulate: false },
|
||||
],
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user