@dynamatix/cat-shared 0.0.80 → 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,12 +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
- if (auditConfig.descriptionResolutorForExternalData) {
55
- log.externalData.description = await resolveExternalData(auditConfig.descriptionResolutorForExternalData, doc[auditConfig.descriptionResolutorForExternalData])
56
- log.externalData.contextId = contextId;
57
- }
58
63
  await AuditLog.create(log);
59
64
  await updateContextAuditCount(contextId, 1);
60
65
 
@@ -91,22 +96,16 @@ function applyAuditMiddleware(schema, collectionName) {
91
96
  const oldValue = this._originalDoc ? this._originalDoc[field] : '';
92
97
 
93
98
  if (oldValue !== newValue) {
94
- // Resolve human-readable values
95
- const { oldValue: resolvedOld, newValue: resolvedNew } =
96
- await resolveAuditValues(field, oldValue, newValue);
97
-
98
- let externalData = {};
99
- if (auditConfig.descriptionResolutorForExternalData) {
100
- externalData.description = await resolveExternalData(auditConfig.descriptionResolutorForExternalData, result[auditConfig.descriptionResolutorForExternalData])
101
- externalData.contextId = contextId || result._id;
102
- }
99
+ // Flexible description
100
+ const description = await resolveDescription(field, result);
101
+
103
102
  logs.push({
104
103
  name: `${collectionName}.${field}`,
105
104
  recordId: contextId || result._id,
106
- oldValue: resolvedOld,
107
- newValue: resolvedNew,
105
+ oldValue,
106
+ newValue,
108
107
  createdBy: userId,
109
- externalData
108
+ description
110
109
  });
111
110
  }
112
111
  }
@@ -137,4 +136,4 @@ export function registerAuditHook(callback) {
137
136
  onAuditLogCreated = callback;
138
137
  }
139
138
 
140
- 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.80",
3
+ "version": "0.0.82",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"