@appaflytech/zeyrek-ai-mcp 0.0.28 → 0.0.31

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 (203) 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 +500 -35
  9. package/dist/knowledge/componentEvents.js +132 -7
  10. package/dist/knowledge/connectDataBind.js +819 -0
  11. package/dist/knowledge/connectDataDefinition.js +341 -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 +59 -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 +859 -0
  20. package/dist/knowledge/mobileComponentEvents.js +239 -0
  21. package/dist/knowledge/normalize.js +236 -67
  22. package/dist/knowledge/outlines.js +36 -0
  23. package/dist/knowledge/platform/lint.js +385 -0
  24. package/dist/knowledge/platform/mobile.js +142 -0
  25. package/dist/knowledge/platform/mobileLayoutLint.js +324 -0
  26. package/dist/knowledge/platform/mobileRules.js +231 -0
  27. package/dist/knowledge/platform/mobileSpacing.js +82 -0
  28. package/dist/knowledge/platform/mobileTabs.js +108 -0
  29. package/dist/knowledge/platform/nativeBoxModel.js +44 -0
  30. package/dist/knowledge/platform/profile.js +25 -0
  31. package/dist/knowledge/platform/resolve.js +122 -0
  32. package/dist/knowledge/platform/web.js +39 -0
  33. package/dist/knowledge/policy.js +18 -4
  34. package/dist/knowledge/process.js +510 -0
  35. package/dist/knowledge/reservedTables.js +79 -0
  36. package/dist/knowledge/rowFilter.js +43 -0
  37. package/dist/knowledge/rules.js +366 -21
  38. package/dist/knowledge/schemaGuard.js +11 -0
  39. package/dist/knowledge/styleResolve.js +50 -4
  40. package/dist/knowledge/styleResolveNative.js +527 -0
  41. package/dist/knowledge/themeResolve.js +3 -3
  42. package/dist/observability/trace.js +6 -3
  43. package/dist/platform/argumentAliases.js +128 -0
  44. package/dist/platform/bodyFile.js +103 -0
  45. package/dist/platform/capture/actions.js +333 -0
  46. package/dist/platform/capture/browser.js +1 -0
  47. package/dist/platform/{screenshot.js → capture/capture.js} +105 -519
  48. package/dist/platform/capture/console-log.js +122 -0
  49. package/dist/platform/capture/index.js +11 -0
  50. package/dist/platform/capture/readiness.js +103 -0
  51. package/dist/platform/capture/summary.js +77 -0
  52. package/dist/platform/capture/target.js +5 -0
  53. package/dist/platform/capture/targets/studio-mobile.js +15 -0
  54. package/dist/platform/capture/targets/studio-web.js +5 -0
  55. package/dist/platform/diagnostics.js +10 -4
  56. package/dist/platform/domSummary.js +1 -1
  57. package/dist/platform/errors.js +162 -10
  58. package/dist/platform/http.js +29 -8
  59. package/dist/platform/impersonation.js +45 -0
  60. package/dist/platform/jsonArray.js +24 -0
  61. package/dist/platform/responses.js +39 -5
  62. package/dist/platform/schemaReadMemory.js +60 -0
  63. package/dist/platform/secrets.js +17 -1
  64. package/dist/platform/strictArguments.js +68 -12
  65. package/dist/platform/tokenVault.js +187 -4
  66. package/dist/resources/examples/bpm-gorev-kontrol.json +294 -0
  67. package/dist/resources/examples/bpm-iso-dokuman.json +228 -0
  68. package/dist/resources/examples/bpm-satinalma.json +376 -0
  69. package/dist/resources/examples/connect-data-convert-verify.json +107 -0
  70. package/dist/resources/examples/connect-data-dropdown-roles.json +66 -0
  71. package/dist/resources/examples/connect-data-edit-m2m.json +73 -0
  72. package/dist/resources/examples/connect-data-query-params.json +50 -0
  73. package/dist/resources/examples/connect-data-table-entity.json +147 -0
  74. package/dist/resources/examples/connect-data-workflow-microservice.json +65 -0
  75. package/dist/resources/examples/middleware-authenticate.json +1 -1
  76. package/dist/resources/examples/mobile-app-shell-drawer.json +243 -0
  77. package/dist/resources/examples/mobile-app-shell-stack.json +157 -0
  78. package/dist/resources/examples/mobile-app-shell-tab.json +208 -0
  79. package/dist/resources/examples/mobile-form-screen.json +365 -0
  80. package/dist/resources/examples/mobile-list-detail-form.json +672 -0
  81. package/dist/resources/examples/page-detail-profile.json +2 -1
  82. package/dist/resources/examples/page-dynamic-form.json +3 -2
  83. package/dist/resources/examples/page-flex-sections.json +1 -1
  84. package/dist/resources/examples/page-html-embed.json +1 -1
  85. package/dist/resources/examples/workflow-basic.json +8 -2
  86. package/dist/resources/guides/access.md +810 -0
  87. package/dist/resources/guides/bpm.md +691 -0
  88. package/dist/resources/guides/case.md +153 -0
  89. package/dist/resources/guides/component.md +92 -5
  90. package/dist/resources/guides/decision.md +185 -0
  91. package/dist/resources/guides/entity.md +50 -8
  92. package/dist/resources/guides/expressions.md +14 -5
  93. package/dist/resources/guides/functions.md +1 -1
  94. package/dist/resources/guides/getting-started.md +38 -1
  95. package/dist/resources/guides/layout.md +11 -7
  96. package/dist/resources/guides/merge.md +37 -3
  97. package/dist/resources/guides/microservice.md +87 -2
  98. package/dist/resources/guides/middleware.md +68 -4
  99. package/dist/resources/guides/mobile-layout.md +193 -0
  100. package/dist/resources/guides/mobile.md +495 -0
  101. package/dist/resources/guides/page.md +456 -75
  102. package/dist/resources/guides/theme.md +8 -2
  103. package/dist/resources/guides/translation.md +1 -1
  104. package/dist/resources/guides/workflow.md +58 -1
  105. package/dist/resources/read.js +41 -0
  106. package/dist/resources/rules.js +11 -5
  107. package/dist/resources/schema-fingerprint.json +7 -5
  108. package/dist/resources/schemas/AccessExplanationDto.json +144 -0
  109. package/dist/resources/schemas/AccessMatrixDto.json +170 -0
  110. package/dist/resources/schemas/AccessPermissionDto.json +57 -0
  111. package/dist/resources/schemas/AccessPolicyDto.json +223 -0
  112. package/dist/resources/schemas/AccessResourceDto.json +86 -0
  113. package/dist/resources/schemas/AppSessionDto.json +53 -0
  114. package/dist/resources/schemas/ConnectDataDescribeDto.json +344 -0
  115. package/dist/resources/schemas/ConnectDataRequestModel.json +202 -0
  116. package/dist/resources/schemas/ConnectDataResultDto.json +421 -0
  117. package/dist/resources/schemas/ConnectorCredentialDto.json +70 -0
  118. package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +37 -0
  119. package/dist/resources/schemas/CreateAccessPolicyCommand.json +209 -0
  120. package/dist/resources/schemas/CreateDecisionCommand.json +221 -0
  121. package/dist/resources/schemas/CreateEntityCommand.json +118 -0
  122. package/dist/resources/schemas/CreateMicroserviceCommand.json +13 -1
  123. package/dist/resources/schemas/CreateProcessDefinitionCommand.json +1337 -0
  124. package/dist/resources/schemas/CreateQueryCommand.json +4 -0
  125. package/dist/resources/schemas/CreateWorkflowCommand.json +146 -1
  126. package/dist/resources/schemas/DataJobDto.json +6 -1
  127. package/dist/resources/schemas/DecisionDto.json +302 -0
  128. package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +28 -0
  129. package/dist/resources/schemas/ExplainAccessQuery.json +33 -0
  130. package/dist/resources/schemas/GenerateProcessDocumentCommand.json +116 -0
  131. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +21 -1
  132. package/dist/resources/schemas/MicroserviceDto.json +15 -3
  133. package/dist/resources/schemas/OrganizationProjectDto.json +335 -0
  134. package/dist/resources/schemas/OrganizationSchemaDto.json +196 -0
  135. package/dist/resources/schemas/OrganizationSchemaVersionDto.json +207 -0
  136. package/dist/resources/schemas/PatchProcessDefinitionCommand.json +76 -0
  137. package/dist/resources/schemas/PreviewMicroserviceCommand.json +10 -1
  138. package/dist/resources/schemas/PreviewWorkflowCommand.json +25 -1
  139. package/dist/resources/schemas/ProcessDefinitionDto.json +1480 -0
  140. package/dist/resources/schemas/ProcessSimulationDto.json +96 -0
  141. package/dist/resources/schemas/SaveConnectorCredentialCommand.json +90 -0
  142. package/dist/resources/schemas/SaveProcessEventSourceCommand.json +61 -0
  143. package/dist/resources/schemas/SaveProcessMailSourceCommand.json +89 -0
  144. package/dist/resources/schemas/SignProcessTaskCommand.json +73 -0
  145. package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +92 -0
  146. package/dist/resources/schemas/StepDto.json +25 -1
  147. package/dist/resources/schemas/UpdateAccessPolicyCommand.json +209 -0
  148. package/dist/resources/schemas/UpdateDecisionCommand.json +216 -0
  149. package/dist/resources/schemas/UpdateEntityCommand.json +118 -0
  150. package/dist/resources/schemas/UpdateMicroserviceCommand.json +13 -1
  151. package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +1357 -0
  152. package/dist/resources/schemas/UpdateQueryCommand.json +4 -0
  153. package/dist/resources/schemas/UpdateViewCommand.json +0 -2
  154. package/dist/resources/schemas/UpdateWorkflowCommand.json +146 -1
  155. package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +1339 -0
  156. package/dist/server.js +27 -1
  157. package/dist/tools/access.js +369 -2
  158. package/dist/tools/accessOperations.js +135 -0
  159. package/dist/tools/accessPolicies.js +170 -0
  160. package/dist/tools/accessRuntime.js +203 -0
  161. package/dist/tools/applications.js +60 -3
  162. package/dist/tools/bpm.js +343 -0
  163. package/dist/tools/bpmGovernance.js +266 -0
  164. package/dist/tools/bpmOperations.js +230 -0
  165. package/dist/tools/bpmReporting.js +154 -0
  166. package/dist/tools/bpmRouting.js +150 -0
  167. package/dist/tools/bpmRuntime.js +396 -0
  168. package/dist/tools/case.js +178 -0
  169. package/dist/tools/caseRuntime.js +89 -0
  170. package/dist/tools/common.js +7 -0
  171. package/dist/tools/components.js +118 -14
  172. package/dist/tools/connectData.js +449 -0
  173. package/dist/tools/connectors.js +193 -0
  174. package/dist/tools/datasources.js +3 -3
  175. package/dist/tools/decisions.js +206 -0
  176. package/dist/tools/dependencies.js +1 -1
  177. package/dist/tools/deployments.js +38 -3
  178. package/dist/tools/designSchemaPatch.js +34 -9
  179. package/dist/tools/dtos.js +36 -5
  180. package/dist/tools/entities.js +79 -12
  181. package/dist/tools/externalComponents.js +26 -5
  182. package/dist/tools/flows.js +122 -14
  183. package/dist/tools/folders.js +1 -1
  184. package/dist/tools/imports.js +5 -2
  185. package/dist/tools/layouts.js +50 -17
  186. package/dist/tools/merges.js +2 -2
  187. package/dist/tools/microservices.js +77 -25
  188. package/dist/tools/mobile.js +221 -0
  189. package/dist/tools/modules.js +48 -0
  190. package/dist/tools/organizationStructure.js +137 -0
  191. package/dist/tools/pages.js +465 -98
  192. package/dist/tools/platformInfo.js +27 -8
  193. package/dist/tools/profileWrite.js +92 -0
  194. package/dist/tools/projects.js +71 -9
  195. package/dist/tools/rows.js +69 -13
  196. package/dist/tools/schemaOps.js +61 -1
  197. package/dist/tools/screenWrite.js +37 -8
  198. package/dist/tools/screens.js +95 -5
  199. package/dist/tools/templates.js +26 -1
  200. package/dist/tools/translations.js +1 -1
  201. package/dist/tools/variables.js +11 -5
  202. package/dist/tools/workflows.js +10 -5
  203. package/package.json +1 -1
@@ -14,8 +14,10 @@ Uydurma fonksiyon adı runtime'da `X is not defined` 500'üdür — yalnız bura
14
14
 
15
15
  **Değişkenler:** step çıktıları (`<stepAdı>.data`), middleware değişkenleri (`user`,
16
16
  `settings`, `permissions`… — `workflow_middleware_variables` ile keşfet), HTTP bağlamı:
17
- `cookie`, `header`, `queryString`, `body`, `triggerSource`/`context` (tetikleyen ucun
18
- type/name/roles/impersonatedUserId'ı). Gövde bir JSON **nesnesi** ise `body.alan` diye okunur,
17
+ `cookie`, `header`, `queryString`, `body`, `triggerSource` (tetikleyen ucun
18
+ type/id/name/slug/roles/pathAndQuery'si — emekliye ayrılacak) ve `context`
19
+ (type/name/roles/path/impersonatedUserId/language). **Kimlik devri yalnız `context.impersonatedUserId`**'dedir;
20
+ `triggerSource`'ta bu alan yoktur (MW-006). Gövde bir JSON **nesnesi** ise `body.alan` diye okunur,
19
21
  gövde bir JSON **dizisi** ise `body[0].alan` diye — 2026-09-04 öncesinde nesne gövde de diziye
20
22
  sarılıyordu ve `body.alan` sessizce `undefined` dönüyordu, bu yüzden gövdeye bakan yetki kapıları
21
23
  açık kalıyordu. Workflow'da istek girdisi `input.`, automation'da
@@ -97,14 +99,16 @@ dalından devam eder.
97
99
  |---|---|
98
100
  | `Page` | `Page.user`, `Page.variables`, `Page.components`, `Page.properties`, `Page.queryParams`, `Page.authorized(roles)` |
99
101
  | **Komponent adları** | Her komponent adıyla doğrudan değişkendir: `specialties_table.rows = data` hem prop'u yazar hem UI'ı günceller (change event). Addaki `-` silinir: `tickets-table` → `ticketstable` |
100
- | `state.page` / `state.app` | Kalıcı state (oku/yaz): `state.page.selectedId = row.id`. **Tanımlı değişkenler de buradadır:** `variable_create` ile yazılan her `key` sayfa düzeyinde `state.page.<key>`, uygulama düzeyinde `state.app.<key>` olur; `value` nesneyse alanlarına inilir (`state.page.MyTest.isActive`) |
102
+ | `state.page` / `state.app` | Sayfa/uygulama state'i (oku/yaz): `state.page.selectedId = row.id`. **Bellekte yaşar** — sayfa her açıldığında tanımlı `value`'dan başlar; mobil uygulamada kalıcı olması için değişkene `storage` verilir (`platform_guide('mobile')` §Kalıcı state). **Tanımlı değişkenler de buradadır:** `variable_create` ile yazılan her `key` sayfa düzeyinde `state.page.<key>`, uygulama düzeyinde `state.app.<key>` olur; `value` nesneyse alanlarına inilir (`state.page.MyTest.isActive`) |
101
103
  | `Steps` | Adım çıktıları: `Steps.load_specialties` — anahtar adımın **ADIdır**, `stepId` değil (`setStorage(task.name, …)`); `Steps.<adım>.error` o adımın hatası — ama YALNIZ HTTP durum metnidir (401 için `'Unauthorized'`), ucun mesajı değil. `Steps.error` ise hata akışı için doldurulur (`onError` koşmadan önce `setStorage('error', …)` yapar) ve **yalnız orada okunur**: storage sayfa başına tek `FlowMachine`'de yaşar, ama dışarıdan başlayan her akış başlarken `'error'`'u ve kendi adımlarının önceki değerlerini temizler (`flow-engine.ts` `run`, 2026-09-25) — normal akışta `Steps.error` boştur; hata akışı ve onun tetiklediği akış (`nested`) onu görür ve şekli `{ message, code, step: { id, name, type, data } }`'dir: kullanıcıya gösterilecek metin `Steps.error.message`'tır (`err.response.data.message`, boşsa durum metni). **Başarılı bir adımda `Steps.<adım>.data` gerçek bir `Array`'dir** — `.map` · `.filter` · `.concat` · `.length` çalışır. Adım HATA dönerse aynı alan ucun hata gövdesini taşır; aşağıdaki kutuya bakın |
102
- | `self` · `item` · `Row` / `RowIndex` | Tetikleyen komponent (yazılabilir) · repeater/tablo satırı (yazmak satırı günceller) |
104
+ | `self` · `item` · `Row` / `RowIndex` | Tetikleyen komponent (yazılabilir) · repeater/tablo satırı (yazmak YALNIZ o satırı günceller). Satır AKIŞINDA (satırdaki düğümün olayı) ARC-121 düzeltmesini (2026-09-27) taşıyan runtime gerekir, eskisinde boştu — sürümden bağımsız yol `<liste>.selectedItem` / `.selectedIndex`. Tekrarlayıcının KENDİ `change`/`select` akışında satır bağlamı yoktur. `item.x = …` yazımı tekrarlayıcının `change` olayı olarak iletilir: `change`'e bağlı akış her yazımda koşar, o akış da `item`'a yazarsa döngü olur |
103
105
  | `event` | `{name, data, source: {id, props}}` |
104
106
  | `cookie` | `cookie.get(name)` / `cookie.set(name, value, {expiresInHours, path})` / `cookie.remove(name)` — tarayıcı cookie'si |
105
107
  | `setComponentProperty(name, key, value)` / `getComponentProperty(name, key)` | fonksiyon alternatifi |
106
108
  | `resetForm(name)` | Formu sıfırlar: alanlar başlangıç değerine döner, form "gönderilmemiş" olur, doğrulama mesajları silinir. Kayıt sonrası "yeni kayıt" için alanları tek tek `null`'a çekme — gönderilmiş formda her biri "zorunlu alan" mesajı çıkarır. Ad ya da komponent değişkeni alır: `resetForm('risk_form')` / `resetForm(risk_form)`. **Yalnız UI flow kodunda** |
107
- | `LocalStorage` · `Widget` · `params` | yerel veri · widget bağlamı · olay parametreleri |
109
+ | `LocalStorage` · `Widget` · `params` | yerel veri · widget bağlamı · olay parametreleri. `LocalStorage` barındırıcının deposudur, salt okunur ve değerler METİNdir: web'de uygulamanın kökenindeki `localStorage` (Studio önizlemesinde Studio'nun kendi anahtarları da görünür), cihazda akışın `storage` deposu. `storage` adımı düz bir anahtara yazınca `LocalStorage.<anahtar>` aynı akışta yeni değeri verir ve sayfanın bağları yeniden değerlendirilir (`isSelected: {{ LocalStorage['zeyrek:theme-mode'] === 'dark' }}`). `state.page\|app.<key>`'e yazan adım `LocalStorage`'a girmez (ARC-147, 2026-09-29) |
110
+ | `Device` | Salt okunur cihaz durumu, barındırıcı günceller: `Device.isOnline` — ağ bağlantısı var mı (bilinmiyorsa `true`). Değişince sayfanın bütün bağları yeniden değerlendirilir; çevrimdışı bandı: `isHidden: {{ Device.isOnline }}`. Cihazda `expo-network`, web'de tarayıcının `online`/`offline` olayları. `Device` adında komponent ifade bağlamından süzülür (ayrılmış ad) |
111
+ | **Ayrılmış adlar** | Bu tablodaki globallerle (ve önsözün iç adlarıyla: `payload`, `error`, `repeaterId`, `_` ile başlayanlar…) aynı `name`'i taşıyan komponent (runtime yalnız İLK `-`'yi siler: `ite-m` da `item` sayılır) ifadede kendi adıyla GÖRÜNMEZ — süzülür, uyarı loglanır (liste: `@ng-apps/flow` `EXPRESSION_PRELUDE_NAMES`). Eskiden aynı ad sayfanın BÜTÜN ifadelerini `SyntaxError`'la düşürürdü (ARC-143). Gateway artık bu adların HEPSİNİ **PAGE-009** ile sayfa/layout yazma yollarında ve `page_schema_validate`'te istek gitmeden reddeder — komponente `t`, `state`, `event`, `item`, `self`, `Page`, `Row` gibi ad verme |
108
112
  | `t(key)` | Çeviri anahtarını çözer: aktif dil → projenin varsayılan dili → anahtarın kendisi. Boş string de "eksik" sayılır. Sözlük `machine.context.state.translations`'tan gelir; dil `language-selector` ile değişince bir sonraki çağrı yeni dili görür. **Yalnız UI flow kodunda vardır** — backend ifadelerinde karşılığı `Loc()`'tur (`platform_guide('workflow')`) | `t('home.welcome')` |
109
113
  | `log(...)` | console (proxy'leri temizler) |
110
114
  | `Functions` | **Kullanıcı fonksiyonları** (`function_create`): `Functions.toplamHesapla(fiyat, adet)` — uygulama kapsamlılar her sayfada, sayfa kapsamlılar yalnız kendi sayfasında. **Yalnız tarayıcı**; sunucuda bu ad alanı yoktur (2026-09-10, `WF-030`) |
@@ -125,6 +129,11 @@ dalından devam eder.
125
129
  > `runtimeErrors` taşır ve hangi komponentin hangi prop'unun yazılamadığını (`element` ·
126
130
  > `property`) söyler. Aynı defter hata dönen microservice adımlarını da kaydeder. **Kare
127
131
  > "çalışıyor" görünse bile `runtimeErrors` doluysa o adımlar işini YAPMAMIŞTIR.**
132
+ >
133
+ > **Prop'a bağlı ifade patlarsa** (Studio'da "Expression error" toast'ı) `page_screenshot` yanıtı
134
+ > `expressionErrors` taşır: `{ elementId, prop, expression, message, count }`, öğe başına en çok iki.
135
+ > Toast da öğeyi adlandırır (`Expression error · tx_baslik.content`); cihazda geliştirme paketi aynı
136
+ > satırı Metro günlüğüne basar (ZM-05).
128
137
 
129
138
  **Prop'a doğrudan ifade bağlama (`{{ }}`):** akış kurmadan bir prop'u ifadeye bağlamak için
130
139
  prop `type: 'code'` olur, **ifade `ref` alanına `{{ }}` içinde** yazılır, `data` tasarım zamanı
@@ -273,7 +273,7 @@ toplamHesapla(row.fiyat, row.adet) > 1000
273
273
  serbesttir — sunucuda o ad alanı yok.
274
274
  - **Önekli hata:** gövde hatası `Functions.<ad>: <mesaj>` (studio) ya da `<ad>: <mesaj>` (workflow)
275
275
  olarak gelir; `Steps.<adım>.error.message` ya da `runtimeErrors`'ta bu öneki ara.
276
- - **Mobil yok** (K11): `apps/mobile` runtime'ı `Functions`'ı boş nesne kurar.
276
+ - **Mobil uygulama:** mobil runtime (`@ng-apps/ui-native`) `appFunctions`/`pageFunctions`'ı `Functions`'a geçirir, çağrı web'deki gibi çalışır.
277
277
  - **Önbellek:** `/view` yolu eski gövdeyi birkaç saniye gösterebilir; `/dev` yolu anlıktır.
278
278
  - **Parametre konumsal:** `parameters` sırasını değiştirmek mevcut çağrıların anlamını değiştirir;
279
279
  `function` adımları ada göre eşlendiği için etkilenmez.
@@ -5,7 +5,10 @@
5
5
  Bağımlılıklar bu sırayı zorunlu kılar; atlama:
6
6
 
7
7
  ```
8
- 1. project_create (application zorunlu: ilk application projeyle birlikte açılır;
8
+ 1. project_create (ÖNCE TÜRÜ SEÇ: accessModel 'simple' | 'complex' — aşağıdaki
9
+ 'Basit mi kompleks mi?' tablosu; sonradan değiştirmek ayrı bir dönüşüm
10
+ işidir.
11
+ application zorunlu: ilk application projeyle birlikte açılır;
9
12
  application slug'ı ORG GENELİNDE tekildir — 'web' büyük olasılıkla
10
13
  doludur, 409'da project_list ile mevcut slug'ları tara.
11
14
  DİL: gateway create'ten sonra projenin dillerini kurar — verirsen
@@ -68,6 +71,8 @@ Bağımlılıklar bu sırayı zorunlu kılar; atlama:
68
71
  13. application_update (homepageId — ana sayfa sayfadan değil application'dan seçilir)
69
72
  ```
70
73
 
74
+ Onay zinciri, görev kutusu, SLA gibi insanı bekleyen işler workflow'a sıkıştırılmaz: entity ve (gerekiyorsa) servis workflow'ları hazır olduktan sonra süreç tanımı yazılır — `platform_guide('bpm')`.
75
+
71
76
  ## İlk kullanıcıyı kim açar? (tavuk-yumurta kilidi)
72
77
 
73
78
  Kimlik kurulmuş yeni bir projede **giriş yapabilecek hiç kimse yoktur** ve zincir kendi kendini
@@ -119,6 +124,38 @@ Middleware bir kontrol listesi maddesi değil; **ihtiyaca** kurulur:
119
124
  `middlewareIds` ile bağlı olmalı. Bir-iki uca bağlayıp gerisini açık bırakmak, hiç kurmamaktan
120
125
  kötüdür — sistem güvenli görünür, değildir.
121
126
 
127
+ ## Basit mi kompleks mi? (proje türü)
128
+
129
+ Tür `project_create` `accessModel` ile proje açılırken seçilir; varsayılan `simple`'dır.
130
+
131
+ | Durum | Tür |
132
+ |---|---|
133
+ | Kimlik ve yetki uygulamanın kendi işi; birkaç rol yeter, satır kapsamı elle yazılan `user.id` filtresi | **simple** — bugünkü davranış, aşağıdaki middleware tablosu geçerli |
134
+ | Kurumun birim/pozisyon ağacı var (holding → şirket → bölge → departman), "müdür ekibinin kayıtlarını görür", maskeli/şifreli alan (TCKN) | **complex** |
135
+
136
+ Kompleks projede fark edilmesi gerekenler:
137
+
138
+ - Proje organizasyonun **yayınlı son** rol şemasının kopyasıyla doğar; yayın yoksa organizasyon
139
+ tabloları boştur (ORG-002). Açmadan önce `organization_schema_get` → `publishedVersion`.
140
+ - Ağaç tabloları (`organization_units`, `organization_positions`, `user_positions`) yalnız
141
+ okunur; `row_*` ile yazılmaz (ORG-001).
142
+ - Abonelik `project_get` → `organizationSchema`: `customizedAt` görünüyorsa proje ayrışmıştır ve
143
+ yeni sürümler artık gelmez.
144
+
145
+ ### Kompleks projede ilk kullanıcı
146
+
147
+ `users` kompleks projede de boş doğar ve yukarıdaki bootstrap deseni **`enforce` ortamda çalışmaz**:
148
+ anonim uç işareti olmadığı için oturumsuz her microservice isteği — bootstrap ucu da — `401` döner.
149
+ Yeni kompleks proje `enforce` başlar. Sıra:
150
+
151
+ 1. Kullanıcıya söyle: development ortamının zorlama modu Studio › Ayarlar › Ortamlar'dan geçici olarak
152
+ `shadow` yapılsın (insan işi, ACC-007; production'a dokunulmaz). `shadow` engellemez.
153
+ 2. Bootstrap desenini uygula (geçici uç → kullanıcı → ucu hemen sil).
154
+ 3. Kullanıcının koltuğu Studio › Organizasyon ekranında atanır (`user_positions`); politika pozisyona ya da
155
+ role atanmışsa yetki buradan gelir.
156
+ 4. Mod `enforce`'a döner; `access_session_create` ile giriş yap, `asUser` ile uçları sına, reddi
157
+ `access_preview` ile açıkla (`platform_guide('access')`).
158
+
122
159
  ## Örnek arama davranışı
123
160
 
124
161
  Örnek gövde için **mevcut projeleri taramak yerine** önce şunlara bak:
@@ -4,6 +4,10 @@ Sayfaların paylaştığı kabuk: yan menü, üst şerit, kullanıcı menüsü v
4
4
  gireceği delik. Şema gövdesi ve koordinat modeli için `platform_guide('page')` (Kural 1,
5
5
  1d, 1f); komponent sözleşmeleri için `platform_guide('component')`.
6
6
 
7
+ > **Mobil uygulamada** kabuk `app-bar` + tek `slot`'tur; sekmeler uygulama ayarı
8
+ > (`properties.mobile.tabs`), çekmece `drawer` widget'ıdır. Web kabuk bileşenleri (`navigations`,
9
+ > `sidebar`, `header`) `MOB-004` alır — `platform_guide('mobile')` §Gezinme.
10
+
7
11
  ## Karar kuralları
8
12
 
9
13
  **1. Layout, tek `slot` içeren SIRADAN bir komponent ağacıdır.** Ayrı bir dil yoktur:
@@ -61,7 +65,7 @@ yapılan eski numaraya artık gerek yok.
61
65
  NEREDE durduğunu değil, BİÇİMİNİ söyler (dikey kolon / yatay şerit / dolgu yüzeyi). Hem
62
66
  runtime hem Studio tuvali bölgeleri 12 kolonluk ızgarayla yerleştirir.
63
67
 
64
- **7. Mobilde flex YIĞILMAZ.** Runtime'ın mobil kuralı yalnız ızgara özelliklerini ezer.
68
+ **7. Dar ekranda flex YIĞILMAZ.** Runtime'ın dar ekran kuralı yalnız ızgara özelliklerini ezer.
65
69
  Telefonda alt alta düşmesi gereken satırı `layout:'grid'` ile kur; `layout:'flex'` +
66
70
  `direction:'row'` telefonda da yan yana kalır (375px'te ölçüldü: ızgara çocukları 375/375px
67
71
  alt alta, flex çocukları 49/310px yan yana). Not: `wrap` varsayılanı artık açık (2026-09-01) —
@@ -140,8 +144,8 @@ bağlantı nesnesi ya da tam yol).
140
144
  "direction": { "type": "static", "data": "row" } },
141
145
  "blocks": [{ "breakpoint": 1024, "size": { "w": 12, "h": 80 }, "position": { "x": 0, "y": 0 } }] }
142
146
 
143
- // KÖTÜ — telefonda 49px'lik yan menü: row flex mobilde yığılmaz (Kural 7)
144
- // Mobilde alt alta düşmesi gerekiyorsa kökü layout:'grid' kur — bedeli, fill'in
147
+ // KÖTÜ — telefonda 49px'lik yan menü: row flex dar ekranda yığılmaz (Kural 7)
148
+ // Dar ekranda alt alta düşmesi gerekiyorsa kökü layout:'grid' kur — bedeli, fill'in
145
149
  // flex anlamının devreye girmemesi.
146
150
  ```
147
151
 
@@ -179,9 +183,9 @@ bunlardan biri olabilir:
179
183
  |---|---|
180
184
  | ~~`heightType` yalnız `auto` \| `fixed`~~ | **28 Ağustos'ta kapandı:** üçüncü değer `fill` (Kural 5b) |
181
185
  | ~~Kök kap viewport'a kilitlenmez~~ | **28 Ağustos'ta kapandı:** `fill` verilmiş kök 100vh (Kural 5b) |
182
- | Flex mobilde yığılmaz | Kural 7 — kabuk bugün bir MASAÜSTÜ kabuğudur |
183
- | Kırılıma duyarlı prop yok | `direction`/`gap` masaüstü ve mobilde AYNI; yalnız `blocks` ve `appearance.hideOn` kırılım bilir |
184
- | Mobil çekmece (overlay) yok | Telefonda içeriğin üstüne binen panel kurulamaz |
186
+ | Flex dar ekranda yığılmaz | Kural 7 — kabuk bugün bir MASAÜSTÜ kabuğudur |
187
+ | Kırılıma duyarlı prop yok | `direction`/`gap` masaüstü ve dar ekranda AYNI; yalnız `blocks` ve `appearance.hideOn` kırılım bilir |
188
+ | Dar ekranda çekmece (overlay) yok | Telefon genişliğinde içeriğin üstüne binen panel kurulamaz (mobil UYGULAMADA çekmece `drawer` widget'ıdır — `platform_guide('mobile')`) |
185
189
 
186
190
  ---
187
191
 
@@ -189,7 +193,7 @@ bunlardan biri olabilir:
189
193
  (`injectPageSchemaIntoSlots`, `getResolvedLayoutViews`), `apps/studio/src/features/page/api/page.mappers.ts`
190
194
  (`mapPageLayoutToPreview`), `packages/ng-apps-ui/src/shared/render/render.functions.ts`
191
195
  (`resolveNodeBoxStyle` — slot'un `y / auto` satırı, flex çocuk genişliği),
192
- `packages/ng-apps-ui/src/shared/render/RenderComponent.svelte` (mobil media kuralı),
196
+ `packages/ng-apps-ui/src/shared/render/RenderComponent.svelte` (dar ekran media kuralı),
193
197
  `packages/ng-apps-screen-builder/src/flex-layout.ts` (`getFlexChildStyle` — `widthType`
194
198
  fill/fixed/auto dalları, `normalizeCssSize` kabul kuralı; tuval ve runtime aynı fonksiyonu okur),
195
199
  `apps/studio/src/features/page/components/appearance/appearance-size.functions.ts` (panelin
@@ -39,6 +39,16 @@ trail tabloları hariç, dış datasource'lara dokunulmaz). Kayıt taşıması a
39
39
  (`promote`) kuralıdır ve orada aynen geçerlidir. **Satırlar merge'de geri taşınmaz** — merge yalnız
40
40
  tanım işidir.
41
41
 
42
+ Tanım sayılan ve merge'in taşıdığı üç şey 2026-09-25'ten beri listede: **çeviriler**
43
+ (translation kalemi, adı çeviri anahtarı), **microfunction'lar** (kod ve arşiv; hedefte **taslak**
44
+ kalır, yayını kullanıcı yapar) ve zamanlanmış işin **duraklatma durumu**. Öncesinde dalda
45
+ eklenen çeviri ve microfunction development'a hiç gelmiyordu.
46
+
47
+ - Aynı çeviri anahtarını (uygulama, dil, anahtar) dal da development da kendi başına eklediyse plan
48
+ yalnız dalınkini `add` gösterir; apply development'ın satırına **dalın değerini** yazar.
49
+ - Microfunction **runtime**'ı merge'de taşınmaz (kimlik bilgisi taşır). Dalda yeni bir runtime kurup
50
+ microfunction'ı ona bağlarsanız apply `23503` ile düşer — runtime'ı önce development'ta kurun.
51
+
42
52
  Dalda `page_screenshot` **çalışır** (2026-09-09'dan beri); ayrıntısı bir sonraki bölümde.
43
53
 
44
54
  ## Dalda görsel doğrulama
@@ -85,7 +95,7 @@ değişkenler, çözülen ref'ler) kareyi tamamlar: kare ne çizildiğini, bu ik
85
95
  - `derivedFromKey`: kalem OTOMATİK ÜRETİLMİŞ bir kayıtsa (varsayılan DTO) kaynağının anahtarı
86
96
  - `elements[]`: `path`, `kind`, `base`, `source` (dal), `target` (development), `resolution`
87
97
 
88
- `dataRisk` bir **uyarıdır, apply'ı bloklamaz**; üç sebepten biriyle doğrudur:
98
+ `dataRisk` bir **uyarıdır, apply'ı bloklamaz**; dört sebepten biriyle doğrudur:
89
99
 
90
100
  | `dataRiskReasons` | Ne demek |
91
101
  |---|---|
@@ -93,8 +103,32 @@ değişkenler, çözülen ref'ler) kareyi tamamlar: kare ne çizildiğini, bu ik
93
103
  | `field-narrowed` | Tip / `nullable` / `unique` daraltılıyor |
94
104
  | `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
105
 
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.
106
+ | `table-removed` | **Hedefte satırı olan** tablo siliniyor; boş tablo riskli sayılmaz |
107
+
108
+ `not-null-…` satırı 2026-09-09'da eklendi; öncesinde bu durum `dataRisk: 0` diyordu ve risk ancak
109
+ apply denenerek öğreniliyordu. Hedef tablo **boşsa** aynı alan riskli sayılmaz.
110
+
111
+ Aynı denetimin sert hâli promote'tadır: deploy başlamadan production verisine karşı koşar ve veri
112
+ bozacak değişikliği 400 ile reddeder (`deployment_start` açıklaması).
113
+
114
+ ### Silinen kaydın yeni bağımlısı: `dependents[]`
115
+
116
+ Dal bir kaydı sildi, development ise dal açıldıktan **sonra** o kaydı kullanmaya başladıysa
117
+ (bir sayfa sorguyu bağladı, bir akış servisi çağırdı) silme `delete` olarak değil **`conflict`**
118
+ olarak gelir ve kalemde `dependents[]` (`{ id, name, module }`) dolar:
119
+
120
+ - `choice: "target"` kaydı ve bağımlısını korur,
121
+ - `choice: "source"` siler — bağımlı FK ile düşebilir ya da kırık bağla kalır.
122
+
123
+ Sorgunun çıktı DTO'su ve alanları **aynı çakışma grubundadır**: biri çözülünce diğerleri de o
124
+ tarafa gider. Dal açılmadan önce var olan ve development'ta değişmeyen bağımlı çakışma üretmez —
125
+ onu dal zaten görmüştü.
126
+
127
+ ### Süreç kenarlarında çakışma
128
+
129
+ `versions[…].model.edges` listesinde iki taraf **aynı geçidin** çıkışlarına dokunduysa tek bir
130
+ çakışma gelir, yolu `versions[id=…].model.edges{from=<düğüm>}` biçimindedir — o geçidin bütün
131
+ çıkışları bir karar olarak çözülür. Farklı geçitlere yapılan değişiklikler kendiliğinden birleşir.
98
132
 
99
133
  `derivedFromKey` dolu olan kalemi ayrıca çözmeye çalışmayın: kaynağını (entity ya da query)
100
134
  çözdüğünüzde aynı yoldaki çakışması **kendiliğinden** aynı tarafa çözülür. Entity adını değiştiren
@@ -243,9 +243,16 @@ DTO'dan süzülmez (WF-026 — `platform_guide('workflow')` §Hata yolu). Sözle
243
243
  - **Operatör sözlüğü kapalıdır:** `eq · neq · lt · lte · gt · gte · contains · icontains ·
244
244
  in · notin · startswith · endswith · istartswith · iendswith · isnull · isnotnull`.
245
245
  **`like` YOKTUR** — metin
246
- araması `contains`/`icontains` iledir. Kritik tuzak: platform bilinmeyen operatörü 400 ile
246
+ araması `contains`/`icontains` iledir. Kritik tuzak: eski backend bilinmeyen operatörü 400 ile
247
247
  reddetmez, **sessizce `eq`'e düşürür** (enum çözümlemesi unknown'da default'a düşer) — uç
248
- testten geçer ama arama hiçbir şey döndürmez. Gateway MS-012/WF-015 bunu istek gitmeden keser.
248
+ testten geçer ama yanlış sonuç döner (koşuda `ne` böyle geçti). 2026-09-27'den sonraki backend
249
+ uç çağrısının `filters` parametresinde (JSON dizisi) 400 verir; workflow tablo adımının filtresi
250
+ hâlâ sessizce `eq`'e düşer. Ad büyük/küçük harfe duyarlıdır: `NEQ` geçersizdir. Gateway her iki
251
+ sürümde istek gitmeden keser: uç tanımında ve
252
+ workflow tablo adımında MS-012/WF-015 (blok), çalışma anında `row_list` / `row_export` filtresinde ve
253
+ `microservice_execute` / `microservice_debug`'ın `filters` parametresinde hata — sık yanlışlara öneriyle
254
+ (`ne`/`!=` → `neq`, `like` → `contains`, `=` → `eq`). Studio'nun filtre ARAYÜZÜNDEKİ adlar
255
+ (`notContains`, `between`…) ayrı bir sözlüktür; arayüz onları bu işleçlere çevirir.
249
256
  - **Write operasyonunda (`create`/`update`) yanıt yalnız primary key'dir** — platform sonucu
250
257
  PK'ya indirger ve `selectFields`'ı kaydederken sessizce boşaltır. Yanıtın başka alan da
251
258
  dönmesi gerekiyorsa **`returnFields`** kullanılır (öğeler `selectFields` ile aynı şekildedir:
@@ -337,6 +344,25 @@ kart doğru sütuna geçer, başlığı ve sorumlusu silinir.
337
344
  > ifadeden gelir ve `undefined` dönen ifade de `null` yazar —
338
345
  > `platform_guide('workflow')` §"Table update adımı".
339
346
 
347
+ ### Toplu güncelleme FİLTREYLE kurulmaz
348
+
349
+ "Bekleyen bütün başvuruları onayla" bir table-source `update` ucuyla YAZILAMAZ. `update`
350
+ operasyonu tam olarak **bir tekil alan filtresi** ister: birden çok filtre
351
+ `InvalidFilterCountException`, tekil olmayan alanla filtre `FilterFieldMustUniqueException`
352
+ döndürür (ölçüldü 2026-09-20, S2-22). Yani hedef kümeyi bir KOŞUL belirleyemez, yalnız bir ANAHTAR
353
+ belirler. İki doğru yol var:
354
+
355
+ | Ne istiyorsun | Yol |
356
+ |---|---|
357
+ | Anahtarlar elinde, hepsi ya hep ya hiç yazılsın | **`bulk-update` ucu** — gövde satır dizisi, filtre yok, tek çağrı, tek transaction (yukarıdaki §"Toplu yazma"). En fazla 1000 satır; bir satır düşerse hiçbiri yazılmaz |
358
+ | Satır başına SONUÇ ve satır başına YETKİ kararı gerekiyor | **İş akışı + döngü** (BK-05 deseni): liste ucunu çağır → her satır için `microservice` adımı → sayaçları topla → özet döndür |
359
+
360
+ Kapsam ve politika koşulu her iki yolda da satır satır uygulanır; fark sonucun şeklidir. Toplu
361
+ onay gibi işlerde ikinci yol tercih edilir çünkü yetkisi yetmeyen satır ötekileri geri almaz:
362
+ çağıran "N onaylandı · M reddedildi" özetini alır (ölçülen koşu: iki satır da 403 ile reddedildi,
363
+ akış "0 onaylandı · 2 reddedildi" döndürdü). Döngüdeki uç, çağıranın kimliğiyle denetlenir —
364
+ akış içinden yazmak yetki YÜKSELTMEZ.
365
+
340
366
  ## İlişki alanı: `row_list` NESNE döner, uç/step JOIN'siz DÜZ FK döner
341
367
 
342
368
  Aynı alan iki yoldan farklı şekilde gelir ve bu fark sessizce yanlış sonuç üretir:
@@ -678,6 +704,20 @@ Rol listesini **değiştirmek** için yukarıdaki §"Patch belgesi OKUMA şeklid
678
704
  > rota `/{project}/m/{application}/{microservice SLUG'ı}`'dır ( `url` alanı rotaya GİRMEZ) ve
679
705
  > `Host: <org>.<suffix>` + `X-Environment` başlıkları zorunludur.
680
706
 
707
+ ### Kompleks projede
708
+
709
+ - `enforce` ortamda **anonim uç yoktur**: oturumsuz her istek `401 AppSessionRequired` döner; yukarıdaki
710
+ anonim veri toplama deseni kompleks projede kurulamaz. Uç izni erişim politikasıyla gelir
711
+ (`microservice.execute`); platform `roleIds`'i hiçbir modda karar için kullanmaz.
712
+ - `middlewareIds`'e bağlı middleware **her modda koşar** ve reddedebilir; set-user adımı ya da yanıttaki
713
+ `user` platformun doldurduğu `user`'ı ezer. Kimlik middleware'ini uçtan çıkarın (ACC-006).
714
+ - Table kaynaklı uç satırları kapsamla SQL'de süzer (kapsam dışı id 404), gizli alanı çıkarır, korumalı
715
+ alanı `__protected` ile işaretler; yetkisiz alana yazma ya da filtre 403.
716
+ - Query kaynaklı uç kapsamlı ya da korumalı tabloya dokunuyorsa sorgu `isUnrestricted` olmadıkça
717
+ `403 AccessQueryNotScoped` (ACC-005).
718
+ - Sınama: `access_session_create` → `asUser`; ret nedeni `access_preview` ve `microservice_debug`
719
+ yanıtındaki `accessDecision`. Kurallar: `platform_guide('access')`.
720
+
681
721
  ## Alias nerede geçerli
682
722
 
683
723
  Alias bir **SQL tablo takma adıdır**: yalnız okunan tarafta anlamı vardır. Sözleşme iki ayrı
@@ -698,6 +738,29 @@ Yazma alanına `alias` koyarsan istek **hata vermez**, alan model bağlamada dü
698
738
  istek gitmeden gövdeden çıkarır ve `gatewayNormalized` ile bildirir — böylece `silentlyDropped`
699
739
  listesi yalnız gerçek kayıpları gösterir.
700
740
 
741
+ ### Kök filtrenin alias'ı entity SLUG'ı olmak zorundadır (MS-023)
742
+
743
+ `filters[].alias` runtime'da iki şeyden birine eşlenir: **ana entity'nin slug'ı** ya da bir **join
744
+ alias'ı** (`PostgreSqlRelationHandler.GetField`). Üçüncü bir seçenek yoktur — `sourceParameters.alias`
745
+ alanına yazdığın kök takma ad da dâhil. Eşleşmeyen alias'lı **zorunlu** filtre isteği 400
746
+ `FilterFieldNotResolvedException` ile düşürür ve parametreyi hangi adla gönderirsen gönder değişmez.
747
+
748
+ Çağrı parametresinin adı aynı kuraldan çıkar:
749
+
750
+ | Filtrenin alias'ı | Çağrı parametresi (`parameterScheme[].name`) | Çalışır mı |
751
+ |---|---|---|
752
+ | entity slug'ı (`kredi_basvurusu`) | `id` — **nitelenmemiş** alan slug'ı | evet |
753
+ | join alias'ı (`musteri`) | `musteri.id` | evet |
754
+ | başka bir şey (`kredi`) | `kredi.id` | **hayır** — 400 `FilterFieldNotResolvedException` |
755
+
756
+ Yani şemadaki ad, uç çalışabildiği sürece runtime'ın beklediği addır; nitelikli bir ad görüyorsan
757
+ alias'ın bir JOIN alias'ı olduğundan emin ol. `microservice_get` join olmayan nitelikli adı
758
+ **MS-023** uyarısıyla işaretler. Düzeltme:
759
+ `microservice_patch { op: 'replace', path: '/sourceParameters/filters/0/alias', value: '<entity slug>' }`.
760
+
761
+ Ölçüldü 2026-09-20 (`rehber-basit/tb119-get`, entity slug `tb119_urun`): alias `u` → parametre
762
+ `u.kod`, çağrı 400; alias `tb119_urun` → parametre `kod`, çağrı 200.
763
+
701
764
  ## Zamanlanmış iş (`type: 'schedule-job'`) — `typeParameters.schedule`
702
765
 
703
766
  Zamanlama tek bir tanımdır; `cronExpression` tek başına verilirse **UTC cron** sayılır (eski gövde).
@@ -813,3 +876,25 @@ Dört gerçek daha:
813
876
  (`{ "op": "add", "path": "/description", "value": "…" }`). Patch yanıtındaki `silentlyDropped`
814
877
  alanı, gönderilen ama kaydedilmeyen alanları listeler — boş değilse platform bir alanı yutmuş
815
878
  demektir.
879
+
880
+ ## Connect Data kaynağı olarak uç
881
+
882
+ Okuyan bir uç prop'a **akışsız** bağlanabilir (`connect_data_bind`, `platform_guide('page')` §Kural 1c-3). Şartlar
883
+ (ölçüldü 2026-09-21, koşu 38):
884
+
885
+ - Uç **okur** (GET tablo `get`, query ya da view kaynağı), **middleware'siz** ve **dönüş şeması** vardır; yazan tablo/sistem
886
+ ucu, middleware'li uç ve şemasız uç `connect_data_describe`'da 422 `ConnectDataSourceUnsupported`.
887
+ **Middleware'li uç bilinçli olarak dışarıda (karar 2026-10-02, qm madde 5C):** connectData yolu ucun middleware
888
+ zincirini koşmaz; kaynak olarak kabul edilseydi ucun korumaları (kimlik, rol, setter değişkenleri) atlanırdı.
889
+ Korumalı ucu listeye bağlamanın yolu **akıştır**: bileşenin `mount` (ve arama/sayfa) akışında microservice adımı
890
+ ucu çağırır — middleware'ler koşar —, setter dönen satırları `rows`'a yazar. Uç projedeki başka bir uygulamada
891
+ olabilir (microservice adımı servisin kendi uygulamasının adresine gider). Middleware'i kaldırıp ucu açmak çözüm
892
+ değildir.
893
+ - **Tablo ucunda `enableDynamicFilters: true`** alanları `canFilter`/`sortable` yapar (kullanıcı filtresi tanım filtresiyle
894
+ AND'lenir); `sort`/`limit` query-string parametreleri offset sayfalama açar. Dinamik filtresiz ya da query kaynaklı uç
895
+ `pageMode: client` kalır (CD-007) ve süzmez.
896
+ - Uç parametreleri bağlantının `params`'ından gelir (`source.parameters`; CD-013).
897
+ - `connect_data_convert` bir bağlantıyı `source: connectData` bir uca çevirir: `m/{app}/{slug}` `POST { op: 'list' }` aynı
898
+ kabiliyet damgalı `{ data, meta, errors }` zarfını döner. Kompleks projede `microservice_execute { asUserId }` ile
899
+ kullanıcı gözüyle doğrulayın; `microservice_preview` Studio ucudur (ROLLBACK'li, kapıları koşmaz).
900
+ - Örnekler: `ngapps://examples/connect-data-workflow-microservice`, `ngapps://examples/connect-data-convert-verify`.
@@ -19,6 +19,16 @@ kavramı olmayan bir üründe auth middleware'i, ayar tablosu olmayan bir ürün
19
19
  kur** — giriş sayfası + korunacak her uç ve her sayfa `middlewareIds`'e bağlı. Kısmi koruma,
20
20
  sistemi güvenli gösterip açık bırakır.
21
21
 
22
+ > **Kompleks projede (`accessModel: 'complex'`) kimlik tarifleri gerekmez — bağlı kalırsa da etkisiz
23
+ > değildir.** Platform uygulama oturumunu kendisi yönetir (`POST /{proje}/runtime/{app}/auth/sign-in`), uç
24
+ > yolunda `user` değişkenini güvenilir özneyle önceden doldurur ve yetkiyi erişim politikasıyla verir. Bağlı
25
+ > middleware'ler ise zorlama modundan bağımsız **her modda koşar** ve reddedebilir; set-user adımı ya da
26
+ > yanıttaki `user` platformun `user`'ını **ezer**. Kimlik middleware'ini uçların ve sayfaların
27
+ > `middlewareIds`'inden çıkarın (ACC-006, warn). Rol listesini (`microservice.roles`, `page.roleIds`)
28
+ > platform hiçbir modda karar için kullanmaz; yalnız `Authorized(user.roles)` çağıran middleware okur.
29
+ > Kompleks projenin yolu `platform_guide('access')` §Runtime; bu rehberin tarifleri basit projede aynen
30
+ > geçerlidir.
31
+
22
32
  ## Açıklama zorunlu
23
33
 
24
34
  Middleware de bir workflow'dur: her adımı ve middleware'in kendisi `description` taşımak
@@ -56,8 +66,20 @@ cevabı adımın ifadesinde gizlidir. Ayrıntı ve yazım ölçütü: `platform_
56
66
  kuracaksan ifadeyi guard'la: `typeof user === 'undefined' ? false : Authorized(user.roles)`.
57
67
  Gateway `set-user` adımı olmadan `user` okuyan middleware'i **MW-003** ile uyarır.
58
68
  4. **`input` YOKTUR.** Middleware girdisini HTTP bağlamından okur: `cookie`, `header`,
59
- `queryString`, `body`, `triggerSource` (hangi microservice/sayfa tetikledi: type, name,
60
- slug, roles, impersonatedUserId). Hazır fonksiyonlar: `system.validateToken(...)`,
69
+ `queryString`, `body`, `triggerSource` (hangi microservice/sayfa tetikledi: type, id, name,
70
+ slug, roles, pathAndQuery — emekliye ayrılacak) ve `context` (type, name, roles, path,
71
+ **impersonatedUserId**, language). `context.path` isteği yapan sayfanın adresidir
72
+ (`/view|dev|branch/{ortam}/{proje}/{uygulama}/{sayfa}`): mobil runtime onu `X-Page-Path`
73
+ başlığıyla yollar, web'de tarayıcının `Referer`'ından okunur. Doğrudan API çağrısında,
74
+ zamanlanmış/otomasyon koşusunda ve sayfası olmayan istekte **`null`'dır** — `split` gibi bir
75
+ metot çağırmadan önce koru: `(context.path || '').split('/')[1]`. İstemci beyanıdır, yetki kararı
76
+ için okunmaz. Kimlik devri **yalnız `context.impersonatedUserId`**'dedir;
77
+ `triggerSource.impersonatedUserId` diye bir alan yoktur, hep `undefined` okunur (MW-006).
78
+ `context.impersonatedUserId` ve start adımının `impersonation` dalı yalnız Studio önizlemesinde
79
+ seçilen uygulama kullanıcısı için dolar; kimlik devrini yalnız super-admin yapabilir, anonim ya da
80
+ yetkisiz istekte başlık platformda silinir. `impersonation` dalı bağlı değilse start
81
+ `success`'e düşer — uygulamanın kendi auth yolu koşar (ZM-22, 2026-09-26). Tarif: 1c. Hazır
82
+ fonksiyonlar: `system.validateToken(...)`,
61
83
  `system.generateToken(...)`, `crypto.JWT.encode/validate`, `Authorized(user.roles)`,
62
84
  `request.url.searchParams`, `GenerateGuid()`, `UtcNow()`, `system.getPageUrl(slug)` —
63
85
  **tam sözlük ve gerçek örnekler: `platform_guide('expressions')`**.
@@ -197,6 +219,31 @@ guard → [condition] triggerSource.type === 'page'
197
219
  Korumalı her sayfada yukarıdaki `redirect → response` zinciri kurulmalı ve **tokensız bir
198
220
  istekle 401 verdiği görülerek** kabul edilmeli. Karşılığı: `platform_guide('page')` Kural 8.
199
221
 
222
+ ## Tarif 1c — Studio önizlemesinde seçilen kullanıcıyla açılış (`impersonation` dalı)
223
+
224
+ Özel auth middleware'li bir uygulamada Studio'nun Preview alt çubuğundaki kullanıcı seçici
225
+ (`impersonated-user-id` başlığı) jeton taşımaz; yalnız jeton yolu olan middleware bu istekte 401
226
+ döner ya da `user` kurmadan biter ve korumalı her uç `user is not defined` ile 500 verir (ZM-22).
227
+ Seçilen kullanıcıyla açılmak için start adımının **`impersonation` dalını** bağlayın:
228
+
229
+ ```
230
+ start ─ success → token → token_check → userTable → setUser → response 200 (normal yol)
231
+ ─ impersonation → kimlik [table get: users, filtre id eq context.impersonatedUserId]
232
+ → var_mi [condition] ─ else → response 401
233
+ → setUser (aynı set-user ifadesi) → response 200
234
+ ```
235
+
236
+ ```jsonc
237
+ // start adımının dalları — impersonation dalının adı ve tipi 'impersonation'
238
+ { "id": "<GUID>", "name": "impersonation", "type": "impersonation", "nextStepId": "<kimlik adımının id'si>" }
239
+ ```
240
+
241
+ - Dal **yalnız** platform kimlik devrini doğruladığında seçilir (Studio önizlemesi, super-admin);
242
+ başlığı elle ekleyen istek normal `success` yolundan geçer. Bu yüzden değer yalnız bu dalda anlamlıdır:
243
+ **`context.impersonatedUserId`'yi dal dışında yetki kararı için okumayın.**
244
+ - Kullanıcı satırını yine tablodan okuyun; değerin kendisi yalnız bir kimliktir, rol ya da sahiplik
245
+ taşımaz. `set-user` ifadesi normal yolla aynı şekli üretmelidir (kapsam workflow'ları `user.id` okur).
246
+
200
247
  ## Tarif 3b — Rol kapısı: `microservice.roles` TEK BAŞINA hiçbir şeyi kapatmaz
201
248
 
202
249
  **Ölçüm (2026-08-19):** `roleIds: ['<admin rol id>']` verilmiş ama `middlewareIds` **boş** bir
@@ -234,12 +281,29 @@ kurulur.** Her projenin ayar middleware'ine ihtiyacı yoktur; okunmayan bir `set
234
281
  sadece fazladan parça demektir. Karar tablosu: `platform_guide('getting-started')`.
235
282
 
236
283
  ```
237
- start → settings [table get: ayarlar tablosu] → setVar [variable name:'settings',
238
- expression: '{ ...settings.data }', dataTransferObjectId: <ayarlar DTO>]
284
+ start → settings [table get: ayarlar tablosu]
285
+ → setPrivate [variable name:'settingsPrivate', expression: '{ ...settings.data }',
286
+ dataTransferObjectId: <ayarlar DTO>, isPrivate: true]
287
+ → setPublic [variable name:'settings',
288
+ expression: '({ app_name: settings.data.app_name, theme: settings.data.theme })']
239
289
  ```
240
290
 
241
291
  Response yok — tek işi değişken kurmak; bağlandığı her uçta `settings.<alan>` okunur.
242
292
 
293
+ **Sayfaya bağlanan middleware'in değişkeni istemciye gider.** Sayfa yanıtı middleware
294
+ değişkenlerini `Page.variables` olarak taşır; tarayıcıda ve cihazda okunur. Bu yüzden:
295
+
296
+ - Gizli değer taşıyan (şifre, `client_secret`, API anahtarı) ya da bütün bir kaydı yayan değişkene
297
+ **`rule.isPrivate: true`** ver (Studio: "Sunucuda tut"). Aynı istekteki sonraki middleware'ler
298
+ onu okumaya devam eder; istemciye gitmez. Sayfanın akışları istemcide koşar ve `Page.variables`'ı
299
+ okur — işaretli değişken orada `undefined`'dır; akışın ihtiyaç duyduğu alanı işaretleme.
300
+ - İstemcinin gerçekten ihtiyaç duyduğu alanları ayrı, işaretsiz bir değişkende **izin listesiyle**
301
+ kur (yukarıdaki `settings`). Aynı ad sonra işaretsiz bir adımla yeniden yazılırsa istemciye açılır.
302
+ - Yalnız microservice uçlarına bağlı middleware'de değişken yanıtla dönmez; işaret yine de zararsızdır.
303
+ - Lint: `MW-007` (işaretsiz değişken bir kaydı yayıyor ya da gizli değer adı taşıyor → warn).
304
+ Ölçüm: qm `[SY] Settings Setter` `{ ...settings.data }` ile `sso_client_secret`'ı istemciye
305
+ veriyordu (2026-10-02).
306
+
243
307
  ## Tarif 3 — Kimlik kapsaması: "sadece benim kayıtlarım" ucu
244
308
 
245
309
  Kullanıcıya özel veri dönen uçlarda kimliği **istemci parametresinden alma** (sahtelenir);