@futdevpro/nts-dynamo 1.15.315 → 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/mcp/_models/control-models/mcp-tool-params.control-model.d.ts +8 -1
- package/build/_modules/mcp/_models/control-models/mcp-tool-params.control-model.d.ts.map +1 -1
- package/build/_modules/mcp/_models/control-models/mcp-tool-params.control-model.js +8 -1
- package/build/_modules/mcp/_models/control-models/mcp-tool-params.control-model.js.map +1 -1
- package/build/_modules/mcp/_services/dynts-mcp.adapter.d.ts.map +1 -1
- package/build/_modules/mcp/_services/dynts-mcp.adapter.js +13 -0
- package/build/_modules/mcp/_services/dynts-mcp.adapter.js.map +1 -1
- 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,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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"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Model, Schema } from 'mongoose';
|
|
2
|
+
import { DyNTS_PrivacyContributorOutcome_Interface } from './_models/privacy-contributor-outcome.interface';
|
|
3
|
+
import { DyNTS_PrivacyContributorPlan_Interface } from './_models/privacy-contributor-plan.interface';
|
|
4
|
+
import { DyNTS_PrivacyLifecycleAdapter_Interface } from './_models/privacy-lifecycle-adapter.interface';
|
|
5
|
+
import { DyNTS_PrivacyRequestPersistenceCreateResult_Interface } from './_models/privacy-request-persistence-create-result.interface';
|
|
6
|
+
import { DyNTS_PrivacyRequestListQuery_Interface } from './_models/privacy-request-list.interface';
|
|
7
|
+
import { DyNTS_PrivacyRequestPersistenceListResult_Interface } from './_models/privacy-request-list-result.interface';
|
|
8
|
+
import { DyNTS_PrivacyRequestRecord_Interface } from './_models/privacy-request-record.interface';
|
|
9
|
+
/** Persistence row of a contributor plan: the contract shape plus its lookup key. */
|
|
10
|
+
export type DyNTS_PrivacyStoredPlan_Row = DyNTS_PrivacyContributorPlan_Interface & {
|
|
11
|
+
requestId: string;
|
|
12
|
+
};
|
|
13
|
+
/** Persistence row of a contributor outcome: the contract shape plus its lookup key. */
|
|
14
|
+
export type DyNTS_PrivacyStoredOutcome_Row = DyNTS_PrivacyContributorOutcome_Interface & {
|
|
15
|
+
requestId: string;
|
|
16
|
+
};
|
|
17
|
+
/** Optional isolated models — integration tests bind them to a dedicated connection. */
|
|
18
|
+
export interface DyNTS_PrivacyLifecycleMongoStore_Settings {
|
|
19
|
+
requestModel?: Model<DyNTS_PrivacyRequestRecord_Interface>;
|
|
20
|
+
planModel?: Model<DyNTS_PrivacyStoredPlan_Row>;
|
|
21
|
+
outcomeModel?: Model<DyNTS_PrivacyStoredOutcome_Row>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Mongo persistence for the privacy lifecycle — the production `DyNTS_PrivacyLifecycleAdapter_Interface`.
|
|
25
|
+
*
|
|
26
|
+
* @description BFR-FUTDEVPRO-010 / BFR-ADVENTOR-025. Before this store the module shipped the contract only,
|
|
27
|
+
* so `DyNTS_PrivacyLifecycle_ControlService` (which REQUIRES an adapter) could not be started, and three
|
|
28
|
+
* products carried their own copies (company-toolmaker, futdevpro, adventor). This is the futdevpro copy,
|
|
29
|
+
* lifted verbatim in behaviour; the collection and model names are unchanged, so existing data stays readable.
|
|
30
|
+
*
|
|
31
|
+
* Atomicity does NOT need a transaction here — every guarantee is a single-document operation:
|
|
32
|
+
* - replay idempotency: the UNIQUE `idempotencyHash` index (the loser of a race reads the winner);
|
|
33
|
+
* - optimistic concurrency: `replaceRequest` puts `revision` INTO the filter, so a stale writer matches
|
|
34
|
+
* nothing and gets `false` (the caller turns that into a 409);
|
|
35
|
+
* - plan/outcome writes: an upsert on the UNIQUE `(requestId, contributorId)` pair.
|
|
36
|
+
*
|
|
37
|
+
* ⚠️ A broken revision check here is not "a bug": it is a lost or doubly executed erasure request —
|
|
38
|
+
* exactly the operation whose provability is the legal requirement (GDPR Art. 17).
|
|
39
|
+
*
|
|
40
|
+
* ⚠️ Consumers that carried a product-side copy must DELETE it in the same change-set that switches to this
|
|
41
|
+
* store: both register the same model names, and `resolveModel` silently returns whichever registered first.
|
|
42
|
+
*/
|
|
43
|
+
export declare class DyNTS_PrivacyLifecycle_MongoStore implements DyNTS_PrivacyLifecycleAdapter_Interface {
|
|
44
|
+
private readonly injected;
|
|
45
|
+
private readiness?;
|
|
46
|
+
/** Accepts isolated models for integration tests; production resolves the singletons lazily. */
|
|
47
|
+
constructor(set?: DyNTS_PrivacyLifecycleMongoStore_Settings);
|
|
48
|
+
/**
|
|
49
|
+
* Creates the indexes BEFORE the first read or write.
|
|
50
|
+
*
|
|
51
|
+
* @description Not a convenience step: idempotency and optimistic concurrency both rest on the UNIQUE
|
|
52
|
+
* indexes. Without them a duplicate would not fail — it would silently become a second record.
|
|
53
|
+
*/
|
|
54
|
+
ensureReady(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Creates one request, or returns the EXACT same request on an idempotent replay.
|
|
57
|
+
*
|
|
58
|
+
* @description The decision is not a racy "does it exist?" read (two parallel callers would both see
|
|
59
|
+
* "no"), but the UNIQUE index: the second writer gets a duplicate-key error and reads the winner.
|
|
60
|
+
*/
|
|
61
|
+
createOrGetRequest(request: DyNTS_PrivacyRequestRecord_Interface): Promise<DyNTS_PrivacyRequestPersistenceCreateResult_Interface>;
|
|
62
|
+
/** Loads one request by id. Does not throw when missing — interpreting absence is the caller's job. */
|
|
63
|
+
findRequestById(requestId: string): Promise<DyNTS_PrivacyRequestRecord_Interface | null>;
|
|
64
|
+
/**
|
|
65
|
+
* One bounded, deterministic, newest-first page of the subject's own requests.
|
|
66
|
+
*
|
|
67
|
+
* @description Sorted by TWO keys (`createdAt`, then `requestId`): with a single key two requests created in
|
|
68
|
+
* the same millisecond would order non-deterministically and paging could skip or repeat a row
|
|
69
|
+
* (`createdAt` is ISO-8601 UTC text, so string order is time order). The cursor is opaque and carries no
|
|
70
|
+
* personal data — a timestamp and a machine id only.
|
|
71
|
+
*/
|
|
72
|
+
listRequests(query: DyNTS_PrivacyRequestListQuery_Interface): Promise<DyNTS_PrivacyRequestPersistenceListResult_Interface>;
|
|
73
|
+
/**
|
|
74
|
+
* State transition with OPTIMISTIC CONCURRENCY.
|
|
75
|
+
*
|
|
76
|
+
* @description `revision` is part of the filter: if someone else rewrote the record meanwhile, the filter
|
|
77
|
+
* matches nothing and `false` is returned. That `false` is not an error — it is the correct answer to a
|
|
78
|
+
* race, and the caller turns it into a 409.
|
|
79
|
+
*/
|
|
80
|
+
replaceRequest(request: DyNTS_PrivacyRequestRecord_Interface, expectedRevision: number): Promise<boolean>;
|
|
81
|
+
/**
|
|
82
|
+
* Stores one contributor plan.
|
|
83
|
+
*
|
|
84
|
+
* @description Overwrites, does not insert: a resumed run may deliver the same plan again. The upsert on the
|
|
85
|
+
* `(requestId, contributorId)` pair keeps it idempotent — never two plans for one contributor.
|
|
86
|
+
*/
|
|
87
|
+
saveContributorPlan(requestId: string, plan: DyNTS_PrivacyContributorPlan_Interface): Promise<void>;
|
|
88
|
+
/** All contributor plans of one request, in a stable order. */
|
|
89
|
+
listContributorPlans(requestId: string): Promise<DyNTS_PrivacyContributorPlan_Interface[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Stores one contributor outcome.
|
|
92
|
+
*
|
|
93
|
+
* @description The overwrite is not only for resumed runs: on a failed verification the lifecycle
|
|
94
|
+
* DELIBERATELY replaces an earlier (successful) outcome with a failed one — an insert-only store would make
|
|
95
|
+
* the request look falsely successful.
|
|
96
|
+
*/
|
|
97
|
+
saveContributorOutcome(requestId: string, outcome: DyNTS_PrivacyContributorOutcome_Interface): Promise<void>;
|
|
98
|
+
/** All contributor outcomes of one request, in a stable order. */
|
|
99
|
+
listContributorOutcomes(requestId: string): Promise<DyNTS_PrivacyContributorOutcome_Interface[]>;
|
|
100
|
+
/**
|
|
101
|
+
* The request-record schema.
|
|
102
|
+
*
|
|
103
|
+
* @description Date fields are `String`, not `Date`: the contract uses an EMPTY string for "has not happened
|
|
104
|
+
* yet" (`identityVerifiedAt: ''`), which a `Date` field cannot represent. `strict: 'throw'` is deliberate —
|
|
105
|
+
* an unknown field must not slip in silently.
|
|
106
|
+
*/
|
|
107
|
+
static createRequestSchema(): Schema<DyNTS_PrivacyRequestRecord_Interface>;
|
|
108
|
+
/** The contributor-plan schema. */
|
|
109
|
+
static createPlanSchema(): Schema<DyNTS_PrivacyStoredPlan_Row>;
|
|
110
|
+
/** The contributor-outcome schema. */
|
|
111
|
+
static createOutcomeSchema(): Schema<DyNTS_PrivacyStoredOutcome_Row>;
|
|
112
|
+
/**
|
|
113
|
+
* The contract shape from a stored row — an ALLOW-list.
|
|
114
|
+
*
|
|
115
|
+
* @description `.lean()` also returns the persistence's own fields (`_id`). Passing them on, the lifecycle's
|
|
116
|
+
* `{ ...request }` spread would write them back — the filtering keeps the domain object clean.
|
|
117
|
+
*/
|
|
118
|
+
private toRequestRecord;
|
|
119
|
+
/** Opaque, but NOT encrypted, paging cursor — it holds no personal data. */
|
|
120
|
+
private encodeCursor;
|
|
121
|
+
/**
|
|
122
|
+
* Decodes the cursor — FAIL-SAFE: a damaged or forged cursor restarts paging on the FIRST page.
|
|
123
|
+
*
|
|
124
|
+
* @description Not a security hole: the `subjectId` + `organizationId` filter is independent of the cursor,
|
|
125
|
+
* so the subject still sees only their own requests.
|
|
126
|
+
*/
|
|
127
|
+
private decodeCursor;
|
|
128
|
+
private getRequestModel;
|
|
129
|
+
private getPlanModel;
|
|
130
|
+
private getOutcomeModel;
|
|
131
|
+
/** Lazy one-time model resolution — a second `mongoose.model(name, schema)` for one name would throw. */
|
|
132
|
+
private resolveModel;
|
|
133
|
+
/** Mongo duplicate-key error — the signal that carries the "idempotent replay" branch. */
|
|
134
|
+
private isDuplicateKey;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=privacy-lifecycle.mongo-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privacy-lifecycle.mongo-store.d.ts","sourceRoot":"","sources":["../../../src/_modules/privacy-lifecycle/privacy-lifecycle.mongo-store.ts"],"names":[],"mappings":"AAAA,OAAiB,EAAoB,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAErE,OAAO,EAAE,yCAAyC,EAAE,MAAM,iDAAiD,CAAC;AAC5G,OAAO,EAAE,sCAAsC,EAAE,MAAM,8CAA8C,CAAC;AACtG,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAC;AACxG,OAAO,EACL,qDAAqD,EACtD,MAAM,+DAA+D,CAAC;AACvE,OAAO,EAAE,uCAAuC,EAAE,MAAM,0CAA0C,CAAC;AACnG,OAAO,EACL,mDAAmD,EACpD,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,oCAAoC,EAAE,MAAM,4CAA4C,CAAC;AAMlG,qFAAqF;AACrF,MAAM,MAAM,2BAA2B,GAAG,sCAAsC,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzG,wFAAwF;AACxF,MAAM,MAAM,8BAA8B,GAAG,yCAAyC,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/G,wFAAwF;AACxF,MAAM,WAAW,yCAAyC;IACxD,YAAY,CAAC,EAAE,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC3D,SAAS,CAAC,EAAE,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAC;CACtD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,iCAAkC,YAAW,uCAAuC;IAC/F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4C;IACrE,OAAO,CAAC,SAAS,CAAC,CAAgB;IAElC,gGAAgG;gBACpF,GAAG,GAAE,yCAA8C;IAI/D;;;;;OAKG;IACU,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAezC;;;;;OAKG;IACU,kBAAkB,CAC7B,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,qDAAqD,CAAC;IA4BjE,uGAAuG;IAC1F,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oCAAoC,GAAG,IAAI,CAAC;IAQrG;;;;;;;OAOG;IACU,YAAY,CACvB,KAAK,EAAE,uCAAuC,GAC7C,OAAO,CAAC,mDAAmD,CAAC;IA+B/D;;;;;;OAMG;IACU,cAAc,CACzB,OAAO,EAAE,oCAAoC,EAC7C,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC;IASnB;;;;;OAKG;IACU,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,sCAAsC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhH,+DAA+D;IAClD,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sCAAsC,EAAE,CAAC;IAWvG;;;;;;OAMG;IACU,sBAAsB,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,yCAAyC,GACjD,OAAO,CAAC,IAAI,CAAC;IAQhB,kEAAkE;IACrD,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,yCAAyC,EAAE,CAAC;IAgB7G;;;;;;OAMG;WACW,mBAAmB,IAAI,MAAM,CAAC,oCAAoC,CAAC;IAkCjF,mCAAmC;WACrB,gBAAgB,IAAI,MAAM,CAAC,2BAA2B,CAAC;IAiBrE,sCAAsC;WACxB,mBAAmB,IAAI,MAAM,CAAC,8BAA8B,CAAC;IAsB3E;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAqBvB,4EAA4E;IAC5E,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,eAAe;IAMvB,yGAAyG;IACzG,OAAO,CAAC,YAAY;IAMpB,0FAA0F;IAC1F,OAAO,CAAC,cAAc;CAIvB"}
|