@dynamatix/cat-shared 0.0.81 → 0.0.82

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.
@@ -6,31 +6,39 @@ import mongoose from 'mongoose';
6
6
 
7
7
  let onAuditLogCreated = null;
8
8
 
9
- // Generic resolver: fetch display values using ValueReferenceMap
10
- async function resolveAuditValues(field, oldValue, newValue) {
11
- const map = await ValueReferenceMap.findOne({ field });
12
- if (!map || (!oldValue && !newValue)) return { oldValue, newValue };
13
-
14
- const Model = mongoose.models[map.model];
15
- if (!Model) return { oldValue, newValue };
16
-
17
- const [oldDoc, newDoc] = await Promise.all([
18
- oldValue ? Model.findById(oldValue).lean() : null,
19
- newValue ? Model.findById(newValue).lean() : null
20
- ]);
21
-
22
- return {
23
- oldValue: oldDoc?.[map.displayField] || oldValue,
24
- newValue: newDoc?.[map.displayField] || newValue
25
- };
26
- }
27
-
28
- async function resolveExternalData(descriptionResolutorForExternalData, recordId) {
29
- const map = await ValueReferenceMap.findOne({ field: descriptionResolutorForExternalData });
30
- const Model = mongoose.models[map.model];
31
- if (!Model) return "";
32
- const doc = await Model.findById(recordId).lean()
33
- return doc[map.displayField];
9
+ // Optionally, define custom resolvers here
10
+ const customResolvers = {
11
+ // Example:
12
+ // expenditureRationale: (doc) => `Rationale for ${doc.type}: ${doc.rationale}`
13
+ };
14
+
15
+ // Flexible description resolver
16
+ async function resolveDescription(field, doc) {
17
+ const config = await ValueReferenceMap.findOne({ field });
18
+ if (!config) return '';
19
+
20
+ switch (config.descriptionResolverType) {
21
+ case 'lookup': {
22
+ const lookupId = doc[config.descriptionField];
23
+ if (!lookupId) return '';
24
+ const lookupDoc = await mongoose.models['Lookup'].findById(lookupId).lean();
25
+ return lookupDoc?.name || '';
26
+ }
27
+ case 'direct':
28
+ return doc[config.descriptionField] || '';
29
+ case 'composite':
30
+ return (config.descriptionFields || [])
31
+ .map(f => doc[f])
32
+ .filter(Boolean)
33
+ .join(' ');
34
+ case 'custom':
35
+ if (typeof customResolvers?.[config.descriptionFunction] === 'function') {
36
+ return await customResolvers[config.descriptionFunction](doc);
37
+ }
38
+ return '';
39
+ default:
40
+ return '';
41
+ }
34
42
  }
35
43
 
36
44
  function applyAuditMiddleware(schema, collectionName) {
@@ -49,13 +57,9 @@ function applyAuditMiddleware(schema, collectionName) {
49
57
  oldValue: null,
50
58
  newValue: 'Document created',
51
59
  createdBy: userId,
52
- contextId
60
+ contextId,
61
+ description: await resolveDescription('created', doc)
53
62
  };
54
- log.externalData = {};
55
- if (auditConfig.descriptionResolutorForExternalData) {
56
- log.externalData.description = await resolveExternalData(auditConfig.descriptionResolutorForExternalData, doc[auditConfig.descriptionResolutorForExternalData])
57
- log.externalData.contextId = contextId;
58
- }
59
63
  await AuditLog.create(log);
60
64
  await updateContextAuditCount(contextId, 1);
61
65
 
@@ -92,22 +96,16 @@ function applyAuditMiddleware(schema, collectionName) {
92
96
  const oldValue = this._originalDoc ? this._originalDoc[field] : '';
93
97
 
94
98
  if (oldValue !== newValue) {
95
- // Resolve human-readable values
96
- const { oldValue: resolvedOld, newValue: resolvedNew } =
97
- await resolveAuditValues(field, oldValue, newValue);
98
-
99
- let externalData = {};
100
- if (auditConfig.descriptionResolutorForExternalData) {
101
- externalData.description = await resolveExternalData(auditConfig.descriptionResolutorForExternalData, result[auditConfig.descriptionResolutorForExternalData])
102
- externalData.contextId = contextId || result._id;
103
- }
99
+ // Flexible description
100
+ const description = await resolveDescription(field, result);
101
+
104
102
  logs.push({
105
103
  name: `${collectionName}.${field}`,
106
104
  recordId: contextId || result._id,
107
- oldValue: resolvedOld,
108
- newValue: resolvedNew,
105
+ oldValue,
106
+ newValue,
109
107
  createdBy: userId,
110
- externalData
108
+ description
111
109
  });
112
110
  }
113
111
  }
@@ -138,4 +136,4 @@ export function registerAuditHook(callback) {
138
136
  onAuditLogCreated = callback;
139
137
  }
140
138
 
141
- export default applyAuditMiddleware;
139
+ export default applyAuditMiddleware;
@@ -4,6 +4,10 @@ const valueReferenceMapSchema = new mongoose.Schema({
4
4
  field: String, // e.g. 'documentTypeId', 'createdBy', 'status'
5
5
  model: String, // e.g. 'DocumentType', 'User', 'ApplicationStatus'
6
6
  displayField: String, // e.g. 'name', 'fullName', 'label'
7
+ descriptionResolverType: { type: String, enum: ['direct', 'lookup', 'composite', 'custom'], default: 'direct' },
8
+ descriptionField: String, // for direct/lookup
9
+ descriptionFields: [String], // for composite
10
+ descriptionFunction: String // for custom
7
11
  });
8
12
 
9
13
  valueReferenceMapSchema.index({ field: 1 }, { unique: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamatix/cat-shared",
3
- "version": "0.0.81",
3
+ "version": "0.0.82",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"