@researchdatabox/sails-hook-redbox-storage-mongo 5.0.4 → 5.1.0-beta.12573
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/README.md +41 -0
- package/dist/config/storage.d.ts +52 -0
- package/dist/config/storage.js +18 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/migrations/index.d.ts +5 -0
- package/dist/migrations/index.js +26 -0
- package/dist/migrations/recordRevisionBackfill.d.ts +26 -0
- package/dist/migrations/recordRevisionBackfill.js +115 -0
- package/dist/models/DeletedRecord.d.ts +8 -0
- package/dist/models/DeletedRecord.js +55 -1
- package/dist/models/Record.d.ts +5 -0
- package/dist/models/Record.js +43 -1
- package/dist/models/RecordAudit.d.ts +2 -0
- package/dist/models/RecordAudit.js +11 -1
- package/dist/models/RecordSchemaArtifact.d.ts +14 -0
- package/dist/models/RecordSchemaArtifact.js +75 -0
- package/dist/models/RecordSchemaReference.d.ts +25 -0
- package/dist/models/RecordSchemaReference.js +128 -0
- package/dist/models/index.d.ts +4 -0
- package/dist/models/index.js +7 -1
- package/dist/services/MongoStorageService.d.ts +174 -11
- package/dist/services/MongoStorageService.js +1901 -271
- package/dist/services/recordSchemaPersistence.d.ts +27 -0
- package/dist/services/recordSchemaPersistence.js +258 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -24,6 +24,47 @@ This package provides the MongoDB-backed storage service, models, and config reg
|
|
|
24
24
|
- The storage models use the Sails datastore named `redboxStorage`
|
|
25
25
|
- Datastore connection details still live in the host portal’s Sails config
|
|
26
26
|
|
|
27
|
+
## Record revision migration
|
|
28
|
+
|
|
29
|
+
This hook registers the restart-safe
|
|
30
|
+
`@researchdatabox/sails-hook-redbox-storage-mongo:20260823T000000-backfill-record-revisions`
|
|
31
|
+
migration. It installs the initial server-owned revision on active records and
|
|
32
|
+
the revision plus `deleted` lifecycle state on legacy tombstones. It does not
|
|
33
|
+
touch record metadata, workflow, authorization, `lastSaveDate`, or search
|
|
34
|
+
documents.
|
|
35
|
+
|
|
36
|
+
Run an upgrade with exactly one lifting portal instance, let migrations finish,
|
|
37
|
+
and only then start the remaining instances. The repository migration runner
|
|
38
|
+
has no distributed migration lock. Back up the database first; do not use
|
|
39
|
+
`REDBOX_SKIP_MIGRATIONS=true` for a strict-concurrency rollout.
|
|
40
|
+
|
|
41
|
+
## Storage concurrency capability
|
|
42
|
+
|
|
43
|
+
Strict record types require a storage adapter to expose `getCapabilities()` and
|
|
44
|
+
return the supported `recordConcurrency` version token from
|
|
45
|
+
`@researchdatabox/redbox-core`. An absent method, absent field, unknown version,
|
|
46
|
+
or a non-Mongo dialect without native atomic operations is unsupported and
|
|
47
|
+
fails closed.
|
|
48
|
+
|
|
49
|
+
The capability covers these adapter methods:
|
|
50
|
+
|
|
51
|
+
- `create(..., options?)`: strips client revision and initializes a server revision;
|
|
52
|
+
- `updateMeta(..., options?)`: atomic active compare-and-set plus increment;
|
|
53
|
+
- `removeActiveRecord(..., options?)`: atomic conditional removal returning the removed state;
|
|
54
|
+
- `updateTombstone(..., options?)`: atomic restore/purge claim plus increment;
|
|
55
|
+
- `removeTombstone(..., options?)`: atomic conditional restore finalization/purge.
|
|
56
|
+
|
|
57
|
+
Every existing signature keeps its optional concurrency options last for source
|
|
58
|
+
compatibility. A supplied `expectedRevision` must always be honored. A
|
|
59
|
+
certified no-match returns `not-applied` with a bounded
|
|
60
|
+
`nonApplicationReason`; a thrown or unrecognized fact after dispatch returns
|
|
61
|
+
`unknown`. Adapters must never fall back to an OID-only Waterline success path
|
|
62
|
+
after advertising strict capability.
|
|
63
|
+
|
|
64
|
+
Hook-provided adapters must verify these guarantees against their real
|
|
65
|
+
datastore/dialect before declaring capability. The bundled Mongo adapter does
|
|
66
|
+
so in `test/integration/MongoStorageConcurrency.integration.test.ts`.
|
|
67
|
+
|
|
27
68
|
## Pagination regression tests
|
|
28
69
|
|
|
29
70
|
Record and deleted-record lists append `_id` to the requested sort so equal
|
package/dist/config/storage.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare const storage: {
|
|
|
12
12
|
'metaMetadata.lastSaveDate'?: undefined;
|
|
13
13
|
redboxOid?: undefined;
|
|
14
14
|
};
|
|
15
|
+
unique?: undefined;
|
|
15
16
|
} | {
|
|
16
17
|
key: {
|
|
17
18
|
harvestId: number;
|
|
@@ -23,6 +24,7 @@ export declare const storage: {
|
|
|
23
24
|
'metaMetadata.lastSaveDate'?: undefined;
|
|
24
25
|
redboxOid?: undefined;
|
|
25
26
|
};
|
|
27
|
+
unique?: undefined;
|
|
26
28
|
} | {
|
|
27
29
|
key: {
|
|
28
30
|
dateCreated: number;
|
|
@@ -34,6 +36,7 @@ export declare const storage: {
|
|
|
34
36
|
'metaMetadata.lastSaveDate'?: undefined;
|
|
35
37
|
redboxOid?: undefined;
|
|
36
38
|
};
|
|
39
|
+
unique?: undefined;
|
|
37
40
|
} | {
|
|
38
41
|
key: {
|
|
39
42
|
lastSaveDate: number;
|
|
@@ -45,6 +48,7 @@ export declare const storage: {
|
|
|
45
48
|
'metaMetadata.lastSaveDate'?: undefined;
|
|
46
49
|
redboxOid?: undefined;
|
|
47
50
|
};
|
|
51
|
+
unique?: undefined;
|
|
48
52
|
} | {
|
|
49
53
|
key: {
|
|
50
54
|
'metaMetadata.brandId': number;
|
|
@@ -56,6 +60,7 @@ export declare const storage: {
|
|
|
56
60
|
'metaMetadata.lastSaveDate'?: undefined;
|
|
57
61
|
redboxOid?: undefined;
|
|
58
62
|
};
|
|
63
|
+
unique?: undefined;
|
|
59
64
|
} | {
|
|
60
65
|
key: {
|
|
61
66
|
'metaMetadata.type': number;
|
|
@@ -67,6 +72,7 @@ export declare const storage: {
|
|
|
67
72
|
'metaMetadata.lastSaveDate'?: undefined;
|
|
68
73
|
redboxOid?: undefined;
|
|
69
74
|
};
|
|
75
|
+
unique?: undefined;
|
|
70
76
|
} | {
|
|
71
77
|
key: {
|
|
72
78
|
'metaMetadata.createdOn': number;
|
|
@@ -78,6 +84,7 @@ export declare const storage: {
|
|
|
78
84
|
'metaMetadata.lastSaveDate'?: undefined;
|
|
79
85
|
redboxOid?: undefined;
|
|
80
86
|
};
|
|
87
|
+
unique?: undefined;
|
|
81
88
|
} | {
|
|
82
89
|
key: {
|
|
83
90
|
'metaMetadata.lastSaveDate': number;
|
|
@@ -89,6 +96,7 @@ export declare const storage: {
|
|
|
89
96
|
'metaMetadata.createdOn'?: undefined;
|
|
90
97
|
redboxOid?: undefined;
|
|
91
98
|
};
|
|
99
|
+
unique?: undefined;
|
|
92
100
|
} | {
|
|
93
101
|
key: {
|
|
94
102
|
redboxOid: number;
|
|
@@ -100,6 +108,50 @@ export declare const storage: {
|
|
|
100
108
|
'metaMetadata.createdOn'?: undefined;
|
|
101
109
|
'metaMetadata.lastSaveDate'?: undefined;
|
|
102
110
|
};
|
|
111
|
+
unique: boolean;
|
|
103
112
|
})[];
|
|
113
|
+
deletedRecordIndices: ({
|
|
114
|
+
key: {
|
|
115
|
+
redboxOid: number;
|
|
116
|
+
lifecycleState?: undefined;
|
|
117
|
+
'lifecycleOperation.requestId'?: undefined;
|
|
118
|
+
'deletedRecordMetadata.metaMetadata.brandId'?: undefined;
|
|
119
|
+
brandId?: undefined;
|
|
120
|
+
};
|
|
121
|
+
unique: boolean;
|
|
122
|
+
} | {
|
|
123
|
+
key: {
|
|
124
|
+
lifecycleState: number;
|
|
125
|
+
'lifecycleOperation.requestId': number;
|
|
126
|
+
redboxOid?: undefined;
|
|
127
|
+
'deletedRecordMetadata.metaMetadata.brandId'?: undefined;
|
|
128
|
+
brandId?: undefined;
|
|
129
|
+
};
|
|
130
|
+
unique?: undefined;
|
|
131
|
+
} | {
|
|
132
|
+
key: {
|
|
133
|
+
'deletedRecordMetadata.metaMetadata.brandId': number;
|
|
134
|
+
redboxOid: number;
|
|
135
|
+
lifecycleState?: undefined;
|
|
136
|
+
'lifecycleOperation.requestId'?: undefined;
|
|
137
|
+
brandId?: undefined;
|
|
138
|
+
};
|
|
139
|
+
unique?: undefined;
|
|
140
|
+
} | {
|
|
141
|
+
key: {
|
|
142
|
+
brandId: number;
|
|
143
|
+
redboxOid: number;
|
|
144
|
+
lifecycleState?: undefined;
|
|
145
|
+
'lifecycleOperation.requestId'?: undefined;
|
|
146
|
+
'deletedRecordMetadata.metaMetadata.brandId'?: undefined;
|
|
147
|
+
};
|
|
148
|
+
unique?: undefined;
|
|
149
|
+
})[];
|
|
150
|
+
recordIdentityIndices: {
|
|
151
|
+
key: {
|
|
152
|
+
redboxOid: number;
|
|
153
|
+
};
|
|
154
|
+
unique: boolean;
|
|
155
|
+
}[];
|
|
104
156
|
};
|
|
105
157
|
};
|
package/dist/config/storage.js
CHANGED
|
@@ -17,9 +17,24 @@ exports.storage = {
|
|
|
17
17
|
{ key: { 'metaMetadata.createdOn': -1 } },
|
|
18
18
|
{ key: { 'metaMetadata.lastSaveDate': 1 } },
|
|
19
19
|
{ key: { 'metaMetadata.lastSaveDate': -1 } },
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
// Active create/restore classification relies on duplicate-key facts;
|
|
21
|
+
// keep the native Mongo index explicit as well as the Waterline model
|
|
22
|
+
// constraint. One single-field index serves both scan directions.
|
|
23
|
+
{ key: { redboxOid: 1 }, unique: true },
|
|
22
24
|
],
|
|
25
|
+
// Every tombstone lookup starts from the OID, so it leads the compound
|
|
26
|
+
// keys; the brand is a filter on the single document the OID selects. The
|
|
27
|
+
// lifecycle key supports scanning for interrupted staged operations.
|
|
28
|
+
deletedRecordIndices: [
|
|
29
|
+
{ key: { redboxOid: 1 }, unique: true },
|
|
30
|
+
{ key: { lifecycleState: 1, 'lifecycleOperation.requestId': 1 } },
|
|
31
|
+
{ key: { 'deletedRecordMetadata.metaMetadata.brandId': 1, redboxOid: 1 } },
|
|
32
|
+
{ key: { brandId: 1, redboxOid: 1 } },
|
|
33
|
+
],
|
|
34
|
+
// A committed incarnation is intentionally never purged. The only safe
|
|
35
|
+
// exception is an unused create reservation released after a certified
|
|
36
|
+
// non-write and authoritative empty-state checks.
|
|
37
|
+
recordIdentityIndices: [{ key: { redboxOid: 1 }, unique: true }],
|
|
23
38
|
},
|
|
24
39
|
};
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvc3RvcmFnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBYSxRQUFBLE9BQU8sR0FBRztJQUNyQixXQUFXLEVBQUUscUJBQXFCO0lBQ2xDLE9BQU8sRUFBRTtRQUNQLE9BQU8sRUFBRTtZQUNQLEVBQUUsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3pCLEVBQUUsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxzQkFBc0IsRUFBRSxDQUFDLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDNUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDM0IsRUFBRSxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUM1QixFQUFFLEdBQUcsRUFBRSxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUM1QixFQUFFLEdBQUcsRUFBRSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQzdCLEVBQUUsR0FBRyxFQUFFLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDdEMsRUFBRSxHQUFHLEVBQUUsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNuQyxFQUFFLEdBQUcsRUFBRSxFQUFFLHdCQUF3QixFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3hDLEVBQUUsR0FBRyxFQUFFLEVBQUUsd0JBQXdCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUN6QyxFQUFFLEdBQUcsRUFBRSxFQUFFLDJCQUEyQixFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzNDLEVBQUUsR0FBRyxFQUFFLEVBQUUsMkJBQTJCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUM1QyxzRUFBc0U7WUFDdEUsc0VBQXNFO1lBQ3RFLGtFQUFrRTtZQUNsRSxFQUFFLEdBQUcsRUFBRSxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO1NBQ3hDO1FBQ0QsdUVBQXVFO1FBQ3ZFLDBFQUEwRTtRQUMxRSxxRUFBcUU7UUFDckUsb0JBQW9CLEVBQUU7WUFDcEIsRUFBRSxHQUFHLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtZQUN2QyxFQUFFLEdBQUcsRUFBRSxFQUFFLGNBQWMsRUFBRSxDQUFDLEVBQUUsOEJBQThCLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDakUsRUFBRSxHQUFHLEVBQUUsRUFBRSw0Q0FBNEMsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUU7U0FDdEM7UUFDRCx1RUFBdUU7UUFDdkUsdUVBQXVFO1FBQ3ZFLGtEQUFrRDtRQUNsRCxxQkFBcUIsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQztLQUNqRTtDQUNGLENBQUMifQ==
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { storage } from './config/storage';
|
|
|
3
3
|
import { record } from './config/record';
|
|
4
4
|
import { MongoModels } from './models';
|
|
5
5
|
import { ServiceExports } from './services';
|
|
6
|
+
import { registerRedboxMigrations } from './migrations';
|
|
6
7
|
type RedboxStorageMongoHook = ((_sails: unknown) => SailsHook) & {
|
|
7
8
|
registerRedboxModels: () => typeof MongoModels;
|
|
8
9
|
registerRedboxServices: () => typeof ServiceExports;
|
|
@@ -10,6 +11,7 @@ type RedboxStorageMongoHook = ((_sails: unknown) => SailsHook) & {
|
|
|
10
11
|
storage: typeof storage;
|
|
11
12
|
record: typeof record;
|
|
12
13
|
};
|
|
14
|
+
registerRedboxMigrations: typeof registerRedboxMigrations;
|
|
13
15
|
ServiceExports: typeof ServiceExports;
|
|
14
16
|
};
|
|
15
17
|
declare const hook: RedboxStorageMongoHook;
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ const storage_1 = require("./config/storage");
|
|
|
3
3
|
const record_1 = require("./config/record");
|
|
4
4
|
const models_1 = require("./models");
|
|
5
5
|
const services_1 = require("./services");
|
|
6
|
+
const migrations_1 = require("./migrations");
|
|
6
7
|
const hook = ((_sails) => ({
|
|
7
8
|
initialize(cb) {
|
|
8
9
|
cb();
|
|
@@ -27,5 +28,6 @@ hook.registerRedboxConfig = function registerRedboxConfig() {
|
|
|
27
28
|
};
|
|
28
29
|
};
|
|
29
30
|
hook.ServiceExports = services_1.ServiceExports;
|
|
31
|
+
hook.registerRedboxMigrations = migrations_1.registerRedboxMigrations;
|
|
30
32
|
module.exports = hook;
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUNBLDhDQUEyQztBQUMzQyw0Q0FBeUM7QUFDekMscUNBQXVDO0FBQ3ZDLHlDQUE0QztBQUM1Qyw2Q0FBd0Q7QUFVeEQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLE1BQWUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNsQyxVQUFVLENBQUMsRUFBeUI7UUFDbEMsRUFBRSxFQUFFLENBQUM7SUFDUCxDQUFDO0lBQ0QsTUFBTSxFQUFFO1FBQ04sTUFBTSxFQUFFLEVBQUU7UUFDVixLQUFLLEVBQUUsRUFBRTtLQUNWO0lBQ0QsU0FBUyxLQUFJLENBQUM7SUFDZCxRQUFRLEVBQUUsRUFBRTtDQUNiLENBQUMsQ0FBMkIsQ0FBQztBQUU5QixJQUFJLENBQUMsb0JBQW9CLEdBQUcsU0FBUyxvQkFBb0I7SUFDdkQsT0FBTyxvQkFBVyxDQUFDO0FBQ3JCLENBQUMsQ0FBQztBQUVGLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxTQUFTLHNCQUFzQjtJQUMzRCxPQUFPLHlCQUFjLENBQUM7QUFDeEIsQ0FBQyxDQUFDO0FBRUYsSUFBSSxDQUFDLG9CQUFvQixHQUFHLFNBQVMsb0JBQW9CO0lBQ3ZELE9BQU87UUFDTCxPQUFPLEVBQVAsaUJBQU87UUFDUCxNQUFNLEVBQU4sZUFBTTtLQUNQLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixJQUFJLENBQUMsY0FBYyxHQUFHLHlCQUFjLENBQUM7QUFDckMsSUFBSSxDQUFDLHdCQUF3QixHQUFHLHFDQUF3QixDQUFDO0FBRXpELGlCQUFTLElBQUksQ0FBQyJ9
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RedboxMigration } from '@researchdatabox/redbox-core';
|
|
2
|
+
export * from './recordRevisionBackfill';
|
|
3
|
+
export declare const MigrationExports: RedboxMigration[];
|
|
4
|
+
/** Synchronous registry consumed by the generated ReDBox migration shim. */
|
|
5
|
+
export declare function registerRedboxMigrations(): RedboxMigration[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.MigrationExports = void 0;
|
|
18
|
+
exports.registerRedboxMigrations = registerRedboxMigrations;
|
|
19
|
+
const recordRevisionBackfill_1 = require("./recordRevisionBackfill");
|
|
20
|
+
__exportStar(require("./recordRevisionBackfill"), exports);
|
|
21
|
+
exports.MigrationExports = [recordRevisionBackfill_1.recordRevisionBackfillMigration];
|
|
22
|
+
/** Synchronous registry consumed by the generated ReDBox migration shim. */
|
|
23
|
+
function registerRedboxMigrations() {
|
|
24
|
+
return exports.MigrationExports;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlncmF0aW9ucy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7OztBQVFBLDREQUVDO0FBVEQscUVBQTJFO0FBRTNFLDJEQUF5QztBQUU1QixRQUFBLGdCQUFnQixHQUFzQixDQUFDLHdEQUErQixDQUFDLENBQUM7QUFFckYsNEVBQTRFO0FBQzVFLFNBQWdCLHdCQUF3QjtJQUN0QyxPQUFPLHdCQUFnQixDQUFDO0FBQzFCLENBQUMifQ==
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Db } from 'mongodb';
|
|
2
|
+
import { type RedboxMigration } from '@researchdatabox/redbox-core';
|
|
3
|
+
export declare const RECORD_REVISION_BACKFILL_MIGRATION_NAME = "@researchdatabox/sails-hook-redbox-storage-mongo:20260823T000000-backfill-record-revisions";
|
|
4
|
+
export declare const RECORD_REVISION_BACKFILL_BATCH_SIZE = 500;
|
|
5
|
+
export interface RecordRevisionBackfillStats {
|
|
6
|
+
activeUpdated: number;
|
|
7
|
+
tombstonesUpdated: number;
|
|
8
|
+
batches: number;
|
|
9
|
+
durationMs: number;
|
|
10
|
+
}
|
|
11
|
+
type MigrationLogger = Pick<Console, 'info' | 'error'>;
|
|
12
|
+
interface BackfillOptions {
|
|
13
|
+
batchSize?: number;
|
|
14
|
+
now?: () => number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Restart-safe backfill. Only the new wrapper fields are written; record
|
|
18
|
+
* metadata, workflow, authorization, lastSaveDate, and search documents are
|
|
19
|
+
* deliberately absent from every update document.
|
|
20
|
+
*
|
|
21
|
+
* Each batch re-queries the documents that still need the backfill, so an
|
|
22
|
+
* interrupted run resumes simply by being run again.
|
|
23
|
+
*/
|
|
24
|
+
export declare function backfillRecordRevisions(db: Db, recordCollectionName: string, tombstoneCollectionName: string, logger: MigrationLogger, options?: BackfillOptions): Promise<RecordRevisionBackfillStats>;
|
|
25
|
+
export declare const recordRevisionBackfillMigration: RedboxMigration;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.recordRevisionBackfillMigration = exports.RECORD_REVISION_BACKFILL_BATCH_SIZE = exports.RECORD_REVISION_BACKFILL_MIGRATION_NAME = void 0;
|
|
4
|
+
exports.backfillRecordRevisions = backfillRecordRevisions;
|
|
5
|
+
const redbox_core_1 = require("@researchdatabox/redbox-core");
|
|
6
|
+
exports.RECORD_REVISION_BACKFILL_MIGRATION_NAME = '@researchdatabox/sails-hook-redbox-storage-mongo:20260823T000000-backfill-record-revisions';
|
|
7
|
+
exports.RECORD_REVISION_BACKFILL_BATCH_SIZE = 500;
|
|
8
|
+
/** Equality against `null` matches both a null value and an absent field. */
|
|
9
|
+
const MISSING_REVISION = { revision: null };
|
|
10
|
+
const MISSING_LIFECYCLE_STATE = { lifecycleState: null };
|
|
11
|
+
const PENDING = {
|
|
12
|
+
active: MISSING_REVISION,
|
|
13
|
+
tombstone: { $or: [MISSING_REVISION, MISSING_LIFECYCLE_STATE] },
|
|
14
|
+
};
|
|
15
|
+
const SAFE_FAILURE_CODES = new Set([
|
|
16
|
+
'record-revision-backfill-no-progress',
|
|
17
|
+
'record-revision-backfill-invalid-batch-size',
|
|
18
|
+
]);
|
|
19
|
+
function safeFailureCode(error) {
|
|
20
|
+
const message = error instanceof Error ? error.message : '';
|
|
21
|
+
return SAFE_FAILURE_CODES.has(message) ? message : 'record-revision-backfill-failed';
|
|
22
|
+
}
|
|
23
|
+
async function backfillCollection(collection, kind, batchSize) {
|
|
24
|
+
const pending = PENDING[kind];
|
|
25
|
+
let updated = 0;
|
|
26
|
+
let batches = 0;
|
|
27
|
+
for (;;) {
|
|
28
|
+
const documents = await collection
|
|
29
|
+
.find(pending, { projection: { _id: 1, revision: 1, lifecycleState: 1 } })
|
|
30
|
+
.limit(batchSize)
|
|
31
|
+
.toArray();
|
|
32
|
+
if (documents.length === 0)
|
|
33
|
+
break;
|
|
34
|
+
const operations = documents.map(document => ({
|
|
35
|
+
updateOne: {
|
|
36
|
+
filter: { $and: [{ _id: document._id }, pending] },
|
|
37
|
+
// Evaluate the fallback against the value present when Mongo applies
|
|
38
|
+
// the update, not the earlier projected snapshot. This preserves a
|
|
39
|
+
// revision or lifecycle state installed by a concurrent/resumed run
|
|
40
|
+
// while still filling whichever sibling field remains absent.
|
|
41
|
+
update: [
|
|
42
|
+
{
|
|
43
|
+
$set: {
|
|
44
|
+
revision: { $ifNull: ['$revision', redbox_core_1.INITIAL_RECORD_REVISION] },
|
|
45
|
+
...(kind === 'tombstone' ? { lifecycleState: { $ifNull: ['$lifecycleState', 'deleted'] } } : {}),
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
const result = await collection.bulkWrite(operations, { ordered: false });
|
|
52
|
+
updated += result.modifiedCount;
|
|
53
|
+
batches += 1;
|
|
54
|
+
// Guard against an unsupported dialect silently reporting success and
|
|
55
|
+
// looping forever. Another idempotent runner may legitimately have won the
|
|
56
|
+
// whole batch, so only a batch whose own documents are still pending is a
|
|
57
|
+
// genuine failure to progress.
|
|
58
|
+
if (result.modifiedCount === 0) {
|
|
59
|
+
const stillPending = await collection.countDocuments({ $and: [{ _id: { $in: documents.map(document => document._id) } }, pending] }, { limit: 1 });
|
|
60
|
+
if (stillPending > 0) {
|
|
61
|
+
throw new Error('record-revision-backfill-no-progress');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { updated, batches };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Restart-safe backfill. Only the new wrapper fields are written; record
|
|
69
|
+
* metadata, workflow, authorization, lastSaveDate, and search documents are
|
|
70
|
+
* deliberately absent from every update document.
|
|
71
|
+
*
|
|
72
|
+
* Each batch re-queries the documents that still need the backfill, so an
|
|
73
|
+
* interrupted run resumes simply by being run again.
|
|
74
|
+
*/
|
|
75
|
+
async function backfillRecordRevisions(db, recordCollectionName, tombstoneCollectionName, logger, options = {}) {
|
|
76
|
+
const now = options.now ?? Date.now;
|
|
77
|
+
const start = now();
|
|
78
|
+
const batchSize = options.batchSize ?? exports.RECORD_REVISION_BACKFILL_BATCH_SIZE;
|
|
79
|
+
try {
|
|
80
|
+
if (!Number.isSafeInteger(batchSize) || batchSize < 1 || batchSize > 10_000) {
|
|
81
|
+
throw new TypeError('record-revision-backfill-invalid-batch-size');
|
|
82
|
+
}
|
|
83
|
+
const active = await backfillCollection(db.collection(recordCollectionName), 'active', batchSize);
|
|
84
|
+
const tombstones = await backfillCollection(db.collection(tombstoneCollectionName), 'tombstone', batchSize);
|
|
85
|
+
const stats = {
|
|
86
|
+
activeUpdated: active.updated,
|
|
87
|
+
tombstonesUpdated: tombstones.updated,
|
|
88
|
+
batches: active.batches + tombstones.batches,
|
|
89
|
+
durationMs: Math.max(0, now() - start),
|
|
90
|
+
};
|
|
91
|
+
logger.info(`Record revision backfill complete: active=${stats.activeUpdated}, tombstones=${stats.tombstonesUpdated}, ` +
|
|
92
|
+
`batches=${stats.batches}, durationMs=${stats.durationMs}.`);
|
|
93
|
+
return stats;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
// The logged code stays bounded: a driver message can carry record detail,
|
|
97
|
+
// so only this migration's own codes are echoed. The original error travels
|
|
98
|
+
// as the thrown error's cause for the operator's stack trace.
|
|
99
|
+
const durationMs = Math.max(0, now() - start);
|
|
100
|
+
logger.error(`Record revision backfill failed: code=${safeFailureCode(error)}, durationMs=${durationMs}.`);
|
|
101
|
+
throw new Error('record-revision-backfill-failed', { cause: error });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.recordRevisionBackfillMigration = {
|
|
105
|
+
name: exports.RECORD_REVISION_BACKFILL_MIGRATION_NAME,
|
|
106
|
+
async up(params) {
|
|
107
|
+
const sails = params?.context;
|
|
108
|
+
if (!sails?.models?.record || !sails?.models?.deletedrecord) {
|
|
109
|
+
throw new Error('record-revision-backfill-models-unavailable');
|
|
110
|
+
}
|
|
111
|
+
const db = sails.models.record.getDatastore().manager;
|
|
112
|
+
await backfillRecordRevisions(db, sails.models.record.tableName, sails.models.deletedrecord.tableName, sails.log);
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkUmV2aXNpb25CYWNrZmlsbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWdyYXRpb25zL3JlY29yZFJldmlzaW9uQmFja2ZpbGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBeUdBLDBEQW9DQztBQTVJRCw4REFBNkY7QUFFaEYsUUFBQSx1Q0FBdUMsR0FDbEQsNEZBQTRGLENBQUM7QUFFbEYsUUFBQSxtQ0FBbUMsR0FBRyxHQUFHLENBQUM7QUFnQnZELDZFQUE2RTtBQUM3RSxNQUFNLGdCQUFnQixHQUFHLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO0FBQzVDLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFFekQsTUFBTSxPQUFPLEdBQXFEO0lBQ2hFLE1BQU0sRUFBRSxnQkFBZ0I7SUFDeEIsU0FBUyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsdUJBQXVCLENBQUMsRUFBRTtDQUNoRSxDQUFDO0FBRUYsTUFBTSxrQkFBa0IsR0FBd0IsSUFBSSxHQUFHLENBQUM7SUFDdEQsc0NBQXNDO0lBQ3RDLDZDQUE2QztDQUM5QyxDQUFDLENBQUM7QUFFSCxTQUFTLGVBQWUsQ0FBQyxLQUFjO0lBQ3JDLE1BQU0sT0FBTyxHQUFHLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUM1RCxPQUFPLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxpQ0FBaUMsQ0FBQztBQUN2RixDQUFDO0FBRUQsS0FBSyxVQUFVLGtCQUFrQixDQUMvQixVQUFnQyxFQUNoQyxJQUE0QixFQUM1QixTQUFpQjtJQUVqQixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUIsSUFBSSxP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
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
|
+
import { type DeletedRecordLifecycleOperation, type DeletedRecordLifecycleState } from '@researchdatabox/redbox-core';
|
|
2
3
|
export declare class DeletedRecordClass {
|
|
3
4
|
redboxOid?: string;
|
|
5
|
+
/** Sole authority for the current tombstone lifecycle revision. */
|
|
6
|
+
revision: number;
|
|
7
|
+
/** Assigned only by native lifecycle storage from the durable OID owner. */
|
|
8
|
+
incarnationId?: string;
|
|
9
|
+
brandId?: string;
|
|
10
|
+
lifecycleState: DeletedRecordLifecycleState;
|
|
11
|
+
lifecycleOperation?: DeletedRecordLifecycleOperation;
|
|
4
12
|
deletedRecordMetadata?: Record<string, unknown>;
|
|
5
13
|
dateDeleted: string;
|
|
6
14
|
}
|
|
@@ -12,8 +12,40 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.DeletedRecordWLDef = exports.DeletedRecordClass = void 0;
|
|
13
13
|
require("reflect-metadata");
|
|
14
14
|
const redbox_core_1 = require("@researchdatabox/redbox-core");
|
|
15
|
+
/**
|
|
16
|
+
* Ordinary Waterline creates cannot choose a tombstone revision. The storage
|
|
17
|
+
* lifecycle path installs lineage-bearing tombstones through its native
|
|
18
|
+
* primitive after deriving the revision from authoritative active state.
|
|
19
|
+
*/
|
|
20
|
+
const normalizeTombstoneLifecycle = (record, proceed) => {
|
|
21
|
+
record.revision = redbox_core_1.INITIAL_RECORD_REVISION;
|
|
22
|
+
delete record.incarnationId;
|
|
23
|
+
if (!(0, redbox_core_1.isDeletedRecordLifecycleState)(record.lifecycleState)) {
|
|
24
|
+
record.lifecycleState = 'deleted';
|
|
25
|
+
}
|
|
26
|
+
if (record.deletedRecordMetadata && typeof record.deletedRecordMetadata === 'object') {
|
|
27
|
+
delete record.deletedRecordMetadata.revision;
|
|
28
|
+
}
|
|
29
|
+
proceed();
|
|
30
|
+
};
|
|
31
|
+
/** Tombstone revisions only advance through the atomic tombstone primitives. */
|
|
32
|
+
const stripTombstoneRevision = (record, proceed) => {
|
|
33
|
+
delete record.revision;
|
|
34
|
+
delete record.incarnationId;
|
|
35
|
+
if (record.deletedRecordMetadata && typeof record.deletedRecordMetadata === 'object') {
|
|
36
|
+
delete record.deletedRecordMetadata.revision;
|
|
37
|
+
}
|
|
38
|
+
proceed();
|
|
39
|
+
};
|
|
15
40
|
let DeletedRecordClass = class DeletedRecordClass {
|
|
16
41
|
redboxOid;
|
|
42
|
+
/** Sole authority for the current tombstone lifecycle revision. */
|
|
43
|
+
revision = redbox_core_1.INITIAL_RECORD_REVISION;
|
|
44
|
+
/** Assigned only by native lifecycle storage from the durable OID owner. */
|
|
45
|
+
incarnationId;
|
|
46
|
+
brandId;
|
|
47
|
+
lifecycleState = 'deleted';
|
|
48
|
+
lifecycleOperation;
|
|
17
49
|
deletedRecordMetadata;
|
|
18
50
|
dateDeleted;
|
|
19
51
|
};
|
|
@@ -22,6 +54,26 @@ __decorate([
|
|
|
22
54
|
(0, redbox_core_1.Attr)({ type: 'string', unique: true }),
|
|
23
55
|
__metadata("design:type", String)
|
|
24
56
|
], DeletedRecordClass.prototype, "redboxOid", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
(0, redbox_core_1.Attr)({ type: 'number', defaultsTo: redbox_core_1.INITIAL_RECORD_REVISION, custom: redbox_core_1.isRecordRevision }),
|
|
59
|
+
__metadata("design:type", Number)
|
|
60
|
+
], DeletedRecordClass.prototype, "revision", void 0);
|
|
61
|
+
__decorate([
|
|
62
|
+
(0, redbox_core_1.Attr)({ type: 'string', custom: redbox_core_1.isCanonicalSaveRequestId }),
|
|
63
|
+
__metadata("design:type", String)
|
|
64
|
+
], DeletedRecordClass.prototype, "incarnationId", void 0);
|
|
65
|
+
__decorate([
|
|
66
|
+
(0, redbox_core_1.Attr)({ type: 'string' }),
|
|
67
|
+
__metadata("design:type", String)
|
|
68
|
+
], DeletedRecordClass.prototype, "brandId", void 0);
|
|
69
|
+
__decorate([
|
|
70
|
+
(0, redbox_core_1.Attr)({ type: 'string', defaultsTo: 'deleted', isIn: redbox_core_1.DELETED_RECORD_LIFECYCLE_STATES }),
|
|
71
|
+
__metadata("design:type", String)
|
|
72
|
+
], DeletedRecordClass.prototype, "lifecycleState", void 0);
|
|
73
|
+
__decorate([
|
|
74
|
+
(0, redbox_core_1.Attr)({ type: 'json', custom: redbox_core_1.isDeletedRecordLifecycleOperation }),
|
|
75
|
+
__metadata("design:type", Object)
|
|
76
|
+
], DeletedRecordClass.prototype, "lifecycleOperation", void 0);
|
|
25
77
|
__decorate([
|
|
26
78
|
(0, redbox_core_1.Attr)({ type: 'json' }),
|
|
27
79
|
__metadata("design:type", Object)
|
|
@@ -31,7 +83,9 @@ __decorate([
|
|
|
31
83
|
__metadata("design:type", String)
|
|
32
84
|
], DeletedRecordClass.prototype, "dateDeleted", void 0);
|
|
33
85
|
exports.DeletedRecordClass = DeletedRecordClass = __decorate([
|
|
86
|
+
(0, redbox_core_1.BeforeCreate)(normalizeTombstoneLifecycle),
|
|
87
|
+
(0, redbox_core_1.BeforeUpdate)(stripTombstoneRevision),
|
|
34
88
|
(0, redbox_core_1.Entity)('deletedrecord', { datastore: 'redboxStorage' })
|
|
35
89
|
], DeletedRecordClass);
|
|
36
90
|
exports.DeletedRecordWLDef = (0, redbox_core_1.toWaterlineModelDef)(DeletedRecordClass);
|
|
37
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
91
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGVsZXRlZFJlY29yZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlbHMvRGVsZXRlZFJlY29yZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQSw0QkFBMEI7QUFDMUIsOERBY3NDO0FBRXRDOzs7O0dBSUc7QUFDSCxNQUFNLDJCQUEyQixHQUFHLENBQUMsTUFBK0IsRUFBRSxPQUE4QixFQUFFLEVBQUU7SUFDdEcsTUFBTSxDQUFDLFFBQVEsR0FBRyxxQ0FBdUIsQ0FBQztJQUMxQyxPQUFPLE1BQU0sQ0FBQyxhQUFhLENBQUM7SUFDNUIsSUFBSSxDQUFDLElBQUEsMkNBQTZCLEVBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7UUFDMUQsTUFBTSxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUM7SUFDcEMsQ0FBQztJQUNELElBQUksTUFBTSxDQUFDLHFCQUFxQixJQUFJLE9BQU8sTUFBTSxDQUFDLHFCQUFxQixLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3JGLE9BQVEsTUFBTSxDQUFDLHFCQUFpRCxDQUFDLFFBQVEsQ0FBQztJQUM1RSxDQUFDO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDLENBQUM7QUFFRixnRkFBZ0Y7QUFDaEYsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLE1BQStCLEVBQUUsT0FBOEIsRUFBRSxFQUFFO0lBQ2pHLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQztJQUN2QixPQUFPLE1BQU0sQ0FBQyxhQUFhLENBQUM7SUFDNUIsSUFBSSxNQUFNLENBQUMscUJBQXFCLElBQUksT0FBTyxNQUFNLENBQUMscUJBQXFCLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDckYsT0FBUSxNQUFNLENBQUMscUJBQWlELENBQUMsUUFBUSxDQUFDO0lBQzVFLENBQUM7SUFDRCxPQUFPLEVBQUUsQ0FBQztBQUNaLENBQUMsQ0FBQztBQUtLLElBQU0sa0JBQWtCLEdBQXhCLE1BQU0sa0JBQWtCO0lBRXRCLFNBQVMsQ0FBVTtJQUUxQixtRUFBbUU7SUFFNUQsUUFBUSxHQUFXLHFDQUF1QixDQUFDO0lBRWxELDRFQUE0RTtJQUVyRSxhQUFhLENBQVU7SUFHdkIsT0FBTyxDQUFVO0lBR2pCLGNBQWMsR0FBZ0MsU0FBUyxDQUFDO0lBR3hELGtCQUFrQixDQUFtQztJQUdyRCxxQkFBcUIsQ0FBMkI7SUFHaEQsV0FBVyxDQUFVO0NBQzdCLENBQUE7QUExQlksZ0RBQWtCO0FBRXRCO0lBRE4sSUFBQSxrQkFBSSxFQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7O3FEQUNiO0FBSW5CO0lBRE4sSUFBQSxrQkFBSSxFQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUscUNBQXVCLEVBQUUsTUFBTSxFQUFFLDhCQUFnQixFQUFFLENBQUM7O29EQUN0QztBQUkzQztJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLHNDQUF3QixFQUFFLENBQUM7O3lEQUM3QjtBQUd2QjtJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQzs7bURBQ0Q7QUFHakI7SUFETixJQUFBLGtCQUFJLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLDZDQUErQixFQUFFLENBQUM7OzBEQUN4QjtBQUd4RDtJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLCtDQUFpQyxFQUFFLENBQUM7OzhEQUNOO0FBR3JEO0lBRE4sSUFBQSxrQkFBSSxFQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDOztpRUFDZ0M7QUFHaEQ7SUFETixJQUFBLGtCQUFJLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQzs7dURBQ2xCOzZCQXpCakIsa0JBQWtCO0lBSDlCLElBQUEsMEJBQVksRUFBQywyQkFBMkIsQ0FBQztJQUN6QyxJQUFBLDBCQUFZLEVBQUMsc0JBQXNCLENBQUM7SUFDcEMsSUFBQSxvQkFBTSxFQUFDLGVBQWUsRUFBRSxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsQ0FBQztHQUMzQyxrQkFBa0IsQ0EwQjlCO0FBRVksUUFBQSxrQkFBa0IsR0FBRyxJQUFBLGlDQUFtQixFQUFDLGtCQUFrQixDQUFDLENBQUMifQ==
|
package/dist/models/Record.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ export type JsonMap = Record<string, unknown>;
|
|
|
3
3
|
export declare class RecordClass {
|
|
4
4
|
redboxOid?: string;
|
|
5
5
|
harvestId?: string;
|
|
6
|
+
/** Server-owned. Clients must retain the opaque tag rather than assume 0. */
|
|
7
|
+
revision: number;
|
|
8
|
+
/** Assigned only by the native conditional-create storage boundary. */
|
|
9
|
+
incarnationId?: string;
|
|
10
|
+
lifecycleOperationId?: string;
|
|
6
11
|
metaMetadata?: JsonMap;
|
|
7
12
|
metadata?: JsonMap;
|
|
8
13
|
workflow?: JsonMap;
|
package/dist/models/Record.js
CHANGED
|
@@ -12,9 +12,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.RecordWLDef = exports.RecordClass = void 0;
|
|
13
13
|
require("reflect-metadata");
|
|
14
14
|
const redbox_core_1 = require("@researchdatabox/redbox-core");
|
|
15
|
+
/**
|
|
16
|
+
* Ordinary Waterline creates always start a new record lineage. Lifecycle
|
|
17
|
+
* restoration uses a server-owned native storage path so it can continue a
|
|
18
|
+
* tombstone lineage without exposing a caller-controlled way to select the
|
|
19
|
+
* initial revision.
|
|
20
|
+
*/
|
|
21
|
+
const normalizeServerRevision = (record, proceed) => {
|
|
22
|
+
record.revision = redbox_core_1.INITIAL_RECORD_REVISION;
|
|
23
|
+
delete record.incarnationId;
|
|
24
|
+
delete record.lifecycleOperationId;
|
|
25
|
+
proceed();
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Only the atomic compare-and-set path may advance a revision, and it bypasses
|
|
29
|
+
* Waterline to do so. Any other update therefore leaves the stored revision
|
|
30
|
+
* untouched instead of writing a caller-supplied value.
|
|
31
|
+
*/
|
|
32
|
+
const stripServerRevision = (record, proceed) => {
|
|
33
|
+
delete record.revision;
|
|
34
|
+
delete record.incarnationId;
|
|
35
|
+
delete record.lifecycleOperationId;
|
|
36
|
+
proceed();
|
|
37
|
+
};
|
|
15
38
|
let RecordClass = class RecordClass {
|
|
16
39
|
redboxOid;
|
|
17
40
|
harvestId;
|
|
41
|
+
/** Server-owned. Clients must retain the opaque tag rather than assume 0. */
|
|
42
|
+
revision = redbox_core_1.INITIAL_RECORD_REVISION;
|
|
43
|
+
/** Assigned only by the native conditional-create storage boundary. */
|
|
44
|
+
incarnationId;
|
|
45
|
+
lifecycleOperationId;
|
|
18
46
|
metaMetadata;
|
|
19
47
|
metadata;
|
|
20
48
|
workflow;
|
|
@@ -33,6 +61,18 @@ __decorate([
|
|
|
33
61
|
(0, redbox_core_1.Attr)({ type: 'string' }),
|
|
34
62
|
__metadata("design:type", String)
|
|
35
63
|
], RecordClass.prototype, "harvestId", void 0);
|
|
64
|
+
__decorate([
|
|
65
|
+
(0, redbox_core_1.Attr)({ type: 'number', defaultsTo: redbox_core_1.INITIAL_RECORD_REVISION, custom: redbox_core_1.isRecordRevision }),
|
|
66
|
+
__metadata("design:type", Number)
|
|
67
|
+
], RecordClass.prototype, "revision", void 0);
|
|
68
|
+
__decorate([
|
|
69
|
+
(0, redbox_core_1.Attr)({ type: 'string', custom: redbox_core_1.isCanonicalSaveRequestId }),
|
|
70
|
+
__metadata("design:type", String)
|
|
71
|
+
], RecordClass.prototype, "incarnationId", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
(0, redbox_core_1.Attr)({ type: 'string', custom: redbox_core_1.isCanonicalSaveRequestId }),
|
|
74
|
+
__metadata("design:type", String)
|
|
75
|
+
], RecordClass.prototype, "lifecycleOperationId", void 0);
|
|
36
76
|
__decorate([
|
|
37
77
|
(0, redbox_core_1.Attr)({ type: 'json' }),
|
|
38
78
|
__metadata("design:type", Object)
|
|
@@ -66,9 +106,11 @@ __decorate([
|
|
|
66
106
|
__metadata("design:type", String)
|
|
67
107
|
], RecordClass.prototype, "lastSaveDate", void 0);
|
|
68
108
|
exports.RecordClass = RecordClass = __decorate([
|
|
109
|
+
(0, redbox_core_1.BeforeCreate)(normalizeServerRevision),
|
|
110
|
+
(0, redbox_core_1.BeforeUpdate)(stripServerRevision),
|
|
69
111
|
(0, redbox_core_1.Entity)('record', {
|
|
70
112
|
datastore: 'redboxStorage',
|
|
71
113
|
})
|
|
72
114
|
], RecordClass);
|
|
73
115
|
exports.RecordWLDef = (0, redbox_core_1.toWaterlineModelDef)(RecordClass);
|
|
74
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
116
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVjb3JkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZGVscy9SZWNvcmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsNEJBQTBCO0FBQzFCLDhEQVNzQztBQUl0Qzs7Ozs7R0FLRztBQUNILE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxNQUErQixFQUFFLE9BQThCLEVBQUUsRUFBRTtJQUNsRyxNQUFNLENBQUMsUUFBUSxHQUFHLHFDQUF1QixDQUFDO0lBQzFDLE9BQU8sTUFBTSxDQUFDLGFBQWEsQ0FBQztJQUM1QixPQUFPLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQztJQUNuQyxPQUFPLEVBQUUsQ0FBQztBQUNaLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLG1CQUFtQixHQUFHLENBQUMsTUFBK0IsRUFBRSxPQUE4QixFQUFFLEVBQUU7SUFDOUYsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLE9BQU8sTUFBTSxDQUFDLGFBQWEsQ0FBQztJQUM1QixPQUFPLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQztJQUNuQyxPQUFPLEVBQUUsQ0FBQztBQUNaLENBQUMsQ0FBQztBQU9LLElBQU0sV0FBVyxHQUFqQixNQUFNLFdBQVc7SUFFZixTQUFTLENBQVU7SUFHbkIsU0FBUyxDQUFVO0lBRTFCLDZFQUE2RTtJQUV0RSxRQUFRLEdBQVcscUNBQXVCLENBQUM7SUFFbEQsdUVBQXVFO0lBRWhFLGFBQWEsQ0FBVTtJQUd2QixvQkFBb0IsQ0FBVTtJQUc5QixZQUFZLENBQVc7SUFHdkIsUUFBUSxDQUFXO0lBR25CLFFBQVEsQ0FBVztJQUduQixhQUFhLENBQVc7SUFHeEIsa0JBQWtCLENBQVc7SUFHN0IsYUFBYSxDQUFVO0lBR3ZCLFdBQVcsQ0FBVTtJQUdyQixZQUFZLENBQVU7Q0FDOUIsQ0FBQTtBQXpDWSxrQ0FBVztBQUVmO0lBRE4sSUFBQSxrQkFBSSxFQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7OzhDQUNiO0FBR25CO0lBRE4sSUFBQSxrQkFBSSxFQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDOzs4Q0FDQztBQUluQjtJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLHFDQUF1QixFQUFFLE1BQU0sRUFBRSw4QkFBZ0IsRUFBRSxDQUFDOzs2Q0FDdEM7QUFJM0M7SUFETixJQUFBLGtCQUFJLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxzQ0FBd0IsRUFBRSxDQUFDOztrREFDN0I7QUFHdkI7SUFETixJQUFBLGtCQUFJLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxzQ0FBd0IsRUFBRSxDQUFDOzt5REFDdEI7QUFHOUI7SUFETixJQUFBLGtCQUFJLEVBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7O2lEQUNPO0FBR3ZCO0lBRE4sSUFBQSxrQkFBSSxFQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDOzs2Q0FDRztBQUduQjtJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQzs7NkNBQ0c7QUFHbkI7SUFETixJQUFBLGtCQUFJLEVBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7O2tEQUNRO0FBR3hCO0lBRE4sSUFBQSxrQkFBSSxFQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDOzt1REFDYTtBQUc3QjtJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxDQUFDOztrREFDVjtBQUd2QjtJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDOztnREFDbEI7QUFHckI7SUFETixJQUFBLGtCQUFJLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQzs7aURBQ2pCO3NCQXhDbEIsV0FBVztJQUx2QixJQUFBLDBCQUFZLEVBQUMsdUJBQXVCLENBQUM7SUFDckMsSUFBQSwwQkFBWSxFQUFDLG1CQUFtQixDQUFDO0lBQ2pDLElBQUEsb0JBQU0sRUFBQyxRQUFRLEVBQUU7UUFDaEIsU0FBUyxFQUFFLGVBQWU7S0FDM0IsQ0FBQztHQUNXLFdBQVcsQ0F5Q3ZCO0FBRVksUUFBQSxXQUFXLEdBQUcsSUFBQSxpQ0FBbUIsRUFBQyxXQUFXLENBQUMsQ0FBQyJ9
|
|
@@ -6,5 +6,7 @@ export declare class RecordAuditClass {
|
|
|
6
6
|
record?: Record<string, unknown>;
|
|
7
7
|
dateCreated: string;
|
|
8
8
|
action?: string;
|
|
9
|
+
executionSummary?: Record<string, unknown>;
|
|
10
|
+
concurrency?: Record<string, unknown>;
|
|
9
11
|
}
|
|
10
12
|
export declare const RecordAuditWLDef: import("@researchdatabox/redbox-core").WaterlineModelDefinition;
|
|
@@ -19,6 +19,8 @@ let RecordAuditClass = class RecordAuditClass {
|
|
|
19
19
|
record;
|
|
20
20
|
dateCreated;
|
|
21
21
|
action;
|
|
22
|
+
executionSummary;
|
|
23
|
+
concurrency;
|
|
22
24
|
};
|
|
23
25
|
exports.RecordAuditClass = RecordAuditClass;
|
|
24
26
|
__decorate([
|
|
@@ -45,8 +47,16 @@ __decorate([
|
|
|
45
47
|
(0, redbox_core_1.Attr)({ type: 'string' }),
|
|
46
48
|
__metadata("design:type", String)
|
|
47
49
|
], RecordAuditClass.prototype, "action", void 0);
|
|
50
|
+
__decorate([
|
|
51
|
+
(0, redbox_core_1.Attr)({ type: 'json' }),
|
|
52
|
+
__metadata("design:type", Object)
|
|
53
|
+
], RecordAuditClass.prototype, "executionSummary", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
(0, redbox_core_1.Attr)({ type: 'json' }),
|
|
56
|
+
__metadata("design:type", Object)
|
|
57
|
+
], RecordAuditClass.prototype, "concurrency", void 0);
|
|
48
58
|
exports.RecordAuditClass = RecordAuditClass = __decorate([
|
|
49
59
|
(0, redbox_core_1.Entity)('recordaudit', { datastore: 'redboxStorage' })
|
|
50
60
|
], RecordAuditClass);
|
|
51
61
|
exports.RecordAuditWLDef = (0, redbox_core_1.toWaterlineModelDef)(RecordAuditClass);
|
|
52
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
62
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVjb3JkQXVkaXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbW9kZWxzL1JlY29yZEF1ZGl0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLDRCQUEwQjtBQUMxQiw4REFBaUY7QUFHMUUsSUFBTSxnQkFBZ0IsR0FBdEIsTUFBTSxnQkFBZ0I7SUFFcEIsU0FBUyxDQUFVO0lBR25CLFVBQVUsQ0FBVTtJQUdwQixJQUFJLENBQTJCO0lBRy9CLE1BQU0sQ0FBMkI7SUFHakMsV0FBVyxDQUFVO0lBR3JCLE1BQU0sQ0FBVTtJQUdoQixnQkFBZ0IsQ0FBMkI7SUFHM0MsV0FBVyxDQUEyQjtDQUM5QyxDQUFBO0FBeEJZLDRDQUFnQjtBQUVwQjtJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQzs7bURBQ0M7QUFHbkI7SUFETixJQUFBLGtCQUFJLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7O29EQUNFO0FBR3BCO0lBRE4sSUFBQSxrQkFBSSxFQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDOzs4Q0FDZTtBQUcvQjtJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQzs7Z0RBQ2lCO0FBR2pDO0lBRE4sSUFBQSxrQkFBSSxFQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUM7O3FEQUNsQjtBQUdyQjtJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQzs7Z0RBQ0Y7QUFHaEI7SUFETixJQUFBLGtCQUFJLEVBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7OzBEQUMyQjtBQUczQztJQUROLElBQUEsa0JBQUksRUFBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQzs7cURBQ3NCOzJCQXZCbEMsZ0JBQWdCO0lBRDVCLElBQUEsb0JBQU0sRUFBQyxhQUFhLEVBQUUsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLENBQUM7R0FDekMsZ0JBQWdCLENBd0I1QjtBQUVZLFFBQUEsZ0JBQWdCLEdBQUcsSUFBQSxpQ0FBbUIsRUFBQyxnQkFBZ0IsQ0FBQyxDQUFDIn0=
|