@futdevpro/nts-dynamo 1.15.118 → 1.15.119
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/.dynamo/logs/cicd-pipeline/output.log +1906 -1869
- package/.dynamo/logs/cicd-pipeline/status.json +41 -35
- package/build/_models/data-models/schema-migration.data-model.d.ts +29 -0
- package/build/_models/data-models/schema-migration.data-model.d.ts.map +1 -0
- package/build/_models/data-models/schema-migration.data-model.js +47 -0
- package/build/_models/data-models/schema-migration.data-model.js.map +1 -0
- package/build/_models/interfaces/migration-entry.interface.d.ts +20 -0
- package/build/_models/interfaces/migration-entry.interface.d.ts.map +1 -0
- package/build/_models/interfaces/migration-entry.interface.js +3 -0
- package/build/_models/interfaces/migration-entry.interface.js.map +1 -0
- package/build/_services/core/migration-runner.service.d.ts +40 -0
- package/build/_services/core/migration-runner.service.d.ts.map +1 -0
- package/build/_services/core/migration-runner.service.js +75 -0
- package/build/_services/core/migration-runner.service.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -0
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/_models/data-models/schema-migration.data-model.ts +50 -0
- package/src/_models/interfaces/migration-entry.interface.ts +19 -0
- package/src/_services/core/migration-runner.service.spec.ts +91 -0
- package/src/_services/core/migration-runner.service.ts +106 -0
- package/src/index.ts +5 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"pid":
|
|
3
|
-
"startedAt": "2026-07-
|
|
4
|
-
"startedAtMs":
|
|
2
|
+
"pid": 15048,
|
|
3
|
+
"startedAt": "2026-07-26T21:11:37.191Z",
|
|
4
|
+
"startedAtMs": 1785100297191,
|
|
5
5
|
"phase": "npm-publish",
|
|
6
6
|
"pipelineComplete": false,
|
|
7
7
|
"serverRunning": false,
|
|
@@ -10,77 +10,83 @@
|
|
|
10
10
|
"steps": {
|
|
11
11
|
"validate-secrets": {
|
|
12
12
|
"status": "ok",
|
|
13
|
-
"startedAt": "2026-07-
|
|
13
|
+
"startedAt": "2026-07-26T21:11:37.214Z",
|
|
14
14
|
"logLineStart": 2,
|
|
15
15
|
"logLineEnd": 8,
|
|
16
16
|
"durationSec": 0.3
|
|
17
17
|
},
|
|
18
18
|
"discord-start": {
|
|
19
19
|
"status": "ok",
|
|
20
|
-
"startedAt": "2026-07-
|
|
20
|
+
"startedAt": "2026-07-26T21:11:38.480Z",
|
|
21
21
|
"logLineStart": 9,
|
|
22
22
|
"logLineEnd": 14,
|
|
23
|
-
"durationSec":
|
|
23
|
+
"durationSec": 3
|
|
24
24
|
},
|
|
25
25
|
"pre-flight": {
|
|
26
26
|
"status": "ok",
|
|
27
|
-
"startedAt": "2026-07-
|
|
27
|
+
"startedAt": "2026-07-26T21:11:42.473Z",
|
|
28
28
|
"logLineStart": 15,
|
|
29
29
|
"logLineEnd": 17,
|
|
30
|
-
"durationSec": 0.
|
|
30
|
+
"durationSec": 0.2
|
|
31
31
|
},
|
|
32
32
|
"install": {
|
|
33
33
|
"status": "ok",
|
|
34
|
-
"startedAt": "2026-07-
|
|
34
|
+
"startedAt": "2026-07-26T21:11:43.675Z",
|
|
35
35
|
"logLineStart": 18,
|
|
36
|
-
"logLineEnd":
|
|
37
|
-
"durationSec":
|
|
36
|
+
"logLineEnd": 104,
|
|
37
|
+
"durationSec": 25.6
|
|
38
38
|
},
|
|
39
39
|
"check-dev-leftovers": {
|
|
40
40
|
"status": "ok",
|
|
41
|
-
"startedAt": "2026-07-
|
|
42
|
-
"logLineStart":
|
|
43
|
-
"logLineEnd":
|
|
44
|
-
"durationSec":
|
|
41
|
+
"startedAt": "2026-07-26T21:12:10.230Z",
|
|
42
|
+
"logLineStart": 105,
|
|
43
|
+
"logLineEnd": 112,
|
|
44
|
+
"durationSec": 4.4
|
|
45
45
|
},
|
|
46
46
|
"build": {
|
|
47
47
|
"status": "ok",
|
|
48
|
-
"startedAt": "2026-07-
|
|
49
|
-
"logLineStart":
|
|
50
|
-
"logLineEnd":
|
|
51
|
-
"durationSec":
|
|
48
|
+
"startedAt": "2026-07-26T21:12:15.627Z",
|
|
49
|
+
"logLineStart": 113,
|
|
50
|
+
"logLineEnd": 114,
|
|
51
|
+
"durationSec": 27.8
|
|
52
52
|
},
|
|
53
53
|
"test": {
|
|
54
54
|
"status": "ok",
|
|
55
|
-
"startedAt": "2026-07-
|
|
56
|
-
"logLineStart":
|
|
57
|
-
"logLineEnd":
|
|
58
|
-
"durationSec":
|
|
55
|
+
"startedAt": "2026-07-26T21:12:44.425Z",
|
|
56
|
+
"logLineStart": 115,
|
|
57
|
+
"logLineEnd": 2839,
|
|
58
|
+
"durationSec": 20.3,
|
|
59
59
|
"testSummary": {
|
|
60
|
-
"totalSpecs":
|
|
60
|
+
"totalSpecs": 1593,
|
|
61
61
|
"failures": 0,
|
|
62
|
-
"passed":
|
|
63
|
-
"testDurationSec":
|
|
62
|
+
"passed": 1593,
|
|
63
|
+
"testDurationSec": 6.601
|
|
64
64
|
},
|
|
65
65
|
"errors": [
|
|
66
66
|
{
|
|
67
|
-
"line":
|
|
67
|
+
"line": 386,
|
|
68
|
+
"text": "......................................(checkDbReadiness) diagnostics collection failed (non-fatal) Error: diag boom",
|
|
69
|
+
"details": ".Authentication Service missing!\n.Authentication Service missing!\n.Authentication Service missing!\nat Object.get host [as host] (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/build/_modules/server/server-status/server-status.control-service.spec.js:487:36)\nat TestServerStatusControlService.checkDbReadiness (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/build/_modules/server/server-status/server-status.control-service.js:177:29)\nat processTicksAndRejections (node:internal/process/task_queues:95:5)\nat async UserContext.<anonymous> (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/build/_modules/server/server-status/server-status.control-service.spec.js:490:28)",
|
|
70
|
+
"detailLineEnd": 390
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"line": 399,
|
|
68
74
|
"text": "(checkDbReadiness) diagnostics collection failed (non-fatal) Error: boom",
|
|
69
|
-
"details": "at
|
|
70
|
-
"detailLineEnd":
|
|
75
|
+
"details": "at /tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8361:11\nat /tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8241:9\nat processTicksAndRejections (node:internal/process/task_queues:95:5)\nat UserContext.<anonymous> (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/build/_modules/server/server-status/server-status.control-service.spec.js:507:68)\nat QueueRunner.attempt (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8414:40)\nat QueueRunner.run (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8452:27)\nat runNext (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8355:16)\nat /tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8361:11\nat /tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8241:9\nat processTicksAndRejections (node:internal/process/task_queues:95:5)",
|
|
76
|
+
"detailLineEnd": 406
|
|
71
77
|
},
|
|
72
78
|
{
|
|
73
|
-
"line":
|
|
74
|
-
"text": "
|
|
75
|
-
"details": "at
|
|
76
|
-
"detailLineEnd":
|
|
79
|
+
"line": 2056,
|
|
80
|
+
"text": "[dynts-migration] FAILED bad Error: boom",
|
|
81
|
+
"details": "at Object.run (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/build/_services/core/migration-runner.service.spec.js:67:50)\nat DyNTS_Migration_Runner.runPending (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/build/_services/core/migration-runner.service.js:52:49)\nat async UserContext.<anonymous> (/tmp/pipeline-runs/a686f4ed-5884-4898-92e6-77674803c205/build/_services/core/migration-runner.service.spec.js:70:25)",
|
|
82
|
+
"detailLineEnd": 2059
|
|
77
83
|
}
|
|
78
84
|
]
|
|
79
85
|
},
|
|
80
86
|
"npm-publish": {
|
|
81
87
|
"status": "running",
|
|
82
|
-
"startedAt": "2026-07-
|
|
83
|
-
"logLineStart":
|
|
88
|
+
"startedAt": "2026-07-26T21:13:05.802Z",
|
|
89
|
+
"logLineStart": 2840,
|
|
84
90
|
"logLineEnd": null,
|
|
85
91
|
"durationSec": null
|
|
86
92
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DyFM_DataModel_Params, DyFM_Metadata } from '@futdevpro/fsm-dynamo';
|
|
2
|
+
/**
|
|
3
|
+
* **Migráció-nyilvántartó ("server info") LEDGER** — bedrock, újrahasználható az egész flottának.
|
|
4
|
+
* (A token-service app-lokál `SchemaMigration` mintájából emelve bedrock nts-be.)
|
|
5
|
+
*
|
|
6
|
+
* Egy-egy `migrationId` **PONTOSAN EGYSZER** fut le rendszerenként: a `DyNTS_Migration_Runner.runPending()`
|
|
7
|
+
* boot-on (az app `app.server.postProcess()`-éből) lekéri a már-alkalmazott ID-kat, a pending
|
|
8
|
+
* migrációkat lefuttatja, majd egy sort rögzít ide. A `migrationId` **unique index** → race-safe
|
|
9
|
+
* (két párhuzamos instance esetén az egyik `save`-je duplicate-key-re bukik → skip).
|
|
10
|
+
*
|
|
11
|
+
* A ledger a KÖTELEZŐ kanon-adatokat tartja: **mely migrációk futottak** (id + idő) + **mely app-verzió**
|
|
12
|
+
* alkalmazta (a `appliedVersion`-ökből a "mely verziók futottak" levezethető).
|
|
13
|
+
*
|
|
14
|
+
* Az app a saját DB-jében regisztrálja a `dyNTS_schemaMigration_dataParams`-t (`getGlobalServiceCollection
|
|
15
|
+
* ().dbModels`), így per-app saját `dynts_schema_migrations` collection-t kap.
|
|
16
|
+
*/
|
|
17
|
+
export declare class DyNTS_SchemaMigration extends DyFM_Metadata {
|
|
18
|
+
/** A migráció egyedi azonosítója (konvenció: `YYYY-MM-DD-NNN-descriptor`). */
|
|
19
|
+
migrationId?: string;
|
|
20
|
+
/** Alkalmazás időbélyege. */
|
|
21
|
+
appliedAt?: Date;
|
|
22
|
+
/** Az alkalmazó app-verzió (a `package.json` version-je — audit-trail + "mely verziók futottak"). */
|
|
23
|
+
appliedVersion?: string;
|
|
24
|
+
/** Diag — pl. `touched=<n>` vagy hiba-részletek. */
|
|
25
|
+
notes?: string;
|
|
26
|
+
constructor(set?: DyNTS_SchemaMigration);
|
|
27
|
+
}
|
|
28
|
+
export declare const dyNTS_schemaMigration_dataParams: DyFM_DataModel_Params<DyNTS_SchemaMigration>;
|
|
29
|
+
//# sourceMappingURL=schema-migration.data-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-migration.data-model.d.ts","sourceRoot":"","sources":["../../../src/_models/data-models/schema-migration.data-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE7E;;;;;;;;;;;;;;GAcG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;IAEtD,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,IAAI,CAAC;IAEjB,qGAAqG;IACrG,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;gBAEH,GAAG,CAAC,EAAE,qBAAqB;CAMxC;AAED,eAAO,MAAM,gCAAgC,EAAE,qBAAqB,CAAC,qBAAqB,CAUtF,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dyNTS_schemaMigration_dataParams = exports.DyNTS_SchemaMigration = void 0;
|
|
4
|
+
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
5
|
+
/**
|
|
6
|
+
* **Migráció-nyilvántartó ("server info") LEDGER** — bedrock, újrahasználható az egész flottának.
|
|
7
|
+
* (A token-service app-lokál `SchemaMigration` mintájából emelve bedrock nts-be.)
|
|
8
|
+
*
|
|
9
|
+
* Egy-egy `migrationId` **PONTOSAN EGYSZER** fut le rendszerenként: a `DyNTS_Migration_Runner.runPending()`
|
|
10
|
+
* boot-on (az app `app.server.postProcess()`-éből) lekéri a már-alkalmazott ID-kat, a pending
|
|
11
|
+
* migrációkat lefuttatja, majd egy sort rögzít ide. A `migrationId` **unique index** → race-safe
|
|
12
|
+
* (két párhuzamos instance esetén az egyik `save`-je duplicate-key-re bukik → skip).
|
|
13
|
+
*
|
|
14
|
+
* A ledger a KÖTELEZŐ kanon-adatokat tartja: **mely migrációk futottak** (id + idő) + **mely app-verzió**
|
|
15
|
+
* alkalmazta (a `appliedVersion`-ökből a "mely verziók futottak" levezethető).
|
|
16
|
+
*
|
|
17
|
+
* Az app a saját DB-jében regisztrálja a `dyNTS_schemaMigration_dataParams`-t (`getGlobalServiceCollection
|
|
18
|
+
* ().dbModels`), így per-app saját `dynts_schema_migrations` collection-t kap.
|
|
19
|
+
*/
|
|
20
|
+
class DyNTS_SchemaMigration extends fsm_dynamo_1.DyFM_Metadata {
|
|
21
|
+
/** A migráció egyedi azonosítója (konvenció: `YYYY-MM-DD-NNN-descriptor`). */
|
|
22
|
+
migrationId;
|
|
23
|
+
/** Alkalmazás időbélyege. */
|
|
24
|
+
appliedAt;
|
|
25
|
+
/** Az alkalmazó app-verzió (a `package.json` version-je — audit-trail + "mely verziók futottak"). */
|
|
26
|
+
appliedVersion;
|
|
27
|
+
/** Diag — pl. `touched=<n>` vagy hiba-részletek. */
|
|
28
|
+
notes;
|
|
29
|
+
constructor(set) {
|
|
30
|
+
super(set);
|
|
31
|
+
if (set) {
|
|
32
|
+
Object.assign(this, set);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.DyNTS_SchemaMigration = DyNTS_SchemaMigration;
|
|
37
|
+
exports.dyNTS_schemaMigration_dataParams = new fsm_dynamo_1.DyFM_DataModel_Params({
|
|
38
|
+
dataName: 'dynts_schema_migrations',
|
|
39
|
+
addArchive: false,
|
|
40
|
+
properties: {
|
|
41
|
+
migrationId: { type: 'string', required: true, unique: true, index: true },
|
|
42
|
+
appliedAt: { type: 'date', required: true },
|
|
43
|
+
appliedVersion: { type: 'string' },
|
|
44
|
+
notes: { type: 'string' },
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=schema-migration.data-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-migration.data-model.js","sourceRoot":"","sources":["../../../src/_models/data-models/schema-migration.data-model.ts"],"names":[],"mappings":";;;AAAA,sDAA6E;AAE7E;;;;;;;;;;;;;;GAcG;AACH,MAAa,qBAAsB,SAAQ,0BAAa;IAEtD,8EAA8E;IAC9E,WAAW,CAAU;IAErB,6BAA6B;IAC7B,SAAS,CAAQ;IAEjB,qGAAqG;IACrG,cAAc,CAAU;IAExB,oDAAoD;IACpD,KAAK,CAAU;IAEf,YAAY,GAA2B;QACrC,KAAK,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;CACF;AApBD,sDAoBC;AAEY,QAAA,gCAAgC,GAC3C,IAAI,kCAAqB,CAAwB;IAC/C,QAAQ,EAAE,yBAAyB;IACnC,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE;QACV,WAAW,EAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QAC7E,SAAS,EAAO,EAAE,IAAI,EAAE,MAAM,EAAI,QAAQ,EAAE,IAAI,EAAE;QAClD,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAClC,KAAK,EAAW,EAAE,IAAI,EAAE,QAAQ,EAAE;KACnC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Egy regisztrált deploy-integrált migráció leírója. Az app egy `DyNTS_MigrationEntry[]` registry-t
|
|
3
|
+
* ad át a `DyNTS_Migration_Runner.runPending(...)`-nek; a runner a pending (még nem alkalmazott)
|
|
4
|
+
* entry-ket **egyszer** futtatja le, sorrendben, majd a `DyNTS_SchemaMigration` ledgerbe rögzíti.
|
|
5
|
+
*/
|
|
6
|
+
export interface DyNTS_MigrationEntry {
|
|
7
|
+
/** Egyedi, monoton bővíthető ID (konvenció: `YYYY-MM-DD-NNN-descriptor`). A ledger ez alapján run-once-ol. */
|
|
8
|
+
id: string;
|
|
9
|
+
/** Rövid leíró (admin/debug/log). */
|
|
10
|
+
description: string;
|
|
11
|
+
/**
|
|
12
|
+
* A tényleges migráció-logika. Az app már-csatlakozott Mongo-kapcsolatát használja (a runner a
|
|
13
|
+
* `postProcess`-ből fut, ahol a DB már él). Hibára DOBHAT — a runner catch-eli, a `notes`-ba menti,
|
|
14
|
+
* és NEM állítja meg a boot-ot. Visszaad: `{ touched }` (a módosított dokumentumok száma — count/riport).
|
|
15
|
+
*/
|
|
16
|
+
run: (issuer: string) => Promise<{
|
|
17
|
+
touched: number;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=migration-entry.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-entry.interface.d.ts","sourceRoot":"","sources":["../../../src/_models/interfaces/migration-entry.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,8GAA8G;IAC9G,EAAE,EAAE,MAAM,CAAC;IAEX,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-entry.interface.js","sourceRoot":"","sources":["../../../src/_models/interfaces/migration-entry.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DyNTS_SingletonService } from '../base/singleton.service';
|
|
2
|
+
import { DyNTS_DataService } from '../base/data.service';
|
|
3
|
+
import { DyNTS_SchemaMigration } from '../../_models/data-models/schema-migration.data-model';
|
|
4
|
+
import { DyNTS_MigrationEntry } from '../../_models/interfaces/migration-entry.interface';
|
|
5
|
+
/** A `runPending` összesítő eredménye. */
|
|
6
|
+
export interface DyNTS_MigrationRunResult {
|
|
7
|
+
applied: number;
|
|
8
|
+
skipped: number;
|
|
9
|
+
failed: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* **Deploy-integrált migráció-futtató** — bedrock, újrahasználható. Az app a `app.server.postProcess()`-
|
|
13
|
+
* ből hívja: `DyNTS_Migration_Runner.getInstance().runPending(ALL_MIGRATIONS, appVersion)`.
|
|
14
|
+
*
|
|
15
|
+
* Mechanizmus (kanon `deploy-integrated-migrations.md`):
|
|
16
|
+
* - Boot-on lekéri a `DyNTS_SchemaMigration` ledgerből a MÁR-alkalmazott `migrationId`-kat.
|
|
17
|
+
* - A **pending** (még nem alkalmazott) entry-ket **sorrendben, egyszer** lefuttatja.
|
|
18
|
+
* - Mindegyik után egy ledger-sort rögzít (`migrationId` + `appliedAt` + `appliedVersion` + `notes`).
|
|
19
|
+
* - **RUN-ONCE:** a `migrationId` unique-index → re-boot / párhuzamos instance esetén skip (duplicate-key).
|
|
20
|
+
* - **Boot-safe:** egy hibás migráció NEM állítja meg a boot-ot (catch + notes; a runner tovább megy).
|
|
21
|
+
*/
|
|
22
|
+
export declare class DyNTS_Migration_Runner extends DyNTS_SingletonService {
|
|
23
|
+
static getInstance(): DyNTS_Migration_Runner;
|
|
24
|
+
/**
|
|
25
|
+
* TISZTA pending-szelekció (DB nélkül tesztelhető): azok az entry-k, amiknek az `id`-ja NINCS az
|
|
26
|
+
* `appliedIds`-ban. A regisztráció sorrendje megőrződik (a bővítés a tömb VÉGÉRE).
|
|
27
|
+
*/
|
|
28
|
+
static selectPending(migrations: DyNTS_MigrationEntry[], appliedIds: Set<string>): DyNTS_MigrationEntry[];
|
|
29
|
+
/** A ledger-DataService előállítása. `protected` → a spec felül tudja írni (mock-hoz). */
|
|
30
|
+
protected createLedgerDataService(issuer: string): DyNTS_DataService<DyNTS_SchemaMigration>;
|
|
31
|
+
/**
|
|
32
|
+
* A pending migrációk lefuttatása + rögzítése.
|
|
33
|
+
*
|
|
34
|
+
* @param migrations - az app registry-je (`DyNTS_MigrationEntry[]`)
|
|
35
|
+
* @param appVersion - az app aktuális verziója (a ledger `appliedVersion`-jébe)
|
|
36
|
+
* @param issuer - opcionális issuer-cimke (default `DyNTS_Migration_Runner`)
|
|
37
|
+
*/
|
|
38
|
+
runPending(migrations: DyNTS_MigrationEntry[], appVersion: string, issuer?: string): Promise<DyNTS_MigrationRunResult>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=migration-runner.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-runner.service.d.ts","sourceRoot":"","sources":["../../../src/_services/core/migration-runner.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EACL,qBAAqB,EACtB,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAE1F,0CAA0C;AAC1C,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,sBAAuB,SAAQ,sBAAsB;IAEhE,MAAM,CAAC,WAAW,IAAI,sBAAsB;IAI5C;;;OAGG;IACH,MAAM,CAAC,aAAa,CAClB,UAAU,EAAE,oBAAoB,EAAE,EAClC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACtB,oBAAoB,EAAE;IAIzB,0FAA0F;IAC1F,SAAS,CAAC,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAAC,qBAAqB,CAAC;IAQ3F;;;;;;OAMG;IACG,UAAU,CACd,UAAU,EAAE,oBAAoB,EAAE,EAClC,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAiC,GACxC,OAAO,CAAC,wBAAwB,CAAC;CAyCrC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_Migration_Runner = void 0;
|
|
4
|
+
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
5
|
+
const singleton_service_1 = require("../base/singleton.service");
|
|
6
|
+
const data_service_1 = require("../base/data.service");
|
|
7
|
+
const schema_migration_data_model_1 = require("../../_models/data-models/schema-migration.data-model");
|
|
8
|
+
/**
|
|
9
|
+
* **Deploy-integrált migráció-futtató** — bedrock, újrahasználható. Az app a `app.server.postProcess()`-
|
|
10
|
+
* ből hívja: `DyNTS_Migration_Runner.getInstance().runPending(ALL_MIGRATIONS, appVersion)`.
|
|
11
|
+
*
|
|
12
|
+
* Mechanizmus (kanon `deploy-integrated-migrations.md`):
|
|
13
|
+
* - Boot-on lekéri a `DyNTS_SchemaMigration` ledgerből a MÁR-alkalmazott `migrationId`-kat.
|
|
14
|
+
* - A **pending** (még nem alkalmazott) entry-ket **sorrendben, egyszer** lefuttatja.
|
|
15
|
+
* - Mindegyik után egy ledger-sort rögzít (`migrationId` + `appliedAt` + `appliedVersion` + `notes`).
|
|
16
|
+
* - **RUN-ONCE:** a `migrationId` unique-index → re-boot / párhuzamos instance esetén skip (duplicate-key).
|
|
17
|
+
* - **Boot-safe:** egy hibás migráció NEM állítja meg a boot-ot (catch + notes; a runner tovább megy).
|
|
18
|
+
*/
|
|
19
|
+
class DyNTS_Migration_Runner extends singleton_service_1.DyNTS_SingletonService {
|
|
20
|
+
static getInstance() {
|
|
21
|
+
return DyNTS_Migration_Runner.getSingletonInstance();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* TISZTA pending-szelekció (DB nélkül tesztelhető): azok az entry-k, amiknek az `id`-ja NINCS az
|
|
25
|
+
* `appliedIds`-ban. A regisztráció sorrendje megőrződik (a bővítés a tömb VÉGÉRE).
|
|
26
|
+
*/
|
|
27
|
+
static selectPending(migrations, appliedIds) {
|
|
28
|
+
return (migrations ?? []).filter((migration) => !appliedIds.has(migration.id));
|
|
29
|
+
}
|
|
30
|
+
/** A ledger-DataService előállítása. `protected` → a spec felül tudja írni (mock-hoz). */
|
|
31
|
+
createLedgerDataService(issuer) {
|
|
32
|
+
return new data_service_1.DyNTS_DataService(new schema_migration_data_model_1.DyNTS_SchemaMigration(), schema_migration_data_model_1.dyNTS_schemaMigration_dataParams, issuer);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A pending migrációk lefuttatása + rögzítése.
|
|
36
|
+
*
|
|
37
|
+
* @param migrations - az app registry-je (`DyNTS_MigrationEntry[]`)
|
|
38
|
+
* @param appVersion - az app aktuális verziója (a ledger `appliedVersion`-jébe)
|
|
39
|
+
* @param issuer - opcionális issuer-cimke (default `DyNTS_Migration_Runner`)
|
|
40
|
+
*/
|
|
41
|
+
async runPending(migrations, appVersion, issuer = 'DyNTS_Migration_Runner') {
|
|
42
|
+
const result = { applied: 0, skipped: 0, failed: 0 };
|
|
43
|
+
fsm_dynamo_1.DyFM_Log.info(`[dynts-migration] sweep start — ${migrations?.length ?? 0} migration(s) registered · appVersion=${appVersion}`);
|
|
44
|
+
const ledger_DS = this.createLedgerDataService(issuer);
|
|
45
|
+
const applied = await ledger_DS.dataDBService.find({});
|
|
46
|
+
const appliedIds = new Set(applied.map((record) => record.migrationId ?? ''));
|
|
47
|
+
const pending = DyNTS_Migration_Runner.selectPending(migrations, appliedIds);
|
|
48
|
+
result.skipped = (migrations?.length ?? 0) - pending.length;
|
|
49
|
+
for (const migration of pending) {
|
|
50
|
+
try {
|
|
51
|
+
fsm_dynamo_1.DyFM_Log.info(`[dynts-migration] applying ${migration.id} — ${migration.description}`);
|
|
52
|
+
const outcome = await migration.run(issuer);
|
|
53
|
+
// Atomikus claim — a unique-index dob duplicate-ra (race-safe, két párhuzamos instance).
|
|
54
|
+
ledger_DS.data = new schema_migration_data_model_1.DyNTS_SchemaMigration({
|
|
55
|
+
migrationId: migration.id,
|
|
56
|
+
appliedAt: new Date(),
|
|
57
|
+
appliedVersion: appVersion,
|
|
58
|
+
notes: `touched=${outcome?.touched ?? 0}`,
|
|
59
|
+
});
|
|
60
|
+
await ledger_DS.saveData();
|
|
61
|
+
fsm_dynamo_1.DyFM_Log.success(`[dynts-migration] applied ${migration.id} (touched=${outcome?.touched ?? 0})`);
|
|
62
|
+
result.applied++;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
// Egy hibás migráció NEM állíthatja meg a boot-ot (catch + log; a következő entry mehet).
|
|
66
|
+
fsm_dynamo_1.DyFM_Error.logSimple(`[dynts-migration] FAILED ${migration.id}`, error);
|
|
67
|
+
result.failed++;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
fsm_dynamo_1.DyFM_Log.info(`[dynts-migration] sweep done — applied=${result.applied} skipped=${result.skipped} failed=${result.failed}`);
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.DyNTS_Migration_Runner = DyNTS_Migration_Runner;
|
|
75
|
+
//# sourceMappingURL=migration-runner.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-runner.service.js","sourceRoot":"","sources":["../../../src/_services/core/migration-runner.service.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export * from './_models/interfaces/static-client-settings.interface';
|
|
|
19
19
|
export * from './_models/interfaces/cors-settings.interface';
|
|
20
20
|
export * from './_models/interfaces/security-headers-settings.interface';
|
|
21
21
|
export * from './_models/interfaces/db-query-options.interface';
|
|
22
|
+
export * from './_models/interfaces/migration-entry.interface';
|
|
22
23
|
export * from './_collections/security-headers.util';
|
|
23
24
|
export * from './_collections/client-safe-error.util';
|
|
24
25
|
export * from './_collections/load-shed.util';
|
|
@@ -31,6 +32,7 @@ export * from './_models/control-models/endpoint-params.control-model';
|
|
|
31
32
|
export * from './_models/control-models/http-settings.control-model';
|
|
32
33
|
export * from './_models/control-models/system-control.control-model';
|
|
33
34
|
export * from './_models/types/db-update.type';
|
|
35
|
+
export * from './_models/data-models/schema-migration.data-model';
|
|
34
36
|
export * from './_services/core/api.service';
|
|
35
37
|
export * from './_services/core/auth.service';
|
|
36
38
|
export * from './_services/core/email.service';
|
|
@@ -38,6 +40,7 @@ export * from './_services/core/collection-growth-monitor.service';
|
|
|
38
40
|
export * from './_services/core/global.service';
|
|
39
41
|
export * from './_services/core/memory-guard.service';
|
|
40
42
|
export * from './_services/core/service-collection.service';
|
|
43
|
+
export * from './_services/core/migration-runner.service';
|
|
41
44
|
export * from './_services/base/api.service-base';
|
|
42
45
|
export * from './_services/base/archive-data.service';
|
|
43
46
|
export * from './_services/base/data.service';
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA2BA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qDAAqD,CAAC;AACpE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,sCAAsC,CAAC;AAIrD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAK7C,mEAAmE;AACnE,cAAc,uDAAuD,CAAC;AACtE,cAAc,qDAAqD,CAAC;AACpE,cAAc,wDAAwD,CAAC;AACvE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,wDAAwD,CAAC;AACvE,cAAc,uDAAuD,CAAC;AACtE,cAAc,8CAA8C,CAAC;AAC7D,cAAc,0DAA0D,CAAC;AACzE,cAAc,iDAAiD,CAAC;AAChE,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0CAA0C,CAAC;AAGzD,cAAc,wDAAwD,CAAC;AACvE,cAAc,gEAAgE,CAAA;AAC9E,cAAc,mDAAmD,CAAC;AAClE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,wDAAwD,CAAC;AACvE,cAAc,sDAAsD,CAAC;AACrE,cAAc,uDAAuD,CAAC;AAGtE,cAAc,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA2BA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qDAAqD,CAAC;AACpE,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,sCAAsC,CAAC;AAIrD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAK7C,mEAAmE;AACnE,cAAc,uDAAuD,CAAC;AACtE,cAAc,qDAAqD,CAAC;AACpE,cAAc,wDAAwD,CAAC;AACvE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,wDAAwD,CAAC;AACvE,cAAc,uDAAuD,CAAC;AACtE,cAAc,8CAA8C,CAAC;AAC7D,cAAc,0DAA0D,CAAC;AACzE,cAAc,iDAAiD,CAAC;AAChE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0CAA0C,CAAC;AAGzD,cAAc,wDAAwD,CAAC;AACvE,cAAc,gEAAgE,CAAA;AAC9E,cAAc,mDAAmD,CAAC;AAClE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,wDAAwD,CAAC;AACvE,cAAc,sDAAsD,CAAC;AACrE,cAAc,uDAAuD,CAAC;AAGtE,cAAc,gCAAgC,CAAC;AAG/C,cAAc,mDAAmD,CAAC;AAKlE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAE9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oDAAoD,CAAC;AACnE,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC;AAEtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAG1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yCAAyC,CAAC;AACxD,cAAc,oCAAoC,CAAC;AAGnD,cAAc,+BAA+B,CAAC;AAG9C,cAAc,sCAAsC,CAAC;AACrD,cAAc,0CAA0C,CAAC;AAGzD,cAAc,mCAAmC,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -48,6 +48,7 @@ tslib_1.__exportStar(require("./_models/interfaces/static-client-settings.interf
|
|
|
48
48
|
tslib_1.__exportStar(require("./_models/interfaces/cors-settings.interface"), exports);
|
|
49
49
|
tslib_1.__exportStar(require("./_models/interfaces/security-headers-settings.interface"), exports);
|
|
50
50
|
tslib_1.__exportStar(require("./_models/interfaces/db-query-options.interface"), exports);
|
|
51
|
+
tslib_1.__exportStar(require("./_models/interfaces/migration-entry.interface"), exports);
|
|
51
52
|
tslib_1.__exportStar(require("./_collections/security-headers.util"), exports);
|
|
52
53
|
tslib_1.__exportStar(require("./_collections/client-safe-error.util"), exports);
|
|
53
54
|
tslib_1.__exportStar(require("./_collections/load-shed.util"), exports);
|
|
@@ -62,6 +63,8 @@ tslib_1.__exportStar(require("./_models/control-models/http-settings.control-mod
|
|
|
62
63
|
tslib_1.__exportStar(require("./_models/control-models/system-control.control-model"), exports);
|
|
63
64
|
// models/TYPES
|
|
64
65
|
tslib_1.__exportStar(require("./_models/types/db-update.type"), exports);
|
|
66
|
+
// models/DATA-MODELS
|
|
67
|
+
tslib_1.__exportStar(require("./_models/data-models/schema-migration.data-model"), exports);
|
|
65
68
|
// SERVICES
|
|
66
69
|
// services/CORE
|
|
67
70
|
tslib_1.__exportStar(require("./_services/core/api.service"), exports);
|
|
@@ -71,6 +74,7 @@ tslib_1.__exportStar(require("./_services/core/collection-growth-monitor.service
|
|
|
71
74
|
tslib_1.__exportStar(require("./_services/core/global.service"), exports);
|
|
72
75
|
tslib_1.__exportStar(require("./_services/core/memory-guard.service"), exports);
|
|
73
76
|
tslib_1.__exportStar(require("./_services/core/service-collection.service"), exports);
|
|
77
|
+
tslib_1.__exportStar(require("./_services/core/migration-runner.service"), exports);
|
|
74
78
|
// services/BASE
|
|
75
79
|
tslib_1.__exportStar(require("./_services/base/api.service-base"), exports);
|
|
76
80
|
tslib_1.__exportStar(require("./_services/base/archive-data.service"), exports);
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;IAsBI;;;AAEJ,cAAc;AACd,sEAA4C;AAC5C,wFAA8D;AAC9D,8FAAoE;AACpE,sFAA4D;AAC5D,mFAAyD;AACzD,uFAA6D;AAC7D,+EAAqD;AAGrD,QAAQ;AACR,wEAA8C;AAC9C,8EAAoD;AACpD,8EAAoD;AACpD,uEAA6C;AAG7C,6CAA6C;AAE7C,mEAAmE;AACnE,gGAAsE;AACtE,8FAAoE;AACpE,iGAAuE;AACvE,yFAA+D;AAC/D,iGAAuE;AACvE,gGAAsE;AACtE,uFAA6D;AAC7D,mGAAyE;AACzE,0FAAgE;AAChE,+EAAqD;AACrD,gFAAsD;AACtD,wEAA8C;AAC9C,mFAAyD;AAEzD,wBAAwB;AACxB,iGAAuE;AACvE,yGAA8E;AAC9E,4FAAkE;AAClE,qGAA2E;AAC3E,iGAAuE;AACvE,+FAAqE;AACrE,gGAAsE;AAEtE,eAAe;AACf,yEAA+C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;IAsBI;;;AAEJ,cAAc;AACd,sEAA4C;AAC5C,wFAA8D;AAC9D,8FAAoE;AACpE,sFAA4D;AAC5D,mFAAyD;AACzD,uFAA6D;AAC7D,+EAAqD;AAGrD,QAAQ;AACR,wEAA8C;AAC9C,8EAAoD;AACpD,8EAAoD;AACpD,uEAA6C;AAG7C,6CAA6C;AAE7C,mEAAmE;AACnE,gGAAsE;AACtE,8FAAoE;AACpE,iGAAuE;AACvE,yFAA+D;AAC/D,iGAAuE;AACvE,gGAAsE;AACtE,uFAA6D;AAC7D,mGAAyE;AACzE,0FAAgE;AAChE,yFAA+D;AAC/D,+EAAqD;AACrD,gFAAsD;AACtD,wEAA8C;AAC9C,mFAAyD;AAEzD,wBAAwB;AACxB,iGAAuE;AACvE,yGAA8E;AAC9E,4FAAkE;AAClE,qGAA2E;AAC3E,iGAAuE;AACvE,+FAAqE;AACrE,gGAAsE;AAEtE,eAAe;AACf,yEAA+C;AAE/C,qBAAqB;AACrB,4FAAkE;AAGlE,WAAW;AACX,gBAAgB;AAChB,uEAA6C;AAC7C,wEAA8C;AAE9C,yEAA+C;AAC/C,6FAAmE;AACnE,0EAAgD;AAChD,gFAAsD;AAEtD,sFAA4D;AAC5D,oFAA0D;AAE1D,gBAAgB;AAChB,4EAAkD;AAClD,gFAAsD;AACtD,wEAA8C;AAC9C,sEAA4C;AAC5C,kFAAwD;AACxD,6EAAmD;AAEnD,kBAAkB;AAClB,wEAA8C;AAE9C,iBAAiB;AACjB,+EAAqD;AACrD,mFAAyD;AAEzD,kBAAkB;AAClB,4EAAkD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futdevpro/nts-dynamo",
|
|
3
|
-
"version": "01.15.
|
|
3
|
+
"version": "01.15.119",
|
|
4
4
|
"description": "Dynamic NodeTS (NodeJS-Typescript), MongoDB Backend System Framework by Future Development Program Ltd.",
|
|
5
5
|
"DyBu_settings": {
|
|
6
6
|
"packageType": "server-package",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { DyFM_DataModel_Params, DyFM_Metadata } from '@futdevpro/fsm-dynamo';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* **Migráció-nyilvántartó ("server info") LEDGER** — bedrock, újrahasználható az egész flottának.
|
|
5
|
+
* (A token-service app-lokál `SchemaMigration` mintájából emelve bedrock nts-be.)
|
|
6
|
+
*
|
|
7
|
+
* Egy-egy `migrationId` **PONTOSAN EGYSZER** fut le rendszerenként: a `DyNTS_Migration_Runner.runPending()`
|
|
8
|
+
* boot-on (az app `app.server.postProcess()`-éből) lekéri a már-alkalmazott ID-kat, a pending
|
|
9
|
+
* migrációkat lefuttatja, majd egy sort rögzít ide. A `migrationId` **unique index** → race-safe
|
|
10
|
+
* (két párhuzamos instance esetén az egyik `save`-je duplicate-key-re bukik → skip).
|
|
11
|
+
*
|
|
12
|
+
* A ledger a KÖTELEZŐ kanon-adatokat tartja: **mely migrációk futottak** (id + idő) + **mely app-verzió**
|
|
13
|
+
* alkalmazta (a `appliedVersion`-ökből a "mely verziók futottak" levezethető).
|
|
14
|
+
*
|
|
15
|
+
* Az app a saját DB-jében regisztrálja a `dyNTS_schemaMigration_dataParams`-t (`getGlobalServiceCollection
|
|
16
|
+
* ().dbModels`), így per-app saját `dynts_schema_migrations` collection-t kap.
|
|
17
|
+
*/
|
|
18
|
+
export class DyNTS_SchemaMigration extends DyFM_Metadata {
|
|
19
|
+
|
|
20
|
+
/** A migráció egyedi azonosítója (konvenció: `YYYY-MM-DD-NNN-descriptor`). */
|
|
21
|
+
migrationId?: string;
|
|
22
|
+
|
|
23
|
+
/** Alkalmazás időbélyege. */
|
|
24
|
+
appliedAt?: Date;
|
|
25
|
+
|
|
26
|
+
/** Az alkalmazó app-verzió (a `package.json` version-je — audit-trail + "mely verziók futottak"). */
|
|
27
|
+
appliedVersion?: string;
|
|
28
|
+
|
|
29
|
+
/** Diag — pl. `touched=<n>` vagy hiba-részletek. */
|
|
30
|
+
notes?: string;
|
|
31
|
+
|
|
32
|
+
constructor(set?: DyNTS_SchemaMigration) {
|
|
33
|
+
super(set);
|
|
34
|
+
if (set) {
|
|
35
|
+
Object.assign(this, set);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const dyNTS_schemaMigration_dataParams: DyFM_DataModel_Params<DyNTS_SchemaMigration> =
|
|
41
|
+
new DyFM_DataModel_Params<DyNTS_SchemaMigration>({
|
|
42
|
+
dataName: 'dynts_schema_migrations',
|
|
43
|
+
addArchive: false,
|
|
44
|
+
properties: {
|
|
45
|
+
migrationId: { type: 'string', required: true, unique: true, index: true },
|
|
46
|
+
appliedAt: { type: 'date', required: true },
|
|
47
|
+
appliedVersion: { type: 'string' },
|
|
48
|
+
notes: { type: 'string' },
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Egy regisztrált deploy-integrált migráció leírója. Az app egy `DyNTS_MigrationEntry[]` registry-t
|
|
3
|
+
* ad át a `DyNTS_Migration_Runner.runPending(...)`-nek; a runner a pending (még nem alkalmazott)
|
|
4
|
+
* entry-ket **egyszer** futtatja le, sorrendben, majd a `DyNTS_SchemaMigration` ledgerbe rögzíti.
|
|
5
|
+
*/
|
|
6
|
+
export interface DyNTS_MigrationEntry {
|
|
7
|
+
/** Egyedi, monoton bővíthető ID (konvenció: `YYYY-MM-DD-NNN-descriptor`). A ledger ez alapján run-once-ol. */
|
|
8
|
+
id: string;
|
|
9
|
+
|
|
10
|
+
/** Rövid leíró (admin/debug/log). */
|
|
11
|
+
description: string;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A tényleges migráció-logika. Az app már-csatlakozott Mongo-kapcsolatát használja (a runner a
|
|
15
|
+
* `postProcess`-ből fut, ahol a DB már él). Hibára DOBHAT — a runner catch-eli, a `notes`-ba menti,
|
|
16
|
+
* és NEM állítja meg a boot-ot. Visszaad: `{ touched }` (a módosított dokumentumok száma — count/riport).
|
|
17
|
+
*/
|
|
18
|
+
run: (issuer: string) => Promise<{ touched: number }>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { DyNTS_Migration_Runner } from './migration-runner.service';
|
|
2
|
+
import { DyNTS_SchemaMigration } from '../../_models/data-models/schema-migration.data-model';
|
|
3
|
+
import { DyNTS_MigrationEntry } from '../../_models/interfaces/migration-entry.interface';
|
|
4
|
+
|
|
5
|
+
function entry(id: string, run: () => Promise<{ touched: number }>): DyNTS_MigrationEntry {
|
|
6
|
+
return { id: id, description: id, run: run };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
describe('| DyNTS_Migration_Runner', () => {
|
|
10
|
+
|
|
11
|
+
describe('| selectPending (pure)', () => {
|
|
12
|
+
it('| kiszűri a már-alkalmazottakat, megőrzi a sorrendet', () => {
|
|
13
|
+
const migs: DyNTS_MigrationEntry[] = [
|
|
14
|
+
entry('a', async () => ({ touched: 0 })),
|
|
15
|
+
entry('b', async () => ({ touched: 0 })),
|
|
16
|
+
entry('c', async () => ({ touched: 0 })),
|
|
17
|
+
];
|
|
18
|
+
const pending: DyNTS_MigrationEntry[] = DyNTS_Migration_Runner.selectPending(migs, new Set([ 'b' ]));
|
|
19
|
+
expect(pending.map((m) => m.id)).toEqual([ 'a', 'c' ]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('| mind alkalmazva → üres; üres registry → üres', () => {
|
|
23
|
+
const migs: DyNTS_MigrationEntry[] = [ entry('a', async () => ({ touched: 0 })) ];
|
|
24
|
+
expect(DyNTS_Migration_Runner.selectPending(migs, new Set([ 'a' ])).length).toBe(0);
|
|
25
|
+
expect(DyNTS_Migration_Runner.selectPending([], new Set()).length).toBe(0);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe('| runPending (mock ledger)', () => {
|
|
30
|
+
let runner: DyNTS_Migration_Runner;
|
|
31
|
+
let saved: DyNTS_SchemaMigration[];
|
|
32
|
+
let appliedRecords: DyNTS_SchemaMigration[];
|
|
33
|
+
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
runner = DyNTS_Migration_Runner.getInstance();
|
|
36
|
+
saved = [];
|
|
37
|
+
appliedRecords = [];
|
|
38
|
+
|
|
39
|
+
const fakeLedger: any = { // ccap-review-disable-line no-any-type
|
|
40
|
+
dataDBService: { find: async (): Promise<DyNTS_SchemaMigration[]> => appliedRecords },
|
|
41
|
+
data: null,
|
|
42
|
+
saveData: async function (): Promise<void> { saved.push(this.data); appliedRecords.push(this.data); },
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
spyOn(runner as any, 'createLedgerDataService').and.returnValue(fakeLedger); // ccap-review-disable-line no-any-type
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('| a pending-et futtatja + rögzíti (id+version+touched), a már-alkalmazottat SKIP-eli', async () => {
|
|
49
|
+
appliedRecords.push(new DyNTS_SchemaMigration({ migrationId: 'm1' }));
|
|
50
|
+
const ran: string[] = [];
|
|
51
|
+
|
|
52
|
+
const migs: DyNTS_MigrationEntry[] = [
|
|
53
|
+
entry('m1', async () => { ran.push('m1'); return { touched: 1 }; }),
|
|
54
|
+
entry('m2', async () => { ran.push('m2'); return { touched: 5 }; }),
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
const res = await runner.runPending(migs, '1.0.0');
|
|
58
|
+
|
|
59
|
+
expect(ran).toEqual([ 'm2' ]); // m1 skip (már applied), m2 fut
|
|
60
|
+
expect(res.applied).toBe(1);
|
|
61
|
+
expect(res.skipped).toBe(1);
|
|
62
|
+
expect(saved[0].migrationId).toBe('m2');
|
|
63
|
+
expect(saved[0].appliedVersion).toBe('1.0.0');
|
|
64
|
+
expect(saved[0].notes).toBe('touched=5');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('| RUN-ONCE: második sweep-en (m2 már a ledgerben) semmi nem fut', async () => {
|
|
68
|
+
appliedRecords.push(new DyNTS_SchemaMigration({ migrationId: 'm2' }));
|
|
69
|
+
const ran: string[] = [];
|
|
70
|
+
const migs: DyNTS_MigrationEntry[] = [ entry('m2', async () => { ran.push('m2'); return { touched: 0 }; }) ];
|
|
71
|
+
|
|
72
|
+
const res = await runner.runPending(migs, '1.0.0');
|
|
73
|
+
expect(ran.length).toBe(0);
|
|
74
|
+
expect(res.applied).toBe(0);
|
|
75
|
+
expect(res.skipped).toBe(1);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('| BOOT-SAFE: egy hibás migráció NEM dob + NEM állítja meg a többit', async () => {
|
|
79
|
+
const ran: string[] = [];
|
|
80
|
+
const migs: DyNTS_MigrationEntry[] = [
|
|
81
|
+
entry('bad', async () => { throw new Error('boom'); }),
|
|
82
|
+
entry('good', async () => { ran.push('good'); return { touched: 2 }; }),
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
const res = await runner.runPending(migs, '1.0.0');
|
|
86
|
+
expect(res.failed).toBe(1);
|
|
87
|
+
expect(res.applied).toBe(1); // 'good' a hiba UTÁN is lefutott
|
|
88
|
+
expect(ran).toEqual([ 'good' ]);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|