@appaflytech/zeyrek-ai-mcp 0.0.5 → 0.0.7

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 (145) hide show
  1. package/.env.example +2 -2
  2. package/.env.production.example +9 -1
  3. package/README.md +14 -38
  4. package/dist/config.js +36 -3
  5. package/dist/knowledge/backendConstraints.js +982 -0
  6. package/dist/knowledge/componentCatalog.js +549 -92
  7. package/dist/knowledge/componentEvents.js +120 -25
  8. package/dist/knowledge/coverage.js +43 -0
  9. package/dist/knowledge/flowGuards.js +30 -0
  10. package/dist/knowledge/functionGuards.js +134 -0
  11. package/dist/knowledge/guideSections.js +49 -0
  12. package/dist/knowledge/hydrate.js +97 -0
  13. package/dist/knowledge/languageCodes.js +36 -0
  14. package/dist/knowledge/languages.js +105 -0
  15. package/dist/knowledge/layoutSummary.js +10 -0
  16. package/dist/knowledge/localization.js +51 -0
  17. package/dist/knowledge/normalize.js +500 -16
  18. package/dist/knowledge/outlines.js +167 -12
  19. package/dist/knowledge/policy.js +14 -5
  20. package/dist/knowledge/propTypes.js +80 -0
  21. package/dist/knowledge/rules.js +961 -44
  22. package/dist/knowledge/schemaGuard.js +199 -0
  23. package/dist/knowledge/styleResolve.js +63 -4
  24. package/dist/observability/trace.js +27 -3
  25. package/dist/platform/csv.js +123 -0
  26. package/dist/platform/errors.js +107 -6
  27. package/dist/platform/http.js +34 -4
  28. package/dist/platform/patch.js +27 -0
  29. package/dist/platform/refs.js +104 -0
  30. package/dist/platform/responses.js +25 -6
  31. package/dist/platform/screenshot.js +544 -16
  32. package/dist/platform/secrets.js +40 -0
  33. package/dist/platform/tokenVault.js +89 -0
  34. package/dist/platform/writeDiff.js +281 -0
  35. package/dist/resources/examples/flow-call-function.json +66 -0
  36. package/dist/resources/examples/function-total.json +70 -0
  37. package/dist/resources/examples/layout-app-shell.json +1 -1
  38. package/dist/resources/examples/microfunction-node-sum.json +56 -0
  39. package/dist/resources/examples/microservice-table-list.json +2 -4
  40. package/dist/resources/examples/page-dynamic-form.json +3 -3
  41. package/dist/resources/examples/page-flex-sections.json +99 -0
  42. package/dist/resources/examples/page-sign-in.json +4 -3
  43. package/dist/resources/guides/component.md +81 -8
  44. package/dist/resources/guides/entity.md +712 -20
  45. package/dist/resources/guides/expressions.md +47 -2
  46. package/dist/resources/guides/external-component.md +9 -0
  47. package/dist/resources/guides/functions.md +262 -0
  48. package/dist/resources/guides/getting-started.md +82 -7
  49. package/dist/resources/guides/layout.md +53 -10
  50. package/dist/resources/guides/merge.md +231 -0
  51. package/dist/resources/guides/microfunction.md +166 -0
  52. package/dist/resources/guides/microservice.md +287 -15
  53. package/dist/resources/guides/middleware.md +89 -1
  54. package/dist/resources/guides/modify-existing.md +23 -0
  55. package/dist/resources/guides/page.md +402 -49
  56. package/dist/resources/guides/translation.md +150 -8
  57. package/dist/resources/guides/view.md +16 -1
  58. package/dist/resources/guides/workflow.md +199 -28
  59. package/dist/resources/knowledge.js +5 -0
  60. package/dist/resources/rules.js +27 -0
  61. package/dist/resources/schema-fingerprint.json +8 -0
  62. package/dist/resources/schemas/AnalyzeImportQuery.json +51 -0
  63. package/dist/resources/schemas/ApplyMergePlanCommand.json +19 -0
  64. package/dist/resources/schemas/CreateBulkRowCommand.json +36 -0
  65. package/dist/resources/schemas/CreateDatasourceCommand.json +15 -6
  66. package/dist/resources/schemas/CreateDiscoveredEntitiesCommand.json +19 -8
  67. package/dist/resources/schemas/CreateEntityCommand.json +52 -12
  68. package/dist/resources/schemas/CreateEnvironmentCommand.json +31 -0
  69. package/dist/resources/schemas/CreateGlobalFunctionCommand.json +95 -0
  70. package/dist/resources/schemas/CreateImportPlanCommand.json +278 -0
  71. package/dist/resources/schemas/CreateMergePlanCommand.json +34 -0
  72. package/dist/resources/schemas/CreateMicrofunctionCommand.json +117 -0
  73. package/dist/resources/schemas/CreateMicrofunctionRuntimeCommand.json +51 -0
  74. package/dist/resources/schemas/CreateMicroserviceCommand.json +145 -3
  75. package/dist/resources/schemas/CreateQueryCommand.json +56 -3
  76. package/dist/resources/schemas/CreateRowCommand.json +38 -0
  77. package/dist/resources/schemas/CreateViewCommand.json +13 -10
  78. package/dist/resources/schemas/CreateWorkflowCommand.json +106 -14
  79. package/dist/resources/schemas/DataJobDto.json +267 -0
  80. package/dist/resources/schemas/ExportRowsCommand.json +172 -0
  81. package/dist/resources/schemas/Filter.json +3 -1
  82. package/dist/resources/schemas/GetRowsQuery.json +6 -1
  83. package/dist/resources/schemas/GlobalFunctionDto.json +89 -0
  84. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +249 -0
  85. package/dist/resources/schemas/ImportAnalysisDto.json +401 -0
  86. package/dist/resources/schemas/ImportPlanDto.json +260 -0
  87. package/dist/resources/schemas/ImportSampleDto.json +90 -0
  88. package/dist/resources/schemas/InvokeMicrofunctionCommand.json +25 -0
  89. package/dist/resources/schemas/PreviewMicroserviceCommand.json +135 -1
  90. package/dist/resources/schemas/PreviewQueryCommand.json +5 -2
  91. package/dist/resources/schemas/PreviewWorkflowCommand.json +45 -9
  92. package/dist/resources/schemas/ResolveMergeConflictsCommand.json +58 -0
  93. package/dist/resources/schemas/RevertMergePlanCommand.json +19 -0
  94. package/dist/resources/schemas/RunImportCommand.json +62 -0
  95. package/dist/resources/schemas/StepDto.json +34 -3
  96. package/dist/resources/schemas/UpdateBulkRowCommand.json +36 -0
  97. package/dist/resources/schemas/UpdateDatasourceCommand.json +15 -6
  98. package/dist/resources/schemas/UpdateEntityCommand.json +52 -11
  99. package/dist/resources/schemas/UpdateGlobalFunctionCommand.json +66 -0
  100. package/dist/resources/schemas/UpdateMicrofunctionCommand.json +121 -0
  101. package/dist/resources/schemas/UpdateMicrofunctionRuntimeCommand.json +54 -0
  102. package/dist/resources/schemas/UpdateMicroserviceCommand.json +147 -4
  103. package/dist/resources/schemas/UpdateQueryCommand.json +13 -3
  104. package/dist/resources/schemas/UpdateRowCommand.json +40 -0
  105. package/dist/resources/schemas/UpdateViewCommand.json +15 -10
  106. package/dist/resources/schemas/UpdateWorkflowCommand.json +106 -14
  107. package/dist/server.js +17 -1
  108. package/dist/tools/access.js +3 -3
  109. package/dist/tools/activities.js +40 -0
  110. package/dist/tools/applications.js +1 -1
  111. package/dist/tools/automations.js +76 -34
  112. package/dist/tools/common.js +55 -0
  113. package/dist/tools/components.js +16 -7
  114. package/dist/tools/datasources.js +83 -21
  115. package/dist/tools/dependencies.js +1 -1
  116. package/dist/tools/deployments.js +34 -2
  117. package/dist/tools/dtos.js +25 -12
  118. package/dist/tools/entities.js +113 -28
  119. package/dist/tools/environments.js +52 -0
  120. package/dist/tools/externalComponents.js +9 -3
  121. package/dist/tools/files.js +57 -42
  122. package/dist/tools/flows.js +205 -13
  123. package/dist/tools/folders.js +7 -2
  124. package/dist/tools/functions.js +331 -0
  125. package/dist/tools/globalFunctions.js +63 -0
  126. package/dist/tools/importSchemas.js +79 -0
  127. package/dist/tools/imports.js +241 -0
  128. package/dist/tools/layouts.js +103 -29
  129. package/dist/tools/merges.js +113 -0
  130. package/dist/tools/microfunctions.js +155 -0
  131. package/dist/tools/microservices.js +270 -40
  132. package/dist/tools/organizations.js +5 -6
  133. package/dist/tools/pages.js +421 -104
  134. package/dist/tools/platformInfo.js +155 -11
  135. package/dist/tools/projects.js +183 -33
  136. package/dist/tools/queries.js +32 -10
  137. package/dist/tools/revisions.js +94 -0
  138. package/dist/tools/rows.js +484 -50
  139. package/dist/tools/screenWrite.js +68 -0
  140. package/dist/tools/screens.js +28 -0
  141. package/dist/tools/templates.js +32 -5
  142. package/dist/tools/translations.js +24 -8
  143. package/dist/tools/views.js +20 -10
  144. package/dist/tools/workflows.js +56 -21
  145. package/package.json +7 -2
@@ -0,0 +1,231 @@
1
+ # Dal ve Merge Rehberi (environment dallanma)
2
+
3
+ Kendi başına çalışabileceğin bir kopya aç, orada değiştir, sonra `development`'a geri birleştir.
4
+ Deployment (`deployment_start`) bu işin dışındadır: o `development → production` yolu ve **insan
5
+ onaylıdır**. Buradaki tool'ların hiçbiri production'a yazmaz.
6
+
7
+ ## Politika (değişmez)
8
+
9
+ - **Merge hedefi her zaman dalın ebeveynidir.** Ebeveyn `development`'tır; başka bir hedef seçilemez.
10
+ - **Production'a merge eden tool yoktur.** Production'a giden tek yol insan onaylı deployment'tır.
11
+ - Sabit environment'lar (`development`, `production`) silinemez; `environment_delete` bunu HTTP'ye
12
+ gitmeden reddeder.
13
+
14
+ ## Akış
15
+
16
+ ```
17
+ environment_create {projectId, name} → 202, dal "creating"
18
+ environment_list {projectId} → state "ready" olana kadar (30-60 sn)
19
+ … tenant tool'larını environment: "<dal>" ile çağır (page_schema_patch, entity_patch, …)
20
+ merge_plan {projectId, sourceEnvironmentId} → 202, plan "planning"
21
+ merge_get {projectId, planId} → status "planned" olana kadar
22
+ merge_get {projectId, planId, view:"conflicts"} → çakışanları oku
23
+ merge_resolve{projectId, planId, resolutions[]} → her çakışmaya source|target seç
24
+ merge_apply {projectId, planId, message} → 202 (message ZORUNLU)
25
+ merge_get {projectId, planId} → status "applied"
26
+ environment_list {projectId} → dal listede yok, şeması düştü
27
+ ```
28
+
29
+ ## Dalda çalışmak
30
+
31
+ Dal adı `X-Environment` başlığının değeridir. Tenant tool'larına `environment: "odeme_akisi"`
32
+ geçmek yeterlidir; `DEFAULT_ENVIRONMENT` yalnız varsayılandır. Dal `ready` değilken o dalda
33
+ yazmaya çalışmak 400 döner — `environment_list` ile durumu doğrula.
34
+
35
+ Dal açılırken **yalnız tanımlar** kopyalanır. `includeRecords: true` verirsen projenin kendi
36
+ veritabanındaki **bütün** veri tablolarının satırları da gelir — entity'de kayıt taşıması ayarı
37
+ açık olmasa bile (çok dilli companion tablolar ve junction'lar dahil; `files`/`folders` ve audit
38
+ trail tabloları hariç, dış datasource'lara dokunulmaz). Kayıt taşıması ayarı deployment'ın
39
+ (`promote`) kuralıdır ve orada aynen geçerlidir. **Satırlar merge'de geri taşınmaz** — merge yalnız
40
+ tanım işidir.
41
+
42
+ Dalda `page_screenshot` **çalışır** (2026-09-09'dan beri); ayrıntısı bir sonraki bölümde.
43
+
44
+ ## Dalda görsel doğrulama
45
+
46
+ **Dalda kurulan sayfanın karesi dalda alınır** — `page_screenshot {..., environment: "<dal>"}`.
47
+ Studio'nun runtime rotasının üç şeridi vardır ve **ortamı URL belirler**:
48
+
49
+ | Ortam | Şerit |
50
+ |---|---|
51
+ | `production` | `/view/{proje}/{app}/{sayfa}` |
52
+ | `development` | `/dev/{proje}/{app}/{sayfa}` |
53
+ | dal | `/branch/{dal}/{proje}/{app}/{sayfa}` |
54
+
55
+ Sayfanın **bütün** istekleri o dala gider: sayfa şeması da, akışların uç çağrıları da. Yani kare
56
+ "yarı doğru" değildir — gördüğünüz ekran dalın gerçek ekranıdır.
57
+
58
+ Reddedilen tek şey **dal adı olamayacak bir ad**: harfle başlamayan, küçük harf/rakam/alt çizgi
59
+ dışında karakter taşıyan, 3-31 aralığının dışına çıkan ya da rezerve bir ad (`public`, `api`,
60
+ `pg_*` …). Projedeki dalları `environment_list` verir.
61
+
62
+ 2026-09-09 öncesinde bu çağrı **reddediliyordu**: runtime rotası dal adı taşımıyordu, ortam
63
+ modül içi bir store'dan geliyordu ve dal adıyla istenen kare development'ı gösterirdi. O günlerin
64
+ alışkanlığı olan "dalda `page_schema_get` + `page_runtime_get`, kare merge sonrasına" zinciri
65
+ hâlâ geçerli bir doğrulama yoludur, ama artık **zorunlu değildir**.
66
+
67
+ `page_schema_get` (komponent ağacı, prop ve olay bağları) ile `page_runtime_get` (akışlar,
68
+ değişkenler, çözülen ref'ler) kareyi tamamlar: kare ne çizildiğini, bu ikisi neden öyle
69
+ çizildiğini söyler.
70
+
71
+ ## Planı okumak
72
+
73
+ `merge_get` üç görünüm sunar; varsayılan `conflicts`:
74
+
75
+ | view | ne döner |
76
+ |---|---|
77
+ | `summary` | yalnız sayaçlar (`added/updated/deleted/conflicts/unresolved/dataRisk`) |
78
+ | `conflicts` | yalnız çakışan kayıtlar ve onların çakışan elemanları |
79
+ | `full` | değişen her kayıt ve her eleman |
80
+
81
+ `items[]` yalnız **değişen** kayıtları taşır. Her kayıtta:
82
+
83
+ - `kind`: `add` | `update` | `delete` | `conflict`
84
+ - `dataRisk`: entity kaleminde veri riski var — **sebep `dataRiskReasons[]` içindedir**
85
+ - `derivedFromKey`: kalem OTOMATİK ÜRETİLMİŞ bir kayıtsa (varsayılan DTO) kaynağının anahtarı
86
+ - `elements[]`: `path`, `kind`, `base`, `source` (dal), `target` (development), `resolution`
87
+
88
+ `dataRisk` bir **uyarıdır, apply'ı bloklamaz**; üç sebepten biriyle doğrudur:
89
+
90
+ | `dataRiskReasons` | Ne demek |
91
+ |---|---|
92
+ | `field-removed` | Alan siliniyor |
93
+ | `field-narrowed` | Tip / `nullable` / `unique` daraltılıyor |
94
+ | `not-null-without-default-on-populated-table` | **Hedefte satır varken** varsayılansız zorunlu alan ekleniyor — bu apply'ı DDL aşamasında düşürür. Alanı `nullable` yapın ya da `defaultValueType: "default-value"` + `defaultValue` verin |
95
+
96
+ Son satır 2026-09-09'da eklendi; öncesinde bu durum `dataRisk: 0` diyordu ve risk ancak apply
97
+ denenerek öğreniliyordu. Hedef tablo **boşsa** aynı alan riskli sayılmaz.
98
+
99
+ `derivedFromKey` dolu olan kalemi ayrıca çözmeye çalışmayın: kaynağını (entity ya da query)
100
+ çözdüğünüzde aynı yoldaki çakışması **kendiliğinden** aynı tarafa çözülür. Entity adını değiştiren
101
+ bir merge'de entity ve onun varsayılan DTO'su böylece zıt çözülemez.
102
+
103
+ `add` / `update` / `delete` elemanları **otomatik alınır** — karar istemezler. Yalnız `conflict` ve
104
+ `order-conflict` elemanları `merge_resolve` bekler.
105
+
106
+ ## Çakışma çözmek
107
+
108
+ ```json
109
+ { "itemKey": "page:8f1c…", "path": "components[elementId=btn_save].props[name=label].ref", "choice": "source" }
110
+ ```
111
+
112
+ `path` boş bırakılırsa o kaydın **tüm** çakışmaları aynı tarafa çözülür. `source` = dal,
113
+ `target` = development.
114
+
115
+ `merge_resolve` **özet döner** — `{ planId, status, summary, resolved }`. Planın kendisi yanıtta
116
+ yoktur; kalan çakışmalar için `merge_get {planId, view:"conflicts"}` çağırın.
117
+ `summary.unresolved` 0 olduğunda `merge_apply` yolu açıktır.
118
+
119
+ ## Apply'ın reddettiği üç durum
120
+
121
+ | Durum | Kod | Ne yapmalı |
122
+ |---|---|---|
123
+ | Çözülmemiş çakışma var | 409 | `merge_get view:"conflicts"` → `merge_resolve` → tekrar `merge_apply` |
124
+ | Development plan alındığından beri değişti | 409 | `merge_plan` ile **yeniden planla**; eski planı uygulama |
125
+ | Plan 24 saatten eski | 400 | yeniden planla |
126
+
127
+ Aynı `merge_apply` çağrısını tekrarlamak sonucu değiştirmez — 409 geçici bir hata değildir.
128
+
129
+ ## Mesaj zorunludur
130
+
131
+ `merge_apply` mesajsız çalışmaz. Mesaj plana yazılır, plan uygulandıktan sonra da durur ve
132
+ geçmişte bu mesajla görünür — git'teki merge commit mesajının karşılığıdır.
133
+
134
+ - Boş ya da yalnız boşluktan oluşan mesaj **şema katmanında** reddedilir; istek platforma hiç gitmez.
135
+ - En fazla 200 karakter.
136
+ - Kalıp: `<dal> → development: <amaç>`. Ne yaptığını yaz, "merge" yazma.
137
+
138
+ Gateway senin yerine mesaj **uydurmaz**: ne değiştirdiğini bilen sensin.
139
+
140
+ ## Geri almak
141
+
142
+ Uygulanmış bir merge silinmez, **ters bir planla** geri alınır:
143
+
144
+ ```
145
+ merge_revert {projectId, planId, message} → 202, ters plan planning
146
+ merge_get {projectId, planId: <ters plan>} → status planned olana kadar
147
+ merge_apply {projectId, planId: <ters plan>, message}
148
+ ```
149
+
150
+ Bittiğinde ters plan `applied`, kaynak plan `reverted` olur; ikisi de geçmişte durur.
151
+
152
+ Üç şey normal merge'den farklıdır:
153
+
154
+ - **Sütunların anlamı terstir.** Ters planın `elements` satırlarında `source` merge **öncesi**
155
+ değer, `target` **şimdiki** değerdir. Bir kaydı merge'den sonra elle değiştiren biri olduysa o
156
+ satır `conflict` gelir; `source` seçmek geri almayı, `target` seçmek o kaydı olduğu gibi bırakmayı
157
+ seçer.
158
+ - **Pencere vardır.** `RevertWindowDays` (varsayılan 7 gün) dolduğunda 400 döner, çünkü merge
159
+ öncesi anlık görüntü de aynı pencereyle silinir. Uygun bir plan için `merge_list status:'applied'`.
160
+ - **Ters planın ters planı yoktur.** `kind=revert` bir planı geri almaya çalışmak 400 verir; aynı
161
+ değişikliği tekrar istiyorsanız dalı yeniden merge edin.
162
+
163
+ Geri alma reddedildiğinde **mesaj hangi kapıya takıldığını söyler** — üçünü karıştırmayın
164
+ (2026-09-09'dan beri üç ayrı cümle; öncesinde üçü de aynı cümleyi veriyordu):
165
+
166
+ | Ne denendi | Mesaj ne der | Ne yapılır |
167
+ |---|---|---|
168
+ | `kind=revert` bir planı geri almak | "A revert plan cannot itself be reverted" | Ters planın geri aldığı **kaynak planı** geri alın ya da dalı yeniden merge edin |
169
+ | Hiç uygulanmamış plan (`planned`, `failed`, `discarded`) | "this plan is '<durum>'" — planın **gerçek durumu** cümlede | `merge_list status:'applied'` ile uygulanmış planı seçin |
170
+ | Zaten geri alınmış plan | aynı cümle, **`this plan is 'reverted'`** | Geri alma zaten yapılmış; ters planı `merge_get` ile görün |
171
+
172
+ ## Geçmişi okumak
173
+
174
+ Merge sonrası hedefte dokunulan kayıtlar revizyon defterine `source: merge` ile düşer:
175
+ `revision_list {projectId, module, recordId}` bir kaydın merge ile mi yoksa elle mi değiştiğini
176
+ söyler, `revision_diff` ise ne değiştiğini.
177
+
178
+
179
+ `merge_list` projenin merge planlarını en yeniden eskiye verir:
180
+
181
+ ```
182
+ merge_list {projectId} → son planlar (her durumdan)
183
+ merge_list {projectId, status:"applied"} → uygulanmış merge'ler
184
+ merge_list {projectId, environmentId:"<env>"} → o environment'ı kaynak ya da hedef alan planlar
185
+ ```
186
+
187
+ `items[]` bu uçta **her zaman boştur** — bir planın değişiklik listesi için `merge_get`.
188
+ Satırda `message`, `createdBy` (planı alan), `appliedBy` (uygulayan), `appliedAt` ve
189
+ `summary` sayaçları gelir. Sayfalama `pageIndex` / `pageLength` ile.
190
+
191
+ Bir kaydın neden değiştiğini ararken sıra: `merge_list status:"applied"` → ilgili satırın
192
+ `id`'si → `merge_get {planId, view:"full"}`.
193
+
194
+ `activity_list` daha geniştir: dal açma/silme, plan alma/çözme/uygulama ve dağıtım aynı akışta.
195
+
196
+ ```
197
+ activity_list {projectId} → tüm geçmiş, en yeni önce
198
+ activity_list {projectId, kind:"merge.applied"} → yalnız uygulanmış merge'ler
199
+ activity_list {projectId, environmentId:"<env>"} → o dalın hikâyesi
200
+ activity_list {projectId, userId:"<id>"} → bir kişinin yaptıkları
201
+ ```
202
+
203
+ Her satırda `actor`, `actorSource` (`human` | `ai` | `system`) ve türe göre değişen bir
204
+ `summary` vardır. **Bu gateway üzerinden yaptığın her iş `actorSource: "ai"` olarak düşer** —
205
+ istekler `X-Client: mcp` başlığı taşır. Merge satırlarında `subjectId` plan id'sidir;
206
+ ayrıntı için `merge_get`.
207
+
208
+ ## Merge bittikten sonra
209
+
210
+ **Cache için elle bir şey yapmanız gerekmez (2026-09-09'dan beri).** Merge, dokunduğu entity'lerin
211
+ `entityId:` / `entityApi:` / `entityRelationId:` anahtarlarını hedef ortamda **merge biter bitmez**
212
+ yeniden kurar; dalda kurulmuş join'li bir microservice `development`'ta ilk çağrıda çalışır.
213
+ Öncesinde entity anahtarları yalnız geçersizleştiriliyor, yeniden kurulmuyordu ve uç
214
+ `Sequence contains no matching element` ile **500** veriyordu — kurtulmanın tek yolu entity'ye
215
+ anlamsız bir `entity_patch` atmaktı. Cache yenileme hatası merge'i düşürmez: `cacheError`'a yazılır,
216
+ plan `applied` kalır.
217
+
218
+ - `applied` → dal `merged` olur ve **şeması düşer**; `environment_list` artık göstermez.
219
+ - `applied-with-drift` → dal ve şeması **durur**. `verification.driftTables` dal ile development
220
+ arasında hâlâ farklı olan tabloları listeler; incelenmeden dal silinmez.
221
+ - `failed` → plan `failed`, dal `ready`'ye döner. Dal ve içindeki iş kaybolmaz; yeniden planlanır.
222
+
223
+ ## Sınırlar
224
+
225
+ - Projede aynı anda **tek** açık merge planı olur. Yenisini istemeden önce `merge_apply` ya da
226
+ `merge_discard`.
227
+ - Merge sürerken dal ve development'a yazma kilitlidir; **diğer dallar etkilenmez**.
228
+ - Proje başına açık dal sayısı sınırlıdır (varsayılan 5) — sınır bağlantı bütçesidir, ürün kararı
229
+ değil.
230
+ - Dal adı `^[a-z][a-z0-9_]{2,30}$` kuralına uyar ve şema adı olur; `development`, `production`,
231
+ `public`, `pg_*` gibi adlar rezervedir.
@@ -0,0 +1,166 @@
1
+ # Microfunction Rehberi
2
+
3
+ Microfunction, kullanıcının yazdığı **tek bir fonksiyonun** platformun dışında, kendi
4
+ runtime'ında koşmasıdır: Node ya da Python kodu kaydedilir, yayınlanır, workflow adımı onu
5
+ çağırır ve çıktısı sonraki adımlara akar. Platformun JavaScript ifade motoru (global function'lar,
6
+ code step) sürecin İÇİNDE koşar; microfunction ise ayrı bir runtime'dadır — bu yüzden ağır iş,
7
+ üçüncü parti kütüphane ve zaman aşımı riski taşıyan işler oraya taşınır.
8
+
9
+ Kayıtlar **proje + environment** kapsamlıdır (`development` ile `production` ayrı kayıtlardır);
10
+ `microfunction_list` bir uygulamaya değil projeye bakar. Süzme ve sayfalama uçta yapılır:
11
+ `searchTerm` ad, slug ve açıklamada arar, `status` durum süzgecidir, `pageIndex`/`pageLength` sayfa
12
+ verir (gateway kendi çağrısında 200 gönderir; platform varsayılanı 10'dur).
13
+
14
+ ## Ne zaman microfunction, ne zaman code step
15
+
16
+ | İhtiyaç | Doğru yer |
17
+ |---|---|
18
+ | Birkaç satır dönüşüm, alan eşleme, koşul | `code` step / ifade (aynı süreç, en ucuz) |
19
+ | İfadelerde çıplak adla çağrılacak yardımcı | global function (`global_function_create`, JS) |
20
+ | Kütüphane gerektiren iş (kriptografi, PDF, görüntü, parse) | microfunction (zip kaynak) |
21
+ | Python gereken iş | microfunction — platformun ifade motoru YALNIZ JavaScript'tir |
22
+ | Uzun süren/CPU yiyen iş | microfunction (kendi bütçesi, API sürecini bloke etmez) |
23
+
24
+ Global function'lar JS'tir ve Python fonksiyonlarına bağlanmaz; microfunction çağrısı yalnız
25
+ workflow adımından (ve test için `microfunction_invoke`'tan) yapılır.
26
+
27
+ ## Çalışma zamanı sözleşmesi (protocol 1)
28
+
29
+ Kullanıcı kodu **tek bir handler** dışa aktarır. Inline kaynakta dosya adı SABİTTİR: Node'da
30
+ `function.js`, Python'da `function.py`; entrypoint `function.handler`'dır ve gönderilmez.
31
+
32
+ ```js
33
+ // node — function.js
34
+ exports.handler = async (args, context) => {
35
+ return { total: args.a + args.b, environment: context.environment }
36
+ }
37
+ ```
38
+
39
+ ```python
40
+ # python — function.py
41
+ def handler(args, context):
42
+ return {"total": args["a"] + args["b"], "environment": context["environment"]}
43
+ ```
44
+
45
+ - `args` — adımın `rule.expression`'ından üretilen argüman nesnesi. Fonksiyonun
46
+ `parameterDtoId`'si yoksa `{}` gelir.
47
+ - `context` — **salt okunur anlık görüntü**. İçine yazmak hiçbir şeyi değiştirmez; akışa dönen
48
+ tek kanal fonksiyonun DÖNÜŞ DEĞERİdir.
49
+
50
+ `context` şekli (ölçüldü, `MicrofunctionStep.BuildContext`):
51
+
52
+ ```jsonc
53
+ {
54
+ "input": {}, // akışın parameterDto girdisi
55
+ "variables": {}, // workflow değişkenleri (middleware'in kurduğu 'user' dahil)
56
+ "steps": { "<adım adı>": { "data": {}, "error": { "code": null, "message": null, "type": null } } },
57
+ "user": { "id": "…", "email": "…", "roles": [] },
58
+ "request": { "headers": {}, "queryString": {} },
59
+ "triggerSource": {},
60
+ "language": "tr",
61
+ "project": "<proje slug'ı>",
62
+ "environment": "development"
63
+ }
64
+ ```
65
+
66
+ **`request` yalnız `headers` + `queryString` taşır** ve `authorization` · `cookie` ·
67
+ `x-impersonated-user-id` başlıkları AYIKLANIR (ölçüldü 2026-09-10) — token'ı fonksiyona taşımaya
68
+ çalışmayın, taşınmaz. Çerez okuma yolu yoktur.
69
+
70
+ Yanıt zarfını shim üretir; `microfunction_invoke` bunu olduğu gibi döner:
71
+
72
+ ```jsonc
73
+ { "protocol": 1, "ok": true, "output": { "total": 3 }, "error": null, "logs": [], "durationMs": 12 }
74
+ ```
75
+
76
+ - `ok: false` ⇒ `error: { type, message, stack }` ve adım **fail dalına** düşer.
77
+ - `logs` yalnız `preview: true` çağrılarında dolar (`console.log` / `print` yakalanır). Normal
78
+ koşumda log toplanmaz — hata ayıklarken `microfunction_invoke(preview: true)` kullanın.
79
+ - İstek gövdesi (args + context) 5 MB'ı aşarsa adım `MicrofunctionPayloadTooLargeException` ile
80
+ fail dalına düşer: bütün tabloyu fonksiyona geçirmeyin, işi fonksiyona taşıyacak kadarını geçirin.
81
+
82
+ ## Yaşam döngüsü: kayıt yayınlanmadan ÇALIŞMAZ
83
+
84
+ ```
85
+ draft ──publish──▶ publishing ──▶ published ──update──▶ published + hasUnpublishedChanges
86
+ └────────▶ publish-failed (publishError)
87
+ ```
88
+
89
+ 1. `microfunction_create` kaydı **draft** açar. `publish: true` verirseniz aynı çağrıda yayın istenir.
90
+ 2. Yayın **asenkrondur**: çağrı `publishing` döner, kuyruk paketi runtime'a kurar ve bir `probe`
91
+ çağrısıyla duman testi yapar. Sözdizimi/import hatası **yayın anında** `publish-failed` olur —
92
+ koşumda değil. Durumu `microfunction_get` ile birkaç saniye arayla okuyun.
93
+ 3. Yayındaki kaydı `microfunction_update` ile değiştirirseniz runtime **ESKİ sürümü koşmaya
94
+ devam eder**: `hasUnpublishedChanges: true` olur (`revision` ≠ `publishedRevision`). Yeni kodu
95
+ canlıya almak için `microfunction_publish`.
96
+ 4. `microfunction_delete` runtime'daki fonksiyonu da kaldırır; bir workflow adımı kaydı
97
+ kullanıyorsa 400 ile reddedilir.
98
+
99
+ ## Workflow adımı (WF-MF-001)
100
+
101
+ Adım tipi `microfunction`; `workflow`, `automation` ve `middleware` akışlarının hepsinde
102
+ kullanılabilir. Kuralı iki alan taşır:
103
+
104
+ ```jsonc
105
+ {
106
+ "id": "<GUID>",
107
+ "name": "toplam",
108
+ "type": "microfunction",
109
+ "description": "İki sayıyı microfunction'da toplar.",
110
+ "rule": {
111
+ "microfunctionId": "<published kaydın id'si>",
112
+ "expression": "({ a: input.a, b: input.b })"
113
+ },
114
+ "branches": [
115
+ { "id": "<GUID>", "name": "success", "type": "success", "nextStepId": "<sonraki adım>" },
116
+ { "id": "<GUID>", "name": "fail", "type": "fail", "nextStepId": "<hata adımı>" }
117
+ ]
118
+ }
119
+ ```
120
+
121
+ - `microfunctionId` **zorunludur** ve gateway kaydı çağrıdan önce okur: durum `published` değilse
122
+ (ya da kayıt o ortamda yoksa) istek platforma GÖNDERİLMEZ. Adım taslak bir fonksiyona bağlıysa
123
+ akış kaydedilir, koşar ve sessizce fail dalına düşer (`MicrofunctionNotPublishedException`) —
124
+ ön-denetimin varlık sebebi budur.
125
+ - `expression` argüman nesnesini üreten JavaScript ifadesidir; şemayı `microfunction_get`
126
+ çıktısındaki `parameterScheme` verir. Fonksiyonun parametre DTO'su varken ifade boşsa gateway
127
+ uyarır (fonksiyon `args` içinde hiçbir alan göremez).
128
+ - Çıktı sonraki adımlara `Steps.<adım adı>.data` ile akar; şemasını `returnDtoId` belirler.
129
+ - Adım **senkrondur**: akış fonksiyon dönene kadar bekler. Zaman aşımı fonksiyonun
130
+ `timeoutSeconds` bütçesidir, aşılırsa fail dalı.
131
+ - `workflow_preview` adımı GERÇEK runtime'da koşturur; preview'ın rollback garantisi fonksiyonun
132
+ dış dünyada yaptığı işi geri ALMAZ.
133
+
134
+ Tam gövde örneği: `ngapps://examples/microfunction-node-sum`.
135
+
136
+ ## Built-In ve AWS Lambda farkı
137
+
138
+ | | `built-in` | `aws-lambda` |
139
+ |---|---|---|
140
+ | Nerede koşar | Platformun kendi Fission kümesi | Müşterinin AWS hesabı |
141
+ | Runtime kaydı | YOK — `runtimeId` verilmez | `microfunction_runtime_create` ile zorunlu |
142
+ | Zaman aşımı tavanı | 300 s | 900 s |
143
+ | `memoryMb` | kaydedilir, küme limiti geçerlidir | gerçekten uygulanır |
144
+ | Ölçüm alanları | `billedDurationMs`/`memoryUsedMb` boş | Lambda raporundan dolar |
145
+
146
+ `azure-functions` enum'da tanımlıdır ama v1'de reddedilir (Faz 2). Lambda hesabı kimlik
147
+ bilgilerini düz metin tutar (Datasource emsali) ve DTO'da maskeli döner — dar yetkili bir IAM
148
+ kullanıcısı verin, `roleArn` fonksiyonun koşacağı execution rolüdür ve **zorunludur** —
149
+ deseni tutmayan hesap gateway'de durur (MFR-001, block). Kaydettikten sonra
150
+ `microfunction_runtime_test_connection` ile doğrulayın.
151
+
152
+ ## Sınırlar (v1)
153
+
154
+ - **Bağımlılık build'i yok:** inline kod yalnız standart kütüphanedir; bağımlılık zip içinde gelir.
155
+ - **MCP'den zip yükleme ve indirme yok** (`sourceKind: 'archive'` kaydı açılabilir, dosya
156
+ Studio'dan yüklenir) — Faz 2. Yüklenmiş zip platform ucunda okunabilir durumdadır
157
+ (`GET /{proje}/microfunctions/{id}/archive`, `application/zip`) ve Studio inspector'ında bir
158
+ indirme düğmesi taşır.
159
+ - `timeoutSeconds` ve `memoryMb` komutta non-nullable int'tir: **göndermezseniz 0 gider ve platform
160
+ 422 döner.** Gateway değer uydurmaz, eksikliği çağrıdan önce söyler (MF-001, block; ürün
161
+ varsayılanları 30 / 256). Aynı kural provider ↔ `runtimeId` eşleşmesini, inline kaynakta `code`
162
+ zorunluluğunu ve env anahtarlarını da çağrıdan önce denetler.
163
+ - Env değişkenleri düz metin saklanır; anahtar `^[A-Z_][A-Z0-9_]*$`, toplam ≤ 4 KB. Sır yönetimi
164
+ için kullanmayın.
165
+ - Asenkron (fire-and-forget) çağrı, preview ekranı, microservice'in doğrudan microfunction kaynağı
166
+ olması ve metering Faz 2'dedir.