@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.
@@ -1,7 +1,7 @@
1
1
  {
2
- "pid": 3702,
3
- "startedAt": "2026-07-26T19:12:39.969Z",
4
- "startedAtMs": 1785093159969,
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-26T19:12:39.998Z",
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-26T19:12:41.267Z",
20
+ "startedAt": "2026-07-26T21:11:38.480Z",
21
21
  "logLineStart": 9,
22
22
  "logLineEnd": 14,
23
- "durationSec": 10
23
+ "durationSec": 3
24
24
  },
25
25
  "pre-flight": {
26
26
  "status": "ok",
27
- "startedAt": "2026-07-26T19:12:52.294Z",
27
+ "startedAt": "2026-07-26T21:11:42.473Z",
28
28
  "logLineStart": 15,
29
29
  "logLineEnd": 17,
30
- "durationSec": 0.4
30
+ "durationSec": 0.2
31
31
  },
32
32
  "install": {
33
33
  "status": "ok",
34
- "startedAt": "2026-07-26T19:12:54.084Z",
34
+ "startedAt": "2026-07-26T21:11:43.675Z",
35
35
  "logLineStart": 18,
36
- "logLineEnd": 101,
37
- "durationSec": 22.6
36
+ "logLineEnd": 104,
37
+ "durationSec": 25.6
38
38
  },
39
39
  "check-dev-leftovers": {
40
40
  "status": "ok",
41
- "startedAt": "2026-07-26T19:13:17.671Z",
42
- "logLineStart": 102,
43
- "logLineEnd": 109,
44
- "durationSec": 6.9
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-26T19:13:25.768Z",
49
- "logLineStart": 110,
50
- "logLineEnd": 111,
51
- "durationSec": 31.1
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-26T19:13:57.906Z",
56
- "logLineStart": 112,
57
- "logLineEnd": 2802,
58
- "durationSec": 23.4,
55
+ "startedAt": "2026-07-26T21:12:44.425Z",
56
+ "logLineStart": 115,
57
+ "logLineEnd": 2839,
58
+ "durationSec": 20.3,
59
59
  "testSummary": {
60
- "totalSpecs": 1588,
60
+ "totalSpecs": 1593,
61
61
  "failures": 0,
62
- "passed": 1588,
63
- "testDurationSec": 7.319
62
+ "passed": 1593,
63
+ "testDurationSec": 6.601
64
64
  },
65
65
  "errors": [
66
66
  {
67
- "line": 1068,
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 runNext (/tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8355:16)\nat /tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8361:11\nat /tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8241:9\nat UserContext.<anonymous> (/tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/build/_modules/server/server-status/server-status.control-service.spec.js:507:68)\nat QueueRunner.attempt (/tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/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/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8452:27)\nat runNext (/tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8355:16)\nat /tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8361:11\nat /tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8241:9",
70
- "detailLineEnd": 1074
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": 1084,
74
- "text": ".....(checkDbReadiness) diagnostics collection failed (non-fatal) Error: diag boom",
75
- "details": "at runNext (/tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8355:16)\nat /tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8361:11\nat /tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/node_modules/.pnpm/jasmine-core@5.10.0/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8241:9\nat Object.get host [as host] (/tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/build/_modules/server/server-status/server-status.control-service.spec.js:487:36)\nat TestServerStatusControlService.checkDbReadiness (/tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/build/_modules/server/server-status/server-status.control-service.js:177:29)\nat async UserContext.<anonymous> (/tmp/pipeline-runs/955768d5-beca-48b1-97ac-8dace53081bd/build/_modules/server/server-status/server-status.control-service.spec.js:490:28)",
76
- "detailLineEnd": 1087
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-26T19:14:22.317Z",
83
- "logLineStart": 2803,
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,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=migration-entry.interface.js.map
@@ -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';
@@ -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;AAK/C,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;AAG5D,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"}
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);
@@ -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;AAG/C,WAAW;AACX,gBAAgB;AAChB,uEAA6C;AAC7C,wEAA8C;AAE9C,yEAA+C;AAC/C,6FAAmE;AACnE,0EAAgD;AAChD,gFAAsD;AAEtD,sFAA4D;AAE5D,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"}
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.118",
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
+ });