@dhyasama/totem-models 11.122.0 → 11.124.0

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/lib/Financials.js CHANGED
@@ -88,9 +88,6 @@ module.exports = function(mongoose, config) {
88
88
  form: [{
89
89
  name: { type: String, trim: true },
90
90
  type: { type: String, enum: [null, 'header', 'block', 'document', 'metric', 'question'] },
91
- scenario: { type: String, enum: ['actual', 'budget', 'forecast'] },
92
- budget: { type: Number },
93
- forecast: { type: Number },
94
91
  required: { type: Boolean, default: false }
95
92
  }],
96
93
 
@@ -334,8 +331,8 @@ module.exports = function(mongoose, config) {
334
331
  // Check if the metric update was successful
335
332
  const snapshot = updatedDocument.snapshots.find(s => s.uuid === snapshotUUID);
336
333
  if (snapshot) {
337
- const updatedMetric = snapshot.metrics.find(m => m.name === metric.name);
338
- if (updatedMetric && updatedMetric.actual === metric.actual) {
334
+ const updatedMetric = snapshot.metrics.find(m => m.name === metric.name && m.scenario === metric.scenario);
335
+ if (updatedMetric && updatedMetric.value === metric.value) {
339
336
  console.log('Metric was successfully updated:', updatedMetric);
340
337
  result = true;
341
338
  } else {
@@ -364,7 +361,8 @@ module.exports = function(mongoose, config) {
364
361
 
365
362
  console.log('Upserting metric:', metric);
366
363
  console.log('Upserting metric name:', metric.name);
367
- console.log('Upserting metric actual:', metric.actual);
364
+ console.log('Upserting metric scenario:', metric.scenario);
365
+ console.log('Upserting metric value:', metric.value);
368
366
  console.log('Upserting metric breakdown:', metric.breakdown);
369
367
 
370
368
  // Check if the metric exists and update it
@@ -372,16 +370,25 @@ module.exports = function(mongoose, config) {
372
370
  {
373
371
  _id: financialsId,
374
372
  'snapshots.uuid': snapshotUUID,
375
- 'snapshots.metrics.name': metric.name
373
+ 'snapshots.metrics.name': metric.name,
374
+ 'snapshots.metrics.scenario': metric.scenario
376
375
  },
377
376
  {
378
377
  $set: {
379
- 'snapshots.$.metrics.$[metric].actual': metric.actual,
378
+ 'snapshots.$.metrics.$[metric].value': metric.value,
380
379
  'snapshots.$.metrics.$[metric].breakdown': metric.breakdown,
380
+ 'snapshots.$.metrics.$[metric].source': metric.source,
381
+ 'snapshots.$.metrics.$[metric].verified': metric.verified
382
+ },
383
+ $push: {
384
+ 'snapshots.$.metrics.$[metric].history': {
385
+ $each: metric.history || [],
386
+ $position: 0
387
+ }
381
388
  }
382
389
  },
383
390
  {
384
- arrayFilters: [{ 'metric.name': metric.name }],
391
+ arrayFilters: [{ 'metric.name': metric.name, 'metric.scenario': metric.scenario }],
385
392
  new: true,
386
393
  session: _session
387
394
  }
@@ -320,7 +320,6 @@ module.exports = function(mongoose, config) {
320
320
  _id: false,
321
321
  name: { type: String, trim: true },
322
322
  type: { type: String, enum: [null, 'header', 'block', 'document', 'metric', 'question'] },
323
- scenario: { type: String, enum: ['actual', 'budget', 'forecast'] },
324
323
  required: { type: Boolean, default: false }
325
324
  }]
326
325
  }],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhyasama/totem-models",
3
- "version": "11.122.0",
3
+ "version": "11.124.0",
4
4
  "author": "Jason Reynolds",
5
5
  "license": "UNLICENSED",
6
6
  "description": "Models for Totem platform",
@@ -6,14 +6,21 @@
6
6
  * Changes being migrated:
7
7
  * 1. Rename field: review → approval (in recurring and snapshots)
8
8
  * 2. Update status enum value: 'In Review' → 'Pending'
9
- * 3. Populate history[] for documents[], questions[], and metrics[]
10
- * History is populated with submission and approval data from the snapshot
11
- * 4. Add verified: true for metrics[] only
12
- * 5. Convert metrics from old structure { name, actual, budget, forecast, breakdown }
9
+ * 3. Remove budget, forecast, and scenario fields from form[] template (commits 71c84ac, 4bca5a3)
10
+ * 4. Populate history[] for documents[], questions[], and metrics[]
11
+ * - For documents and questions: history uses actions ['updated', 'deleted'] only
12
+ * History populated with submission entry only (1 entry if submitted)
13
+ * - For metrics: history uses actions ['updated', 'deleted', 'verified']
14
+ * History populated with submission and approval entries (2 entries if approved)
15
+ * 5. Set scenario to 'actual' for all existing documents[] (historical data is actual)
16
+ * 6. Remove verified field from documents[] (removed in commit 300a22a)
17
+ * 7. Remove verified field from questions[] (removed in commit 300a22a)
18
+ * 8. Add verified: true for metrics[] only
19
+ * 9. Convert metrics from old structure { name, actual, budget, forecast, breakdown }
13
20
  * to new structure { name, scenario, value, breakdown, source, verified, history }
14
- * 6. Link metrics to their source financial statement documents (Income Statement,
15
- * Balance Sheet, Cash Flow Statement) when available
16
- * 7. Remove projections array from root level
21
+ * 10. Link metrics to their source financial statement documents (Income Statement,
22
+ * Balance Sheet, Cash Flow Statement) when available
23
+ * 11. Remove projections array from root level
17
24
  *
18
25
  * Usage:
19
26
  * node scripts/migrate-financials-schema.js <customerId> [--config <configPath>] [--dry-run]
@@ -155,8 +162,51 @@ async function migrateFinancials() {
155
162
  changes.push(` - Snapshot ${index}: Changed status 'In Review' → 'Pending'`);
156
163
  }
157
164
 
165
+ // 2c. Remove budget, forecast, and scenario fields from form[] template
166
+ if (snapshot.form && snapshot.form.length > 0) {
167
+ snapshot.form.forEach((formItem, fIndex) => {
168
+ let fieldsRemoved = [];
169
+ if ('budget' in formItem) {
170
+ updates.$unset = updates.$unset || {};
171
+ updates.$unset[`snapshots.${index}.form.${fIndex}.budget`] = '';
172
+ fieldsRemoved.push('budget');
173
+ }
174
+ if ('forecast' in formItem) {
175
+ updates.$unset = updates.$unset || {};
176
+ updates.$unset[`snapshots.${index}.form.${fIndex}.forecast`] = '';
177
+ fieldsRemoved.push('forecast');
178
+ }
179
+ if ('scenario' in formItem) {
180
+ updates.$unset = updates.$unset || {};
181
+ updates.$unset[`snapshots.${index}.form.${fIndex}.scenario`] = '';
182
+ fieldsRemoved.push('scenario');
183
+ }
184
+ if (fieldsRemoved.length > 0) {
185
+ changes.push(` - Snapshot ${index}: Removed ${fieldsRemoved.join(', ')} from form[${fIndex}]`);
186
+ }
187
+ });
188
+ }
189
+
158
190
  // Build history array from snapshot submission/approval data
159
- const buildHistory = () => {
191
+ // Note: For documents and questions, only 'updated' and 'deleted' actions are valid
192
+ // Documents/questions are not verified individually - only the snapshot is approved
193
+ // For metrics, 'verified' is also valid since they can be individually verified
194
+ const buildHistoryForDocumentsAndQuestions = () => {
195
+ const history = [];
196
+
197
+ // Add submission history entry only (no approval/verification for individual docs/questions)
198
+ if (snapshot.submittedOn && snapshot.submittedBy) {
199
+ history.push({
200
+ timestamp: snapshot.submittedOn,
201
+ user: snapshot.submittedBy,
202
+ action: 'updated'
203
+ });
204
+ }
205
+
206
+ return history;
207
+ };
208
+
209
+ const buildHistoryForMetrics = () => {
160
210
  const history = [];
161
211
 
162
212
  // Add submission history entry
@@ -168,7 +218,7 @@ async function migrateFinancials() {
168
218
  });
169
219
  }
170
220
 
171
- // Add approval history entry
221
+ // Add approval history entry (use 'verified' for metrics)
172
222
  if (snapshot.approvedOn && snapshot.approvedBy) {
173
223
  history.push({
174
224
  timestamp: snapshot.approvedOn,
@@ -180,29 +230,47 @@ async function migrateFinancials() {
180
230
  return history;
181
231
  };
182
232
 
183
- const historyArray = buildHistory();
233
+ const historyArrayForDocumentsAndQuestions = buildHistoryForDocumentsAndQuestions();
234
+ const historyArrayForMetrics = buildHistoryForMetrics();
184
235
 
185
- // 2c. Add history to documents
236
+ // 2d. Add history to documents, set scenario to 'actual', and remove verified field
186
237
  if (snapshot.documents && snapshot.documents.length > 0) {
187
238
  snapshot.documents.forEach((doc, docIndex) => {
188
239
  if (!('history' in doc)) {
189
- updates[`snapshots.${index}.documents.${docIndex}.history`] = historyArray;
190
- changes.push(` - Snapshot ${index}: Added history (${historyArray.length} entries) to document ${docIndex}`);
240
+ updates[`snapshots.${index}.documents.${docIndex}.history`] = historyArrayForDocumentsAndQuestions;
241
+ changes.push(` - Snapshot ${index}: Added history (${historyArrayForDocumentsAndQuestions.length} entries) to document ${docIndex}`);
242
+ }
243
+ // Set scenario to 'actual' for all existing documents (historical data is actual)
244
+ if (!('scenario' in doc)) {
245
+ updates[`snapshots.${index}.documents.${docIndex}.scenario`] = 'actual';
246
+ changes.push(` - Snapshot ${index}: Set scenario to 'actual' for document ${docIndex}`);
247
+ }
248
+ // Remove verified field if it exists (removed in commit 300a22a)
249
+ if ('verified' in doc) {
250
+ updates.$unset = updates.$unset || {};
251
+ updates.$unset[`snapshots.${index}.documents.${docIndex}.verified`] = '';
252
+ changes.push(` - Snapshot ${index}: Removed verified field from document ${docIndex}`);
191
253
  }
192
254
  });
193
255
  }
194
256
 
195
- // 2d. Add history to questions
257
+ // 2e. Add history to questions and remove verified field
196
258
  if (snapshot.questions && snapshot.questions.length > 0) {
197
259
  snapshot.questions.forEach((question, qIndex) => {
198
260
  if (!('history' in question)) {
199
- updates[`snapshots.${index}.questions.${qIndex}.history`] = historyArray;
200
- changes.push(` - Snapshot ${index}: Added history (${historyArray.length} entries) to question ${qIndex}`);
261
+ updates[`snapshots.${index}.questions.${qIndex}.history`] = historyArrayForDocumentsAndQuestions;
262
+ changes.push(` - Snapshot ${index}: Added history (${historyArrayForDocumentsAndQuestions.length} entries) to question ${qIndex}`);
263
+ }
264
+ // Remove verified field if it exists (removed in commit 300a22a)
265
+ if ('verified' in question) {
266
+ updates.$unset = updates.$unset || {};
267
+ updates.$unset[`snapshots.${index}.questions.${qIndex}.verified`] = '';
268
+ changes.push(` - Snapshot ${index}: Removed verified field from question ${qIndex}`);
201
269
  }
202
270
  });
203
271
  }
204
272
 
205
- // 2e. Migrate metrics structure
273
+ // 2f. Migrate metrics structure
206
274
  if (snapshot.metrics && snapshot.metrics.length > 0) {
207
275
  const oldMetrics = [...snapshot.metrics];
208
276
  const newMetrics = [];
@@ -256,7 +324,7 @@ async function migrateFinancials() {
256
324
  value: metric.actual,
257
325
  breakdown: metric.breakdown || {},
258
326
  verified: true,
259
- history: historyArray
327
+ history: historyArrayForMetrics
260
328
  };
261
329
  if (source) newMetric.source = source;
262
330
  newMetrics.push(newMetric);
@@ -269,7 +337,7 @@ async function migrateFinancials() {
269
337
  value: metric.budget,
270
338
  breakdown: {},
271
339
  verified: true,
272
- history: historyArray
340
+ history: historyArrayForMetrics
273
341
  };
274
342
  if (source) newMetric.source = source;
275
343
  newMetrics.push(newMetric);
@@ -282,7 +350,7 @@ async function migrateFinancials() {
282
350
  value: metric.forecast,
283
351
  breakdown: {},
284
352
  verified: true,
285
- history: historyArray
353
+ history: historyArrayForMetrics
286
354
  };
287
355
  if (source) newMetric.source = source;
288
356
  newMetrics.push(newMetric);
@@ -300,8 +368,8 @@ async function migrateFinancials() {
300
368
  changes.push(` - Snapshot ${index}: Added verified to metric ${mIndex}`);
301
369
  }
302
370
  if (!('history' in metric)) {
303
- updates[`snapshots.${index}.metrics.${mIndex}.history`] = historyArray;
304
- changes.push(` - Snapshot ${index}: Added history (${historyArray.length} entries) to metric ${mIndex}`);
371
+ updates[`snapshots.${index}.metrics.${mIndex}.history`] = historyArrayForMetrics;
372
+ changes.push(` - Snapshot ${index}: Added history (${historyArrayForMetrics.length} entries) to metric ${mIndex}`);
305
373
  }
306
374
  if (!('source' in metric)) {
307
375
  const source = getSourceForMetric(metric.name);