@appaflytech/zeyrek-ai-mcp 0.0.36 → 0.0.40

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.
Files changed (210) hide show
  1. package/.env.example +15 -0
  2. package/README.md +5 -5
  3. package/dist/config.js +37 -0
  4. package/dist/index.js +2 -0
  5. package/dist/knowledge/access.js +802 -0
  6. package/dist/knowledge/backendConstraints.js +18 -1
  7. package/dist/knowledge/case.js +41 -0
  8. package/dist/knowledge/componentCatalog.js +524 -53
  9. package/dist/knowledge/componentEvents.js +132 -7
  10. package/dist/knowledge/connectDataBind.js +851 -0
  11. package/dist/knowledge/connectDataDefinition.js +344 -0
  12. package/dist/knowledge/connectDataExecute.js +93 -0
  13. package/dist/knowledge/connectDataRules.js +128 -0
  14. package/dist/knowledge/decision.js +121 -0
  15. package/dist/knowledge/expressionPrelude.js +60 -0
  16. package/dist/knowledge/layoutSummary.js +140 -2
  17. package/dist/knowledge/microserviceParameters.js +58 -0
  18. package/dist/knowledge/mining.js +94 -0
  19. package/dist/knowledge/mobileComponentCatalog.js +876 -0
  20. package/dist/knowledge/mobileComponentEvents.js +259 -0
  21. package/dist/knowledge/mobileStore.js +396 -0
  22. package/dist/knowledge/normalize.js +240 -72
  23. package/dist/knowledge/outlines.js +36 -0
  24. package/dist/knowledge/platform/lint.js +385 -0
  25. package/dist/knowledge/platform/mobile.js +142 -0
  26. package/dist/knowledge/platform/mobileLayoutLint.js +324 -0
  27. package/dist/knowledge/platform/mobileRules.js +231 -0
  28. package/dist/knowledge/platform/mobileSpacing.js +82 -0
  29. package/dist/knowledge/platform/mobileTabs.js +108 -0
  30. package/dist/knowledge/platform/nativeBoxModel.js +44 -0
  31. package/dist/knowledge/platform/profile.js +25 -0
  32. package/dist/knowledge/platform/resolve.js +122 -0
  33. package/dist/knowledge/platform/web.js +39 -0
  34. package/dist/knowledge/policy.js +18 -4
  35. package/dist/knowledge/process.js +510 -0
  36. package/dist/knowledge/reservedTables.js +79 -0
  37. package/dist/knowledge/rowFilter.js +43 -0
  38. package/dist/knowledge/rules.js +485 -22
  39. package/dist/knowledge/schemaGuard.js +11 -0
  40. package/dist/knowledge/styleResolve.js +64 -10
  41. package/dist/knowledge/styleResolveNative.js +529 -0
  42. package/dist/knowledge/themeResolve.js +3 -3
  43. package/dist/observability/trace.js +13 -5
  44. package/dist/platform/argumentAliases.js +128 -0
  45. package/dist/platform/bodyFile.js +103 -0
  46. package/dist/platform/capture/actions.js +398 -0
  47. package/dist/platform/capture/browser.js +1 -0
  48. package/dist/platform/capture/capture.js +683 -0
  49. package/dist/platform/capture/console-log.js +122 -0
  50. package/dist/platform/capture/index.js +11 -0
  51. package/dist/platform/capture/readiness.js +103 -0
  52. package/dist/platform/capture/summary.js +77 -0
  53. package/dist/platform/capture/target.js +5 -0
  54. package/dist/platform/capture/targets/studio-mobile.js +15 -0
  55. package/dist/platform/capture/targets/studio-web.js +5 -0
  56. package/dist/platform/diagnostics.js +10 -4
  57. package/dist/platform/domSummary.js +1 -1
  58. package/dist/platform/errors.js +163 -10
  59. package/dist/platform/http.js +29 -8
  60. package/dist/platform/impersonation.js +45 -0
  61. package/dist/platform/jsonArray.js +24 -0
  62. package/dist/platform/responses.js +39 -5
  63. package/dist/platform/schemaReadMemory.js +60 -0
  64. package/dist/platform/secrets.js +68 -2
  65. package/dist/platform/strictArguments.js +68 -12
  66. package/dist/platform/tokenVault.js +187 -4
  67. package/dist/resources/examples/bpm-gorev-kontrol.json +294 -0
  68. package/dist/resources/examples/bpm-iso-dokuman.json +228 -0
  69. package/dist/resources/examples/bpm-satinalma.json +376 -0
  70. package/dist/resources/examples/connect-data-convert-verify.json +107 -0
  71. package/dist/resources/examples/connect-data-dropdown-roles.json +66 -0
  72. package/dist/resources/examples/connect-data-edit-m2m.json +73 -0
  73. package/dist/resources/examples/connect-data-query-params.json +50 -0
  74. package/dist/resources/examples/connect-data-table-entity.json +147 -0
  75. package/dist/resources/examples/connect-data-workflow-microservice.json +65 -0
  76. package/dist/resources/examples/middleware-authenticate.json +1 -1
  77. package/dist/resources/examples/mobile-app-shell-drawer.json +244 -0
  78. package/dist/resources/examples/mobile-app-shell-stack.json +157 -0
  79. package/dist/resources/examples/mobile-app-shell-tab.json +208 -0
  80. package/dist/resources/examples/mobile-form-screen.json +365 -0
  81. package/dist/resources/examples/mobile-list-detail-form.json +703 -0
  82. package/dist/resources/examples/page-detail-profile.json +2 -1
  83. package/dist/resources/examples/page-dynamic-form.json +3 -2
  84. package/dist/resources/examples/page-flex-sections.json +1 -1
  85. package/dist/resources/examples/page-html-embed.json +1 -1
  86. package/dist/resources/examples/workflow-basic.json +8 -2
  87. package/dist/resources/guides/access.md +810 -0
  88. package/dist/resources/guides/bpm.md +691 -0
  89. package/dist/resources/guides/case.md +153 -0
  90. package/dist/resources/guides/component.md +92 -5
  91. package/dist/resources/guides/decision.md +185 -0
  92. package/dist/resources/guides/entity.md +50 -8
  93. package/dist/resources/guides/expressions.md +14 -5
  94. package/dist/resources/guides/functions.md +1 -1
  95. package/dist/resources/guides/getting-started.md +38 -1
  96. package/dist/resources/guides/layout.md +11 -7
  97. package/dist/resources/guides/merge.md +42 -7
  98. package/dist/resources/guides/microservice.md +88 -3
  99. package/dist/resources/guides/middleware.md +69 -5
  100. package/dist/resources/guides/mobile-layout.md +193 -0
  101. package/dist/resources/guides/mobile-publish.md +148 -0
  102. package/dist/resources/guides/mobile.md +565 -0
  103. package/dist/resources/guides/page.md +469 -82
  104. package/dist/resources/guides/theme.md +8 -2
  105. package/dist/resources/guides/translation.md +1 -1
  106. package/dist/resources/guides/workflow.md +58 -1
  107. package/dist/resources/read.js +41 -0
  108. package/dist/resources/rules.js +11 -5
  109. package/dist/resources/schema-fingerprint.json +7 -5
  110. package/dist/resources/schemas/AccessExplanationDto.json +144 -0
  111. package/dist/resources/schemas/AccessMatrixDto.json +170 -0
  112. package/dist/resources/schemas/AccessPermissionDto.json +57 -0
  113. package/dist/resources/schemas/AccessPolicyDto.json +223 -0
  114. package/dist/resources/schemas/AccessResourceDto.json +86 -0
  115. package/dist/resources/schemas/AppSessionDto.json +53 -0
  116. package/dist/resources/schemas/ConnectDataDescribeDto.json +344 -0
  117. package/dist/resources/schemas/ConnectDataRequestModel.json +202 -0
  118. package/dist/resources/schemas/ConnectDataResultDto.json +421 -0
  119. package/dist/resources/schemas/ConnectorCredentialDto.json +70 -0
  120. package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +37 -0
  121. package/dist/resources/schemas/CreateAccessPolicyCommand.json +209 -0
  122. package/dist/resources/schemas/CreateDecisionCommand.json +221 -0
  123. package/dist/resources/schemas/CreateEntityCommand.json +118 -0
  124. package/dist/resources/schemas/CreateMicroserviceCommand.json +13 -1
  125. package/dist/resources/schemas/CreateProcessDefinitionCommand.json +1337 -0
  126. package/dist/resources/schemas/CreateQueryCommand.json +4 -0
  127. package/dist/resources/schemas/CreateWorkflowCommand.json +146 -1
  128. package/dist/resources/schemas/DataJobDto.json +6 -1
  129. package/dist/resources/schemas/DecisionDto.json +302 -0
  130. package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +28 -0
  131. package/dist/resources/schemas/ExplainAccessQuery.json +33 -0
  132. package/dist/resources/schemas/GenerateProcessDocumentCommand.json +116 -0
  133. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +24 -0
  134. package/dist/resources/schemas/MicroserviceDto.json +15 -3
  135. package/dist/resources/schemas/OrganizationProjectDto.json +343 -0
  136. package/dist/resources/schemas/OrganizationSchemaDto.json +196 -0
  137. package/dist/resources/schemas/OrganizationSchemaVersionDto.json +207 -0
  138. package/dist/resources/schemas/PatchProcessDefinitionCommand.json +76 -0
  139. package/dist/resources/schemas/PreviewMicroserviceCommand.json +10 -1
  140. package/dist/resources/schemas/PreviewWorkflowCommand.json +25 -1
  141. package/dist/resources/schemas/ProcessDefinitionDto.json +1480 -0
  142. package/dist/resources/schemas/ProcessSimulationDto.json +96 -0
  143. package/dist/resources/schemas/SaveConnectorCredentialCommand.json +90 -0
  144. package/dist/resources/schemas/SaveProcessEventSourceCommand.json +61 -0
  145. package/dist/resources/schemas/SaveProcessMailSourceCommand.json +89 -0
  146. package/dist/resources/schemas/SignProcessTaskCommand.json +73 -0
  147. package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +92 -0
  148. package/dist/resources/schemas/StartMobileBuildCommand.json +54 -0
  149. package/dist/resources/schemas/StepDto.json +25 -1
  150. package/dist/resources/schemas/UpdateAccessPolicyCommand.json +209 -0
  151. package/dist/resources/schemas/UpdateDecisionCommand.json +216 -0
  152. package/dist/resources/schemas/UpdateEntityCommand.json +118 -0
  153. package/dist/resources/schemas/UpdateMicroserviceCommand.json +13 -1
  154. package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +1357 -0
  155. package/dist/resources/schemas/UpdateQueryCommand.json +4 -0
  156. package/dist/resources/schemas/UpdateViewCommand.json +0 -2
  157. package/dist/resources/schemas/UpdateWorkflowCommand.json +146 -1
  158. package/dist/resources/schemas/UpsertMobileStoreSettingsCommand.json +333 -0
  159. package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +1339 -0
  160. package/dist/server.js +31 -1
  161. package/dist/tools/access.js +369 -2
  162. package/dist/tools/accessOperations.js +135 -0
  163. package/dist/tools/accessPolicies.js +170 -0
  164. package/dist/tools/accessRuntime.js +203 -0
  165. package/dist/tools/applications.js +63 -3
  166. package/dist/tools/bpm.js +343 -0
  167. package/dist/tools/bpmGovernance.js +266 -0
  168. package/dist/tools/bpmOperations.js +230 -0
  169. package/dist/tools/bpmReporting.js +154 -0
  170. package/dist/tools/bpmRouting.js +150 -0
  171. package/dist/tools/bpmRuntime.js +396 -0
  172. package/dist/tools/case.js +178 -0
  173. package/dist/tools/caseRuntime.js +89 -0
  174. package/dist/tools/common.js +19 -6
  175. package/dist/tools/components.js +118 -14
  176. package/dist/tools/connectData.js +450 -0
  177. package/dist/tools/connectors.js +193 -0
  178. package/dist/tools/datasources.js +3 -3
  179. package/dist/tools/decisions.js +206 -0
  180. package/dist/tools/dependencies.js +1 -1
  181. package/dist/tools/deployments.js +38 -3
  182. package/dist/tools/designSchemaPatch.js +34 -9
  183. package/dist/tools/dtos.js +36 -5
  184. package/dist/tools/entities.js +79 -12
  185. package/dist/tools/environments.js +1 -1
  186. package/dist/tools/externalComponents.js +26 -5
  187. package/dist/tools/flows.js +119 -13
  188. package/dist/tools/folders.js +1 -1
  189. package/dist/tools/imports.js +5 -2
  190. package/dist/tools/layouts.js +50 -17
  191. package/dist/tools/merges.js +2 -2
  192. package/dist/tools/microservices.js +77 -25
  193. package/dist/tools/mobile.js +280 -0
  194. package/dist/tools/mobileStore.js +572 -0
  195. package/dist/tools/modules.js +48 -0
  196. package/dist/tools/organizationStructure.js +137 -0
  197. package/dist/tools/pages.js +467 -100
  198. package/dist/tools/platformInfo.js +28 -8
  199. package/dist/tools/profileWrite.js +92 -0
  200. package/dist/tools/projects.js +71 -9
  201. package/dist/tools/rows.js +69 -13
  202. package/dist/tools/schemaOps.js +61 -1
  203. package/dist/tools/screenWrite.js +36 -7
  204. package/dist/tools/screens.js +95 -5
  205. package/dist/tools/templates.js +26 -1
  206. package/dist/tools/translations.js +1 -1
  207. package/dist/tools/variables.js +11 -5
  208. package/dist/tools/workflows.js +10 -5
  209. package/package.json +2 -2
  210. package/dist/platform/screenshot.js +0 -1162
@@ -0,0 +1,691 @@
1
+ # Süreç Rehberi — Hibrit BPM
2
+
3
+ İnsanı bekleyen, durumlu iş süreçleri: tanım, yürütme, görev kutusu, bölge olayları. Süreç
4
+ **workflow değildir**: workflow tek istekte biten sunucu akışıdır (`platform_guide('workflow')`);
5
+ süreç günlerce insan görevlerinde, zamanlayıcılarda ve dış olaylarda bekler, her adımı hash zincirli
6
+ bir defterde tutar. Bir süreç düğümü gerektiğinde workflow'u `service` düğümüyle çağırır.
7
+
8
+ ## Başlangıç
9
+
10
+ Sıra her zaman aynıdır:
11
+
12
+ 1. **İş nesnesi** — sürecin konusu olan entity (`gorevler`, `satinalma_talepleri`). Süreç o satırın
13
+ üstünde koşar: ifadelerde `row`, `writeBack` ile satıra yazar.
14
+ 2. **Tanım** — `process_definition_create`. Önce altın örneği okuyun:
15
+ `ngapps://examples/bpm-gorev-kontrol` (satır olayı → görev → onay → iade),
16
+ `ngapps://examples/bpm-satinalma` (seviye servisi → sıralı yönetici zinciri → paralel kontrol),
17
+ `ngapps://examples/bpm-iso-dokuman` (onay birimi → okuma turu → düzenleme isteği bölge olayı).
18
+ 3. **Önizleme** — `process_definition_preview` ile önce `definition` gövdesiyle doğrulama, kayıttan
19
+ sonra `id` + `subjectRowId` ile kuru koşu: her insan adımında kimin görev alacağını görürsünüz.
20
+ 4. **Yayın** — `process_definition_publish`. Taslak aktif olur; production'a yayın yoktur (BPM-001).
21
+ 5. **Yürütme** — `process_execute(slug, subjectRowId, vars, asUser)`; görevler `process_task_list(tab,
22
+ asUser)` kutusunda, eylemler `process_task_update(id, action, version, asUser)`, defter
23
+ `process_instance_get(id, view: 'timeline')`.
24
+
25
+ Tanımı düzeltirken tam gövdeyi yeniden göndermeyin: `process_definition_get` (outline) →
26
+ `process_definition_patch` (`/nodes[id=<düğüm>]/…` seçicileriyle).
27
+
28
+ ## Tanım modeli
29
+
30
+ ```jsonc
31
+ {
32
+ "slug": "gorev-kontrol", // kebab-case, uygulamada benzersiz; yayından sonra değişmez
33
+ "name": "Görev kontrol", // tek dil düz metin; çok dilli nesne gelirse gateway düz metne çevirir
34
+ "description": "…", // ZORUNLU (BPM-002), tek dil düz metin
35
+ "analysis": { "purpose": { "en": "…", "tr": "…" }, "summary": { "en": "…", "tr": "…" } }, // ZORUNLU (BPM-023) — § Analiz dokümanı
36
+ "subject": { "entity": "gorevler" }, // entity slug ya da id
37
+ "singleton": "per-subject", // aynı satırda açık örnek varsa yeni başlatma mevcut örneği döner
38
+ "withdrawPolicy": "before-first-decision", // never | before-first-decision | anytime
39
+ "history": "full", // full | audit | minimal — defter ayrıntısı
40
+ "sod": ["not-initiator"], // başlatan kendi onayını veremez
41
+ "params": { "esikTutar": { "default": 50000, "type": "number", "editable": "params" } },
42
+ "emailActions": false, // true: onay e-postasına tek kullanımlık onay/ret bağlantısı
43
+ "nodes": [ … ],
44
+ "edges": [ ["baslangic", "bildir"], { "from": "karar", "to": "red", "condition": "!vars.uygun" } ],
45
+ "on": [ … ] // süreç düzeyi olay işleyicileri
46
+ }
47
+ ```
48
+
49
+ Kurallar:
50
+
51
+ - **Her düğüm ve tanımın kendisi `description` taşır** (BPM-002, block). Kutuda ve tasarımcıda
52
+ görevin ne istediğini anlatır; mekanizmayı değil niyeti yazın. Gerçek bir tuzak varsa `caution`.
53
+ - **Tanım ve her düğüm iki dilli `analysis` taşır** (BPM-023, block): Studio'nun Analiz dokümanı
54
+ sekmesi onu gösterir. Biçim ve yazım kuralı § Analiz dokümanı.
55
+ - Düğüm `id`'leri kebab-case ve tanım içinde benzersizdir; kenarlar ve `back-to:` bu id'lerle bağlanır.
56
+ - **Adımın okunabilir adı (`resultKey`) snake_case'dir, kebab-case DEĞİL.** `id` kenarların anahtarıdır,
57
+ ifadede okunmaz; ifade sonucu adıyla ve noktayla okur: `vars.tasks.ik_kaydi.action`,
58
+ `vars.approvals.yonetici_onayi.outcome`. Her `user-task` ve `approval` düğümüne id'nin snake_case'ini
59
+ `resultKey` olarak yazın (`"id": "ik-kaydi"` → `"resultKey": "ik_kaydi"`). Köşeli parantezle kebab
60
+ anahtar okumayın — `vars.tasks?.['ik-kaydi']?.action` yazmayın; Studio kartı ve ifade tamamlaması
61
+ adı snake_case gösterir, kebab anahtar yalnız eski ifadeler bozulmasın diye yazılır.
62
+ - Tam bir `start` üst düzeydedir; bölgenin içinde `start` yoktur.
63
+ - İfadeler Jint'tir: `vars` (süreç değişkenleri), `row` (iş satırı), `previousRow` (satır olayında),
64
+ `initiator` (başlatan kullanıcı id). `{{…}}` yer tutucu yalnız şablon metinlerinde ve `chain` argümanında.
65
+ - Kısa biçimler gateway'de tam biçime çevrilir ve yanıtta `gatewayNormalized` ile bildirilir:
66
+ `"sla": "P2D"` → `[{ "duration": "P2D" }]`, `"assignee": "unit-manager of initiator"` → nesne,
67
+ `[from, to]` → `{ from, to }`.
68
+ - Parametre (`params`) varsayılanları başlatmada `vars`'a yazılır; başlatma girdisi üstüne biner.
69
+ - `history` defterin ayrıntısıdır: `full` her olayı, `audit` kararları, görev yaşam döngüsünü (açılma,
70
+ üstlenme, bilgi isteme), SLA ihlallerini ve yorumları, `minimal` yalnız başlangıç/bitiş, kararlar,
71
+ tamamlanan görevler ve satıra yazmaları tutar — `minimal`de raporun ret döngüsü ve SLA ihlali boş kalır.
72
+
73
+ ## Analiz dokümanı
74
+
75
+ Studio'da süreç tasarımcısının alt bilgi çubuğundaki **Analysis document** paneli, süreci hiç görmemiş bir iş
76
+ kullanıcısına her adımda ne olduğunu anlatır. Kullanıcının çizdiği süreçte metin şablonla üretilir;
77
+ **AI'ın yazdığı süreçte metni siz yazarsınız** ve gateway zorunlu tutar (BPM-023, block —
78
+ create, update ve patch'in sonucu denetlenir).
79
+
80
+ ```jsonc
81
+ "analysis": { // tanım düzeyi
82
+ "purpose": { "en": "…", "tr": "…" }, // bu süreç neden var, hangi ihtiyacı karşılıyor
83
+ "summary": { "en": "…", "tr": "…" } // baştan sona ne oluyor, 2-3 cümle
84
+ }
85
+ "analysis": { // her düğüm, bölge içindekiler dahil
86
+ "what": { "en": "…", "tr": "…" }, // bu adımda ne yapılıyor, kim yapıyor
87
+ "data": { "en": "…", "tr": "…" }, // hangi değerleri kullanıyor, nereden geliyor, ne yazıyor
88
+ "why": { "en": "…", "tr": "…" }, // bu adım neden gerekli; olmasa ne ters gider
89
+ "example": { "en": "…", "tr": "…" } // gerçek hayattan küçük bir örnek: bu adım bir vakada ne yapar
90
+ }
91
+ ```
92
+
93
+ Yazım kuralı — sekmeyi okuyan kişi teknik değildir:
94
+
95
+ - **İş diliyle, 1-3 kısa cümle.** Alan ve id yerine etiketini yazın: "talebin tutarı", `row.tutar`
96
+ değil; "birim yöneticisi", `unit-manager of initiator` değil. İfade ya da JSON yazmayın.
97
+ - **`what` eylemi ve eylemi yapanı söyler**, mekanizmayı değil: "Finans ekibinden biri bütçeyi kontrol
98
+ eder ve onaylar ya da reddeder."
99
+ - **`data` somut değerleri sayar**: okunan alanlar, dal koşulunun baktığı değer, yazılan sonuç. Değer
100
+ kullanmayan adımda bunu söyleyin: "Değer kullanmaz; yalnız süreci bitirir."
101
+ - **`why` gerekçeyi verir**: kural, risk, denetim ihtiyacı — `description`'ın tekrarı değil.
102
+ - **`example` bu adımı somut bir vakayla gösterir**: adı, tutarı olan bir kişi ve talep ("Ayşe'nin
103
+ yöneticisi Mehmet, 25.000 TL'lik dizüstü talebini kutusunda görür ve onaylar"). Bütün adımlarda aynı
104
+ vakayı sürdürün ki okuyan akışı tek hikâye gibi izlesin; dal ya da ret yolundaki adımda vakanın o
105
+ yola nasıl düştüğünü söyleyin ("tutar 60.000 TL olsaydı talep CFO onayına giderdi").
106
+ - **İki dil aynı şeyi söyler**; biri diğerinin çevirisidir, `en` kısaltılmış değildir.
107
+ - Var olan bir sürecin analizi yoksa her yazma BPM-023'e takılır: aynı çağrıda eksikleri ekleyin
108
+ (`process_definition_patch` ile `add /nodes[id=x]/analysis`).
109
+
110
+ Örnek — satın alma onayındaki bir `approval` düğümü:
111
+
112
+ ```json
113
+ "analysis": {
114
+ "what": { "en": "The requester's unit manager reviews the request and approves or rejects it.", "tr": "Talep sahibinin birim yöneticisi talebi inceler; onaylar ya da reddeder." },
115
+ "data": { "en": "Reads the title, category and amount of the request. A rejection ends the process.", "tr": "Talebin başlığını, kategorisini ve tutarını okur. Ret süreci bitirir." },
116
+ "why": { "en": "No money is spent without the manager knowing about it.", "tr": "Yöneticinin haberi olmadan harcama yapılmasın diye." },
117
+ "example": { "en": "Ayşe's manager Mehmet sees her 25,000 TL laptop request in his inbox and approves it the same day.", "tr": "Ayşe'nin yöneticisi Mehmet, 25.000 TL'lik dizüstü talebini kutusunda görür ve aynı gün onaylar." }
118
+ }
119
+ ```
120
+
121
+ ## Düğümler
122
+
123
+ Her türün alanları ve örneği: `process_step_schema(type)`. Özet:
124
+
125
+ **start** — `trigger: row-event | manual | api | schedule | sub-process | message | signal`, `entity`, `operation`,
126
+ `condition`. `row-event` bağlıdır (ölçüldü 2026-09-18): aktif sürümün konu entity'sine
127
+ (`subject.entity`; start düğümündeki `entity` eşleşmeye BAKILMAZ) ilk start düğümünün `operation`'ı
128
+ (boşsa `create`; `delete` hiç başlatmaz) yazılıp `condition` sağlanınca örnek kendiliğinden açılır —
129
+ yetki denetimi bastırılır, başlatan satırı yazan kullanıcıdır. Yayından önce yazılmış satırlar
130
+ başlatmaz. Aynı olaya workflow `process` adımıyla ikinci başlatma eklemeyin — iki örnek açılır.
131
+ Kendiliğinden başlatan yalnız `row-event` ve `message`tır; `manual`, `api`, `schedule`, `sub-process` ve
132
+ `signal` belgeleyicidir — örnek açık bir başlatmayla açılır (`process_execute`, uygulamanın Süreçler sayfası,
133
+ `Page.bpm.start`, üst sürecin `sub-process` düğümü, bitiş düğümünün `schedule`'ı). Sinyal bugün yalnız bekleyen
134
+ örneği ilerletir, yeni örnek açmaz.
135
+
136
+ **user-task** — insan görevi. `assignee` zorunlu. `mode: claim` (varsayılan) adaylardan birinin
137
+ üstlenmesini bekler; `mode: individual` her kişiye ayrı görev açar ve `join: all | any | force-complete`
138
+ ile birleşir. `actions[]` özel eylemler: `completes: true` görevi bitirir (`evidence: read-proof`
139
+ defterde okuma kanıtı bırakır), `completes: false` görevi açık bırakıp `emits: signal:<ad>` yayar.
140
+ `completeOn { trigger: row-event, operation: update, condition }` görevi satır değişince bitirir.
141
+ `requestInfo: true` başlatandan bilgi isteme; `allowReassign`, `external: true` (dış kullanıcı görevi,
142
+ yalnız atanan görür), `revisionBound: true` (bölge yeniden başlarsa eski görev `superseded`),
143
+ `undoWindow: "PT5M"` (karar geri alma). Tamamlanan görevin sonucu
144
+ `vars.tasks.<resultKey>` altına `{ outcome, action, completedBy, payload }` olarak yazılır.
145
+ `resultKey` yoksa anahtar id'nin snake_case hâlidir (`teslimat-kontrol` → `vars.tasks.teslimat_kontrol`);
146
+ eski ifadeler bozulmasın diye sonuç kebab-case id altına da yazılır, ama ifadeyi hep snake_case
147
+ ve noktayla yazın — slug değil, `vars.tasks?.['teslimat-kontrol']` gibi köşeli parantezli kebab değil. **Süreç kurarken her `user-task` ve `approval` düğümüne snake_case bir
148
+ `resultKey` verin** — id kebab-case kalır: `{ "id": "teslimat-kontrol", "resultKey": "teslimat_kontrol" }`
149
+ ve geçitte `vars.tasks.teslimat_kontrol.action === 'sorunlu'`. Ad harf, rakam ve `_`'dır; tire yok,
150
+ aynı tipte benzersiz (başka adımın id'si ve snake_case'i de dolu sayılır). Yazılmamış bir adı okumak
151
+ (`vars.tasks.teslimatKontrol` — camelCase, ne ad ne id) `undefined` verir ve geçit hiç o dala gitmez.
152
+
153
+ **approval** — onay görevi + politika:
154
+ `policy: sequential | all | any | quorum(n) | majority | weighted(0.6)`,
155
+ `rejectPolicy: any-reject | quorum(n) | majority`, `onReject: end | back-to:<düğüm> | restart`,
156
+ `commentRequired: true | "outcome === 'rejected'"`, `selfApproval: escalate | skip | allow`,
157
+ `weights: { "position:P-SATIS": 2, "role:yk-baskani": 3 }`, `veto: ["user:…"]`, `abstain: true`,
158
+ `countAs: "vars.onaySayisi"`. `sequential` sonraki halkayı **karar anında** çözer (geç bağlama).
159
+ `rejectPolicy` yazılmazsa: sequential/all ilk retle, any herkes reddedince, quorum/majority eşiğe
160
+ ulaşılamaz olunca reddeder. Karar `vars.approvals.<resultKey>` altına yazılır; `resultKey` yoksa
161
+ anahtar id'nin snake_case hâlidir (`grup-onayi` → `vars.approvals.grup_onayi`; kebab-case id altına
162
+ da yazılır) — yine de açık bir snake_case ad verin (`"resultKey": "grup_onayi"`).
163
+ **`back-to:` bir SIÇRAMADIR ve düğümün `writeBack`'ini ÇALIŞTIRMAZ** (yalnız onaylanan dal ve bitiş
164
+ düğümü geri yazar). "Ret satıra durum yazsın" isteyen tasarım, ret hedefini geri yazmayı yapan bir
165
+ `script` düğümü yapar ve oradan asıl hedefe bir kenar çeker (ölçüldü 2026-09-21, S-6 CAPA).
166
+
167
+ **service** — workflow çağrısı: `workflowId` (zorunlu; yalnız `workflowSlug` yazılan düğüm önizlemede ve yayında
168
+ `DefinitionInvalid` alır — slug değişebilir, bağ kimlikle tutulur; yanıt ikisini birlikte döner), `input: { ad: "<Jint>" }`, `output: "vars.x"`,
169
+ `retry: { count }`. Başarısızlık `retry.count` (varsayılan 3) sonra örneği `faulted` yapar.
170
+ `runAs: system` gerekçesi `caution`'da durur (BPM-005). `input` anahtarları workflow'un **parametre DTO
171
+ alanlarının `slug`'larıdır** (`dto_get` → `children[].slug`); platform onları alan kimliğine bağlar. DTO'da
172
+ olmayan anahtar kayıtta, önizlemede ve yayında `ServiceInputUnknown` verir (mesaj geçerli parametreleri sayar).
173
+ DTO alanı yeniden adlandırılınca tanım yeni adı gösterir, yayındaki sürüm de doğru anahtarla çağırır. Süreçte
174
+ kullanılan alan `dto_update` ile silinemez (422 `ReferencedByProcess`). Parametre DTO'su olmayan workflow'un
175
+ girdisi denetlenmez. Workflow gövdesindeki `input.x` adları elle güncellenir.
176
+
177
+ **notify** — `to` (atama sözlüğü), `channels: ["inbox", "email"]`, `template { subject, body }`
178
+ (`{{row.baslik}}`), `ackRequired`. Kutu bildirimi satırı aynı transaction'da yazılır.
179
+
180
+ **gateway** — `kind: exclusive` (ilk doğru kenar, yoksa `default`), `parallel` (çatallanır;
181
+ birleşmede gelen kenar sayısı kadar varış bekler), `inclusive` (koşulu tutan **her** kenar, hiçbiri
182
+ tutmazsa `default`; birleşmede o gateway'e hâlâ ulaşabilecek token kalmayınca devam eder) ya da
183
+ `event-based` (yalnız `wait`/`timer` düğümlerine gider; ilk gelen olay kazanır, diğer bekleyişler
184
+ iptal edilir, defterde `event-gateway-resolved`).
185
+
186
+ **timer** — `duration` (ISO) ya da `until` (Jint). `duration` **düz metindir, ifade
187
+ değerlendirilmez**; beklemeyi bir parametreye bağlamanın tek yolu `until`'dır
188
+ (`until: "new Date(Date.now() + vars.beklemeGunu * 86400000).toISOString()"`). **wait** — `message { name, correlationKey }` +
189
+ `output: "vars.x"` (mesaj gövdesi), `signal: "<ad>"` (`process_trigger kind signal` ile gelir) ya da
190
+ `link: "<ad>"` (yakalama noktası; gelen kenarı olmaz).
191
+
192
+ **send** — `message { name, correlationKey: "<Jint>" }` + `input` (gövde) mesajı kuyruktan atar;
193
+ alıcı yoksa `timeout: "PT10M"` (en çok `P1D`) boyunca tamponda bekler ve sonra açılan `wait` hemen
194
+ tüketir. `link: "<ad>"` verilirse aynı kapsamdaki `wait { link }` düğümüne sıçrar. BPMN karşılığı
195
+ *intermediate throw event*'tir (message ya da link) — bildirim değildir ve **e-posta göndermez**; mesaj kuyruktan
196
+ aynı adla bekleyen `wait`'e ya da mesajla başlayan sürece gider, e-posta `notify { channels: ["email"] }` işidir.
197
+ Studio adımı kipine göre adlandırır: `message` → **Mesaj gönder** (sinyal anteni), `link` → **Bağlantıya atla** (ok); yakalayan
198
+ `wait { link }` → **Bağlantı noktası** (ok); palette kutucuğu **Mesaj**. Kullanıcıya bu adlarla anlat.
199
+ **manual** — sistem dışı iş; görev satırı açmaz, `process_instance_update { operation: skip }` ile geçilir.
200
+ Süre dolunca: `sla[]` ya da `deadline` (Jint tarih) ile `skipOnDeadline: true` adımı geçer, `onTimeout: "end:<sonuç>"`
201
+ örneği o sonuçla bitirir; ikisi de yoksa adım yöneticiyi bekler.
202
+ **script** — `code` Jint (2 sn, dosya/HTTP/CLR yok); `vars.x = …` yazar, son ifade `output` yoluna. Globaller
203
+ `vars`, `row`, `previousRow`, `initiator`.
204
+ **case** — `caseSlug` (aktif sürümü olan vaka tanımı; yayında denetlenir, yoksa `CaseUnknown`),
205
+ `input { vakaDosyasıÖğesi: "<Jint>" }` (tanımsız öğe düşer), `output: "vars.x"` (vaka kimliği). Vakayı iş satırı
206
+ üzerinde, örneği başlatan adına açar ve **beklemez**; defterde `case-started`.
207
+ **document** — şablondan belge üretir ve beklemez; alanları § Bağlayıcı ve belge'de. `output` → `{ fileId, name }`.
208
+
209
+ **sub-process** — ayrı örnek başlatır ve bekler: `processSlug`, `subject { rowId: "<Jint>" }` (farklı iş
210
+ nesnesi), `input`, `output`, `binding: latest (varsayılan) | deployed | v:<n>` (`latest` ve `deployed` bugün ikisi de
211
+ aktif sürümü okur; sabitlemek için `v:<n>`), `forEach { entity, where: "item.aktif === true",
212
+ batch }` (partili başlatma, hepsi bitince devam). Alt örnek kuyruktan başlar; üst örnek
213
+ `sub-process-completed` ile ilerler.
214
+ `v:<n>` yayında **o sürümün kimliğine** bağlanır; numara ortamın yerel sayacıdır ve merge/promote
215
+ ara sürümleri taşımaz. Aktarım bağı hedefte **aynı içerikli** sürüme yeniden yazar (numara değişebilir,
216
+ ör. development `v:3` → production `v:2`); hedefte o içerik yoksa promote 422
217
+ `SubProcessBindingNotCarried` ile durur — önce çağrılan sürümü taşıyın ya da bağı değiştirin.
218
+
219
+ **region** — uyarlanabilir blok ve olay kapsamı: `nodes`, `edges`, `limits { maxSteps, nodeTypes,
220
+ assigneeRules }`, `on[]`. Girişler iç kenarlarda hedef olmayan düğümlerdir; iç tokenlar bitince dış
221
+ kenardan devam eder.
222
+
223
+ **end** — `outcome`, `writeBack`, `reopenWindow: "P30D"`. Bölge içindeki `end` yalnız o kolu kapatır.
224
+ `kind: terminate` bütün dalları iptal eder, `onCancel` workflow'unu koşar ve `terminated` sonucuyla
225
+ biter (bölge içinde yalnız o bölgeyi kapatır). `kind: error` + `code` en yakın bölgenin
226
+ `on: [{ event: "error:<code>", afterHandlers: "exit-region:<hedef>" }]` işleyicisine sıçrar; yoksa süreç
227
+ `error:<code>` sonucuyla biter ve üst sürecin `sub-process` düğümündeki aynı biçimli `on[]` yakalar
228
+ (yakalamazsa üst örnek `faulted`).
229
+
230
+ `writeBack { alan: "<Jint>" }` her düğümde düğüm çıkışında iş satırına yazar; satır otomasyonları bu
231
+ yazmada tetiklenmez (sonsuz döngü koruması).
232
+
233
+ ## Atama sözlüğü
234
+
235
+ `assignee` nesnesi `{ rule, arg, of, unit, fallback, selfApproval, dedupe, sod, expand, items }` ya da
236
+ kısa biçim `"rule:arg of <referans>@unit:<kod>"`. Referans (`of`): `initiator` (varsayılan),
237
+ `subject-field:<alan>`, `user:<id>`, `vars.<yol>`.
238
+
239
+ | Kural | Çözüm |
240
+ |---|---|
241
+ | `initiator` | başlatan |
242
+ | `subject-field:<alan>` | iş satırındaki kullanıcı id'si |
243
+ | `user:<id>` | sabit kişi |
244
+ | `unit-manager` | referansın birincil pozisyonunun birimi → `manager_position_id` → aktif sahip (vekil `acting` önce). Referans birimin yöneticisiyse bir üst birimin yöneticisi. Pozisyon boşsa üst birime tırmanır (`source: escalation`) |
245
+ | `parent-unit-manager` | birincil birimin üst biriminin yöneticisi |
246
+ | `ancestor-manager:<tip>` | en yakın ata birim; `unit_type`, `function_code` ya da `code` eşleşir (`mudurluk`) |
247
+ | `chain:<n>` · `chain:{{vars.seviye}}` | referanstan yukarı n yönetici, sıralı; `dedupe: true` aynı kişiyi atlar |
248
+ | `role:<slug>` | rol adayı + rolün pozisyon sahipleri ve kullanıcıları; `mode: claim` ile grup görevi |
249
+ | `unit-members:<kod>` | birimin (`includeDescendants`) pozisyon sahipleri; aday grup |
250
+ | `position:<kod>` | pozisyonun aktif sahibi; boşsa üst pozisyon (`strategy: functional` işlevsel hat) |
251
+ | `list` | `items[]` ya da `of` — **`of` burada REFERANS DEĞİL Jint İFADESİDİR** (`vars.liste`, `row.birimler.split(",")`); `subject-field:x` yazmak motoru 500 JavaScriptException ile düşürür. Değerler `["user:…", "unit:satis", "position:P-X", "role:…"]`, `expand: members` |
252
+ | `expression` | Jint → id ya da id dizisi (sıra korunur) |
253
+ | `previous-approver-manager` | Görev sayacının ihlalinde (`onBreach`) atanmış görevin asıl sahibinin yöneticisi — zincirde bir üst halka, kökte `admin-queue`; düğüm/süreç sayacında, grup görevinde ve ihlal dışında son onaylayanın yöneticisi |
254
+ | `chain-until-authority` | `{ rule: 'chain', arg: 'until-authority', category, amount: 'vars.tutar' }` — yukarı yönetici zinciri, limiti (`process_authority_limit_*`; pozisyon limiti kişiyi ezer) tutarı karşılayan ilk halkada durur; hiçbiri yetmezse tüm zincir + uyarı |
255
+ | `partner:<kod>` | kabul edilmiş partner ilişkisinin (Organization.API `organizations/{id}/partners`) karşı kurumu aday olur (`candidates: partner`); ilişki etkin değilse ya da süreç izinli listede yoksa çözülmez (fallback). Doğrulama `PartnerUnknown`; partner kullanıcısının görevi açması henüz yok |
256
+ | `pool:<kod>` | havuz (`process_pool_*`) stratejisi: `round-robin` · `least-loaded` (açık görev / haftalık kapasite — saat, yalnız ağırlık: 20 saatlik kişi 40 saatlik kişinin yarısı kadar iş alır) · `skill-match` (`skills: ["vars.dil"]` + havuz becerileri) · `manual` (havuzda bekler). İş yükü kaydında `maxOpenTasks` doluysa açık görevi o sayıya ulaşan kişi manual dışı stratejilerde seçilmez; boşsa tavan yoktur. Havuzu kullanan süreçler `process_pool_list` çıktısında `usedBy`; kullanılan havuz silinemez (`process_pool_update { id, remove: true }` → 422 `ReferencedByProcess`) |
257
+
258
+ Çözüm sırası: strateji → SoD (`not-initiator`) → `selfApproval` → pasif kullanıcı süzgeci (kullanıcı
259
+ tablosunda olmayan kişi seçilmez; bitişi geçmiş pozisyon ataması sayılmaz) → **vekalet** (aktif
260
+ vekaleti olan kişinin yerine vekil; görevde `principalUserId` asıl, zincir izlenmez, SoD vekile de uygulanır) → `dedupe`
261
+ (vekil ikameden SONRA: vekil zincirde zaten varsa tek adım alır — asıl kişinin seviyesi vekilin kararıyla kapanır ve
262
+ zincir bir halka kısalır; `chain:2`'de Murat→Selin vekaletiyle tek karar yeter) → `fallback`
263
+ (`escalate` referansın yöneticisi, `role:<slug>`, varsayılan `admin-queue` havuzu). Kimse çıkmazsa görev
264
+ `admin-queue` havuzuna düşer; süreç yöneticisi görür. Kim çıkacağını yayından önce
265
+ `process_definition_preview(id, subjectRowId)` gösterir.
266
+
267
+ ## Yaşam döngüsü ve işletim
268
+
269
+ **SLA ve takvim.** `sla: "PT8H"` ya da `[{ name, duration, calendar, stopOn: state-change, reminders: [0.5], onBreach: [{ notify | escalate | reassign+ | priority }] }]`;
270
+ süreler iş takvimiyle (`process_calendar_*`; kod → birim → `default` → Pzt–Cum 08–18) hesaplanır. Tatil `{ date, name, workEnd }`: `workEnd` yoksa gün tam tatil, varsa yarım gündür ve süre o saate kadar sayılır (arife `workEnd: '13:00'`); `P1D` yarım güne düşer ve saat `workEnd`'i geçerse vade o günün `workEnd`'idir. Kullanılan takvim silinemez (`process_calendar_update { id, remove: true }` → 422); `default` ya da birim takvimi silinince zincirin sonraki halkası kullanılır — yani **`P5D` beş İŞ GÜNÜDÜR**, takvimde 7+ gün eder; senaryoda sayacı ihlal etmek için saati ona göre ilerletin (`{ clock: 'P10D' }`). **Sayaç yalnız `duration` ile kurulur:** `deadline` alanı platformun SLA şemasında YOKTUR (sessizce düşer) ve `duration`suz sayaç 422 `DefinitionInvalid` verir — vadeyi iş satırındaki bir tarihe bağlamanın yolu bugün yok (ölçüldü 2026-09-22, S-9 ECN). Görev `dueAt` ilk sayaçtır; kutu `priority DESC, dueAt ASC` sıralar, görevde `slaRatio`. Son sayaç ihlalinde
271
+ `onTimeout: approve | reject | end:<sonuç>`, `join: force-complete`, alt süreçte `skipOnDeadline`. `reassign+` görevi asıl
272
+ sahibinde bırakıp çözülen kişiyi aday ekler; doğrudan atanmış görevde ilk karar veren kapatır. Devralma yalnız
273
+ `reassign+`'ın eklediği kişiye açıktır — kural adayı, gruptan üstlenilmiş ya da yeniden atanmış görevi devralamaz. Süreç düzeyi `sla`
274
+ ihlali örneği `critical` yapar; `priorityRule` başlangıç önceliği. Askıya alma ve bilgi isteme sayacı durdurur.
275
+ Timer'lar 15 sn'de bir taranır (Tenant.API job'u).
276
+
277
+ **Servis hatası.** Servis düğümü başarısız olursa `retry { count, backoff: fixed | exponential, delay }` timer'la yeniden
278
+ dener; son denemede örnek `faulted`. Müdahale `process_instance_update`: `retry` (yalnız faulted), `skip` / `jump`
279
+ (`reason` zorunlu, defterde kırmızı satır, atlanan görevler iptal). Tanım düzeyi `onCancel` (servis düğümü biçimi:
280
+ `workflowId`/`connector`/`ai`/`externalEngine` ve/veya `writeBack`; yalnız `workflowSlug` canlıda çözülmez) iptalde, geri çekmede ve `terminate` bitişinde telafi koşar; `writeBack` ifadesi
281
+ `cancel.cause`'u (`cancelled` · `withdrawn` · `terminated`) okur — geri çekilen talebin durumunu iş satırına böyle
282
+ yazın: `"onCancel": { "writeBack": { "durum": "cancel.cause === 'withdrawn' ? 'geri-cekildi' : 'iptal'" } }`.
283
+ Terminate bitişinde bu `writeBack` önce, bitiş düğümününki sonra koşar. Telafi başarısızsa örnek kapanmaz, `faulted` kalır.
284
+
285
+ **Vekalet ve devir.** `process_delegation_create { toUserId, startsAt, endsAt, processSlugs, onBehalfOf }` —
286
+ başkası adına açmak birim/üst birim yöneticiliği ya da `process.manage` ister; vekilin kesişen tarih ve süreçte bitmemiş
287
+ vekaleti varsa BPM-008.
288
+ Ayrılan kullanıcı: önce `process_handover_preview(userId)`, sonra `process_handover_create { decisions[], force }`
289
+ (`force`: kararsız assigned-tasks yöneticiye ya da admin-queue'ya, candidate-tasks gruba);
290
+ açık görevi olan birim kapatılamaz (`OpenTasksExist` 422). Yönetici değişince `rebindOnManagerChange: true`
291
+ tanımlarında üstlenilmemiş yönetici görevleri yeni yöneticiye taşınır; üyelik değişince aday görevler yeniden hesaplanır.
292
+ Servis adımı yerine workflow `process` adımı `processOperation: delegate` ile izin süreci vekalet yazar.
293
+
294
+ **Toplu işlem.** `process_batch_execute`: `start` (100.000 satır, arka planda) · `reassign` · `extend-due` · `cancel`
295
+ (en çok 500 görev) → `process_batch_get`; `process_batch_update { operation: undo }` yalnız reassign/extend-due.
296
+
297
+ **Bildirim.** Bildirimler outbox'tan (15 sn) kanallara gider: `inbox` (hub `/hubs/process-notifications`),
298
+ `socket` (`task-changed`), `email`; kanal hatasında 1/5/25/125 dk sonra yeniden, 5 denemede bırakılır. Aynı
299
+ `dedupeKey` ile okunmamış bildirim tazelenir. Tercih `process_preference_update` (`immediate | digest | sla-only`,
300
+ sessiz saat, özet saati). `process_instance_update { operation: watch }` karar/kapanış bildirimlerini izletir;
301
+ görev yorumunda `@<kullanıcı-id>` bahsetme bildirimi üretir.
302
+
303
+ **Tetikleyiciler.** `process_trigger { kind: message, name, correlationKey }` bekleyen `wait` düğümünü ilerletir ya da
304
+ mesaj başlangıçlı tanımı başlatır; anahtarsız mesaj yalnız anahtarsız bekleyen örneklere gider ve `broadcast: true` ister.
305
+ Dış sistemden gelen webhook `POST bpm/webhooks/{slug}`: `X-Zeyrek-Signature: sha256=HMAC(sır, "{timestamp}.{slug}.{gövde}")`,
306
+ `X-Zeyrek-Timestamp` (±300 sn) ve `X-Zeyrek-Delivery` zorunlu; sır proje + ortam + slug başına türetilir ve
307
+ `GET bpm/webhooks/{slug}/secret` (`process.manage`) ile alınır. Giden olaylar için `process_webhook_subscription_create` (HMAC imzalı CloudEvents).
308
+
309
+ ## Bölge olayları
310
+
311
+ ```jsonc
312
+ "on": [ { "event": "signal:duzenleme-istegi", // signal:<ad> | membership-added | subject-changed
313
+ "interrupt": false, // true: bölge tokenları ve görevleri askıya alınır
314
+ "handler": { "type": "sub-process", "processSlug": "dokuman-duzenleme", "input": { "istek": "event.form" } },
315
+ "afterHandlers": "restart-region", // continue | restart-region | exit-region:<düğüm> | append
316
+ "restartWhen": "no-open-handlers", // | each
317
+ "restartIf": "handler.outcome === 'approved'",
318
+ "restartScope": "all", // | pending-only
319
+ "cancelStale": "superseded" } ] // | cancelled
320
+ ```
321
+
322
+ - Olay en içteki açık bölgenin `on[]` listesinde aranır, yoksa `process.on[]`'da.
323
+ - `handler.type`: `sub-process` (kuyruktan başlar, sayaç artar), `notify` (hemen), `append-task`
324
+ (bölgenin bekleyen bireysel görevine olaydaki kişi için tek görev ekler — `membership-added` ile).
325
+ - `restart-region`: revizyon artar, açık görevler `cancelStale` ile kapanır, liste yeniden açılır;
326
+ tamamlanmış görevler ve `read-proof` satırları kanıt olarak kalır. Üç düzenleme isteği gelse de
327
+ `no-open-handlers` ile tek yeniden başlatma olur; reddedilen istek (`restartIf` yanlış) başlatmaz.
328
+ - Olay tetiklemek: görevin `completes: false` eylemi (`emits`) ya da `POST bpm/signals
329
+ { instanceId, name, payload }`. `withdraw` ve `reopen` adları yerleşiktir.
330
+
331
+ ## Uyarlama
332
+
333
+ `editable` dereceleri: `locked` (varsayılan), `params` (`editableParams` listesindeki alanlar),
334
+ `open` (yalnız `region` — BPM-003). `open` bölgede eklenen düğümün atama kuralı
335
+ `limits.assigneeRules` içinden seçilir (BPM-004, platform 422 `RuleNotAllowed`), düğüm türü
336
+ `limits.nodeTypes`, adım sayısı `limits.maxSteps` ile sınırlıdır. Tanım yazarken dereceyi bilinçli
337
+ seçin — dışarıdan değişmesi riskli adımı `locked` bırakın.
338
+
339
+ **Uyarlama katmanı.** Uygulama yöneticisi aktif sürümün üstüne ortam başına bir JSON Patch yazar
340
+ (tenant iş verisi; deployment ile taşınmaz). Okuma `process_override_get` (`editableScopes` hangi
341
+ düğümün hangi derecede açık olduğunu, `outline` etkin tanımı gösterir; `view: 'studio'` salt okunur).
342
+ Uygulama ekranı aynısını `process.override.*` sistem işlemleriyle yapar; `process.manage` ister, modül kurulumu vermez.
343
+ Yazma `process_override_update` — yönetici adına (BPM-013; Studio jetonu 403): development'ta parolasız `asUserId` (users satır id'si) ya da `asUser` (uygulama jetonu):
344
+
345
+ | Yol | İzin |
346
+ |---|---|
347
+ | `/params/<ad>/default` | parametre `editable: params` ya da `open` ise |
348
+ | `/nodes[id=<düğüm>]/<alan>` (üst düzey) · `/nodes[id=<bölge>]/nodes[id=<adım>]/<alan>` (bölge çocuğu — seçici yalnız doğrudan çocukları bulur) | düğüm `params` ise yalnız `editableParams`; açık bölgenin derecesiz çocuğunda her alan. `id/type/editable/editableParams/limits`, `nodes` ve `edges` `editableParams`'ta yazsa da kilitli |
349
+ | `/nodes[id=<bölge>]/nodes/-` (add) | bölge `open`; eklenen adım `editable`, `editableParams`, `limits`, `nodes` taşımaz, `region` değildir |
350
+ | `/nodes[id=<bölge>]/nodes[id=<adım>]` | bölge `open` ve adımın kendi derecesi yok: `remove` ya da aynı `id`/`type` ile düz adım `replace` |
351
+ | `/nodes[id=<bölge>]/edges…` | bölge `open` |
352
+ | `move` · `copy`, bölgenin bütün `nodes` dizisi, diğer her yol | kilitli (BPM-010, 422 `RegionLocked` / `ParamNotEditable`) |
353
+
354
+ Gateway yazmadan önce patch'i temel modele uygular ve istek gitmeden durdurur: kilitli yol BPM-010,
355
+ bölgenin izin vermediği atama kuralı BPM-011 (liste atamasında kalemlerin kuralı), adım sayısı ya da düğüm türü sınırı BPM-012; bilinçli istisnada `policyOverride: true`. Platform ayrıca etkin tanımın referanslarını denetler (`RoleUnknown`, `WorkflowUnknown`).
356
+ `mode: 'append'` (varsayılan) mevcut uyarlamanın sonuna ekler; iyimser kilit aktif sürüm +
357
+ `overrideRevision`'dır (409 → `process_override_get`).
358
+
359
+ **Yeni örnek, açık örnek.** Kayıttan sonra başlayan örnek uyarlamayla koşar; açık örnek eski
360
+ zincirle biter. `operation: 'migrate-open'` açık örnekleri güncel uyarlamaya bağlar — açık düğümü
361
+ (ya da açık bölgesi) etkin tanımda olmayan örnek atlanır ve `skipped` listesinde döner.
362
+ `operation: 'reset'` varsayılana döner (yeni örnekler için).
363
+
364
+ **Yeni sürüm yayını (üç yönlü birleştirme).** Geliştirici yeni sürüm yayınlayınca uyarlama yeni modele
365
+ yeniden uygulanır: tüm yollar hâlâ izinliyse yeni revizyon açılır; bölge kaldırıldıysa ya da
366
+ kilitlendiyse uyarlama `conflictState: conflicted` olur, `conflictDetail` hangi yolun neden
367
+ düştüğünü söyler, tanım sahibine ve uyarlamayı yazana gelen kutusu bildirimi gider ve yeni örnekler
368
+ varsayılanla başlar — sessiz ezme yoktur. Çözüm: `process_override_get` → patch'i yeni sürüme göre
369
+ kurup `mode: 'replace'` ile yazın. `process_definition_preview(id)` kuru koşusu kayıtlı uyarlamayı içerir.
370
+
371
+ ## Yürütme ve kutu
372
+
373
+ - Süreç sayfaları hazır gelir: projede ilk tanım (create, BPMN içe aktarma, klon) `bpm-management`
374
+ sistem şablonunu tanımın uygulamasına öneksiz kurar (sayfa slug'ı doluysa kurmaz) — `gorevlerim`, `gorev-detayi` (`?task=` /
375
+ `?instance=`), `surecler`, `surec-izleme`, `vekaletler`, `bildirimler`. Kompleks projede sayfalar
376
+ **Yetki kabuğuna** bağlanır ve `MENÜ` / `YÖNETİM` grupları Yetki kabuğu menüsüne eklenir (ikinci layout
377
+ doğmaz); Yetki kabuğu olmayan uygulamada kendi `Süreç kabuğu` layout'uyla gelir.
378
+ Proje başına bir kez kurulur, production'a dağıtılmaz. Sayfalar süreçten bağımsızdır (ad, form alanı,
379
+ özel eylem sunucudan gelir): yeni süreç ya da sürüm için sayfa YAZMAYIN, önce `page_list`.
380
+ - Başlatma: `process_execute { slug, subjectRowId, vars, asUser }` (REST `POST bpm/processes/{slug}/start`)
381
+ → yeni örnek; tekil (`singleton`) tanımda aynı satırda açık örnek varsa mevcut örnek döner. Yetki
382
+ `process.start` (`process:<tanımId>`). production'a yürütme yok (BPM-001).
383
+ - Örnek: `process_instance_get { id, view: 'timeline' }` (defter, güncel ve sonraki düğümler,
384
+ `isLedgerValid`); `process_instance_list`; müdahale `process_instance_update { operation: cancel |
385
+ suspend (reason zorunlu) | resume | withdraw (withdrawPolicy) | reopen (reopenWindow içinde) }`.
386
+ - Olay: `process_trigger { instanceId, name, payload, eventId }` — bölge işleyicisi, `completeOn`,
387
+ `membership-added`.
388
+ - Kutu: `process_task_list { tab: mine | group | delegated | started | done | all, asUser }`.
389
+ Görünürlük: atanan, aday (rol/birim/pozisyon/kişi), başlatan; `all` sekmesi `process.view-all` ya da
390
+ `process.manage` ister. `process_task_get` eylem listesini ve `version`'ı verir.
391
+ - Görev eylemleri tek kapıdan: `process_task_update { action, actionId, payload, comment, version,
392
+ asUser }` — `claim` (sürüm denetimli; ikinci üstlenme 409 `TaskAlreadyClaimed`, bayat `version` 409 `AggregateVersionConflictException` — ikisinde de görevi yeniden okuyun),
393
+ `unclaim`, `complete` (özel eylem `actionId`), `approve`, `reject`, `request-info { question }` →
394
+ başlatana `provide-info` görevi, `provide-info { answer }`, `reassign { targetUserId, reason }`, `undo`.
395
+ kimlik zorunludur (BPM-006): development'ta parolasız `asUserId` — `/bpm/*` uçları platform şemasıyla `[Authorize]` edildiği için uygulama jetonu orada 401 alır — ya da `asUser`; yetki `task.complete` (`task:<tanımId>`); Studio jetonu görev eylemi
396
+ yapamaz.
397
+ - Görev durumları: `open`, `claimed`, `waiting-info`, `suspended`, `unassigned`, `completed`,
398
+ `superseded`, `cancelled`, `expired`.
399
+ - E-postadan karar: `emailActions: true` süreçte atanan kişiye onay/ret bağlantısı üretilir; bağlantı
400
+ tek kullanımlıktır, 72 saat geçerlidir, ikinci kullanım 410 döner.
401
+ - Sayfadan: süreç çalışma zamanına **sistem mikroservisiyle** gidilir (BPM-022, warn).
402
+ `microservice_system_operation_list` `process.*` işlemlerini verir — kutu `process.task.list`, görev
403
+ `process.task.get/claim/unclaim/complete/request-info/provide-info/reassign/sign/assessment.start`, örnek
404
+ `process.instance.*`, `process.batch.*`, `process.delegation.*`, `process.handover.*`,
405
+ `process.notification(-preference).*`, `process.report.get`, uyarlama `process.override.*`, seçici listeleri
406
+ `process.definition.list/user.list/directory.get`. `microservice_create { source: 'system', systemOperation }`
407
+ ucu kurar; akışta `microservice` adımı çağırır, sonraki `code` adımı `Steps.<adım>.data`'yı okur, hatada
408
+ `Steps.<adım>.error` doludur (`Conflict`, gövde `.data`'da). Hata dalı kurmayın: ilk hatada akışı keser;
409
+ kayıt başına çağrı `condition` → `microservice` → `code` çevrimiyle yazılır. Yanıt REST `bpm/*` ile aynı alan
410
+ adlarındadır, listeler düz dizidir (`meta` yok). İzin boş işlemde kararı servis verir, `process.override.*`
411
+ `process.manage` ister. Hazır süreç sayfaları (`bpm-management` 1.1.0) bu desenle kuruludur; yeni ekran onların
412
+ akışını örnek alır.
413
+ - Sistem işlemi olmayan işler eski yolda kalır ve BPM-022 onlarda uyarmaz: başlatma **Süreç** adımıyla
414
+ (`type: 'bpm'`; argüman `value` sütununda JSON METNİ — `args: { value: '{"operation":"start","processSlug":"satin-alma","subjectRowId":"Page.queryParams.id"}' }`,
415
+ düz `args.operation` DÜŞER; hata `fail` dalına) ya da `Page.bpm.start(slug, { subjectRowId, vars })`; vaka
416
+ `Page.bpm.cases.*`, belge `documents.print/generate`, `analytics`, `exportLog`, çevrimdışı kuyruk `offline.*`.
417
+ `start` slug tek uygulamadaysa tanımı bulur, iki uygulamada varsa `applicationId` ister. Sinyal adı
418
+ `signal:<ad>`; `completeOn` bekleyen görev yalnız `completeOn.trigger` adındaki sinyalle kapanır.
419
+
420
+ ## Simülasyon ve test
421
+
422
+ `process_definition_preview` **yan etkisizdir**: transaction açmaz, satır/görev/bildirim yazmaz.
423
+
424
+ - `definition` ile: platform doğrulayıcısı — bulgular `{ code, path, message }` (`path`:
425
+ `/nodes[id=onay]/assignee`).
426
+ - `id` ile: doğrulama + kuru koşu. Kuru koşu başlangıçtan yürür; exclusive gateway `vars` ile karar
427
+ verir, paralel dallar ve bölge girişleri açılır, her `user-task`/`approval`/`notify` için atanan
428
+ kişiler (ad soyad) ve adaylar döner. `vars` servis çıktılarını taklit eder (`{ "seviye": 3 }`);
429
+ servis düğümü çalıştırılmaz. `send { link }` motor gibi yakalayan `wait { link }`'e sıçrar (not
430
+ `→ <id>`). Kuru koşu her adımı bir kez yürür: geri dönen bir döngü (düzeltme → yeniden kontrol) tekrar
431
+ yürünmez, dönülen adım rotanın sonunda `walked before; the dry run does not repeat it` notuyla yer alır.
432
+
433
+ Yayından önce: `findings` boş, `steps` beklenen kişileri gösteriyor, her `back-to:` hedefi mevcut.
434
+
435
+ ### Senaryo test paketi
436
+
437
+ Kuru koşu "kim yapar"ı söyler; **senaryo** bütün yolu gerçek motorla oynatır ve beklenenle karşılaştırır.
438
+
439
+ - `process_scenario_create { fromInstanceId, name }` gerçek örneğin defterinden kaydeder: insan kararları,
440
+ zaman atlamaları, sinyal/mesaj/alt süreç sonuçları adım; servis çıktıları `stubs`; girilen düğümler,
441
+ atananlar, sonuç beklenen olur. Elle: `{ definitionId, name, given, stubs, steps, expect }`.
442
+ - Adım başına **tek eylem**: `{ task: 'onay', as: 'user:<id>', action: 'approve' | 'reject' | 'complete', form }`
443
+ (görev verisi `form`'dadır, `payload` görev adımında okunmaz) · `action: 'sign'` — `signature` taşıyan düğümde
444
+ **zorunludur**: `approve`/`complete` adımı canlı uçtaki gibi 422 `SignatureRequired` alır ve senaryo kırmızı düşer
445
+ (ret ve çekimser imzasız geçer). Senaryo parola istemez ve `SignatureRecord` yazmaz; defterine düğümün
446
+ `meaning`/`level`'ıyla bir `TaskSigned` satırı düşer (ölçüldü 2026-09-22, S-7 sözleşme) ·
447
+ `action: 'request-info'` (`comment` soru; görev
448
+ `waiting-info`, SLA durur) ve başlatanın `action: 'provide-info'` (`comment` yanıt; aynı görev yeniden açılır) ·
449
+ `{ clock: 'P3D' }` (vadesi gelen zamanlayıcılar sırayla ateşlenir, sonrakiler senaryo saatinden kurulur) ·
450
+ `{ signal }` (`{ signal: 'withdraw', as: 'user:<başlatan>' }` `withdrawPolicy`'ye göre geri çeker) ·
451
+ `{ message, correlationKey }` · `{ subProcess: '<düğüm>', outcome }` (çocuk örnek açılmaz).
452
+ - `expect`: `path` (girilen düğüm dizisi birebir), `assignees` (düğüm → kullanıcılar, alt küme), `outcome`,
453
+ `state`, `vars` (nokta yolu), `writeBack`. Yazılmayan alan denetlenmez.
454
+ - `process_scenario_execute { definitionId | id, version? }` yan etkisizdir: writeBack satıra yazılmaz,
455
+ bildirim/webhook/e-posta jetonu gitmez, `service` düğümü workflow çağırmaz (stub anahtarı
456
+ `workflowSlug → workflowId → düğüm id`; `workflowSlug` yalnız düğümde yazılıysa eşleşir — `workflowId`'li
457
+ düğümde düğüm id'sini kullanın; stub yoksa örnek `faulted`). Yalnız son koşu sonucu kaydedilir.
458
+ `version` yoksa taslak — v3 senaryolarını v4 taslağında koşmak sürüm regresyonudur.
459
+ - Sonuç: ilk sapma `divergence { kind: step | error | path | assignee | outcome | state | vars | write-back,
460
+ nodeId, stepIndex, expected, actual, message }` ve `coverage`; `process_scenario_list { view: 'coverage' }`
461
+ `untestedEdgeKeys` ('from->to') hiç test edilmeyen dalları listeler.
462
+ - Senaryo düzenlenince son koşu silinir. Senaryolar ortam verisidir; deployment/merge taşımaz.
463
+
464
+ ## Yayın ve taşıma
465
+
466
+ - `process_definition_publish`: taslak → `active`; önceki aktif `retiring` olur, açık örnekler kendi
467
+ sürümünde biter. Yayın doğrulamadan geçmezse 422 `DefinitionInvalid` döner, liste `errors[]`'dadır.
468
+ - Yayınlanmış tanımda slug değişmez; değişiklik yeni taslak sürümdür (`process_definition_update`
469
+ ya da `patch` taslağı yazar).
470
+ - production'a yayın ve yürütme gateway'de durur (BPM-001); production'a taşıma insan onaylı
471
+ deployment işidir.
472
+ - **Diff:** `process_definition_diff { id, from?, to? }` anlamsal satırlar (`node-added`, `assignee-changed`,
473
+ `editable-changed`, `param-type-changed` …); `isOverrideRisk` yöneticinin uyarlamasını bozabilecek değişikliktir. Yayından önce okuyun.
474
+ - **Dört göz:** aktif sürüm ya da taslak `publishPolicy: four-eyes` ve ortamda `process-publish` (bpm-management modülü)
475
+ kuruluysa `process_definition_publish` gerekçesiz 403 `PublishApprovalRequired` alır — taslakta politikayı `direct` yapmak
476
+ kapıyı açmaz. `{ reason }` ile istek açılır: `isPublished: false`, `request.instanceId`; onay görevi tanım sahibine düşer.
477
+ Yalnız isteyenden farklı bir kullanıcının onay kararı yayınlar; yönetici atlaması onay sayılmaz. Onay gerekmiyorsa aynı
478
+ çağrı doğrudan yayınlar.
479
+ - **Yayın kapısı:** aktif sürüm ya da taslakta `requireGreenScenarios: true` iken her senaryo taslak sağlamasında yeşil
480
+ koşmuş olmalı, yoksa 422 `ScenarioFailed` — doğrudan yayında da `{ reason }` ile istek açarken de (istek açılmaz).
481
+ Onaydan sonra kapıya takılan istek `rejected` olur. Gateway kapı kapalıyken de uyarır (BPM-015): önce `process_scenario_execute`.
482
+ - **SOP ve yorum:** `process_documentation_get` HTML (kulvar, RACI, SLA, diyagram); tasarım notları
483
+ `process_comment_list/create/update { resolved }`.
484
+ - **Sahiplik ve portföy:** tanımın sahibi (kullanıcı kimliği) dört göz onay görevini alır; RACI rolleri
485
+ (`responsible`, `accountable`, `consulted`, `informed`) atama kurallarıdır ve SOP'ta görünür
486
+ (`PUT bpm/definitions/{id}/governance`, bugün yalnız Studio'da). Studio'daki süreç portföyü
487
+ (`GET bpm/definitions/portfolio`) uygulamanın tanımlarını sahip, RACI, aktif/taslak sürüm, açık/kapalı
488
+ örnek, SLA ve son yayınla listeler; yayın onayı bekleyenler üstte.
489
+ - **Taşınan / taşınmayan (K-26):** deployment, dal açma, merge ve şablon tanımı ve iş takvimini taşır;
490
+ uyarlama, örnek, görev, timer, defter, bildirim, yorum, vekalet, havuz ve yetki limiti taşınmaz.
491
+ - **Hedefte ne olur:** tanım `(slug, applicationId)` ile eşleşir. Yeni tanım gelen kimlik ve sürümlerle
492
+ kurulur. Var olan tanımda aktif modelin sağlaması farklıysa hedefte **yeni sürüm olarak yayınlanır**
493
+ (production'da gelişte aktif) ve hedefin uyarlaması korunur ya da çatışma bildirimi gelir. Taslak
494
+ yalnız dal açma ve merge'de taşınır. Hedefte workflow/entity/rol eksikse taşıma `DefinitionInvalid` ile
495
+ düşer. Kaynakta olmayan tanım silinir; açık örneği varsa emekliye ayrılır.
496
+ - **Şablon:** `template_items(module: 'process-definition')` yalnız aktif sürümü taşır; kurulum yeni
497
+ kimlik verir, uygulama/workflow/sayfa/DTO kimliklerini yeniden eşler.
498
+ - **Merge planı:** tanım farkı `versions[…].model.nodes[<düğüm id>]…` yolunda görünür.
499
+ - **Silme kapısı:** kullanan tanım varken entity ve workflow silinmez (422 `ReferencedByProcess`,
500
+ mesajda tanım slug'ları); kimin kullandığını `dependency_graph(module: 'process-definition' | 'entity' | 'workflow')` gösterir.
501
+ - **Modül paketleri:** `module_list` katalog + kurulum; `module_update { operation: install | upgrade | detach, module, applicationId }`.
502
+ Katalogdaki tek süreç modülü `bpm-management`'tır (süreç sayfaları ve tr-mesai takvimi); `requires`
503
+ taşıyan bir modül, gerektirdiği modül aynı application'a kurulmadan 409 `ModuleRequiresModule` döner.
504
+ Kurulum tabloları (yoksa), takvimi ve süreçleri getirir; güncelleme değişen
505
+ süreci yeni sürümle yayınlar, uyarlamayı ve tablo verisini korur; ayırma içeriği bırakır. production'a kurulum
506
+ gateway'de durur (BPM-014).
507
+
508
+ ## BPMN 2.0
509
+
510
+ - **Dışa:** `process_bpmn_get { id, version?, outPath? }` — düğüm ve süreç alanları `zeyrek:` uzantısında,
511
+ saklı diyagram korunur. 256 KB üstü için `outPath`.
512
+ - **İçe:** yeni tanım `process_definition_create { bpmn }`; var olan tanımın taslağı
513
+ `process_bpmn_update { id, xml | filePath }` (≤ 5 MB). `zeyrek:` uzantılı XML kayıpsız döner.
514
+ - **Başka modelleyiciden (uzantısız):** düğüm öğe türünden türetilir (`userTask` → `user-task`,
515
+ `exclusiveGateway` → `gateway`, `callActivity` → `sub-process`, `subProcess` → `region` …), kimlikler
516
+ kebab-case olur, **derece `locked`**, insan adımı ve bildirimin ataması **yer tutucu `initiator`**, SLA/politika boş
517
+ (BPM-016 uyarısı). İçe aktardıktan sonra `process_definition_get { view: 'outline' }` → atamaları
518
+ `process_definition_patch` ile düzelt → `process_definition_preview`. Bağlama isteyen öğe (`serviceTask` workflow'suz,
519
+ `callActivity` süreçsiz) için yer tutucu yoktur: içe aktarım 422 `DefinitionInvalid` döner.
520
+ - Şerit, havuz, not, veri nesnesi gibi yürütülmeyen öğeler kaybolmaz (alt süreç içindekiler dahil); içlerindeki kimlik
521
+ başvuruları normalize kimliklere çevrilir ve dışa aktarımda yerine yazılır. DTD/dış varlık içeren XML 400.
522
+
523
+ ## Bağlayıcı ve belge
524
+
525
+ **Karar düğümü** `decision { decisionSlug, binding, input, output }` eşik ve seviye kurallarını DMN tablosundan
526
+ okur — tablo yazımı, FEEL ve DRD `platform_guide('decision')`.
527
+
528
+ **Bağlayıcı:** `connector_list` kataloğu (salesforce, sap-odata, microsoft-graph, google-workspace, jira, uipath, imap,
529
+ netgsm, twilio, teams-webhook, slack, camunda8, camunda7, flowable) her satırda `category` (ai · process-engine ·
530
+ productivity · messaging · business-app · rpa) taşır ve `category` ile süzülür; `connector_get { name }` işlem girdi şemaları.
531
+ Kimlik önce kasaya: `connector_credential_create { name, connectorName, kind, … sırlar }` →
532
+ `connector_credential_update { id, operation: 'test' }`. Sırlar şifreli saklanır, hiçbir yanıtta dönmez (BPM-017).
533
+ Düğümde:
534
+
535
+ ```jsonc
536
+ { "id": "lead", "type": "service", "description": "Satış fırsatı açar", "output": "vars.lead",
537
+ "connector": { "name": "salesforce", "operation": "create", "credentialRef": "sf-sandbox",
538
+ "input": { "sobject": "'Lead'", "fields": "({ LastName: vars.soyad, Company: row.firma })" } } }
539
+ ```
540
+
541
+ `input` değerleri Jint ifadesidir (metin sabiti tek tırnakla). Hata `502 ConnectorFailed` ve `retry` politikası workflow
542
+ servis düğümüyle aynıdır.
543
+
544
+ **Dış motor:** Camunda/Flowable'da koşan süreci başlatıp sonucunu bekleyin:
545
+
546
+ ```jsonc
547
+ { "id": "camunda", "type": "service", "description": "Dış siparişi başlatır", "output": "vars.dis",
548
+ "externalEngine": { "engine": "camunda8", "processKey": "siparis", "credentialRef": "c8", "input": { "tutar": "vars.tutar" } } },
549
+ { "id": "dis-bitti", "type": "wait", "description": "Dış süreç biter",
550
+ "message": { "name": "external-engine.done", "correlationKey": "vars.dis.zeyrekInstanceId" } }
551
+ ```
552
+
553
+ Dış süreç değişkeninde `zeyrekInstanceId` gelir; bitişte `POST bpm/messages { name: "external-engine.done",
554
+ correlationKey: <zeyrekInstanceId>, payload }` çağırması gerekir (MCP'den deneme: `process_trigger { kind: 'message' }`).
555
+
556
+ **Olay ve e-posta kaynağı:** `process_event_source_create { name, kind: 'http', messageName, correlationKey:
557
+ 'payload.siparisNo' }` dış olayı mesaja çevirir, olay `process_trigger { kind: 'event-source', name, eventId, payload }`.
558
+ `process_mail_source_create { kind: imap | graph, credentialRef, rules[{ subjectPattern, messageName, correlationKey }] }`
559
+ e-postayı mesaja çevirir (ekler files'a); yoklama `process_trigger { kind: 'mail-source', sourceId }`. `credentialRef` kasadaki
560
+ kaydın adıdır: olmayan ad kayıtta 404 döner, kasa kaydı yeniden adlandırılırsa kaynak yeni adı gösterir, kaynağın kullandığı
561
+ kasa kaydı silinemez. Mesajı bekleyen
562
+ `wait` düğümü ya da message start'lı tanım yoksa olay kaybolur — `bufferSeconds` verin.
563
+
564
+ **Belge:** süreçte `type: 'document'` düğümü `document { templateFileId, format: docx | pdf | html, fileName, folderId,
565
+ data: { alan: '<Jint>' }, stamp { revision, state, watermark, note } }` ve `output`; tek başına
566
+ `process_document_execute { operation: generate | stamp | print }`. Şablon DOCX ya da HTML, yer tutucu `{{alan}}`: DOCX
567
+ şablon `docx | pdf`, HTML şablon `html | pdf` üretir, başka biçim hata verir. `fileName` şablon metnidir, uzantısı biçime
568
+ uyar; `folderId` boşsa şablonun klasörü. Damga HTML çıktıya basılmaz.
569
+
570
+ **İmza:** `user-task`/`approval` düğümünde `signature { meaning, level: SES }` varsa görev imzasız tamamlanamaz
571
+ (422 `SignatureRequired`); `process_task_update { action: 'sign', password, meaning?, email?, fileId?, version, asUser }`.
572
+ Parola zorunlu (BPM-018; yalnız `signature.reauth: false` düğümde değil), gateway günlüğüne maskeli yazılır. `meaning` verilmezse düğümünki. İmzalanan dosya kilitlenir (409 `FileLocked`).
573
+
574
+ **Kanallar:** `notify` `channels` `inbox | email | socket | sms | teams | slack`. `sms` kullanıcının tercihindeki numaraya
575
+ (`process_preference_update { phone }`) `notification-sms` kasa kimliğiyle (bağlayıcı netgsm ya da twilio); `teams` ve
576
+ `slack` kullanıcının e-postasıyla `notification-teams` / `notification-slack` kimlikleriyle gider. Kimlik yoksa kanal sessizce
577
+ atlanır. `push` henüz yok.
578
+
579
+ ## Doküman kontrolü ve AI
580
+
581
+ **Değerlendirme (okuma sınavı):** `user-task`'ta `assessment { questionBank { entity, where, questionField, optionsField,
582
+ answerField }, count, passScore, attempts, random, completeAction }`. Akış: `process_task_update { action: 'start-assessment' }`
583
+ (sorular cevapsız döner) → `{ action: 'submit-assessment', answers: { soruId: cevap } }`. **Submit'te `version` gönderme:**
584
+ sınavı açmak görevi üstlenir ve sürümünü ilerletir, elindeki sürüm bayattır (409). Başlatma yanıtı `{ id, taskId, number,
585
+ passScore, questions, startedAt, attempts, lastScore, isPassed }`: `attempts` adımın izin verdiği hak, `lastScore`/`isPassed`
586
+ **bu kullanıcının** son gönderilmiş denemesinin sonucudur (ilk denemede null). Denemeler **kullanıcı başına** sayılır (defterdeki
587
+ `number` örnek genelinde artar) ve sınavı yalnız görevin atandığı kişi açıp gönderebilir — başkası 403 `TaskComplete`.
588
+ Görev ayrıntısı (`process_task_get`) sınav isteyen adımda `assessment { count, passScore, attempts }` kuralını taşır; deneme
589
+ açılmadan önce paneli o kural açar. Soru bankası ve konu satırı okuyucunun alan izinlerine bakılmadan okunur; `passScore`
590
+ gerçekten sorulan soru sayısına kırpılır (banka `count`'tan az soru döndürürse geçme notu o sayıya iner). Cevap anahtarı boş
591
+ ya da yalnız boşluk olan soru **hiçbir cevapla doğru sayılmaz**. Geçen deneme görevi `completeAction` (yoksa düğümün okuma
592
+ kanıtı eylemi, o da yoksa `complete`) ile kapatır; kalan deneme hak varsa görevi açık bırakır, hak bitince sonuç
593
+ `assessment-failed` (geçide yönlendirin). Sınavsız okuma kanıtı 422. `passScore` 1..`count` (BPM-020).
594
+
595
+ **Yürürlük tarihi:** `end` düğümünde `effectiveAt: "<Jint tarih>"` + `revision { stateField, groupField, effectiveValue,
596
+ supersededValue, numberField }`; tarihte satır `effective`, aynı gruptaki önceki `superseded` olur. Grup satırları alan
597
+ filtresiyle okunur (10.000 satır sınırı yok). `numberField` verilirse sıra **numaraya** göre kurulur: yürürlüğe giren revizyon
598
+ numarası yürürlükteki bir satırdan küçükse **gelen satır** `superseded` olur, yürürlükteki yerinde kalır — geç işlenen eski bir
599
+ revizyon yeniyi düşürmez. `numberField` yoksa gelen satır her zaman yürürlüğe girer. **Check-out:** dosya
600
+ `POST files/{id}/checkout { taskId }` ile kilitlenir, başkası yazarsa 409 `FileCheckedOut`; görev **hangi yolla kapanırsa
601
+ kapansın** (eylem, imza, e-posta jetonu, zaman aşımı) kilit bırakılır. Kilitli ya da check-out'lu dosya barındıran klasör
602
+ silinemez.
603
+
604
+ **B2B:** `process_partner_create` ilişki önerir, karşı organizasyon `process_partner_update { operation: 'accept' }` ile
605
+ açar; tanımda `assignee: "partner:<kod>"` yalnız `active` ve süreci izinli ilişkiyle yayınlanır (`PartnerUnknown`).
606
+
607
+ **AI önerisi (service düğümü):**
608
+
609
+ ```jsonc
610
+ { "id": "oneri", "type": "service", "description": "Karar önerir", "output": "vars.oneri",
611
+ "ai": { "operation": "suggest-decision", "labels": ["approve", "reject"], "input": { "talep": "vars.talep" } } }
612
+ ```
613
+
614
+ `operation`: `summarize` → `{ summary }` · `classify` (`labels`) → `{ label }` · `extract` (`schema.properties`,
615
+ `files` PDF/görsel) → `{ fields }` · `suggest-assignee` (`input.candidates`) → `{ userId }` · `suggest-decision`
616
+ (`labels`) → `{ outcome }`; liste/şema dışı değer `null`. AI **karar vermez**: çıktı yalnız `output` yoluna yazılır,
617
+ sonraki onay görevi açık kalır; geçitte kullanacaksanız kişi onaylasın. Korumalı alanlar modele `***` gider. Her öneri
618
+ defterde `ai-suggestion { promptHash }`. `autonomy: act-in-adhoc` yalnız `adHoc` süreçte (BPM-019) ve bugün öneriyle aynı.
619
+ Model ve kasa kimliği ortam ayarıdır (`Bpm:AiModel`, `Bpm:AiCredentialRef`); yoksa 400.
620
+
621
+ **Görev yardımcısı:** `process_task_get { view: 'assistant' }` özet ve önerilen eylem, `question` ile soru-cevap döner
622
+ (`aiSuggestion` rozetiyle; `outcome` yoktur). `process_task_list { q: 'bu ay geciken satınalmalar' }` süzgeci
623
+ `appliedFilter` ile döner. Kullanıcı başına dakikalık sınır 429 `AiRateLimited`.
624
+
625
+ ## Operasyon
626
+
627
+ - **Rapor:** `process_report_get { slug, from, to }` — defterden türer, arşivlenmiş örneği saymaz. Çevrim
628
+ `instance-started` → `instance-completed`; SLA içinde % son termine (uzatma dahil) göre; `rejectLoops` ardından yeni
629
+ görev açılan retler; `units[]` başlatanın birincil birimi. Pencere en çok 366 gün; `isTruncated` 5000 örneği aştığını
630
+ söyler — pencereyi daraltın. Yetki `process.view-all`.
631
+ - **Madencilik:** `process_export_get { format: xes | ocel, definition, from, to, outPath }` IEEE XES (iz = örnek, olay =
632
+ defter satırı, `org:resource` eylemci, vekalette `zeyrek:principal`) ya da OCEL 2.0 JSON (örnek, görev, konu, belge
633
+ nesneleri, dosya `.json`) indirir; gateway dosyayı yapısal denetler (`validated`, `problems`) — resmî XSD değil;
634
+ `isTruncated: true` 5000 örnek tavanıdır, pencereyi bölün. ProM/Celonis için
635
+ `outPath`. `process_analytics_get { definition, view: variants | heatmap | conformance | prediction, from, to }`: yol
636
+ varyantları (pay % yolu olan örneklere göre), insan görevi düğümü başına süre, tanım dışı geçişler (sıçrama, atlama, göç), açık örnekte kalan süre
637
+ medyanı. Pencere ve 5000 örnek tavanı rapor ile aynı; `history: minimal` tanımda yol eksik kalır.
638
+ - **Defter:** `process_instance_get { view: 'events' }` CSV (en çok 256 KB satır içi), `view: 'verify'`
639
+ `{ isValid, brokenAtSequence }`. `isValid: false` defterin sonradan değiştirildiğini gösterir; kırık satırı
640
+ zaman çizelgesinde bulun, örneği düzeltmeye çalışmayın — denetim kaydıdır.
641
+ - **Saklama ve yasal bekletme:** tanımda `retention` (ör. `P5Y`) doluysa kapanmış örnek saatlik işte arşive taşınır,
642
+ 30 gün sonra silinir. `process_legal_hold_create { scope: process | instance | user, scopeKey, reason }` taşımayı ve
643
+ silmeyi durdurur; `process_legal_hold_delete` kaldırır (kayıt kalır). İkisi de production'a gitmez (BPM-001).
644
+ - **Sağlık:** `process_health_get` — `timerLagSeconds` 60 sn'yi aşarsa `degraded`, 600 sn'yi aşarsa `unhealthy`
645
+ (timer işi durmuş ya da geride); `notificationLagSeconds` 300 sn üstü ve 10'dan çok `faulted` örnek de `degraded`.
646
+ `faulted` örnek için `process_instance_list { state: 'faulted' }` → `process_instance_update { operation: 'retry' }`.
647
+ - **Yarı yolda örnek:** `process_execute { slug, subjectRowId, vars, importAt: { nodeId, assigneeUserId, startedAt } }`
648
+ kâğıttan ya da eski sistemden gelen işi o düğümde açar; defterin ilk satırı `instance-imported`, rapordaki çevrim
649
+ `startedAt`'tan sayılır. Düğüm başlangıç, bitiş ya da bölge içi olamaz; yetki `process.manage`.
650
+ - **Tanım yedeği:** `process_definition_list { view: 'export' }` bütün tanımları (sürümler, taslak, RACI) ve takvimleri
651
+ verir; `process_definition_create { restore: <export data> }` geri yükler (takvim üzerine yazılır, değişen aktif sürüm
652
+ yayınlanır, yedekte olmayan tanım silinmez). Ortamlar arası taşıma için yedek değil deployment kullanılır.
653
+
654
+ ## Hata sözlüğü
655
+
656
+ | Kod | HTTP | Anlam ve çözüm |
657
+ |---|---|---|
658
+ | `DefinitionInvalid` | 422 | Yapı: tek start, ulaşılamayan düğüm, tanımsız kenar, açıklama. `errors[]` satırlarını düzeltin |
659
+ | `RuleNotAllowed` · `RegionLocked` · `ParamNotEditable` · `MaxStepsExceeded` · `NodeTypeNotAllowed` | 422 | Bölge ya da uyarlama sınırı ihlali — §Uyarlama yol tablosu |
660
+ | `ExpressionInvalid` | 422 | Jint ifadesi derlenmiyor |
661
+ | `SubjectEntityUnknown` · `WorkflowUnknown` · `RoleUnknown` | 422 | Referans çözülmedi |
662
+ | `ServiceInputUnknown` | 422 | Servis düğümünün `input` anahtarı workflow'un parametre DTO'sunda yok — `dto_get` ile alan slug'larını okuyun |
663
+ | `TaskAlreadyClaimed` | 409 | Görev başkasında — görevi yeniden okuyun |
664
+ | `AggregateVersionConflictException` | 409 | `version` bayat (görev ya da tanım siz okuduktan sonra değişti) — `process_task_get` / `process_definition_get` ile yeniden okuyun |
665
+ | `TaskStateTransitionNotAllowed` | 422 | Görev bu durumda bu eylemi almaz (ör. `waiting-info` iken onay) |
666
+ | `TaskCommentRequired` | 422 | `commentRequired` koşulu yorum ister |
667
+ | `InstanceStateTransitionNotAllowed` | 409 | Örnek bu durumda değişmez (tamamlanmış örneği askıya alma) |
668
+ | `WithdrawNotAllowed` | 422 | `withdrawPolicy` geri çekmeye izin vermiyor |
669
+ | `UndoWindowClosed` | 409 | Geri alma penceresi geçti ya da sonraki insan görevi açıldı |
670
+ | `TaskActionTokenInvalid` | 410 | E-posta bağlantısı kullanılmış ya da süresi dolmuş |
671
+ | `OpenTasksExist` | 422 | Kullanıcının ya da birimin açık görevi var — önce `process_handover_preview` / `process_handover_create` |
672
+ | `HandoverIncomplete` | 422 | Kararı olmayan görev grubu var — karar verin ya da `force: true` |
673
+ | `DelegationOverlap` | 409 | Asıl kişinin kesişen vekaleti var |
674
+ | `DelegationChainNotAllowed` | 422 | Vekil aynı aralıkta kendi görevlerini devretmiş |
675
+ | `BatchOperationNotUndoable` | 422 | Yalnız tamamlanmış reassign / extend-due bir kez geri alınır |
676
+ | `PublishApprovalRequired` | 403 | Dört göz tanımı — `process_definition_publish { reason }` ile yayın isteği açın |
677
+ | `ScenarioFailed` | 422 | `requireGreenScenarios` ve senaryo bu taslakta yeşil değil — `process_scenario_execute` |
678
+
679
+ ## Sık tuzaklar
680
+
681
+ - **Süreç ≠ workflow.** Tek istekte biten iş için workflow yazın; bekleme, insan kararı, SLA varsa süreç.
682
+ - **`description` eksik düğüm** gateway'de durur (BPM-002); her düğüme niyet cümlesi yazın.
683
+ - **İki dilli `analysis` eksik tanım ya da düğüm** gateway'de durur (BPM-023); § Analiz dokümanı.
684
+ - **`editable: open` bölge dışında** geçersizdir (BPM-003).
685
+ - **Sıralı zincirin uzunluğu `vars`'tan geliyorsa** önceki `service` düğümü `output: vars.seviye` yazmalı;
686
+ kuru koşuda aynı değeri `vars` ile verin.
687
+ - **`back-to:` bölge dışına** dönebilir; bölge koşusu `exited` olur ve içindeki açık görevler iptal edilir.
688
+ - **Paralel birleşme** gelen kenar sayısını bekler; birleşmeye koşullu olarak gelmeyen bir kol süreci
689
+ asılı bırakır — koşullu dalları önce exclusive gateway'de toplayın.
690
+ - **Görev eylemi app kullanıcısı adına yapılır**; Studio jetonuyla `complete` 403 alır.
691
+ - **production** hedefine yayın/yürütme gönderilmez (BPM-001).