mirror of
https://github.com/bckelley/cgm-remote-monitor.git
synced 2026-08-24 03:14:12 -05:00
This reverts commit3b786ab3. On review the V3 (app, defaultProfile) collapse was too aggressive and broke parity with how the rest of the ecosystem treats the profile collection: - Loop (NightscoutKit) and Trio (NightscoutAPI.swift:411) both POST /api/v1/profile without _id on every settings edit, accumulating one doc per upload via lib/server/profile.js:create(). They have done so for years. - The Nightscout profile collection is historical/append-only by design; the NS UI profile editor lets users navigate prior snapshots, and lib/server/profile.js:last() picks the most recent for display. - Collapsing AAPS V3 edits onto a single (app, defaultProfile) row diverged from Loop/Trio/AAPS-V1 behavior and erased the upload history that NS UI exposes. The original 'AAPS edits not appearing' user complaint is sufficiently addressed by: - the V1 websocket retry dedup (commit85f7e6ac), which kills the 60s ack-window race; and - the {startDate: -1, _id: -1} secondary sort in profile.last() (also85f7e6ac), which deterministically picks the newest row when startDate ties. Both of those help every uploader (Loop, Trio, AAPS V1, AAPS V3) without changing the ecosystem-wide profile-as-history semantic. The characterization tests added inddabdc6care restored by this revert and continue to document V3's request-level (date-based) dedup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
49 lines
1.5 KiB
JavaScript
49 lines
1.5 KiB
JavaScript
'use strict';
|
|
|
|
const apiConst = require('../../const.json')
|
|
, opTools = require('../../shared/operationTools')
|
|
;
|
|
|
|
|
|
/**
|
|
* Validation of document to update
|
|
* @param {Object} opCtx
|
|
* @param {Object} doc
|
|
* @param {Object} storageDoc
|
|
* @param {Object} options
|
|
* @returns string with error message if validation fails, true in case of success
|
|
*/
|
|
function validate (opCtx, doc, storageDoc, options) {
|
|
|
|
const { res } = opCtx;
|
|
const { isPatching, isDeduplication } = options || {};
|
|
|
|
const immutable = ['identifier', 'date', 'utcOffset', 'eventType', 'device', 'app',
|
|
'srvCreated', 'subject', 'srvModified', 'modifiedBy', 'isValid'];
|
|
|
|
if (storageDoc.isReadOnly === true || storageDoc.readOnly === true || storageDoc.readonly === true) {
|
|
return opTools.sendJSONStatus(res, apiConst.HTTP.UNPROCESSABLE_ENTITY,
|
|
apiConst.MSG.HTTP_422_READONLY_MODIFICATION);
|
|
}
|
|
|
|
for (const field of immutable) {
|
|
|
|
// change of identifier is allowed in deduplication (for APIv1 documents)
|
|
if (field === 'identifier' && isDeduplication)
|
|
continue;
|
|
|
|
// changing deleted document is without restrictions
|
|
if (storageDoc.isValid === false)
|
|
continue;
|
|
|
|
if (typeof(doc[field]) !== 'undefined' && doc[field] !== storageDoc[field]) {
|
|
return opTools.sendJSONStatus(res, apiConst.HTTP.BAD_REQUEST,
|
|
apiConst.MSG.HTTP_400_IMMUTABLE_FIELD.replace('{0}', field));
|
|
}
|
|
}
|
|
|
|
return opTools.validateCommon(doc, res, { isPatching });
|
|
}
|
|
|
|
module.exports = validate;
|