@futdevpro/nts-dynamo 1.15.316 → 1.15.320
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/build/_collections/database-unavailable.util.d.ts +27 -0
- package/build/_collections/database-unavailable.util.d.ts.map +1 -0
- package/build/_collections/database-unavailable.util.js +55 -0
- package/build/_collections/database-unavailable.util.js.map +1 -0
- package/build/_modules/privacy-lifecycle/index.d.ts +2 -0
- package/build/_modules/privacy-lifecycle/index.d.ts.map +1 -1
- package/build/_modules/privacy-lifecycle/index.js +5 -1
- package/build/_modules/privacy-lifecycle/index.js.map +1 -1
- package/build/_modules/privacy-lifecycle/privacy-ledger.mongo-store.d.ts +92 -0
- package/build/_modules/privacy-lifecycle/privacy-ledger.mongo-store.d.ts.map +1 -0
- package/build/_modules/privacy-lifecycle/privacy-ledger.mongo-store.js +295 -0
- package/build/_modules/privacy-lifecycle/privacy-ledger.mongo-store.js.map +1 -0
- package/build/_modules/privacy-lifecycle/privacy-lifecycle.mongo-store.d.ts +136 -0
- package/build/_modules/privacy-lifecycle/privacy-lifecycle.mongo-store.d.ts.map +1 -0
- package/build/_modules/privacy-lifecycle/privacy-lifecycle.mongo-store.js +316 -0
- package/build/_modules/privacy-lifecycle/privacy-lifecycle.mongo-store.js.map +1 -0
- package/build/_modules/usage/index.d.ts +2 -0
- package/build/_modules/usage/index.d.ts.map +1 -1
- package/build/_modules/usage/index.js +2 -0
- package/build/_modules/usage/index.js.map +1 -1
- package/build/_modules/usage/usage-session-account-query.interface.d.ts +13 -0
- package/build/_modules/usage/usage-session-account-query.interface.d.ts.map +1 -0
- package/build/_modules/usage/usage-session-account-query.interface.js +3 -0
- package/build/_modules/usage/usage-session-account-query.interface.js.map +1 -0
- package/build/_modules/usage/usage-session-owner.interface.d.ts +15 -0
- package/build/_modules/usage/usage-session-owner.interface.d.ts.map +1 -0
- package/build/_modules/usage/usage-session-owner.interface.js +3 -0
- package/build/_modules/usage/usage-session-owner.interface.js.map +1 -0
- package/build/_modules/usage/usage.controller.d.ts +16 -0
- package/build/_modules/usage/usage.controller.d.ts.map +1 -1
- package/build/_modules/usage/usage.controller.js +42 -9
- package/build/_modules/usage/usage.controller.js.map +1 -1
- package/build/_modules/usage/usage.data-service.d.ts +41 -1
- package/build/_modules/usage/usage.data-service.d.ts.map +1 -1
- package/build/_modules/usage/usage.data-service.js +112 -0
- package/build/_modules/usage/usage.data-service.js.map +1 -1
- package/build/_services/base/db.service.d.ts.map +1 -1
- package/build/_services/base/db.service.js +7 -2
- package/build/_services/base/db.service.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recognises "the database is not reachable right now" errors and maps them to a truthful HTTP status.
|
|
3
|
+
*
|
|
4
|
+
* @description BFR-FDPAUTHSERVICE-008. A database outage window (Mongo container recreate, network re-attach,
|
|
5
|
+
* driver reconnect) used to surface as a plain `500` through every DyNTS wrapper — the worst possible answer:
|
|
6
|
+
* the caller cannot tell "server bug" from "try again in a moment", and nothing retries. These errors are
|
|
7
|
+
* TRANSIENT and not caused by the request, so they are `503 Service Unavailable`.
|
|
8
|
+
*
|
|
9
|
+
* Measured (2026-09-22, real driver): an operation on a disconnected client throws `MongoNotConnectedError`;
|
|
10
|
+
* the 2026-06 live incident threw mongoose's "buffering timed out after 10000ms"; a lost host gives a
|
|
11
|
+
* server-selection / network error. Anything else (validation, duplicate key, bad query) stays a `500`.
|
|
12
|
+
*/
|
|
13
|
+
export declare class DyNTS_DatabaseUnavailable_Util {
|
|
14
|
+
/** The HTTP status of a transient database outage. */
|
|
15
|
+
static readonly status: number;
|
|
16
|
+
/** A user-facing message that is honest and actionable, without internals. */
|
|
17
|
+
static readonly userMessage: string;
|
|
18
|
+
/** Driver / mongoose error names that mean "not reachable", never "bad request" or "bug". */
|
|
19
|
+
private static readonly unavailableErrorNames;
|
|
20
|
+
/**
|
|
21
|
+
* True if the error (or any error it wraps, e.g. a `DyFM_Error` chain) is a transient database outage.
|
|
22
|
+
*
|
|
23
|
+
* @param error any thrown value
|
|
24
|
+
*/
|
|
25
|
+
static isDatabaseUnavailable(error: unknown): boolean;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=database-unavailable.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-unavailable.util.d.ts","sourceRoot":"","sources":["../../src/_collections/database-unavailable.util.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,qBAAa,8BAA8B;IACzC,sDAAsD;IACtD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAO;IAErC,8EAA8E;IAC9E,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CACwD;IAE3F,6FAA6F;IAC7F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAQ1C;IAEH;;;;OAIG;IACH,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;CAsBtD"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_DatabaseUnavailable_Util = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Recognises "the database is not reachable right now" errors and maps them to a truthful HTTP status.
|
|
6
|
+
*
|
|
7
|
+
* @description BFR-FDPAUTHSERVICE-008. A database outage window (Mongo container recreate, network re-attach,
|
|
8
|
+
* driver reconnect) used to surface as a plain `500` through every DyNTS wrapper — the worst possible answer:
|
|
9
|
+
* the caller cannot tell "server bug" from "try again in a moment", and nothing retries. These errors are
|
|
10
|
+
* TRANSIENT and not caused by the request, so they are `503 Service Unavailable`.
|
|
11
|
+
*
|
|
12
|
+
* Measured (2026-09-22, real driver): an operation on a disconnected client throws `MongoNotConnectedError`;
|
|
13
|
+
* the 2026-06 live incident threw mongoose's "buffering timed out after 10000ms"; a lost host gives a
|
|
14
|
+
* server-selection / network error. Anything else (validation, duplicate key, bad query) stays a `500`.
|
|
15
|
+
*/
|
|
16
|
+
class DyNTS_DatabaseUnavailable_Util {
|
|
17
|
+
/** The HTTP status of a transient database outage. */
|
|
18
|
+
static status = 503;
|
|
19
|
+
/** A user-facing message that is honest and actionable, without internals. */
|
|
20
|
+
static userMessage = 'The service is temporarily unable to reach its database. Please try again in a moment.';
|
|
21
|
+
/** Driver / mongoose error names that mean "not reachable", never "bad request" or "bug". */
|
|
22
|
+
static unavailableErrorNames = new Set([
|
|
23
|
+
'MongoNotConnectedError',
|
|
24
|
+
'MongoServerSelectionError',
|
|
25
|
+
'MongooseServerSelectionError',
|
|
26
|
+
'MongoNetworkError',
|
|
27
|
+
'MongoNetworkTimeoutError',
|
|
28
|
+
'MongoTopologyClosedError',
|
|
29
|
+
'MongoPoolClosedError',
|
|
30
|
+
]);
|
|
31
|
+
/**
|
|
32
|
+
* True if the error (or any error it wraps, e.g. a `DyFM_Error` chain) is a transient database outage.
|
|
33
|
+
*
|
|
34
|
+
* @param error any thrown value
|
|
35
|
+
*/
|
|
36
|
+
static isDatabaseUnavailable(error) {
|
|
37
|
+
let current = error;
|
|
38
|
+
// walk the wrap chain (DyFM_Error keeps the cause in `error`); bounded, so a cyclic object cannot hang us
|
|
39
|
+
for (let depth = 0; depth < 16 && typeof current === 'object' && current !== null; depth++) {
|
|
40
|
+
const name = Reflect.get(current, 'name');
|
|
41
|
+
const message = Reflect.get(current, 'message');
|
|
42
|
+
if (typeof name === 'string' && DyNTS_DatabaseUnavailable_Util.unavailableErrorNames.has(name)) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
// mongoose (no connection yet / lost): "Operation `accounts.findOne()` buffering timed out after 10000ms"
|
|
46
|
+
if (typeof message === 'string' && /buffering timed out after \d+ms/u.test(message)) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
current = Reflect.get(current, 'error');
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.DyNTS_DatabaseUnavailable_Util = DyNTS_DatabaseUnavailable_Util;
|
|
55
|
+
//# sourceMappingURL=database-unavailable.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-unavailable.util.js","sourceRoot":"","sources":["../../src/_collections/database-unavailable.util.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;GAWG;AACH,MAAa,8BAA8B;IACzC,sDAAsD;IACtD,MAAM,CAAU,MAAM,GAAW,GAAG,CAAC;IAErC,8EAA8E;IAC9E,MAAM,CAAU,WAAW,GACzB,wFAAwF,CAAC;IAE3F,6FAA6F;IACrF,MAAM,CAAU,qBAAqB,GAAwB,IAAI,GAAG,CAAS;QACnF,wBAAwB;QACxB,2BAA2B;QAC3B,8BAA8B;QAC9B,mBAAmB;QACnB,0BAA0B;QAC1B,0BAA0B;QAC1B,sBAAsB;KACvB,CAAC,CAAC;IAEH;;;;OAIG;IACH,MAAM,CAAC,qBAAqB,CAAC,KAAc;QACzC,IAAI,OAAO,GAAY,KAAK,CAAC;QAE7B,0GAA0G;QAC1G,KAAK,IAAI,KAAK,GAAW,CAAC,EAAE,KAAK,GAAG,EAAE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACnG,MAAM,IAAI,GAAY,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,OAAO,GAAY,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAEzD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,8BAA8B,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/F,OAAO,IAAI,CAAC;YACd,CAAC;YAED,0GAA0G;YAC1G,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,kCAAkC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpF,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;;AA7CH,wEA8CC"}
|
|
@@ -20,6 +20,8 @@ export { DyNTS_PrivacyConsentAuthorization_ControlService } from './privacy-cons
|
|
|
20
20
|
export { DyNTS_PrivacyExportArtifact_ControlService } from './privacy-export-artifact.control-service';
|
|
21
21
|
export { DyNTS_PrivacyExportArtifactPrivacyContributor_ControlService, DyNTS_privacyExportArtifactContributorId } from './privacy-export-artifact-privacy-contributor.control-service';
|
|
22
22
|
export { DyNTS_PrivacyExportArtifact_MongoStore } from './privacy-export-artifact.mongo-store';
|
|
23
|
+
export { DyNTS_PrivacyLifecycle_MongoStore, DyNTS_PrivacyLifecycleMongoStore_Settings, DyNTS_PrivacyStoredOutcome_Row, DyNTS_PrivacyStoredPlan_Row } from './privacy-lifecycle.mongo-store';
|
|
24
|
+
export { DyNTS_PrivacyLedger_MongoStore, DyNTS_PrivacyLedgerMongoStore_Settings, DyNTS_PrivacyStoredConsent_Row, DyNTS_PrivacyStoredLegalAcceptance_Row } from './privacy-ledger.mongo-store';
|
|
23
25
|
export { DyNTS_PrivacyExportBundle_ControlService } from './privacy-export-bundle.control-service';
|
|
24
26
|
export { DyNTS_PrivacyConsentDecision_Type } from './_enums/privacy-consent-decision.type-enum';
|
|
25
27
|
export { DyNTS_PrivacyConsentAuthorizationReason_Type } from './_enums/privacy-consent-authorization-reason.type-enum';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/privacy-lifecycle/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/privacy-lifecycle/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DyNTS_PrivacyRequest_Type = exports.DyNTS_PrivacyRequestState_Type = exports.DyNTS_PrivacyContributorOutcome_Type = exports.DyNTS_PrivacyContributorExecutionMode_Type = exports.DyNTS_PrivacyContributorAction_Type = exports.DyNTS_PrivacyConsentAuthorizationReason_Type = exports.DyNTS_PrivacyConsentDecision_Type = exports.DyNTS_PrivacyExportBundle_ControlService = exports.DyNTS_PrivacyExportArtifact_MongoStore = exports.DyNTS_privacyExportArtifactContributorId = exports.DyNTS_PrivacyExportArtifactPrivacyContributor_ControlService = exports.DyNTS_PrivacyExportArtifact_ControlService = exports.DyNTS_PrivacyConsentAuthorization_ControlService = exports.DyNTS_PrivacyLedger_ControlService = exports.DyNTS_PrivacyRequestCursor_ControlService = exports.DyNTS_PrivacyMutationGate_MongoStore = exports.DyNTS_PrivacyRightsNotificationState_Type = exports.DyNTS_PrivacyRightsNotificationChannel_Type = exports.DyNTS_PrivacyRightsRectificationDecision_Type = exports.DyNTS_PrivacyRightsPurposeDecision_Type = exports.DyNTS_PrivacyRightsValue_Type = exports.DyNTS_PrivacyRightsNotification_MongoStore = exports.DyNTS_PrivacyRightsExecution_MongoStore = exports.DyNTS_PrivacyRightsCustody_MongoStore = exports.DyNTS_PrivacyRightsInput_ControlService = exports.DyNTS_PrivacyContributorRequestRouter_ControlService = exports.DyNTS_PrivacyLifecycle_ControlService = void 0;
|
|
3
|
+
exports.DyNTS_PrivacyRequest_Type = exports.DyNTS_PrivacyRequestState_Type = exports.DyNTS_PrivacyContributorOutcome_Type = exports.DyNTS_PrivacyContributorExecutionMode_Type = exports.DyNTS_PrivacyContributorAction_Type = exports.DyNTS_PrivacyConsentAuthorizationReason_Type = exports.DyNTS_PrivacyConsentDecision_Type = exports.DyNTS_PrivacyExportBundle_ControlService = exports.DyNTS_PrivacyLedger_MongoStore = exports.DyNTS_PrivacyLifecycle_MongoStore = exports.DyNTS_PrivacyExportArtifact_MongoStore = exports.DyNTS_privacyExportArtifactContributorId = exports.DyNTS_PrivacyExportArtifactPrivacyContributor_ControlService = exports.DyNTS_PrivacyExportArtifact_ControlService = exports.DyNTS_PrivacyConsentAuthorization_ControlService = exports.DyNTS_PrivacyLedger_ControlService = exports.DyNTS_PrivacyRequestCursor_ControlService = exports.DyNTS_PrivacyMutationGate_MongoStore = exports.DyNTS_PrivacyRightsNotificationState_Type = exports.DyNTS_PrivacyRightsNotificationChannel_Type = exports.DyNTS_PrivacyRightsRectificationDecision_Type = exports.DyNTS_PrivacyRightsPurposeDecision_Type = exports.DyNTS_PrivacyRightsValue_Type = exports.DyNTS_PrivacyRightsNotification_MongoStore = exports.DyNTS_PrivacyRightsExecution_MongoStore = exports.DyNTS_PrivacyRightsCustody_MongoStore = exports.DyNTS_PrivacyRightsInput_ControlService = exports.DyNTS_PrivacyContributorRequestRouter_ControlService = exports.DyNTS_PrivacyLifecycle_ControlService = void 0;
|
|
4
4
|
var privacy_lifecycle_control_service_1 = require("./privacy-lifecycle.control-service");
|
|
5
5
|
Object.defineProperty(exports, "DyNTS_PrivacyLifecycle_ControlService", { enumerable: true, get: function () { return privacy_lifecycle_control_service_1.DyNTS_PrivacyLifecycle_ControlService; } });
|
|
6
6
|
var privacy_contributor_request_router_control_service_1 = require("./privacy-contributor-request-router.control-service");
|
|
@@ -36,6 +36,10 @@ Object.defineProperty(exports, "DyNTS_PrivacyExportArtifactPrivacyContributor_Co
|
|
|
36
36
|
Object.defineProperty(exports, "DyNTS_privacyExportArtifactContributorId", { enumerable: true, get: function () { return privacy_export_artifact_privacy_contributor_control_service_1.DyNTS_privacyExportArtifactContributorId; } });
|
|
37
37
|
var privacy_export_artifact_mongo_store_1 = require("./privacy-export-artifact.mongo-store");
|
|
38
38
|
Object.defineProperty(exports, "DyNTS_PrivacyExportArtifact_MongoStore", { enumerable: true, get: function () { return privacy_export_artifact_mongo_store_1.DyNTS_PrivacyExportArtifact_MongoStore; } });
|
|
39
|
+
var privacy_lifecycle_mongo_store_1 = require("./privacy-lifecycle.mongo-store");
|
|
40
|
+
Object.defineProperty(exports, "DyNTS_PrivacyLifecycle_MongoStore", { enumerable: true, get: function () { return privacy_lifecycle_mongo_store_1.DyNTS_PrivacyLifecycle_MongoStore; } });
|
|
41
|
+
var privacy_ledger_mongo_store_1 = require("./privacy-ledger.mongo-store");
|
|
42
|
+
Object.defineProperty(exports, "DyNTS_PrivacyLedger_MongoStore", { enumerable: true, get: function () { return privacy_ledger_mongo_store_1.DyNTS_PrivacyLedger_MongoStore; } });
|
|
39
43
|
var privacy_export_bundle_control_service_1 = require("./privacy-export-bundle.control-service");
|
|
40
44
|
Object.defineProperty(exports, "DyNTS_PrivacyExportBundle_ControlService", { enumerable: true, get: function () { return privacy_export_bundle_control_service_1.DyNTS_PrivacyExportBundle_ControlService; } });
|
|
41
45
|
var privacy_consent_decision_type_enum_1 = require("./_enums/privacy-consent-decision.type-enum");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/privacy-lifecycle/index.ts"],"names":[],"mappings":";;;AAAA,yFAA4F;AAAnF,0JAAA,qCAAqC,OAAA;AAC9C,2HAE8D;AAD5D,0LAAA,oDAAoD,OAAA;AAEtD,+FAAiG;AAAxF,+JAAA,uCAAuC,OAAA;AAChD,2FAA6F;AAApF,2JAAA,qCAAqC,OAAA;AAC9C,+FAAiG;AAAxF,+JAAA,uCAAuC,OAAA;AAChD,qGAAuG;AAA9F,qKAAA,0CAA0C,OAAA;AAUnD,0FAAwF;AAA/E,+IAAA,6BAA6B,OAAA;AACtC,gGAGoD;AAFlD,4JAAA,uCAAuC,OAAA;AACvC,kKAAA,6CAA6C,OAAA;AAgC/C,oHAG8D;AAF5D,0KAAA,2CAA2C,OAAA;AAC3C,wKAAA,yCAAyC,OAAA;AAE3C,yFAA2F;AAAlF,yJAAA,oCAAoC,OAAA;AAM7C,mGAAqG;AAA5F,mKAAA,yCAAyC,OAAA;AAClD,mFAAsF;AAA7E,oJAAA,kCAAkC,OAAA;AAC3C,iHAEyD;AADvD,iLAAA,gDAAgD,OAAA;AAElD,qGAAuG;AAA9F,qKAAA,0CAA0C,OAAA;AACnD,6IAGuE;AAFrE,2MAAA,4DAA4D,OAAA;AAC5D,uLAAA,wCAAwC,OAAA;AAE1C,6FAA+F;AAAtF,6JAAA,sCAAsC,OAAA;AAC/C,iGAAmG;AAA1F,iKAAA,wCAAwC,OAAA;AACjD,kGAAgG;AAAvF,uJAAA,iCAAiC,OAAA;AAC1C,0HAEiE;AAD/D,8KAAA,4CAA4C,OAAA;AAE9C,sGAAoG;AAA3F,2JAAA,mCAAmC,OAAA;AAC5C,sHAE+D;AAD7D,0KAAA,0CAA0C,OAAA;AAE5C,wGAAsG;AAA7F,6JAAA,oCAAoC,OAAA;AAC7C,4FAA0F;AAAjF,iJAAA,8BAA8B,OAAA;AACvC,gFAA+E;AAAtE,sIAAA,yBAAyB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/privacy-lifecycle/index.ts"],"names":[],"mappings":";;;AAAA,yFAA4F;AAAnF,0JAAA,qCAAqC,OAAA;AAC9C,2HAE8D;AAD5D,0LAAA,oDAAoD,OAAA;AAEtD,+FAAiG;AAAxF,+JAAA,uCAAuC,OAAA;AAChD,2FAA6F;AAApF,2JAAA,qCAAqC,OAAA;AAC9C,+FAAiG;AAAxF,+JAAA,uCAAuC,OAAA;AAChD,qGAAuG;AAA9F,qKAAA,0CAA0C,OAAA;AAUnD,0FAAwF;AAA/E,+IAAA,6BAA6B,OAAA;AACtC,gGAGoD;AAFlD,4JAAA,uCAAuC,OAAA;AACvC,kKAAA,6CAA6C,OAAA;AAgC/C,oHAG8D;AAF5D,0KAAA,2CAA2C,OAAA;AAC3C,wKAAA,yCAAyC,OAAA;AAE3C,yFAA2F;AAAlF,yJAAA,oCAAoC,OAAA;AAM7C,mGAAqG;AAA5F,mKAAA,yCAAyC,OAAA;AAClD,mFAAsF;AAA7E,oJAAA,kCAAkC,OAAA;AAC3C,iHAEyD;AADvD,iLAAA,gDAAgD,OAAA;AAElD,qGAAuG;AAA9F,qKAAA,0CAA0C,OAAA;AACnD,6IAGuE;AAFrE,2MAAA,4DAA4D,OAAA;AAC5D,uLAAA,wCAAwC,OAAA;AAE1C,6FAA+F;AAAtF,6JAAA,sCAAsC,OAAA;AAC/C,iFAKyC;AAJvC,kJAAA,iCAAiC,OAAA;AAKnC,2EAKsC;AAJpC,4IAAA,8BAA8B,OAAA;AAKhC,iGAAmG;AAA1F,iKAAA,wCAAwC,OAAA;AACjD,kGAAgG;AAAvF,uJAAA,iCAAiC,OAAA;AAC1C,0HAEiE;AAD/D,8KAAA,4CAA4C,OAAA;AAE9C,sGAAoG;AAA3F,2JAAA,mCAAmC,OAAA;AAC5C,sHAE+D;AAD7D,0KAAA,0CAA0C,OAAA;AAE5C,wGAAsG;AAA7F,6JAAA,oCAAoC,OAAA;AAC7C,4FAA0F;AAAjF,iJAAA,8BAA8B,OAAA;AACvC,gFAA+E;AAAtE,sIAAA,yBAAyB,OAAA"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ClientSession, Model, Schema } from 'mongoose';
|
|
2
|
+
import { DyNTS_PrivacyConsentPersistenceResult_Interface } from './_models/privacy-consent-persistence-result.interface';
|
|
3
|
+
import { DyNTS_PrivacyConsentRecord_Interface } from './_models/privacy-consent-record.interface';
|
|
4
|
+
import { DyNTS_PrivacyLedgerAdapter_Interface } from './_models/privacy-ledger-adapter.interface';
|
|
5
|
+
import { DyNTS_PrivacyLedgerAdapterPageQuery_Interface } from './_models/privacy-ledger-page.interface';
|
|
6
|
+
import { DyNTS_PrivacyLegalAcceptance_Interface } from './_models/privacy-legal-acceptance.interface';
|
|
7
|
+
import { DyNTS_PrivacyLegalAcceptancePersistenceResult_Interface } from './_models/privacy-legal-acceptance-persistence-result.interface';
|
|
8
|
+
/** Stored legal acceptance: the contract shape with `acceptedAt` as a real `Date` (correct keyset order). */
|
|
9
|
+
export type DyNTS_PrivacyStoredLegalAcceptance_Row = Omit<DyNTS_PrivacyLegalAcceptance_Interface, 'acceptedAt'> & {
|
|
10
|
+
acceptedAt: Date;
|
|
11
|
+
};
|
|
12
|
+
/** Stored consent event: the contract shape with `occurredAt` as a real `Date` (correct keyset order). */
|
|
13
|
+
export type DyNTS_PrivacyStoredConsent_Row = Omit<DyNTS_PrivacyConsentRecord_Interface, 'occurredAt'> & {
|
|
14
|
+
occurredAt: Date;
|
|
15
|
+
};
|
|
16
|
+
/** Optional isolated models — integration tests bind them to a dedicated connection. */
|
|
17
|
+
export interface DyNTS_PrivacyLedgerMongoStore_Settings {
|
|
18
|
+
legalModel?: Model<DyNTS_PrivacyStoredLegalAcceptance_Row>;
|
|
19
|
+
consentModel?: Model<DyNTS_PrivacyStoredConsent_Row>;
|
|
20
|
+
/** Upper bound of the legacy UNPAGED reads (`listLegalAcceptances` / `listConsentHistory`). Default 100. */
|
|
21
|
+
unpagedReadMax?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Append-only Mongo persistence for the legal-acceptance and consent ledger — the production
|
|
25
|
+
* `DyNTS_PrivacyLedgerAdapter_Interface` (BFR-FUTDEVPRO-010, second half).
|
|
26
|
+
*
|
|
27
|
+
* @description Lifted from the company-toolmaker `PR_PrivacyLedger_MongoAdapter` (behaviour, keyset order, the
|
|
28
|
+
* bounded unpaged read), but standalone: no product data-model, own strict schemas and collections.
|
|
29
|
+
*
|
|
30
|
+
* - Append-only: every field is immutable and the store exposes NO update/delete — the ledger is evidence.
|
|
31
|
+
* - Idempotent replay: the UNIQUE `idempotencyHash` index decides; the loser of a race returns the winner.
|
|
32
|
+
* - Keyset paging newest-first by `(time, eventId)` — both unique together, so no row is skipped or repeated.
|
|
33
|
+
*
|
|
34
|
+
* ⚠️ TRANSACTIONS. When the caller passes a `session`, a duplicate-key error ABORTS the Mongo transaction, so the
|
|
35
|
+
* "catch, then read the winner" replay cannot run inside it (the toolmaker copy would fail there). Inside a
|
|
36
|
+
* session the store therefore reads FIRST, and if a concurrent transaction still wins the insert race, the
|
|
37
|
+
* duplicate-key error is labelled `TransientTransactionError` — the caller's `withTransaction` retries, and the
|
|
38
|
+
* retry's read finds the committed winner. Without a session the classic insert-then-replay path is used.
|
|
39
|
+
* (Measured on a real replica set: under snapshot isolation a concurrent winner usually surfaces as a
|
|
40
|
+
* server-labelled WriteConflict; the store's own label covers the E11000 variant — both end in a retry.)
|
|
41
|
+
*/
|
|
42
|
+
export declare class DyNTS_PrivacyLedger_MongoStore implements DyNTS_PrivacyLedgerAdapter_Interface {
|
|
43
|
+
private readonly injected;
|
|
44
|
+
private readonly unpagedReadMax;
|
|
45
|
+
private readiness?;
|
|
46
|
+
/** Accepts isolated models for integration tests; production resolves the singletons lazily. */
|
|
47
|
+
constructor(set?: DyNTS_PrivacyLedgerMongoStore_Settings);
|
|
48
|
+
/** Creates the unique replay/id and the paging indexes BEFORE the first read or write. */
|
|
49
|
+
ensureReady(): Promise<void>;
|
|
50
|
+
/** Appends one legal acceptance, or returns the stored one on an exact idempotent replay. */
|
|
51
|
+
appendLegalAcceptance(acceptance: DyNTS_PrivacyLegalAcceptance_Interface, session?: ClientSession): Promise<DyNTS_PrivacyLegalAcceptancePersistenceResult_Interface>;
|
|
52
|
+
/** Appends one consent event, or returns the stored one on an exact idempotent replay. */
|
|
53
|
+
appendConsent(record: DyNTS_PrivacyConsentRecord_Interface, session?: ClientSession): Promise<DyNTS_PrivacyConsentPersistenceResult_Interface>;
|
|
54
|
+
/** All legal evidence of one subject+organization, oldest first — bounded, fail-closed above the limit. */
|
|
55
|
+
listLegalAcceptances(subjectId: string, organizationId: string): Promise<DyNTS_PrivacyLegalAcceptance_Interface[]>;
|
|
56
|
+
/** The consent history of one subject+organization in durable append order, oldest first — bounded. */
|
|
57
|
+
listConsentHistory(subjectId: string, organizationId: string): Promise<DyNTS_PrivacyConsentRecord_Interface[]>;
|
|
58
|
+
/** The latest exact-purpose decision, or null. Insertion order resolves equal timestamps. */
|
|
59
|
+
findLatestConsent(subjectId: string, organizationId: string, purposeCode: string): Promise<DyNTS_PrivacyConsentRecord_Interface | null>;
|
|
60
|
+
/** One newest-first legal page with a strict `(acceptedAt, acceptanceId)` keyset. */
|
|
61
|
+
listLegalAcceptancesPage(subjectId: string, organizationId: string, query: DyNTS_PrivacyLedgerAdapterPageQuery_Interface): Promise<DyNTS_PrivacyLegalAcceptance_Interface[]>;
|
|
62
|
+
/** One newest-first consent-history page with a strict `(occurredAt, consentId)` keyset. */
|
|
63
|
+
listConsentHistoryPage(subjectId: string, organizationId: string, query: DyNTS_PrivacyLedgerAdapterPageQuery_Interface): Promise<DyNTS_PrivacyConsentRecord_Interface[]>;
|
|
64
|
+
/** Only the latest decision per purpose, then the same strict newest-first page order. */
|
|
65
|
+
listCurrentConsentsPage(subjectId: string, organizationId: string, query: DyNTS_PrivacyLedgerAdapterPageQuery_Interface): Promise<DyNTS_PrivacyConsentRecord_Interface[]>;
|
|
66
|
+
/** Strict legal-acceptance schema — every field immutable (append-only evidence). */
|
|
67
|
+
static createLegalAcceptanceSchema(): Schema<DyNTS_PrivacyStoredLegalAcceptance_Row>;
|
|
68
|
+
/** Strict consent-event schema — every field immutable (append-only evidence). */
|
|
69
|
+
static createConsentSchema(): Schema<DyNTS_PrivacyStoredConsent_Row>;
|
|
70
|
+
/**
|
|
71
|
+
* The shared append-or-replay core of both ledgers.
|
|
72
|
+
*
|
|
73
|
+
* @description Without a session: insert, and on a duplicate key read the winner. Inside a session: read first
|
|
74
|
+
* (a duplicate-key error would abort the transaction), insert only when absent, and label a lost insert race
|
|
75
|
+
* `TransientTransactionError` so the caller's `withTransaction` retries into the read-first branch.
|
|
76
|
+
*/
|
|
77
|
+
private appendIdempotent;
|
|
78
|
+
/** Fail-closed guard of the legacy unpaged reads — above the bound the caller must page. */
|
|
79
|
+
private assertBoundedRead;
|
|
80
|
+
/** Keyset filter strictly AFTER the given `(time, eventId)` position in newest-first order. */
|
|
81
|
+
private afterFilter;
|
|
82
|
+
/** Contract shape from a stored row — an ALLOW-list, so `_id` never leaks into the domain. */
|
|
83
|
+
private toLegalRecord;
|
|
84
|
+
/** Contract shape from a stored row — an ALLOW-list, so `_id` never leaks into the domain. */
|
|
85
|
+
private toConsentRecord;
|
|
86
|
+
private getLegalModel;
|
|
87
|
+
private getConsentModel;
|
|
88
|
+
/** Lazy one-time model resolution — a second `mongoose.model(name, schema)` for one name would throw. */
|
|
89
|
+
private resolveModel;
|
|
90
|
+
private isDuplicateKey;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=privacy-ledger.mongo-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privacy-ledger.mongo-store.d.ts","sourceRoot":"","sources":["../../../src/_modules/privacy-lifecycle/privacy-ledger.mongo-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_PrivacyLedger_MongoStore = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const mongoose_1 = tslib_1.__importStar(require("mongoose"));
|
|
6
|
+
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
7
|
+
const privacy_consent_decision_type_enum_1 = require("./_enums/privacy-consent-decision.type-enum");
|
|
8
|
+
const DyNTS_privacyLegalAcceptanceModelName = 'DyNTSPrivacyLegalAcceptance';
|
|
9
|
+
const DyNTS_privacyConsentModelName = 'DyNTSPrivacyConsent';
|
|
10
|
+
/**
|
|
11
|
+
* Append-only Mongo persistence for the legal-acceptance and consent ledger — the production
|
|
12
|
+
* `DyNTS_PrivacyLedgerAdapter_Interface` (BFR-FUTDEVPRO-010, second half).
|
|
13
|
+
*
|
|
14
|
+
* @description Lifted from the company-toolmaker `PR_PrivacyLedger_MongoAdapter` (behaviour, keyset order, the
|
|
15
|
+
* bounded unpaged read), but standalone: no product data-model, own strict schemas and collections.
|
|
16
|
+
*
|
|
17
|
+
* - Append-only: every field is immutable and the store exposes NO update/delete — the ledger is evidence.
|
|
18
|
+
* - Idempotent replay: the UNIQUE `idempotencyHash` index decides; the loser of a race returns the winner.
|
|
19
|
+
* - Keyset paging newest-first by `(time, eventId)` — both unique together, so no row is skipped or repeated.
|
|
20
|
+
*
|
|
21
|
+
* ⚠️ TRANSACTIONS. When the caller passes a `session`, a duplicate-key error ABORTS the Mongo transaction, so the
|
|
22
|
+
* "catch, then read the winner" replay cannot run inside it (the toolmaker copy would fail there). Inside a
|
|
23
|
+
* session the store therefore reads FIRST, and if a concurrent transaction still wins the insert race, the
|
|
24
|
+
* duplicate-key error is labelled `TransientTransactionError` — the caller's `withTransaction` retries, and the
|
|
25
|
+
* retry's read finds the committed winner. Without a session the classic insert-then-replay path is used.
|
|
26
|
+
* (Measured on a real replica set: under snapshot isolation a concurrent winner usually surfaces as a
|
|
27
|
+
* server-labelled WriteConflict; the store's own label covers the E11000 variant — both end in a retry.)
|
|
28
|
+
*/
|
|
29
|
+
class DyNTS_PrivacyLedger_MongoStore {
|
|
30
|
+
injected;
|
|
31
|
+
unpagedReadMax;
|
|
32
|
+
readiness;
|
|
33
|
+
/** Accepts isolated models for integration tests; production resolves the singletons lazily. */
|
|
34
|
+
constructor(set = {}) {
|
|
35
|
+
this.injected = set;
|
|
36
|
+
this.unpagedReadMax = set.unpagedReadMax ?? 100;
|
|
37
|
+
if (!Number.isSafeInteger(this.unpagedReadMax) || this.unpagedReadMax < 1) {
|
|
38
|
+
throw new Error('DYNTS|PRIVACY_LEDGER|INVALID_SETTINGS');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Creates the unique replay/id and the paging indexes BEFORE the first read or write. */
|
|
42
|
+
async ensureReady() {
|
|
43
|
+
this.readiness ??= Promise.all([
|
|
44
|
+
this.getLegalModel().createIndexes(),
|
|
45
|
+
this.getConsentModel().createIndexes(),
|
|
46
|
+
])
|
|
47
|
+
.then(() => undefined)
|
|
48
|
+
.catch((error) => {
|
|
49
|
+
this.readiness = undefined;
|
|
50
|
+
throw error;
|
|
51
|
+
});
|
|
52
|
+
await this.readiness;
|
|
53
|
+
}
|
|
54
|
+
/** Appends one legal acceptance, or returns the stored one on an exact idempotent replay. */
|
|
55
|
+
async appendLegalAcceptance(acceptance, session) {
|
|
56
|
+
const result = await this.appendIdempotent(this.getLegalModel(), { ...acceptance, acceptedAt: new Date(acceptance.acceptedAt) }, session);
|
|
57
|
+
return { acceptance: this.toLegalRecord(result.row), created: result.created };
|
|
58
|
+
}
|
|
59
|
+
/** Appends one consent event, or returns the stored one on an exact idempotent replay. */
|
|
60
|
+
async appendConsent(record, session) {
|
|
61
|
+
const result = await this.appendIdempotent(this.getConsentModel(), { ...record, occurredAt: new Date(record.occurredAt) }, session);
|
|
62
|
+
return { consent: this.toConsentRecord(result.row), created: result.created };
|
|
63
|
+
}
|
|
64
|
+
/** All legal evidence of one subject+organization, oldest first — bounded, fail-closed above the limit. */
|
|
65
|
+
async listLegalAcceptances(subjectId, organizationId) {
|
|
66
|
+
const rows = await this.getLegalModel()
|
|
67
|
+
.find({ subjectId: subjectId, organizationId: organizationId })
|
|
68
|
+
.sort({ acceptedAt: 1, acceptanceId: 1 })
|
|
69
|
+
.limit(this.unpagedReadMax + 1)
|
|
70
|
+
.lean().exec();
|
|
71
|
+
this.assertBoundedRead(rows.length);
|
|
72
|
+
return rows.map((row) => this.toLegalRecord(row));
|
|
73
|
+
}
|
|
74
|
+
/** The consent history of one subject+organization in durable append order, oldest first — bounded. */
|
|
75
|
+
async listConsentHistory(subjectId, organizationId) {
|
|
76
|
+
const rows = await this.getConsentModel()
|
|
77
|
+
.find({ subjectId: subjectId, organizationId: organizationId })
|
|
78
|
+
.sort({ occurredAt: 1, _id: 1 })
|
|
79
|
+
.limit(this.unpagedReadMax + 1)
|
|
80
|
+
.lean().exec();
|
|
81
|
+
this.assertBoundedRead(rows.length);
|
|
82
|
+
return rows.map((row) => this.toConsentRecord(row));
|
|
83
|
+
}
|
|
84
|
+
/** The latest exact-purpose decision, or null. Insertion order resolves equal timestamps. */
|
|
85
|
+
async findLatestConsent(subjectId, organizationId, purposeCode) {
|
|
86
|
+
const row = await this.getConsentModel()
|
|
87
|
+
.findOne({ subjectId: subjectId, organizationId: organizationId, purposeCode: purposeCode })
|
|
88
|
+
.sort({ occurredAt: -1, _id: -1 })
|
|
89
|
+
.lean().exec();
|
|
90
|
+
return row ? this.toConsentRecord(row) : null;
|
|
91
|
+
}
|
|
92
|
+
/** One newest-first legal page with a strict `(acceptedAt, acceptanceId)` keyset. */
|
|
93
|
+
async listLegalAcceptancesPage(subjectId, organizationId, query) {
|
|
94
|
+
const rows = await this.getLegalModel().find({
|
|
95
|
+
subjectId: subjectId,
|
|
96
|
+
organizationId: organizationId,
|
|
97
|
+
...this.afterFilter(query, 'acceptedAt', 'acceptanceId'),
|
|
98
|
+
}).sort({ acceptedAt: -1, acceptanceId: -1 })
|
|
99
|
+
.limit(query.limit)
|
|
100
|
+
.lean().exec();
|
|
101
|
+
return rows.map((row) => this.toLegalRecord(row));
|
|
102
|
+
}
|
|
103
|
+
/** One newest-first consent-history page with a strict `(occurredAt, consentId)` keyset. */
|
|
104
|
+
async listConsentHistoryPage(subjectId, organizationId, query) {
|
|
105
|
+
const rows = await this.getConsentModel().find({
|
|
106
|
+
subjectId: subjectId,
|
|
107
|
+
organizationId: organizationId,
|
|
108
|
+
...this.afterFilter(query, 'occurredAt', 'consentId'),
|
|
109
|
+
}).sort({ occurredAt: -1, consentId: -1 })
|
|
110
|
+
.limit(query.limit)
|
|
111
|
+
.lean().exec();
|
|
112
|
+
return rows.map((row) => this.toConsentRecord(row));
|
|
113
|
+
}
|
|
114
|
+
/** Only the latest decision per purpose, then the same strict newest-first page order. */
|
|
115
|
+
async listCurrentConsentsPage(subjectId, organizationId, query) {
|
|
116
|
+
const after = this.afterFilter(query, 'occurredAt', 'consentId');
|
|
117
|
+
const rows = await this.getConsentModel()
|
|
118
|
+
.aggregate([
|
|
119
|
+
{ $match: { subjectId: subjectId, organizationId: organizationId } },
|
|
120
|
+
// `_id` last: the same insertion-order tie-break as findLatestConsent, so "current" never disagrees with it
|
|
121
|
+
{ $sort: { purposeCode: 1, occurredAt: -1, _id: -1 } },
|
|
122
|
+
{ $group: { _id: '$purposeCode', record: { $first: '$$ROOT' } } },
|
|
123
|
+
{ $replaceRoot: { newRoot: '$record' } },
|
|
124
|
+
...(Object.keys(after).length ? [{ $match: after }] : []),
|
|
125
|
+
{ $sort: { occurredAt: -1, consentId: -1 } },
|
|
126
|
+
{ $limit: query.limit },
|
|
127
|
+
]).exec();
|
|
128
|
+
return rows.map((row) => this.toConsentRecord(row));
|
|
129
|
+
}
|
|
130
|
+
/** Strict legal-acceptance schema — every field immutable (append-only evidence). */
|
|
131
|
+
static createLegalAcceptanceSchema() {
|
|
132
|
+
const schema = new mongoose_1.Schema({
|
|
133
|
+
acceptanceId: { type: String, required: true, immutable: true, maxlength: 128 },
|
|
134
|
+
subjectId: { type: String, required: true, immutable: true, maxlength: 256 },
|
|
135
|
+
organizationId: { type: String, required: true, immutable: true, maxlength: 256 },
|
|
136
|
+
documentType: { type: String, required: true, immutable: true, maxlength: 128 },
|
|
137
|
+
documentVersion: { type: String, required: true, immutable: true, maxlength: 128 },
|
|
138
|
+
documentChecksum: { type: String, required: true, immutable: true, match: /^[a-f0-9]{64}$/u },
|
|
139
|
+
sourceCode: { type: String, required: true, immutable: true, maxlength: 128 },
|
|
140
|
+
idempotencyHash: { type: String, required: true, immutable: true, match: /^[a-f0-9]{64}$/u },
|
|
141
|
+
requestFingerprint: { type: String, required: true, immutable: true, match: /^[a-f0-9]{64}$/u },
|
|
142
|
+
acceptedAt: { type: Date, required: true, immutable: true },
|
|
143
|
+
}, {
|
|
144
|
+
collection: 'dynts_privacy_legal_acceptances',
|
|
145
|
+
strict: 'throw',
|
|
146
|
+
versionKey: false,
|
|
147
|
+
});
|
|
148
|
+
schema.index({ idempotencyHash: 1 }, { unique: true, name: 'uq_dynts_privacy_legal_idempotency' });
|
|
149
|
+
schema.index({ acceptanceId: 1 }, { unique: true, name: 'uq_dynts_privacy_legal_id' });
|
|
150
|
+
schema.index({ subjectId: 1, organizationId: 1, acceptedAt: -1, acceptanceId: -1 }, { name: 'ix_dynts_privacy_legal_subject_page' });
|
|
151
|
+
return schema;
|
|
152
|
+
}
|
|
153
|
+
/** Strict consent-event schema — every field immutable (append-only evidence). */
|
|
154
|
+
static createConsentSchema() {
|
|
155
|
+
const schema = new mongoose_1.Schema({
|
|
156
|
+
consentId: { type: String, required: true, immutable: true, maxlength: 128 },
|
|
157
|
+
subjectId: { type: String, required: true, immutable: true, maxlength: 256 },
|
|
158
|
+
organizationId: { type: String, required: true, immutable: true, maxlength: 256 },
|
|
159
|
+
purposeCode: { type: String, required: true, immutable: true, maxlength: 128 },
|
|
160
|
+
policyVersion: { type: String, required: true, immutable: true, maxlength: 128 },
|
|
161
|
+
decision: {
|
|
162
|
+
type: String, required: true, immutable: true, enum: Object.values(privacy_consent_decision_type_enum_1.DyNTS_PrivacyConsentDecision_Type),
|
|
163
|
+
},
|
|
164
|
+
sourceCode: { type: String, required: true, immutable: true, maxlength: 128 },
|
|
165
|
+
idempotencyHash: { type: String, required: true, immutable: true, match: /^[a-f0-9]{64}$/u },
|
|
166
|
+
requestFingerprint: { type: String, required: true, immutable: true, match: /^[a-f0-9]{64}$/u },
|
|
167
|
+
occurredAt: { type: Date, required: true, immutable: true },
|
|
168
|
+
}, {
|
|
169
|
+
collection: 'dynts_privacy_consents',
|
|
170
|
+
strict: 'throw',
|
|
171
|
+
versionKey: false,
|
|
172
|
+
});
|
|
173
|
+
schema.index({ idempotencyHash: 1 }, { unique: true, name: 'uq_dynts_privacy_consent_idempotency' });
|
|
174
|
+
schema.index({ consentId: 1 }, { unique: true, name: 'uq_dynts_privacy_consent_id' });
|
|
175
|
+
schema.index({ subjectId: 1, organizationId: 1, occurredAt: -1, consentId: -1 }, { name: 'ix_dynts_privacy_consent_subject_page' });
|
|
176
|
+
schema.index({ subjectId: 1, organizationId: 1, purposeCode: 1, occurredAt: -1 }, { name: 'ix_dynts_privacy_consent_subject_purpose' });
|
|
177
|
+
return schema;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* The shared append-or-replay core of both ledgers.
|
|
181
|
+
*
|
|
182
|
+
* @description Without a session: insert, and on a duplicate key read the winner. Inside a session: read first
|
|
183
|
+
* (a duplicate-key error would abort the transaction), insert only when absent, and label a lost insert race
|
|
184
|
+
* `TransientTransactionError` so the caller's `withTransaction` retries into the read-first branch.
|
|
185
|
+
*/
|
|
186
|
+
async appendIdempotent(model, data, session) {
|
|
187
|
+
if (session) {
|
|
188
|
+
const existing = await model.findOne({ idempotencyHash: data.idempotencyHash })
|
|
189
|
+
.session(session).lean().exec();
|
|
190
|
+
if (existing) {
|
|
191
|
+
return { row: existing, created: false };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
const created = session
|
|
196
|
+
? await model.create([data], { session: session })
|
|
197
|
+
: await model.create([data]);
|
|
198
|
+
const value = created[0]?.toObject();
|
|
199
|
+
if (!value) {
|
|
200
|
+
throw new Error('DYNTS|PRIVACY_LEDGER|CREATE_EMPTY');
|
|
201
|
+
}
|
|
202
|
+
return { row: value, created: true };
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
if (!this.isDuplicateKey(error)) {
|
|
206
|
+
throw error;
|
|
207
|
+
}
|
|
208
|
+
if (session) {
|
|
209
|
+
if (error instanceof mongoose_1.mongo.MongoServerError) {
|
|
210
|
+
error.addErrorLabel('TransientTransactionError');
|
|
211
|
+
}
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
const existing = await model.findOne({ idempotencyHash: data.idempotencyHash }).lean().exec();
|
|
215
|
+
if (!existing) {
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
return { row: existing, created: false };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/** Fail-closed guard of the legacy unpaged reads — above the bound the caller must page. */
|
|
222
|
+
assertBoundedRead(rowCount) {
|
|
223
|
+
if (rowCount <= this.unpagedReadMax) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
227
|
+
status: 503,
|
|
228
|
+
errorCode: 'DYNTS|PRIVACY_LEDGER|PAGE_REQUIRED',
|
|
229
|
+
message: `The privacy ledger exceeds the safe unpaged read bound (${this.unpagedReadMax}); use the page API.`,
|
|
230
|
+
userMessage: 'The privacy history is temporarily unavailable. Please try again later.',
|
|
231
|
+
issuerService: this.constructor.name,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/** Keyset filter strictly AFTER the given `(time, eventId)` position in newest-first order. */
|
|
235
|
+
afterFilter(query, timeField, eventIdField) {
|
|
236
|
+
if (!query.after) {
|
|
237
|
+
return {};
|
|
238
|
+
}
|
|
239
|
+
const time = new Date(query.after.occurredAt);
|
|
240
|
+
return {
|
|
241
|
+
$or: [
|
|
242
|
+
{ [timeField]: { $lt: time } },
|
|
243
|
+
{ [timeField]: time, [eventIdField]: { $lt: query.after.eventId } },
|
|
244
|
+
],
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/** Contract shape from a stored row — an ALLOW-list, so `_id` never leaks into the domain. */
|
|
248
|
+
toLegalRecord(row) {
|
|
249
|
+
return {
|
|
250
|
+
acceptanceId: row.acceptanceId,
|
|
251
|
+
subjectId: row.subjectId,
|
|
252
|
+
organizationId: row.organizationId,
|
|
253
|
+
documentType: row.documentType,
|
|
254
|
+
documentVersion: row.documentVersion,
|
|
255
|
+
documentChecksum: row.documentChecksum,
|
|
256
|
+
sourceCode: row.sourceCode,
|
|
257
|
+
idempotencyHash: row.idempotencyHash,
|
|
258
|
+
requestFingerprint: row.requestFingerprint,
|
|
259
|
+
acceptedAt: new Date(row.acceptedAt).toISOString(),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/** Contract shape from a stored row — an ALLOW-list, so `_id` never leaks into the domain. */
|
|
263
|
+
toConsentRecord(row) {
|
|
264
|
+
return {
|
|
265
|
+
consentId: row.consentId,
|
|
266
|
+
subjectId: row.subjectId,
|
|
267
|
+
organizationId: row.organizationId,
|
|
268
|
+
purposeCode: row.purposeCode,
|
|
269
|
+
policyVersion: row.policyVersion,
|
|
270
|
+
decision: row.decision,
|
|
271
|
+
sourceCode: row.sourceCode,
|
|
272
|
+
idempotencyHash: row.idempotencyHash,
|
|
273
|
+
requestFingerprint: row.requestFingerprint,
|
|
274
|
+
occurredAt: new Date(row.occurredAt).toISOString(),
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
getLegalModel() {
|
|
278
|
+
return this.injected.legalModel ?? this.resolveModel(DyNTS_privacyLegalAcceptanceModelName, DyNTS_PrivacyLedger_MongoStore.createLegalAcceptanceSchema());
|
|
279
|
+
}
|
|
280
|
+
getConsentModel() {
|
|
281
|
+
return this.injected.consentModel ?? this.resolveModel(DyNTS_privacyConsentModelName, DyNTS_PrivacyLedger_MongoStore.createConsentSchema());
|
|
282
|
+
}
|
|
283
|
+
/** Lazy one-time model resolution — a second `mongoose.model(name, schema)` for one name would throw. */
|
|
284
|
+
resolveModel(name, schema) {
|
|
285
|
+
return mongoose_1.default.modelNames().includes(name)
|
|
286
|
+
? mongoose_1.default.model(name)
|
|
287
|
+
: mongoose_1.default.model(name, schema);
|
|
288
|
+
}
|
|
289
|
+
isDuplicateKey(error) {
|
|
290
|
+
return typeof error === 'object' && error !== null && 'code' in error
|
|
291
|
+
&& Object.getOwnPropertyDescriptor(error, 'code')?.value === 11000;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
exports.DyNTS_PrivacyLedger_MongoStore = DyNTS_PrivacyLedger_MongoStore;
|
|
295
|
+
//# sourceMappingURL=privacy-ledger.mongo-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privacy-ledger.mongo-store.js","sourceRoot":"","sources":["../../../src/_modules/privacy-lifecycle/privacy-ledger.mongo-store.ts"],"names":[],"mappings":"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"}
|