@futdevpro/nts-dynamo 1.15.115 → 1.15.117

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.
@@ -81,15 +81,28 @@ export class DyNTS_AIMock_Service {
81
81
  };
82
82
  }
83
83
 
84
- /** A közös replay/reject-mag. */
84
+ /**
85
+ * A közös replay/reject-mag.
86
+ *
87
+ * **Sorrend: FIXTURE ELŐSZÖR, validátor csak fallbackként.** Ha van beégetett fixture erre a pontos
88
+ * kérésre, az a FÖLDIGAZSÁG — valódi providertől rögzített, byte-hű válasz vagy hiba —, ezért mindig
89
+ * az nyer a szintetizált validátor-hibával szemben.
90
+ *
91
+ * (Korábban fordítva volt, „ahogy a szerver is validál a generálás előtt". Csakhogy emiatt a
92
+ * byte-pontosan rögzített provider-hibák SOSEM jutottak érvényre: pl. `gpt-4o-mini` + `temperature: 3`
93
+ * esetén a sablonom „out of range" szövege jött a valódi „decimal above maximum value. Expected a
94
+ * value <= 2, but got 3 instead." helyett. A capture értelme épp az, hogy a valódit adjuk vissza.)
95
+ *
96
+ * Fixture hiányában a `settingsSchema`-alapú validáció fut — így a NEM rögzített szabálysértések is
97
+ * provider-hű hibát kapnak, nem pusztán „nincs ilyen fixture"-t.
98
+ */
85
99
  private replay(request: DyNTS_AIMock_Request): unknown {
86
- // FR-048: a config-validáció a modell `settingsSchema.unsupported`-ja alapján — MÉG a fixture-lookup
87
- // ELŐTT, ahogy a valódi providernél is a szerver utasítja el a rossz paramétert.
88
- this.validateConfig(request);
89
-
90
100
  const fixture: DyNTS_AIMock_Fixture | undefined = this.store.resolve(request);
91
101
 
92
102
  if (!fixture) {
103
+ // nincs rogzitett valasz → a schema-alapu validacio meg adhat provider-hu hibat
104
+ this.validateConfig(request);
105
+
93
106
  throw this.rejectOnUnknown(request);
94
107
  }
95
108
 
@@ -1,12 +1,253 @@
1
1
  import { DyNTS_AIMock_Fixture } from '../_models/interfaces/aim-fixture.interface';
2
2
 
3
3
  /**
4
- * Valodi AI-generalasbol beegetve (live capture 2026-07-21/22). Kezzel NE szerkeszd.
4
+ * Valodi AI-hivasokbol beegetve (live capture 2026-07-21/22). Kezzel NE szerkeszd.
5
5
  *
6
6
  * Determinisztikus sorrend (match-kulcs szerint) + rendezett objektum-kulcsok, hogy az ujra-generalas
7
7
  * ne okozzon zajos diff-et. Forras: `DyNTS_AIMock_FixtureSerializer_Util`.
8
8
  */
9
9
  export const DyNTS_AIMock_TextFixtures: DyNTS_AIMock_Fixture[] = [
10
+ {
11
+ "capturedAt": "2026-07-22T14:43:14.877Z",
12
+ "config": {},
13
+ "error": {
14
+ "httpStatus": 404,
15
+ "providerErrorBody": {
16
+ "error": {
17
+ "message": "model: claude-does-not-exist-xyz",
18
+ "type": "not_found_error"
19
+ },
20
+ "request_id": "req_011CdHGoEQRATWS7pGsctzvi",
21
+ "type": "error"
22
+ },
23
+ "reason": "aai-unknown-model"
24
+ },
25
+ "input": "hi",
26
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
27
+ "modality": "text",
28
+ "model": "claude-does-not-exist-xyz",
29
+ "provider": "anthropic",
30
+ "sourceModel": "claude-does-not-exist-xyz"
31
+ },
32
+ {
33
+ "capturedAt": "2026-07-22T14:44:01.069Z",
34
+ "config": {
35
+ "maxTokens": 32
36
+ },
37
+ "input": "Reply with exactly: PONG",
38
+ "inputHash": "0fb5aed1b51b28b04409b7963b2453fe1597d198c3b8396fc8ebd072104511de",
39
+ "modality": "text",
40
+ "model": "claude-haiku-4-5",
41
+ "output": {
42
+ "content": "PONG",
43
+ "model": "claude-haiku-4-5-20251001",
44
+ "stop_reason": "end_turn",
45
+ "usage": {
46
+ "cache_creation": {
47
+ "ephemeral_1h_input_tokens": 0,
48
+ "ephemeral_5m_input_tokens": 0
49
+ },
50
+ "cache_creation_input_tokens": 0,
51
+ "cache_read_input_tokens": 0,
52
+ "inference_geo": "not_available",
53
+ "input_tokens": 14,
54
+ "output_tokens": 6,
55
+ "service_tier": "standard"
56
+ }
57
+ },
58
+ "provider": "anthropic",
59
+ "sourceModel": "claude-haiku-4-5"
60
+ },
61
+ {
62
+ "capturedAt": "2026-07-22T14:44:01.756Z",
63
+ "config": {
64
+ "maxTokens": 32
65
+ },
66
+ "input": "What is the capital of Hungary? One word.",
67
+ "inputHash": "85c5b3ea12c8e34d97a18cb75ae55936aeb2ef0af90eb2f395a44ace6ce997e8",
68
+ "modality": "text",
69
+ "model": "claude-haiku-4-5",
70
+ "output": {
71
+ "content": "Budapest",
72
+ "model": "claude-haiku-4-5-20251001",
73
+ "stop_reason": "end_turn",
74
+ "usage": {
75
+ "cache_creation": {
76
+ "ephemeral_1h_input_tokens": 0,
77
+ "ephemeral_5m_input_tokens": 0
78
+ },
79
+ "cache_creation_input_tokens": 0,
80
+ "cache_read_input_tokens": 0,
81
+ "inference_geo": "not_available",
82
+ "input_tokens": 17,
83
+ "output_tokens": 4,
84
+ "service_tier": "standard"
85
+ }
86
+ },
87
+ "provider": "anthropic",
88
+ "sourceModel": "claude-haiku-4-5"
89
+ },
90
+ {
91
+ "capturedAt": "2026-07-22T14:43:13.881Z",
92
+ "config": {
93
+ "temperature": 0.5
94
+ },
95
+ "error": {
96
+ "httpStatus": 400,
97
+ "providerErrorBody": {
98
+ "error": {
99
+ "message": "`temperature` is deprecated for this model.",
100
+ "type": "invalid_request_error"
101
+ },
102
+ "request_id": "req_011CdHGo9kdD2NVBTFPkMgXs",
103
+ "type": "error"
104
+ },
105
+ "reason": "aai-opus-temperature"
106
+ },
107
+ "input": "hi",
108
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
109
+ "modality": "text",
110
+ "model": "claude-opus-4-8",
111
+ "provider": "anthropic",
112
+ "sourceModel": "claude-opus-4-8"
113
+ },
114
+ {
115
+ "capturedAt": "2026-07-22T14:43:13.493Z",
116
+ "config": {
117
+ "temperature": 1.5
118
+ },
119
+ "error": {
120
+ "httpStatus": 400,
121
+ "providerErrorBody": {
122
+ "error": {
123
+ "message": "temperature: range: 0..1",
124
+ "type": "invalid_request_error"
125
+ },
126
+ "request_id": "req_011CdHGo7aeyfawRbTxee9oA",
127
+ "type": "error"
128
+ },
129
+ "reason": "aai-sonnet-temperature-1.5"
130
+ },
131
+ "input": "hi",
132
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
133
+ "modality": "text",
134
+ "model": "claude-sonnet-4-6",
135
+ "provider": "anthropic",
136
+ "sourceModel": "claude-sonnet-4-6"
137
+ },
138
+ {
139
+ "capturedAt": "2026-07-22T14:43:15.035Z",
140
+ "config": {
141
+ "temperature": 5
142
+ },
143
+ "error": {
144
+ "httpStatus": 400,
145
+ "providerErrorBody": {
146
+ "error": {
147
+ "code": 400,
148
+ "message": "* GenerateContentRequest.generation_config.temperature: temperature must be in the range [0.0, 2.0].\n",
149
+ "status": "INVALID_ARGUMENT"
150
+ }
151
+ },
152
+ "reason": "gai-range-temperature"
153
+ },
154
+ "input": "hi",
155
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
156
+ "modality": "text",
157
+ "model": "gemini-3.5-flash",
158
+ "provider": "google",
159
+ "sourceModel": "gemini-3.5-flash"
160
+ },
161
+ {
162
+ "capturedAt": "2026-07-22T14:43:15.224Z",
163
+ "config": {
164
+ "topP": 1.5
165
+ },
166
+ "error": {
167
+ "httpStatus": 400,
168
+ "providerErrorBody": {
169
+ "error": {
170
+ "code": 400,
171
+ "message": "* GenerateContentRequest.generation_config.top_p: top_p must be in the range [0.0, 1.0].\n",
172
+ "status": "INVALID_ARGUMENT"
173
+ }
174
+ },
175
+ "reason": "gai-range-topP"
176
+ },
177
+ "input": "hi",
178
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
179
+ "modality": "text",
180
+ "model": "gemini-3.5-flash",
181
+ "provider": "google",
182
+ "sourceModel": "gemini-3.5-flash"
183
+ },
184
+ {
185
+ "capturedAt": "2026-07-22T14:43:15.333Z",
186
+ "config": {
187
+ "topK": -1
188
+ },
189
+ "error": {
190
+ "httpStatus": 400,
191
+ "providerErrorBody": {
192
+ "error": {
193
+ "code": 400,
194
+ "message": "* GenerateContentRequest.generation_config.top_k: top_k must be nonnegative.\n",
195
+ "status": "INVALID_ARGUMENT"
196
+ }
197
+ },
198
+ "reason": "gai-range-topK"
199
+ },
200
+ "input": "hi",
201
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
202
+ "modality": "text",
203
+ "model": "gemini-3.5-flash",
204
+ "provider": "google",
205
+ "sourceModel": "gemini-3.5-flash"
206
+ },
207
+ {
208
+ "capturedAt": "2026-07-22T14:43:15.528Z",
209
+ "config": {
210
+ "candidateCount": 99
211
+ },
212
+ "error": {
213
+ "httpStatus": 400,
214
+ "providerErrorBody": {
215
+ "error": {
216
+ "code": 400,
217
+ "message": "* GenerateContentRequest.generation_config.candidate_count: candidate_count must be in the range [1, 8].\n",
218
+ "status": "INVALID_ARGUMENT"
219
+ }
220
+ },
221
+ "reason": "gai-range-candidateCount"
222
+ },
223
+ "input": "hi",
224
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
225
+ "modality": "text",
226
+ "model": "gemini-3.5-flash",
227
+ "provider": "google",
228
+ "sourceModel": "gemini-3.5-flash"
229
+ },
230
+ {
231
+ "capturedAt": "2026-07-22T14:43:15.636Z",
232
+ "config": {},
233
+ "error": {
234
+ "httpStatus": 404,
235
+ "providerErrorBody": {
236
+ "error": {
237
+ "code": 404,
238
+ "message": "models/gemini-does-not-exist-xyz is not found for API version v1beta, or is not supported for generateContent. Call ModelService.ListModels to see the list of available models and their supported methods.",
239
+ "status": "NOT_FOUND"
240
+ }
241
+ },
242
+ "reason": "gai-unknown-model"
243
+ },
244
+ "input": "hi",
245
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
246
+ "modality": "text",
247
+ "model": "gemini-does-not-exist-xyz",
248
+ "provider": "google",
249
+ "sourceModel": "gemini-does-not-exist-xyz"
250
+ },
10
251
  {
11
252
  "capturedAt": "2026-07-22T00:58:38.792Z",
12
253
  "config": {
@@ -38,6 +279,174 @@ export const DyNTS_AIMock_TextFixtures: DyNTS_AIMock_Fixture[] = [
38
279
  "provider": "open-ai",
39
280
  "sourceModel": "gpt-4o-mini"
40
281
  },
282
+ {
283
+ "capturedAt": "2026-07-22T14:43:10.345Z",
284
+ "config": {
285
+ "temperature": 3
286
+ },
287
+ "error": {
288
+ "httpStatus": 400,
289
+ "providerErrorBody": {
290
+ "error": {
291
+ "code": "decimal_above_max_value",
292
+ "message": "Invalid 'temperature': decimal above maximum value. Expected a value <= 2, but got 3 instead.",
293
+ "param": "temperature",
294
+ "type": "invalid_request_error"
295
+ }
296
+ },
297
+ "reason": "oai-range-temperature-3"
298
+ },
299
+ "input": "hi",
300
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
301
+ "modality": "text",
302
+ "model": "gpt-4o-mini",
303
+ "provider": "open-ai",
304
+ "sourceModel": "gpt-4o-mini"
305
+ },
306
+ {
307
+ "capturedAt": "2026-07-22T14:43:10.778Z",
308
+ "config": {
309
+ "topP": 1.5
310
+ },
311
+ "error": {
312
+ "httpStatus": 400,
313
+ "providerErrorBody": {
314
+ "error": {
315
+ "code": "decimal_above_max_value",
316
+ "message": "Invalid 'top_p': decimal above maximum value. Expected a value <= 1, but got 1.5 instead.",
317
+ "param": "top_p",
318
+ "type": "invalid_request_error"
319
+ }
320
+ },
321
+ "reason": "oai-range-top_p-1.5"
322
+ },
323
+ "input": "hi",
324
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
325
+ "modality": "text",
326
+ "model": "gpt-4o-mini",
327
+ "provider": "open-ai",
328
+ "sourceModel": "gpt-4o-mini"
329
+ },
330
+ {
331
+ "capturedAt": "2026-07-22T14:43:11.056Z",
332
+ "config": {
333
+ "frequencyPenalty": 5
334
+ },
335
+ "error": {
336
+ "httpStatus": 400,
337
+ "providerErrorBody": {
338
+ "error": {
339
+ "code": "decimal_above_max_value",
340
+ "message": "Invalid 'frequency_penalty': decimal above maximum value. Expected a value <= 2, but got 5 instead.",
341
+ "param": "frequency_penalty",
342
+ "type": "invalid_request_error"
343
+ }
344
+ },
345
+ "reason": "oai-range-frequency_penalty-5"
346
+ },
347
+ "input": "hi",
348
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
349
+ "modality": "text",
350
+ "model": "gpt-4o-mini",
351
+ "provider": "open-ai",
352
+ "sourceModel": "gpt-4o-mini"
353
+ },
354
+ {
355
+ "capturedAt": "2026-07-22T14:43:07.580Z",
356
+ "config": {
357
+ "temperature": 0.5
358
+ },
359
+ "error": {
360
+ "httpStatus": 400,
361
+ "providerErrorBody": {
362
+ "error": {
363
+ "code": null,
364
+ "message": "Could not finish the message because max_tokens or model output limit was reached. Please try again with higher max_tokens.",
365
+ "param": null,
366
+ "type": "invalid_request_error"
367
+ }
368
+ },
369
+ "reason": "oai-reasoning-temperature"
370
+ },
371
+ "input": "hi",
372
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
373
+ "modality": "text",
374
+ "model": "gpt-5.4-mini",
375
+ "provider": "open-ai",
376
+ "sourceModel": "gpt-5.4-mini"
377
+ },
378
+ {
379
+ "capturedAt": "2026-07-22T14:43:08.623Z",
380
+ "config": {
381
+ "top_p": 0.5
382
+ },
383
+ "error": {
384
+ "httpStatus": 400,
385
+ "providerErrorBody": {
386
+ "error": {
387
+ "code": null,
388
+ "message": "Could not finish the message because max_tokens or model output limit was reached. Please try again with higher max_tokens.",
389
+ "param": null,
390
+ "type": "invalid_request_error"
391
+ }
392
+ },
393
+ "reason": "oai-reasoning-top_p"
394
+ },
395
+ "input": "hi",
396
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
397
+ "modality": "text",
398
+ "model": "gpt-5.4-mini",
399
+ "provider": "open-ai",
400
+ "sourceModel": "gpt-5.4-mini"
401
+ },
402
+ {
403
+ "capturedAt": "2026-07-22T14:43:09.268Z",
404
+ "config": {
405
+ "frequency_penalty": 0.5
406
+ },
407
+ "error": {
408
+ "httpStatus": 400,
409
+ "providerErrorBody": {
410
+ "error": {
411
+ "code": null,
412
+ "message": "Could not finish the message because max_tokens or model output limit was reached. Please try again with higher max_tokens.",
413
+ "param": null,
414
+ "type": "invalid_request_error"
415
+ }
416
+ },
417
+ "reason": "oai-reasoning-frequency_penalty"
418
+ },
419
+ "input": "hi",
420
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
421
+ "modality": "text",
422
+ "model": "gpt-5.4-mini",
423
+ "provider": "open-ai",
424
+ "sourceModel": "gpt-5.4-mini"
425
+ },
426
+ {
427
+ "capturedAt": "2026-07-22T14:43:09.908Z",
428
+ "config": {
429
+ "presence_penalty": 0.5
430
+ },
431
+ "error": {
432
+ "httpStatus": 400,
433
+ "providerErrorBody": {
434
+ "error": {
435
+ "code": null,
436
+ "message": "Could not finish the message because max_tokens or model output limit was reached. Please try again with higher max_tokens.",
437
+ "param": null,
438
+ "type": "invalid_request_error"
439
+ }
440
+ },
441
+ "reason": "oai-reasoning-presence_penalty"
442
+ },
443
+ "input": "hi",
444
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
445
+ "modality": "text",
446
+ "model": "gpt-5.4-mini",
447
+ "provider": "open-ai",
448
+ "sourceModel": "gpt-5.4-mini"
449
+ },
41
450
  {
42
451
  "capturedAt": "2026-07-22T00:58:37.828Z",
43
452
  "config": {
@@ -100,6 +509,28 @@ export const DyNTS_AIMock_TextFixtures: DyNTS_AIMock_Fixture[] = [
100
509
  "provider": "open-ai",
101
510
  "sourceModel": "gpt-5.4-nano"
102
511
  },
512
+ {
513
+ "capturedAt": "2026-07-22T14:43:11.254Z",
514
+ "config": {},
515
+ "error": {
516
+ "httpStatus": 404,
517
+ "providerErrorBody": {
518
+ "error": {
519
+ "code": "model_not_found",
520
+ "message": "The model `gpt-does-not-exist-xyz` does not exist or you do not have access to it.",
521
+ "param": null,
522
+ "type": "invalid_request_error"
523
+ }
524
+ },
525
+ "reason": "oai-unknown-model"
526
+ },
527
+ "input": "hi",
528
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
529
+ "modality": "text",
530
+ "model": "gpt-does-not-exist-xyz",
531
+ "provider": "open-ai",
532
+ "sourceModel": "gpt-does-not-exist-xyz"
533
+ },
103
534
  {
104
535
  "capturedAt": "2026-07-22T13:50:16.666Z",
105
536
  "config": {
@@ -162,6 +593,30 @@ export const DyNTS_AIMock_TextFixtures: DyNTS_AIMock_Fixture[] = [
162
593
  "provider": "open-ai",
163
594
  "sourceModel": "text-embedding-3-small"
164
595
  },
596
+ {
597
+ "capturedAt": "2026-07-22T14:43:12.230Z",
598
+ "config": {
599
+ "dimensions": 5000
600
+ },
601
+ "error": {
602
+ "httpStatus": 400,
603
+ "providerErrorBody": {
604
+ "error": {
605
+ "code": null,
606
+ "message": "Invalid value for 'dimensions' = 5000. Must be less than or equal to 1536.",
607
+ "param": null,
608
+ "type": "invalid_request_error"
609
+ }
610
+ },
611
+ "reason": "oai-emb-dimensions-5000"
612
+ },
613
+ "input": "hi",
614
+ "inputHash": "8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4",
615
+ "modality": "embedding",
616
+ "model": "text-embedding-3-small",
617
+ "provider": "open-ai",
618
+ "sourceModel": "text-embedding-3-small"
619
+ },
165
620
  {
166
621
  "capturedAt": "2026-07-22T00:58:39.020Z",
167
622
  "config": {},
@@ -237,6 +237,27 @@ describe('| DyNTS_ServerStatus_Controller', () => {
237
237
  expect(guardCalls).withContext('guard runs despite configure() AFTER setupEndpoints').toBe(1);
238
238
  });
239
239
 
240
+ // 2026-07-22 — a `/diag` EGYIK listaban sem szerepelt (sem publikus-proba, sem default-vedett),
241
+ // ezert MINDEN FDP-szolgaltatason NYITOTT volt: elesben 200 + event-loop lag-history, aktiv
242
+ // handle-ok, memoria-nyomas, uptime. Nem szandek volt, hanem kimaradas. Ez a teszt rogziti, hogy
243
+ // explicit lista NELKUL a diag VEDETT — es hogy a publikus probak ettol valtozatlanul nyitva vannak.
244
+ it('| getServerDiag is protected BY DEFAULT, while the public probes stay open', async (): Promise<void> => {
245
+ const c: any = new (TestServerStatusController as any)(); // ccap-review-disable-line no-any-type
246
+ c.setupEndpoints();
247
+ DyNTS_ServerStatus_Controller.configure({ authPreProcess: spyAuth }); // NINCS explicit lista → default
248
+
249
+ await runGuard(c, 'getServerDiag');
250
+ expect(guardCalls).withContext('a /diag guard-olt a default listaval').toBe(1);
251
+
252
+ guardCalls = 0;
253
+ await runGuard(c, 'getServerHealth');
254
+ expect(guardCalls).withContext('a publikus proba NEM gate-elt').toBe(0);
255
+
256
+ guardCalls = 0;
257
+ await runGuard(c, 'getServerReadiness');
258
+ expect(guardCalls).withContext('a readiness-proba NEM gate-elt').toBe(0);
259
+ });
260
+
240
261
  it('| getAuthConfig() returns the active config', (): void => {
241
262
  const fakeAuth = async (): Promise<void> => { /* noop */ };
242
263
  DyNTS_ServerStatus_Controller.configure({ authPreProcess: fakeAuth, protectedEndpoints: [ 'getErrorStatistics' ] });
@@ -57,11 +57,27 @@ const PUBLIC_PROBE_ENDPOINTS: string[] = [
57
57
  ];
58
58
 
59
59
  /**
60
- * Default vedett vegpontok (ha a host nem ad `protectedEndpoints`-t): csak a valodi
61
- * admin-adat vegpont (`getErrorStatistics`). A status-vegpontok publikusak (lasd fent).
60
+ * Default vedett vegpontok (ha a host nem ad `protectedEndpoints`-t): a valodi admin-adat
61
+ * vegpontok. A status-probak publikusak (lasd `PUBLIC_PROBE_ENDPOINTS` fent).
62
+ *
63
+ * `getServerDiag` (2026-07-22): a `/diag` **EGYIK listaban sem szerepelt** — sem a publikus
64
+ * probak kozott, sem itt —, ezert **minden FDP-szolgaltatason NYITOTT volt**: elesben 200-at adott
65
+ * event-loop lag-history-val, aktiv handle-szammal, memoria-nyomassal es uptime-mal. Ez nem szandek
66
+ * volt, hanem kimaradas: az endpoint a BFR-OVERSEER-007-tel keszult, es a ket lista egyiket sem
67
+ * frissitettek hozza. A sajat doc-blockja "belso jel"-nek nevezi (amit a kivulrol-nezo health NEM lat),
68
+ * es `lazyPreProcessesFor`-ral kotott — vagyis SZANDEKOSAN gate-elheto, ellentetben a hard-publikus
69
+ * probakkal. Ezert a biztonsagos default: VEDETT.
70
+ *
71
+ * Kockazat: az operativ telemetria (mikor van a szolgaltatas nyomas alatt) tamado szamara
72
+ * idozites-informacio. Merve: a flottaban SEMMI nem fogyasztja (`fdp` CLI, webhook, compose-healthcheck,
73
+ * e2e-suite-ok — mind ures), tehat a gate-eles nem tor el semmit.
74
+ *
75
+ * ⚠️ A host `protectedEndpoints`-ja FELULIRJA ezt a listat — az explicit listat hasznalo appokban
76
+ * kulon fel kell venni a nevet (l. a projekt-szintu kovetes).
62
77
  */
63
78
  const DEFAULT_PROTECTED_ENDPOINTS: string[] = [
64
79
  'getErrorStatistics',
80
+ 'getServerDiag',
65
81
  ];
66
82
 
67
83
  /**