@appaflytech/zeyrek-ai-mcp 0.0.11 → 0.0.13

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.
@@ -227,19 +227,68 @@ tanımı kendi global-error dalınla gönder — dal **bağlıysa** (`nextStepId
227
227
  dokunmaz. `nextStepId: null` ile bağlanmamış gönderirsen gateway ikinci bir dal eklemez, mevcut
228
228
  dalını enjekte ettiği hata adımına bağlar.
229
229
 
230
- **Fail dallarını tek tek bağlamana gerek yok.** Bir adımın `fail` dalı bağlanmamışsa
231
- (`nextStepId: null`) ya da hiç yoksa, hata **kendiliğinden** global-error dalına gider. `fail`
232
- dalını yalnız o adıma özel bir telafi akışı (örn. "kayıt yoksa oluştur") istiyorsan bağla.
230
+ ### `gatewayOnError`'un 500 gövdesi: patlayan adım ve alt akış zinciri (2026-09-16)
231
+
232
+ ```jsonc
233
+ // POST /m/web/ticket-ac → 500 (ebeveyn → callChild → çocuk akış → childBoom patladı)
234
+ { "code": "JavaScriptException", "message": "Error: x is not defined\n at <anonymous>:1:8",
235
+ "detail": "…", "type": "JavaScriptException",
236
+ "step": { "name": "callChild", "type": "workflow" }, // bu akışta patlayan adım
237
+ "cause": { "code": "JavaScriptException", "message": "…", // alt akışın KENDİ hata gövdesi
238
+ "step": { "name": "childBoom", "type": "code" } } } // çocukta patlayan adım
239
+ ```
240
+
241
+ - **`step` yalnız `{ name, type }`'tır.** `error.step.input` ifade değerlerini (parola dahil),
242
+ `error.step.data` adımın çıktısını taşır; ikisi de dışarı yazılmaz. `error.step`'i bütün olarak
243
+ gövdeye koyarsan platform onu **siler** (`ResponseStep` global-error kipinde `error.step` ile
244
+ birebir aynı `step` alanını kaldırır) — alt küme yaz.
245
+ - **`cause` bir seviye aşağıyı taşır** ve her seviyede yalnız `code`, `message`, `detail`, `type`,
246
+ `step { name, type }` ve `cause` geçer (gateway beyaz listeye süzer, en fazla dokuz seviye). Backend
247
+ 2026-09-17'den beri zinciri `error.cause`'ta kendisi kurar; üç durum kapsanır:
248
+ - **Alt akış patladı:** `cause.step` çocukta patlayan adım, çocuk da alt akış çağırıyorsa zincir
249
+ seviye seviye iç içe iner. Çocuk Studio'da hata yolsuz kurulduysa da adım adı gelir.
250
+ - **Loop iterasyonu patladı:** `step` loop adımı, `cause.step.name` `loopRows[0]` gibi
251
+ `<loop adı>[<sıra>]`, iterasyondaki alt akışın zinciri onun altında.
252
+ - **Çocuk istisnasız 2xx dışı döndü** (`response` 422): `code` `SubWorkflowFailedException`,
253
+ `message` `Sub-workflow '<ad>' returned 422 (<gövde code>): <gövde message>`.
254
+
255
+ Eski backend'de `error.cause` yoktur; gateway o zaman patlayan `workflow` adımının `step.data`'sına
256
+ (çocuğun kendi gövdesi) düşer — loop ve istisnasız çocuk orada kaybolur. Çocuk kendi 4xx/5xx yanıtını
257
+ elle yazdıysa (`({ success: false, token })`, `({ err: error })`) o gövdenin yalnız bu alanları geçer.
258
+ Canlı ölçüldü (2026-09-16/17): torunun `token` ve `step.input`'u üst gövdeye ulaşmadı; üç seviyeli
259
+ zincir ve `loopRows` → `loopRows[0]` → `boomStep` hem hata yolsuz hem gateway hata yollu uçta döndü.
260
+ - **Gateway zinciri okur (yalnız 5xx):** `microservice_execute`/`debug`/`preview` `runtimeErrors`'a
261
+ `hata gövdesi — hata yolu: 'callChild' (workflow) → 'childBoom' (code) · 'childBoom' (code)
262
+ JavaScriptException: …` satırını ekler (debug ucunun `{ data, executionItems }` sarmalı açılır);
263
+ fırlatan çağrıların (senkron automation'lı `row_create`, `workflow_preview`…) araç hatası da
264
+ gövdede bulunan `detail`'i, koddan farklı `type`'ı ve varsa zinciri yazar. 4xx gövdeleri
265
+ süslenmez — onlar bilinçli iş yanıtıdır.
266
+ - **Eski kayıtlar:** 2026-09-16 öncesi gateway `({ code: error.code, message: error.message })`
267
+ yazıyordu. Global-error dalının hedefi olan, adı `gatewayOnError[n]`, ifadesi bu metinle AYNEN
268
+ aynı ve açıklaması gateway'in eski metni (ya da boş) olan adım bir sonraki
269
+ `workflow_create`/`update`/`patch`/`preview`'da yeni gövdeye yükseltilir (`gatewayNormalized`:
270
+ "hata gövdesi genişletildi"; önizleme kaydetmez). Yanıta alan eklenir, `code`/`message` değişmez.
271
+ Açıklaması ya da ifadesi elle değiştirilmiş adıma dokunulmaz; yükseltme açıklamayı da yenilediği
272
+ için sonradan bilerek eski gövdeye dönen `bodyExpression` bir daha ezilmez.
273
+ - **Dışarı ne verdiğine sen karar verirsin.** Adım adları iç yapıyı, `detail` iç istisna mesajını
274
+ (kısıt adı, host) gösterebilir. **Middleware'in 500 gövdesi korumalı uçların anonim çağıranına da
275
+ gider** (`ExecuteMicroserviceBehavior`). Herkese açık yüzeyde istemiyorsan hata adımının
276
+ `bodyExpression`'ını daralt, örn. `({ code: error.code, message: error.message })`.
233
277
 
234
278
  Global-error dalında `error` değişkeni tanımlıdır:
235
279
 
236
280
  ```jsonc
237
281
  { "code": "RowAlreadyExists", "message": "…", "detail": "…", "type": "…",
238
- "step": { "id": "…", "name": "writeRow", "type": "table", "data": …, "input": [ … ] } }
282
+ "step": { "id": "…", "name": "writeRow", "type": "table", "data": …, "input": [ … ] },
283
+ "cause": null } // alt akış / loop iterasyonunda { code, message, detail, type, step: { name, type }, cause }
239
284
  ```
240
285
 
241
- `error.step` hangi adımın patladığını söyler — hata yanıtına koymadan önce iki kez düşün, iç
242
- yapıyı dışarı sızdırır.
286
+ Fail dalında aynı zincir `<adım adı>.error.cause`'tadır (`<adım adı>.error` = `{ code, message, detail,
287
+ type, cause }`).
288
+
289
+ `error.step` hangi adımın patladığını söyler. `input`/`data` alanları ifade değerlerini ve adım
290
+ çıktısını taşır — gövdeye yalnız ihtiyaç duyduğun alt kümeyi yaz (gateway'in varsayılanı
291
+ `{ name, type }`'tır, yukarıdaki §`gatewayOnError`'un 500 gövdesi).
243
292
 
244
293
  **Kurallar ve sınırlar:**
245
294
 
@@ -257,9 +306,14 @@ yapıyı dışarı sızdırır.
257
306
  bağlı — §izin matrisi) ya da `email`/`table` adımına bağla. Bağlı hata yolu yoksa `WF-021` uyarır.
258
307
  - **Hata yolu hiç yoksa** (fail dalı ve global-error dalı bağlı değil) adım patladığında motor
259
308
  canlıda `WorkflowStepFailedException` fırlatır (2026-09-16): HTTP yanıt 500 +
260
- `{ code, message, detail, type }` (patlayan adımın hatası), zamanlanmış iş ve automation geçmişi
261
- `failed` + `Step 'x' failed: <sebep>`, senkron automation tetikleyen satır yazımını düşürür.
262
- Önizlemede fırlatmaz, ağaç döner. Çalışır, ama çıktı lokalize değildir.
309
+ `{ code, message, detail, type, step: { name, type }, cause }` — `step` ve `cause` 2026-09-17'den
310
+ beri, gateway hata adımıyla aynı şekil (yerel ortamda ayrıca `stackTrace`). Zamanlanmış iş ve
311
+ automation geçmişi `failed` + `Step 'x' failed: <sebep>`, senkron automation tetikleyen satır
312
+ yazımını düşürür. Önizlemede fırlatmaz, ağaç döner. Çalışır, ama çıktı lokalize değildir.
313
+ - **Adım hata yolunun DIŞINDA patlarsa** (ör. `revert`'in `revertType` ifadesi tırnaksız) kod
314
+ `EvaluateWorkflowStepFailedException`, mesaj `Step '<ad>' threw outside its error path: <sebep>`
315
+ olur: fail dalı ve global-error dalı ÇALIŞMAZ, canlı koşu düşer. 2026-09-17'den beri önizleme
316
+ ağacı kaybolmaz; adım `hasError: true` ile işaretlenir.
263
317
 
264
318
  > **Preview HTTP 200 dönerken bile akış patlamış olabilir.** `executionSuccess` yalnız SON adıma
265
319
  > bakar; ortada patlayıp hata dalından dönen akış `true` gösterir. Gateway tüm adımları (iç içe
@@ -347,6 +401,100 @@ gidilir, hiçbiri tutmazsa `else` dalı yürür:
347
401
  > `rule.isExpression` bayrağı bu iki alan için **okunmaz**.
348
402
 
349
403
 
404
+ ## HTTP adımı: gövde ayrı alan değil, `payloadExpression` üç anahtarı birden taşır (WF-033)
405
+
406
+ Dört alan: `rule.urlExpression` · `httpMethod` · `contentType` · `payloadExpression`.
407
+ **Gövdenin kendi alanı yoktur** — `payloadExpression` tek bir ifadeyle `{ header, body,
408
+ queryString }` **üçünü birden** üretmek zorundadır; yürütücü üçüne de `dynamic` üye erişimiyle
409
+ bakar (`HttpStep.cs:32,42,59`).
410
+
411
+ ```jsonc
412
+ "rule": {
413
+ "stepType": "http",
414
+ "urlExpression": "'https://api.example.com/orders'",
415
+ "httpMethod": "POST",
416
+ "contentType": "application/json",
417
+ "payloadExpression": "({ body: { orderId: input.orderId }, header: { Authorization: 'Bearer ' + system.token }, queryString: {} })"
418
+ }
419
+ ```
420
+
421
+ | Tuzak | Ne olur |
422
+ |---|---|
423
+ | Bir anahtar eksik (`queryString` yok) | Adım **düşer**: `RuntimeBinderException` — ölçülen mesaj birebir `'System.Dynamic.ExpandoObject' does not contain a definition for 'queryString'`. Boş da olsa `{}` yazın |
424
+ | `urlExpression` tırnaksız | İfadedir, düz metin değil: `https://…` yazarsan JS onu değişken sanır ve adım `x is not defined` der |
425
+ | `contentType` boş | Gövde `body.ToString()` ile gider (`HttpStep.cs:63-85`); nesne gövdesi tip adına dönüşür. POST/PUT'ta açıkça yazın |
426
+ | Yanıt JSON değil | Gövde **sessizce** boş nesne olur (`:92`) — XML dönen uçtan veri de hata da alamazsınız |
427
+ | Adım adında boşluk | Çıktıya adım adıyla erişilir; ad geçerli JS tanımlayıcısı olmalı (`call_roles`, `Call Roles` değil) |
428
+
429
+ **Çıktıyı okurken şemaya değil ölçüme güvenin (2026-09-16).** `workflow_step_schema('http')`
430
+ `returnScheme`'i kök seviyede `{ httpStatusCode, data }` ilan eder, ama koşumda ifade bağlamındaki
431
+ adım `{ data, meta: { elapsedTime, httpStatusCode, totalCount }, error }` şeklindedir:
432
+
433
+ - gövde → **`<adım>.data`**
434
+ - durum kodu → **`<adım>.meta.httpStatusCode`**
435
+ - `<adım>.httpStatusCode` → **undefined** (şemanın vaat ettiği ad çalışmaz)
436
+
437
+ Tam örnek ve POST varyantı: `ngapps://examples/workflow-http-step`.
438
+
439
+ ## Workflow adımı: başka bir akışı parametreyle çağırmak (WF-032)
440
+
441
+ Ortak mantığı (kayıt açma, bildirim, numaralandırma) **bir kez** `type:'workflow'` akışı olarak
442
+ yazıp diğer akışlardan çağırmanın yolu budur — 30 adımı kopyalamak değil. Adım tipi `workflow`;
443
+ üç akış tipinde de kullanılabilir. Kuralı **iki alan** taşır ve girdi eşlemesi ikincisidir:
444
+
445
+ ```jsonc
446
+ { "id": "<GUID>", "name": "createTicket", "type": "workflow",
447
+ "description": "Telemetri olayından create-ticket akışıyla kayıt açar.",
448
+ "rule": {
449
+ "workflowId": "<create-ticket akışının id'si>",
450
+ "expression": "({ title: input.title, source: 'telemetry', payload: parseEvent.data })"
451
+ },
452
+ "branches": [
453
+ { "id": "<GUID>", "name": "success", "type": "success", "nextStepId": "<sonraki>" },
454
+ { "id": "<GUID>", "name": "fail", "type": "fail", "nextStepId": "<hata adımı>" }
455
+ ] }
456
+ ```
457
+
458
+ - **Eşleme `rule.expression`'daki nesne literalidir: her anahtar çağrılan akışın parametre
459
+ DTO'sundaki bir alan, her değer bir JS ifadesi** (`input.x`, önceki adımın `<ad>.data.x`'i,
460
+ sabit). Studio'nun adım editörü de aynı şeyi yapar — akış seçilince ifadeyi `parameterScheme`'den
461
+ `{ "alan": <örnek> }` olarak doldurur (`WorkflowTrigger.svelte`). Table adımının `fields[]`
462
+ listesinin buradaki karşılığı budur; ayrı bir liste alanı **yoktur** ve gerekmez.
463
+ - **Çağrılan akışın `parameterDtoId` + `parameterBehavior`'ı OLMAK ZORUNDA.** `WorkflowStep`
464
+ ifadeyi yalnız `workflow.HasParameter` iken değerlendirir (`WorkflowStep.cs`); DTO'suz alt
465
+ akışa yazılan ifade hiç koşmaz, alt akış boş `input` ile çalışır ve **200 döner**. Gateway
466
+ çağrılan akışı okuyup bunu **block** eder (WF-032). Reçete: `dto_create` → `workflow_patch(id:
467
+ <alt akış>, ops: [{ op: 'add', path: '/parameterDtoId', value: <dtoId> }, { op: 'add', path:
468
+ '/parameterBehavior', value: 'object' }])`.
469
+ - **Başka hiçbir alan girdi taşımaz.** Şema üyeleri (`payloadExpression`, `customParameters`,
470
+ `queryParameters`, `bodyExpression`, `fields`) kaydedilir ama `WorkflowStep` okumaz; şema dışı
471
+ adlar (`parameters`, `input`, `payload`, `args`…) platformda hiç kaydedilmez (`unmappedMembers`).
472
+ İki durumda da alt akış boş girdi alır (RFQ koşusu W-7, 2026-09-14: beş biçim denendi, beşinde
473
+ de boş girdi). Gateway DOLU değer görürse block eder; `workflow_get`'in geri okuttuğu
474
+ `fields: []` / `customParameters: null` gibi boş varsayılanlar kuralı tetiklemez.
475
+ - **Ad tuzağı:** `rule.expression` `code` adımında GÖVDE (çalıştırılan kod), `workflow` ve
476
+ `microfunction` adımında GİRDİ (argüman nesnesi) demektir. Aynı ad, iki anlam.
477
+ - **Alt akış girdiyi `input.<alan>` ile okur ve onun `input`'u bu nesnedir** — çağıranın
478
+ `input`'unu görmez; çağıranın bir alanı gerekiyorsa eşlemeye koy. `parameterBehavior: 'array'`
479
+ ise ifade dizi üretmelidir (gateway nesne literali görürse uyarır).
480
+ - **Çıktı alt akışın yanıt gövdesidir** (`response` adımının `returnDtoId` süzgecinden geçmiş
481
+ hâli) ve sonraki adımlara `<adım adı>.data` ile akar. Alt akış 2xx dışı dönerse ya da bir
482
+ adımı düşerse çağıran adım **fail** dalına gider; `<adım adı>.data` o zaman alt akışın hata
483
+ gövdesidir.
484
+ - **Şekli tahmin etme, oku:** `workflow_step_schema(step)` çağrılan akışın `parameterScheme` ve
485
+ `returnScheme`'ini döner; ya da `workflow_get(<workflowId>)` → `parameterDtoId` → `dto_get`.
486
+ - **Loop içinde:** `rule.stepType: 'workflow'`, `rule.arrayExpression`, çocuk kural
487
+ `rule.stepRule: { workflowId, expression: "({ title: loopItem.title })" }` — WF-032 çocuğu da
488
+ denetler.
489
+ - **Önizlemede** alt akışın kendi adım izi `steps[].children[]` altında `kind: 'subWorkflow'` ile
490
+ gelir; çağıran adımın `input[]` listesinde `member: 'parameter'` satırı ifadenin ürettiği nesneyi
491
+ gösterir — **satır yoksa ya da değeri boşsa girdi bağlanmamıştır.** Alt akışı tek başına
492
+ sınamak için kendi `previewPayload`'ı ile `workflow_preview` çağır.
493
+ - Aynı alt akışı birden çok adımdan çağırmak serbesttir; özyineleme runner'ın koşum sayacına
494
+ takılır (kural envanteri WF-028 — gateway kuralı değil, backend davranışı).
495
+
496
+ Tam örnek (çağıran + çağrılan akış, canlı ölçümle yazıldı): `ngapps://examples/workflow-call-workflow`.
497
+
350
498
  ## Loop step — dizinin her öğesi için bir adım koştur
351
499
 
352
500
  Tek uçta "başlık + N alt kayıt" yazmanın yolu budur (anket + sorular + seçenekler tek çağrıda;
@@ -367,9 +515,19 @@ Tek uçta "başlık + N alt kayıt" yazmanın yolu budur (anket + sorular + seç
367
515
  (`StepRuleDto StepRule`); `children` gönderirsen `rule.Children` boş kalır ve loop
368
516
  **`NullReferenceException`** ile patlar — hata mesajı `arrayExpression`'ı işaret ettiği için
369
517
  seni ifadeyi suçlamaya iter, oysa sorun anahtar adıdır.
370
- - **Geçerli öğe `loopItem`'dır.** Çocuğun `fields[].value` / `filters[].value` ifadelerinde
371
- `loopItem.<alan>` yazılır; `input` ve önceki adımlar (`createSurvey.data.id`) da görünmeye
372
- devam eder.
518
+ - **Geçerli öğe `loopItem`'dır — ama YALNIZ loop'un kendi değerlendirdiği ifadelerde.** Çocuğun
519
+ `fields[].value` / `filters[].value` ifadelerinde `loopItem.<alan>` yazılır (ölçüldü 2026-09-16:
520
+ `table` çocuğunun filtresinde `loopItem.slug` → `'super-admin'`); `input` ve önceki adımlar
521
+ (`createSurvey.data.id`) da görünmeye devam eder.
522
+ - **`code` çocuğunda `loopItem` YOKTUR (ölçüm 2026-09-16).** `code` adımı kendi JS motorunu kurar
523
+ ve `LoopStep`'in `loopItem` ataması oraya ulaşmaz: adım **`Error: loopItem is not defined`** ile
524
+ düşer, o yinelemenin çıktısında `result` hiç oluşmaz. Motorda görünenler `input` · `system` ·
525
+ `file` · `crypto` · `convert` ve ifade fonksiyonlarıdır. **Her öğe için hesap yapman gerekiyorsa
526
+ hesabı `arrayExpression`'da önden yap** — orası JS'tir ve diziyi istediğin şekle sokabilirsin:
527
+ `(input.kalemler || []).map(k => ({ ...k, tutar: k.fiyat * k.adet }))`; çocuk sonra
528
+ `loopItem.tutar`'a bakar.
529
+ - **İndeks değişkeni yoktur.** Sıra numarası gerekiyorsa diziyi `arrayExpression`'da üret:
530
+ `input.kalemler.map((k, i) => ({ ...k, sira: i }))`.
373
531
  - **Çıktı `[{ item, result }]` dizisidir.** `result` çocuk adımın çıktısıdır; `table create`
374
532
  için `{ id }`. Sonraki adımda `loopQuestions.data` ile okunur — **yazılan kayıtların id'sini
375
533
  girdideki öğeyle eşleştirmenin yolu budur.**
@@ -385,6 +543,9 @@ Tek uçta "başlık + N alt kayıt" yazmanın yolu budur (anket + sorular + seç
385
543
  İstemci alt kayıtları **düz** gönderir ve satırları `key`/`qkey` ile eşler — iç içe dizi
386
544
  göndermek gerekmez (iç içe loop denenmedi; `loopItem` iç loop'ta gölgeleneceği için önerilmez).
387
545
 
546
+ Tam örnek, ölçülen çıktı şekli ve `code` çocuğu tuzağının çıkış yolu:
547
+ `ngapps://examples/workflow-loop-step`.
548
+
388
549
  > **Table step'te `create`/`update` satır değerleri `fields[]`'tedir ve JS İFADESİDİR.**
389
550
  > `{ "fieldId": "<alan id>", "source": "expression", "value": "input.title", "order": 0 }` —
390
551
  > `PrepareParameters` her `fields[].value`'yu `EvaluateExpression` ile koşturur
@@ -1,8 +1,10 @@
1
1
  {
2
- "hash": "54430a8d4050fd201aaee88608a5d06b947edf6d561ad31354914422df4e94ce",
3
- "generatedAt": "2026-09-16T11:17:11.569Z",
4
- "types": 185,
5
- "files": 107,
2
+ "hash": "05c7864d58e308973805f7becee1578ce9eddad196abcdf7eebb43b1e7677549",
3
+ "generatedAt": "2026-09-16T15:53:10.903Z",
4
+ "types": 186,
5
+ "files": 108,
6
6
  "note": "Şemaları üreten backend kaynaklarının parmak izi. Elle düzenlemeyin: 'npm run generate-schemas' yazar, 'npm run schema:check' denetler.",
7
- "missing": []
7
+ "missing": [
8
+ "NgApps.Infrastructure.Models.IdNamePair`1[[System.Guid, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]"
9
+ ]
8
10
  }