@appaflytech/zeyrek-ai-mcp 0.0.30 → 0.0.32

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 +0 -15
  2. package/README.md +5 -5
  3. package/dist/config.js +0 -37
  4. package/dist/index.js +0 -2
  5. package/dist/knowledge/backendConstraints.js +1 -18
  6. package/dist/knowledge/boxSections.js +184 -0
  7. package/dist/knowledge/componentCatalog.js +232 -562
  8. package/dist/knowledge/componentEvents.js +21 -141
  9. package/dist/knowledge/layoutSummary.js +2 -140
  10. package/dist/knowledge/normalize.js +67 -236
  11. package/dist/knowledge/outlines.js +0 -36
  12. package/dist/knowledge/policy.js +4 -18
  13. package/dist/knowledge/reservedTables.js +0 -79
  14. package/dist/knowledge/rules.js +21 -319
  15. package/dist/knowledge/schemaGuard.js +0 -11
  16. package/dist/knowledge/styleResolve.js +38 -55
  17. package/dist/knowledge/themeResolve.js +3 -3
  18. package/dist/observability/trace.js +3 -6
  19. package/dist/platform/diagnostics.js +4 -10
  20. package/dist/platform/domSummary.js +1 -1
  21. package/dist/platform/errors.js +10 -162
  22. package/dist/platform/http.js +8 -29
  23. package/dist/platform/responses.js +5 -39
  24. package/dist/platform/{capture/capture.js → screenshot.js} +519 -105
  25. package/dist/platform/secrets.js +1 -17
  26. package/dist/platform/strictArguments.js +12 -68
  27. package/dist/platform/tokenVault.js +4 -187
  28. package/dist/resources/examples/layout-app-shell.json +707 -229
  29. package/dist/resources/examples/page-detail-profile.json +1 -2
  30. package/dist/resources/examples/page-dynamic-form.json +2 -3
  31. package/dist/resources/examples/page-flex-sections.json +1 -1
  32. package/dist/resources/examples/page-html-embed.json +1 -1
  33. package/dist/resources/examples/workflow-basic.json +2 -8
  34. package/dist/resources/guides/component.md +4 -91
  35. package/dist/resources/guides/entity.md +8 -50
  36. package/dist/resources/guides/expressions.md +5 -14
  37. package/dist/resources/guides/functions.md +1 -1
  38. package/dist/resources/guides/getting-started.md +1 -38
  39. package/dist/resources/guides/layout.md +58 -55
  40. package/dist/resources/guides/microservice.md +2 -81
  41. package/dist/resources/guides/middleware.md +2 -44
  42. package/dist/resources/guides/page.md +75 -454
  43. package/dist/resources/guides/theme.md +2 -8
  44. package/dist/resources/guides/translation.md +1 -1
  45. package/dist/resources/guides/workflow.md +1 -58
  46. package/dist/resources/rules.js +5 -11
  47. package/dist/resources/schema-fingerprint.json +5 -7
  48. package/dist/resources/schemas/CreateEntityCommand.json +0 -118
  49. package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
  50. package/dist/resources/schemas/CreateQueryCommand.json +0 -4
  51. package/dist/resources/schemas/CreateWorkflowCommand.json +1 -143
  52. package/dist/resources/schemas/DataJobDto.json +1 -6
  53. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -21
  54. package/dist/resources/schemas/MicroserviceDto.json +3 -15
  55. package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
  56. package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -22
  57. package/dist/resources/schemas/StepDto.json +1 -22
  58. package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
  59. package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
  60. package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
  61. package/dist/resources/schemas/UpdateViewCommand.json +2 -0
  62. package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -143
  63. package/dist/server.js +1 -27
  64. package/dist/tools/access.js +2 -369
  65. package/dist/tools/applications.js +3 -60
  66. package/dist/tools/common.js +0 -7
  67. package/dist/tools/components.js +14 -118
  68. package/dist/tools/datasources.js +3 -3
  69. package/dist/tools/dependencies.js +1 -1
  70. package/dist/tools/deployments.js +2 -2
  71. package/dist/tools/designSchemaPatch.js +18 -34
  72. package/dist/tools/dtos.js +5 -36
  73. package/dist/tools/entities.js +12 -79
  74. package/dist/tools/externalComponents.js +5 -26
  75. package/dist/tools/flows.js +14 -122
  76. package/dist/tools/folders.js +1 -1
  77. package/dist/tools/imports.js +2 -5
  78. package/dist/tools/layouts.js +17 -50
  79. package/dist/tools/merges.js +1 -1
  80. package/dist/tools/microservices.js +25 -77
  81. package/dist/tools/pages.js +112 -465
  82. package/dist/tools/platformInfo.js +8 -27
  83. package/dist/tools/projects.js +9 -71
  84. package/dist/tools/rows.js +13 -69
  85. package/dist/tools/schemaOps.js +1 -61
  86. package/dist/tools/screenWrite.js +8 -37
  87. package/dist/tools/screens.js +5 -95
  88. package/dist/tools/templates.js +1 -26
  89. package/dist/tools/translations.js +1 -1
  90. package/dist/tools/variables.js +5 -11
  91. package/dist/tools/workflows.js +5 -10
  92. package/package.json +2 -2
  93. package/dist/knowledge/access.js +0 -802
  94. package/dist/knowledge/case.js +0 -41
  95. package/dist/knowledge/connectDataBind.js +0 -819
  96. package/dist/knowledge/connectDataDefinition.js +0 -341
  97. package/dist/knowledge/connectDataExecute.js +0 -93
  98. package/dist/knowledge/connectDataRules.js +0 -128
  99. package/dist/knowledge/decision.js +0 -121
  100. package/dist/knowledge/expressionPrelude.js +0 -59
  101. package/dist/knowledge/microserviceParameters.js +0 -58
  102. package/dist/knowledge/mining.js +0 -94
  103. package/dist/knowledge/mobileComponentCatalog.js +0 -859
  104. package/dist/knowledge/mobileComponentEvents.js +0 -239
  105. package/dist/knowledge/platform/lint.js +0 -385
  106. package/dist/knowledge/platform/mobile.js +0 -142
  107. package/dist/knowledge/platform/mobileLayoutLint.js +0 -324
  108. package/dist/knowledge/platform/mobileRules.js +0 -231
  109. package/dist/knowledge/platform/mobileSpacing.js +0 -82
  110. package/dist/knowledge/platform/mobileTabs.js +0 -108
  111. package/dist/knowledge/platform/nativeBoxModel.js +0 -44
  112. package/dist/knowledge/platform/profile.js +0 -25
  113. package/dist/knowledge/platform/resolve.js +0 -122
  114. package/dist/knowledge/platform/web.js +0 -39
  115. package/dist/knowledge/process.js +0 -510
  116. package/dist/knowledge/rowFilter.js +0 -43
  117. package/dist/knowledge/styleResolveNative.js +0 -527
  118. package/dist/platform/argumentAliases.js +0 -128
  119. package/dist/platform/bodyFile.js +0 -103
  120. package/dist/platform/capture/actions.js +0 -333
  121. package/dist/platform/capture/browser.js +0 -1
  122. package/dist/platform/capture/console-log.js +0 -122
  123. package/dist/platform/capture/index.js +0 -11
  124. package/dist/platform/capture/readiness.js +0 -103
  125. package/dist/platform/capture/summary.js +0 -77
  126. package/dist/platform/capture/target.js +0 -5
  127. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  128. package/dist/platform/capture/targets/studio-web.js +0 -5
  129. package/dist/platform/impersonation.js +0 -45
  130. package/dist/platform/jsonArray.js +0 -24
  131. package/dist/platform/schemaReadMemory.js +0 -60
  132. package/dist/resources/examples/bpm-gorev-kontrol.json +0 -294
  133. package/dist/resources/examples/bpm-iso-dokuman.json +0 -228
  134. package/dist/resources/examples/bpm-satinalma.json +0 -376
  135. package/dist/resources/examples/connect-data-convert-verify.json +0 -107
  136. package/dist/resources/examples/connect-data-dropdown-roles.json +0 -66
  137. package/dist/resources/examples/connect-data-edit-m2m.json +0 -73
  138. package/dist/resources/examples/connect-data-query-params.json +0 -50
  139. package/dist/resources/examples/connect-data-table-entity.json +0 -147
  140. package/dist/resources/examples/connect-data-workflow-microservice.json +0 -65
  141. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -243
  142. package/dist/resources/examples/mobile-app-shell-stack.json +0 -157
  143. package/dist/resources/examples/mobile-app-shell-tab.json +0 -208
  144. package/dist/resources/examples/mobile-form-screen.json +0 -365
  145. package/dist/resources/examples/mobile-list-detail-form.json +0 -672
  146. package/dist/resources/guides/access.md +0 -796
  147. package/dist/resources/guides/bpm.md +0 -686
  148. package/dist/resources/guides/case.md +0 -153
  149. package/dist/resources/guides/decision.md +0 -185
  150. package/dist/resources/guides/mobile-layout.md +0 -193
  151. package/dist/resources/guides/mobile.md +0 -495
  152. package/dist/resources/read.js +0 -41
  153. package/dist/resources/schemas/AccessExplanationDto.json +0 -144
  154. package/dist/resources/schemas/AccessMatrixDto.json +0 -170
  155. package/dist/resources/schemas/AccessPermissionDto.json +0 -57
  156. package/dist/resources/schemas/AccessPolicyDto.json +0 -223
  157. package/dist/resources/schemas/AccessResourceDto.json +0 -86
  158. package/dist/resources/schemas/AppSessionDto.json +0 -53
  159. package/dist/resources/schemas/ConnectDataDescribeDto.json +0 -344
  160. package/dist/resources/schemas/ConnectDataRequestModel.json +0 -202
  161. package/dist/resources/schemas/ConnectDataResultDto.json +0 -421
  162. package/dist/resources/schemas/ConnectorCredentialDto.json +0 -70
  163. package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +0 -37
  164. package/dist/resources/schemas/CreateAccessPolicyCommand.json +0 -209
  165. package/dist/resources/schemas/CreateDecisionCommand.json +0 -221
  166. package/dist/resources/schemas/CreateProcessDefinitionCommand.json +0 -1337
  167. package/dist/resources/schemas/DecisionDto.json +0 -302
  168. package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +0 -28
  169. package/dist/resources/schemas/ExplainAccessQuery.json +0 -33
  170. package/dist/resources/schemas/GenerateProcessDocumentCommand.json +0 -116
  171. package/dist/resources/schemas/OrganizationProjectDto.json +0 -335
  172. package/dist/resources/schemas/OrganizationSchemaDto.json +0 -196
  173. package/dist/resources/schemas/OrganizationSchemaVersionDto.json +0 -207
  174. package/dist/resources/schemas/PatchProcessDefinitionCommand.json +0 -76
  175. package/dist/resources/schemas/ProcessDefinitionDto.json +0 -1480
  176. package/dist/resources/schemas/ProcessSimulationDto.json +0 -96
  177. package/dist/resources/schemas/SaveConnectorCredentialCommand.json +0 -90
  178. package/dist/resources/schemas/SaveProcessEventSourceCommand.json +0 -61
  179. package/dist/resources/schemas/SaveProcessMailSourceCommand.json +0 -89
  180. package/dist/resources/schemas/SignProcessTaskCommand.json +0 -73
  181. package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +0 -92
  182. package/dist/resources/schemas/UpdateAccessPolicyCommand.json +0 -209
  183. package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
  184. package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
  185. package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +0 -1339
  186. package/dist/tools/accessOperations.js +0 -135
  187. package/dist/tools/accessPolicies.js +0 -170
  188. package/dist/tools/accessRuntime.js +0 -203
  189. package/dist/tools/bpm.js +0 -343
  190. package/dist/tools/bpmGovernance.js +0 -266
  191. package/dist/tools/bpmOperations.js +0 -230
  192. package/dist/tools/bpmReporting.js +0 -154
  193. package/dist/tools/bpmRouting.js +0 -150
  194. package/dist/tools/bpmRuntime.js +0 -396
  195. package/dist/tools/case.js +0 -178
  196. package/dist/tools/caseRuntime.js +0 -89
  197. package/dist/tools/connectData.js +0 -449
  198. package/dist/tools/connectors.js +0 -193
  199. package/dist/tools/decisions.js +0 -206
  200. package/dist/tools/mobile.js +0 -221
  201. package/dist/tools/modules.js +0 -48
  202. package/dist/tools/organizationStructure.js +0 -137
  203. package/dist/tools/profileWrite.js +0 -92
@@ -1,495 +0,0 @@
1
- # Mobil uygulama rehberi
2
-
3
- Mobil uygulama (`application_create` → `type: 'mobile'`) web uygulamasıyla **aynı şemayı**, aynı
4
- micro-op sözlüğünü ve aynı akış motorunu kullanır; farkı çizerdedir. Sayfalar
5
- `@ng-apps/ui-native` ile React Native olarak çizilir: Studio'da (kanvas, `/preview`, `/dev|/view`)
6
- react-native-web üzerinde, cihazda Expo uygulamasında. Gateway uygulamanın tipini kendisi okur
7
- (platform profili) ve mobilde çizilmeyecek her yazımı `MOB-*` satırıyla söyler — yazım yine
8
- platforma gider, veri düşürülmez.
9
-
10
- **Sözlük.** Bu rehberde "mobil" yalnız **mobil uygulama** demektir. Web uygulamasının telefondaki
11
- dar ekran kırılımı (`hideOn: 'mobile'`, `breakpoint: mobile`) ayrı bir kavramdır ve
12
- `platform_guide('page')` / `platform_guide('layout')`'ta anlatılır; alan adları değişmedi, yalnız
13
- anlamları ayrı.
14
-
15
- ## Kurulum sırası
16
-
17
- 1. **Uygulama ve kabuk.** Tek çağrıda: `mobile_app_create` (uygulama + sayfalar + kabuk layout'u +
18
- sekme ayarı + ana sayfa bağı, `dryRun` ile önce planı görün). Tekil araçlarla aynı sıra:
19
- `application_create({ type: 'mobile' })` → `page_create` × N → `layout_create` (kabuk) →
20
- `page_update({ layoutId })` × N → `application_update({ homepageId, properties.mobile.tabs })`.
21
- Sekme ayarı sayfa **id**'si ister; bu yüzden sayfalardan SONRA yazılır.
22
- 2. **Veri.** Entity, microservice ve workflow web'dekiyle aynıdır (`platform_guide('microservice')`).
23
- Sayfa akışı `microservice` adımıyla aynı uçları çağırır.
24
- 3. **Ekranlar.** `page_schema_patch` ile bileşen ekle, akış bağla (`flow_create` → `set_event`).
25
- 4. **Doğrulama.** `page_screenshot` (mobilde varsayılan `device: 'phone'`, 390x844 @2) ve
26
- `page_runtime_get({ resolveStyles: true })` (düğümün React Native stili). Ayrıntı §Doğrulama.
27
-
28
- `page_create` mobil uygulamada kökü kendisi kurar: `page_container`, `layout` prop'u YOK,
29
- `direction: 'column'`, `blocks: []`, `appearance.heightType: 'fill'` — kök telefon ekranını doldurur.
30
-
31
- ## Bileşenler
32
-
33
- Mobil uygulamanın bileşen kataloğu ayrıdır (backend satırları `(slug, type: 'mobile')`).
34
- `component_list` ve `component_get` mobil uygulamada **kendiliğinden** mobil kataloğu okur.
35
- `component_get` yanıtı `platform: 'mobile'` ile üç katman taşır: `knowledge` (web kaydı — mobil
36
- şema web sınıfını genişlettiği için prop'ların anlamı oradadır), `mobileKnowledge` (bu bileşenin
37
- mobil farkları: düşen prop, değişen etkileşim, mobile özgü prop notları) ve `mobileNotes` (bütün
38
- mobil bileşenlere geçen notlar). Web'de karşılığı olmayan bileşende (`app-bar`, `safe-area`,
39
- `scroll-view`, `choice-chips`, `tooltip`, `markdown`, `calendar`, `stack`, `list-item`, `fab`, `timer`,
40
- `audio`, `lottie`, `webview`, `map`, `grouped-list`, `floating-container`, `skeleton`, `photo-viewer`) bilgi yalnız
41
- `mobileKnowledge`'tadır. Olay yükleri
42
- (`events[].payload`) önce mobile özgü sözleşmeden okunur (`app-bar.clickAction`, `repeater.swipe`,
43
- `choice-chips.change`…), yoksa web'inkinden.
44
-
45
- - **S5 (2026-09-28):** `timeline` (gün başlıkları, küçük resimler) ve `dropdown-button` (⋮ bağlam menüsü) web
46
- ikizleri; `skeleton` (yükleme yer tutucusu) ve `photo-viewer` (tam ekran galeri, `share`/`delete` akışa) mobile
47
- özgü. Tek düğümün `isLoading`'ini kabuk çizer (örtü ya da iskelet). Bileşenlerin kendi hareketi — açılır kap,
48
- çekmece, alt sayfa yayı, toast/FAB girişi, carousel noktası, belirsiz/çizgili `progress`, `icon.isSpinning`,
49
- iskelet parıltısı — kanvasta ve "hareketi azalt"ta durur; kare bu yüzden donuktur (§Doğrulama).
50
- - Katalogda olmayan tip `MOB-003` alır ve backend `unknown-type` (422) ile reddeder. Mobil pakette
51
- olan ama bu uygulamanın kataloğuna yazılmamış tip için gateway katalog senkronunu gösterir; web'de
52
- olup mobilde henüz olmayan için ne zaman geleceğini söyler (Dalga 2, Faz 3).
53
- - **Katalog A** (FlutterFlow paritesi, 2026-09-24) on bileşen ekledi: `badge`, `avatar`, `progress`,
54
- `radio`, `checkboxgroup`, `choice-chips`, `collapsible-container`, `slider`, `tabs`, `tooltip`;
55
- `button` mobilde `secondary`/`ghost`/`link`/`tonal` varyantlarını ve `icon` boyunu alır. Tam liste
56
- `component_list`'tir.
57
- - **Katalog B** (FlutterFlow paritesi) önce dört prop'la başladı; hepsi YALNIZ mobil şemadadır:
58
- `scroll-view.stickyHeader` (ilk çocuk dikey kaydırmada üstte kalır), `numberinput.variant: stepper`
59
- (± düğmeleri, iç roller `__decrement`/`__increment`), `modal.presentation: center | sheet | fullscreen`
60
- (alt sayfa şeritten aşağı sürükleyince `change { isOpen: false }` ile kapanır; en çok ekranın %90'ı,
61
- uzun içerik için içine `scroll-view`). En-boy oranı yeni
62
- prop DEĞİLDİR: boyut panelinin `appearance.aspectRatio`'su mobilde kaplara da uygulanır
63
- (§Yerleşim).
64
- İkinci adımda dört bileşen: `markdown` (Markdown çizer, HTML çalıştırmaz; bağlantı `linkClick { href }`)
65
- ve `calendar` (satır içi takvim, tek gün ya da aralık; prop adları ve `change` biçimi web
66
- `datepicker`ınki) mobile özgüdür; `otpinput` ve `qrcode` web ikizleridir, kuralları web modülünden.
67
- Üçüncü adımda dört bileşen daha: `stack` (katmanlar: ilk çocuk taban, üsttekiler yığının 9 noktalı
68
- `alignment`ıyla hizalanır — çocukta hiza alanı YOKTUR), `list-item` (satır: baş · başlık · alt başlık ·
69
- son; `click`), `fab` (yüzen düğme: sayfanın neresinde olursa olsun ekranın alt köşesinde durur, içerikle
70
- kaymaz; `click`, iç rol `__press`) mobile özgüdür; `carousel` web ikizidir (`activeIndex`,
71
- `slideChange`) ve mobilde bırakılabilir — çocukları sayfalardır.
72
- Dördüncü adım Katalog B'yi kapattı: `timer` (mobile özgü; başlat/duraklat `isRunning`, sıfırlama `value`
73
- yazmak; `tick { value }` her saniye, `finish`), `rating`, `multi-select` (değer `{ label, value }`
74
- dizisi) ve `toast` web ikizleridir. `toast`ın bildirimi sayfadan bağımsız yaşar (`redirect`ten sonra da
75
- görünür), açık modal ya da çekmecenin de üstünde çizilir; akışın tipli `alert` uyarıları cihazda da
76
- toast'tur.
77
- - **Katalog C** (cihaz modüllü bileşenler) medyayla başladı: `video` web ikizidir (cihazda `expo-video`,
78
- kanvas ve önizlemede HTML5 `<video>`; `click` yalnız `controls: false` iken), `audio` (oynat/duraklat,
79
- ilerleme izi; iç roller `__toggle`, `__track`) ve `lottie` (Lottie JSON ya da `.lottie`) mobile özgüdür.
80
- İkisinde çalma `isPlaying` prop'udur: akış `true`/`false` yazar, bileşen `play`/`pause`/`ended` ya da
81
- `finish` olayında `{ isPlaying }` yayar ve prop'u gerçeğe döndürür.
82
- İkinci adım: `signature` web ikizidir (her vuruşta `change { value }` PNG data URL; vuruş sürerken sayfa
83
- kaymaz; iOS 26'da itilmiş sayfada sağa vuruş sayfayı kapatır — platformun geri jesti) ve `webview` mobile özgüdür (web
84
- `iframe`inin karşılığı): `src` ya da `html`; yüklemeden sonra başka belgeye giden gezinme varsayılan olarak
85
- engellenir ve `navigate { url }` yayar, adres yalnız kullanıcının dokunduğu bağlantıda sistem tarayıcısında
86
- açılır (`allowNavigation` görünümde açar); sayfa akışa `window.ReactNativeWebView.postMessage(metin)` →
87
- `message { data }` ile yazar, yüklenemeyen sayfa `error` yayar.
88
- Üçüncü adım: `chart` web ikizidir — seçenek ve olay eşlemesi web'in modülünden gelir, iki platform aynı
89
- ECharts seçeneğini çizer (cihazda SVG); dışa aktarma, tip değiştirici, yenile ve kırıntı araç çubuğu
90
- düşer. `map` mobile özgüdür (cihazda Apple/Google Haritalar, kanvas ve önizlemede Leaflet +
91
- OpenStreetMap): görünüm `latitude`/`longitude`/`zoom` sayılarıdır ve akış yazınca harita oraya gider;
92
- kullanıcı haritayı hareket ettirince `regionChange { latitude, longitude, zoom }` düğüme geri yazılır,
93
- işaretçiye dokunmak `markerClick { markerId }` yayar.
94
- Dördüncü adım: `datepicker`, `timepicker` ve `datetimepicker` web ikizleridir — kutuya dokununca cihazda
95
- işletim sisteminin seçicisi (iOS alttan açılan sayfa, seçim Tamam'la yazılır; Android iletişim kutusu),
96
- önizlemede tarayıcının seçicisi açılır; değer ve `change` yükü web ile aynıdır. Sistem seçicisi tek tek
97
- saati kapatamadığı için `minTime`/`maxTime`/`disabledTimes` dışındaki seçim izinli en yakın saate yaslanır;
98
- `datetimepicker` tek kutudur (`timePlaceholder` yok). `page_screenshot` `set` kökte değil
99
- `<elementId>__input`ta, HTML biçimiyle çalışır (`2026-08-01`, `09:30`, `2026-08-01T09:30`). Tasarım takvim
100
- istiyorsa (Pazartesi başlangıcı, "Bugün / Dün" çipleri, `24.09.2026`): `datepicker` `presentation: calendar` +
101
- `quickPicks` + `displayFormat`; aralık için `daterangepicker` (web ikizi, `valueFrom`/`valueTo`, hep takvim
102
- sayfası). `fileInput` ve `filebutton` de web ikizidir:
103
- değer web gibi base64 veri URL'sidir — bileşen kendisi yüklemez, kayda Table microservice'in FILE
104
- parametresiyle yazılır (§Dosya ve fotoğraf); tür/boyut/adet kapısı ve uyarılar web kuralı.
105
- Seçiciyi mobile özgü `source` seçer — `files` (belge seçici), `library` (fotoğraf arşivi), `camera`,
106
- `ask` (her seferinde sorar; `filebutton`'ın varsayılanı); fotoğraflar `maxImageDimension` (varsayılan
107
- 1600 px uzun kenar) ile küçültülüp `quality` ile sıkıştırılır ve iOS'ta HEIC JPEG'e çevrilir.
108
- Önizlemede tarayıcının dosya penceresi açılır (kanvasta alan kilitli); kırpma yoktur.
109
- - **Liste ve sabit konum** (2026-09-26): `grouped-list` (başlıklı gruplu liste — §Güne göre görev
110
- listesi) ve `floating-container` (ekranın 9 noktasından birine sabit kap — §Ekrana sabit içerik)
111
- mobile özgüdür. `scroll-view`'de ilk çocuk dışındaki doğrudan çocuklar `states.isSticky: true` ile
112
- kaydırırken üstte kalır (Studio panelinde alanı yok; şemaya MCP yazar).
113
- - **Faz 10** (FlutterFlow D listesi): `datatable` web ikizidir — kolon biçimi, sıralama ve sayfa hesabı web'in
114
- modülünden, akış sözleşmesi aynı (sıralama/sayfa değişince `sortField`/`sortType`/`offset` düğüme yazılır ve
115
- `mount` yeniden koşar; satır eylemi `selectedRow`u yazıp eylemin akışını koşturur). Mobile özgü `variant`:
116
- `table` (varsayılan, yatay kaydırılan tablo; başlığa dokunuş `__sort-<kolon>`) ya da `cards` (satır başına
117
- kart). Eylemler `__action-<satır>-<sıra>`, `dropdown` kipinde `__more-<satır>` → alttan eylem sayfası;
118
- sayfa çubuğu `__page-prev`/`__page-next`. Filtre düzenleyicisi, özet satırı ve sabit eylem sütunu yok.
119
- - Web'e özgü bileşenlerin mobil karşılığı:
120
-
121
- | Web | Mobilde |
122
- |---|---|
123
- | `navigations`, `sidebar`, `header`, `layout-shell` | `app-bar` + Ayarlar › Sekmeler + `drawer` widget'ı (`MOB-004`) |
124
- | `popover` | `modal` widget'ı |
125
- | `pagination` | `repeater` + "daha fazla yükle" düğmesi |
126
- | `breadcrumb` | yığın gezinmesi (app-bar geri düğmesi) |
127
- | `iframe` | `webview` (`src` ya da `html`) |
128
- | `theme-toggle` | cihaz teması |
129
- | `fileUpload` | `fileInput` (alan) ya da `filebutton` (düğme) — sürükle-bırak yok |
130
-
131
- **Harici bileşen mobilde yoktur** (`MOB-006`): protokol v1 tarayıcı `.mjs` paketidir;
132
- `external_component_*` araçları mobil uygulamada platforma gitmez. **Geçici yol `html`** (2026-09-28):
133
- katalogda karşılığı olmayan küçük görünüm (özel rozet, SVG, biçimli metin) `html` ile konur — içerik
134
- kendi korumalı belgesinde çizilir (uygulamanın çerezine/jetonuna ulaşamaz), tema `:root` değişkeni
135
- olarak gelir (`hsl(var(--primary))`, `var(--ng-…)`), boy içeriğe göre ayarlanır, bağlantı sistem
136
- tarayıcısında açılır. Akışla iki yön: belgede `fireEvent(key, data)` → `actions` satırının akışı,
137
- `window.ngApps.emit(name, data)` → `message` olayı (`event.name`/`event.data`); akışın `message`
138
- prop'una yazdığı değer belgede `window.ngApps.on(name, fn)` ile alınır. Aynı köprü `webview`de de var.
139
- - **Etkileşim yüzeyleri** (2026-09-27): bileşik kart `container` + `click` ile kurulur (mobile-only olay;
140
- bağlıysa kap runtime'da basılır, içteki düğme kabın `click`ini tetiklemez) — `card` çocuk almaz.
141
- `button` ikonu (`icon` + `iconPosition: left|right|top`) ve rozeti (`badgeValue`, `'•'` nokta) çizer;
142
- `iconPosition: top` + `heightType: fixed` + `variant: tonal` dikey hızlı eylem karosudur. `size: icon`
143
- yalnız glif çizer: `ariaLabel` verin (MOB-013). `icon` `click`/`href` ile basılır, `isDisabled` soldurur.
144
- `modal`/`drawer` `actions` düğme satırı çizer (`action` olayı, `currentItem`; `type: submit` formu
145
- gönderir). Dış bağlantı (`href`) sistem tarayıcısında açılır; uygulama içi yol akışın `redirect`'idir.
146
-
147
- ## Dosya ve fotoğraf
148
-
149
- "Fotoğraf çek → kaydet → listede göster" üç parçadır; yükleme ucu yoktur, dosya kaydın yazıldığı
150
- istekle gider.
151
-
152
- 1. **Tablo.** Entity'ye `dbType: 'FILE'` + `commonType: 'file'` alanı (ör. `foto`; tekil dosya,
153
- `relationId` verilmez — `platform_guide('entity')`).
154
- 2. **Yazma ucu.** Table microservice `operation: 'create'` (ya da `upsert`); `fields`'ta alanı
155
- `{ fieldSlug: 'foto' }` ile listeleyin. Uç gövdede alanın slug'ıyla `type: 'file'` bir parametre
156
- bekler ve değeri `{ type, value, fileName }` biçiminde okur (`TableFileParameter`): `type: 'file'`
157
- base64'ü depoya yazar ve kayda dosya kimliğini koyar, `type: 'ref'` var olan dosyayı (`value` =
158
- dosya id'si) bağlar, `value: null` alanı boşaltır. Dosya alanının DEĞERİ bu biçimdedir — dönüştürmeyin.
159
- 3. **Form sayfası.** `fileInput` (`source: 'camera' | 'library' | 'ask'`) ya da `filebutton` + kaydet
160
- düğmesi. Düğmenin akışında `microservice` adımı, parametre alanın değerini olduğu gibi taşır:
161
-
162
- ```json
163
- { "name": "foto", "type": "file", "source": "body",
164
- "value": { "type": "property", "ref": { "element": "foto_in", "property": "value" } } }
165
- ```
166
-
167
- Base64 gövdeyle gider: fotoğraflar istemcide `maxImageDimension` (1600 px) ile küçültülür,
168
- `maxFileSizeMb` mobilde varsayılan 10'dur — ikisini de sıfırlamayın. Kamera izni reddedilirse alan
169
- Ayarlar'a yönlendiren bir uyarı gösterir.
170
- 4. **Liste.** `get` ucu FILE alanını `{ id, type: 'ref', value: <dosya id>, absolute_path: <url>,
171
- fileName }` olarak döndürür. `image.src`, `avatar.src`, `card.image`, `list-item.leadingImage`'a
172
- **nesnenin kendisini** verin: `{ "type": "code", "ref": "{{ item.foto }}" }` (`.absolute_path` da
173
- çalışır). `{{ item.foto.value }}` dosya **kimliğidir** (GUID), görsel çizilmez — `MOB-011` uyarır.
174
- Gateway alan tipini şemadan bilemediği için uyarı metinseldir: `.value` ile biten en az üç parçalı
175
- yol (`urlInput.value` gibi bileşen değeri ve `fileInput1.value.value` uyarı almaz).
176
-
177
- Workflow'un dosya yükleme adımı yalnız `{ id }` döndürür (URL yok); görsel adresi kaydı okuyan uçtan
178
- gelir. `page_screenshot` ile listede görseli doğrulayın.
179
-
180
- ## Güne göre görev listesi
181
-
182
- Başlıklar altında gruplanmış liste (güne, odaya, kategoriye göre) **tek `grouped-list`** ile kurulur.
183
- İç içe repeater `PAGE-013` ile reddedilir; `textarea` hilesi de gerekmez — liste düz satır dizisidir,
184
- bölümleri bileşen render anında çıkarır.
185
-
186
- 1. **Veri.** Düz satırlar (ör. `q_tasks` sorgusu: `title`, `dueDate`, `done`). Sıralama sorguda
187
- değil bileşende: `sectionOrder` `asc` (varsayılan) · `desc` · `asis`.
188
- 2. **Düğüm.** `rows: { type: 'code', ref: '{{ q_tasks.data }}' }`, `groupBy: 'dueDate'` (noktalı yol
189
- olabilir: `plant.room`). Tarih/saat değeri cihazın yerel gününe (`2026-09-26`) indirgenir; alanı
190
- boş satırlar en sonda `otherSectionTitle` (varsayılan `Other`) bölümündedir.
191
- 3. **Çocuklar konumsaldır:** çocuk 0 bölüm başlığı, çocuk 1 öğe şablonu; fazlası çizilmez.
192
-
193
- ```json
194
- { "elementId": "tasks", "name": "tasks", "type": "grouped-list",
195
- "props": { "rows": { "type": "code", "ref": "{{ q_tasks.data }}" },
196
- "groupBy": { "type": "static", "data": "dueDate" },
197
- "itemPressable": { "type": "static", "data": true } },
198
- "children": [
199
- { "elementId": "day_title", "name": "day_title", "type": "text",
200
- "props": { "content": { "type": "code", "ref": "{{ Section.title }} · {{ Section.count }}" } } },
201
- { "elementId": "task_row", "name": "task_row", "type": "container", "props": {},
202
- "children": [ { "elementId": "task_title", "name": "task_title", "type": "text",
203
- "props": { "content": { "type": "code", "ref": "{{ item.title }}" } } } ] } ] }
204
- ```
205
-
206
- Başlık `Section` okur (`{ key, title, count, items }`), satır kapsamı taşımaz; bölüm dışında
207
- `Section` boş nesnedir (`Row` gibi). Öğe repeater satırıyla aynıdır: `Row`, `RowIndex`,
208
- `{{ item.<alan> }}`; akışta tıklanan satır `tasks.selectedItem`. Şablon çocukları setter hedefi
209
- değildir — satır dışına (sayfadaki bir metne, modala) yazın.
210
- 4. **Olaylar.** `itemPress { index, row }` (yalnız `itemPressable`; öğe şablonu `list-item`/`button`
211
- ise dokunuş onun `click`'ine gider), `swipe { key, index, row }` (`swipeActions`),
212
- `change { selectedIndex }`, `sectionPress` (yük `Section`). `index` `rows` içindeki DÜZ indekstir.
213
- 5. **Yapışkan gün başlığı.** `stickySectionHeaders: true` + `appearance.heightType: 'fixed'` +
214
- `heightString`. Sayfanın kendisi kaydırıcıdır; `auto` ya da `fill` liste içerik kadar uzar ve başlık
215
- yapışmaz. Başlık kabına kendi zeminini verin.
216
-
217
- ## Ekrana sabit içerik — FAB, alt eylem çubuğu, üst şerit
218
-
219
- Mobil şemada `style.position`/`zIndex` yoktur (`MOB-002`); sayfa kayarken yerinde duran içerik iki
220
- bileşenle kurulur. İkisi de sayfanın neresine konursa konsun runtime'da ekran katmanına taşınır —
221
- düğümü sayfa kök kabının SONUNA koyun (akıştaki yeri boş kalır).
222
-
223
- - **Sağ alt tek düğme:** `fab` (`position: bottom-right | bottom-center | bottom-left`, `icon`,
224
- `click`). Sekme çubuğu varsa onun üstünde, kenardan 16 dp.
225
- - **Alt eylem çubuğu / birden çok düğme / üst ya da orta çapa:** `floating-container`.
226
- `anchor` 9 nokta (`top-left` … `bottom-right`, varsayılan `bottom-right`), `offsetX`/`offsetY` (dp,
227
- varsayılan 16, çapalı kenardan içeri), `fullWidth` (alt/üst orta satırı kaplar; `offsetX` yok
228
- sayılır), `respectSafeArea` (varsayılan açık). Alt eylem çubuğu:
229
-
230
- ```json
231
- { "elementId": "action_bar", "name": "action_bar", "type": "floating-container",
232
- "props": { "anchor": { "type": "static", "data": "bottom-center" },
233
- "fullWidth": { "type": "static", "data": true } },
234
- "children": [ { "elementId": "bar", "name": "bar", "type": "container",
235
- "props": { "direction": { "type": "static", "data": "row" } }, "children": [] } ] }
236
- ```
237
-
238
- Kabın kendi yüzeyi yoktur: zemin, köşe, gölge ve iç boşluk içerideki kaba (`surfaceStyle`) verilir.
239
- Dip sekme çubuğunun tepesidir — `aboveTabBar` diye bir prop YOKTUR. App-bar sayfayla kayar; üst
240
- çapalı kap app-bar'ın üstüne biner, sabit app-bar'ın altına `offsetY` ile inilir (ör. 72).
241
- - **Kaydırırken üstte kalan başlık:** `scroll-view` içinde ilk çocuk `stickyHeader: true`, diğer
242
- doğrudan çocuklar düğüm durumu `states: { isSticky: true }` ile (yalnız dikey; kaydırıcıya `fixed`
243
- boy verin). Sayfayı örten katman için `modal` / `drawer` widget'ı.
244
-
245
- `page_screenshot` (viewport karesi, `layoutReport: true`) sabit içeriğin çapalı noktada, sekme çubuğunun
246
- üstünde durduğunu gösterir; uzun sayfada içerik kabın altından akar.
247
-
248
- ## Yerleşim — yalnız flex
249
-
250
- > **Mizanpaj sözleşmesi** (güvenli alan, kaydırma, kenar boşluğu, aralık ritmi, genişlik, yarıçap/yazı ölçeği,
251
- > MOB-015…021 reçeteleri): `platform_guide('mobile-layout')`. Bu bölüm yalnız flex modelini anlatır.
252
-
253
- Mobil çizer 12 sütunlu ızgarayı **okumaz**: sıra dizi indeksidir, yerleşim flex'tir.
254
-
255
- - `blocks[]`, `set_block`, `layout: 'grid' | 'cssgrid'` yazılır ama çizilmez (`MOB-001`).
256
- `add_component` / `move_component`'ın `index`'i dizideki sıradır; gateway konum çevirisi yapmaz.
257
- - Kaplar flex kabıdır: `direction`, `gap`, `horizontalAlign`, `verticalAlign`, `wrap`, `size`.
258
- Mobil `container` şemasında `layout` prop'u yoktur.
259
- - Ölçü `appearance` ile: `widthType: 'fill' | 'auto' | 'fixed'` (+ `widthString`),
260
- `heightType: 'fill' | 'auto' | 'fixed'` (+ `heightString`). `fill` kalan alanı alır.
261
- - En-boy oranı `appearance.aspectRatio` (sayı; 16:9 için `1.78`): boy genişlikten türer. Koşullar:
262
- `heightType: 'auto'` ve genişlik belli — `widthType: 'fill'` ya da `'fixed'` (içerik genişliğinde
263
- web ile cihaz oranı ters yönden çözer, uygulanmaz). Web'den farkı: mobilde **akış kapları** da oran
264
- alır (`container`, `form`, `safe-area`, `scroll-view`) ve akışları oranlı boyu doldurur; öteki
265
- bırakılabilir tipler, widget örneği, sayfa kökü ve `modal`/`drawer` almaz; `image` oranı kendi
266
- çizimine yazar.
267
- - `image` boyu: `heightType: 'fixed'` + `heightString` (`px`/`%`) ya da `'fill'` → görsel kabuğu doldurur
268
- (`%` ve `fill`de 96 dp taban boyun altına inmez: atası içerik boyundaki kapta yüzde çözülmez); yoksa `aspectRatio` + `heightType: 'auto'` + belli genişlik → boy orandan; ikisi de yoksa 96 dp taban boy
269
- ve MOB-012 bilgi satırı. Küçük resim için `widthType: 'fixed'` + `widthString` + oran `1` kullanın.
270
- - Satırda (`direction: row`) `widthType: 'fill'` kalan genişliği alır ve uzun metinde daralıp kırılır;
271
- `heightType: 'fill'` satırın yüksekliğine gerilir. Esnek `spacer` (`mode: 'flex'`) kabın ana ekseninde
272
- kalanı ister — [metin · spacer · düğme] düğmeyi sağa yaslar. Web ile aynı kural (ZM-15; 2026-09-29'a dek
273
- cihazda `fill` içerik genişliğinde kalıyordu).
274
- - Hiza (`verticalAlign` `top | middle | bottom`, `horizontalAlign` `left | center | right`) web ile
275
- aynıdır. Dikey hizanın boşluğu kabın boyundan gelir: `heightType` `fill`, `fixed` ya da oranlı kapta
276
- akış kabın boyunu doldurur; boyu içerikten gelen sütun kapta dikey hiza etkisizdir (satır kapta farklı
277
- boydaki kardeşleri yine hizalar). `stretch` de web gibi: ana eksende çocukları yayar, çapraz eksende gerer.
278
- - Birim: `px` ve `%`. `em`/`rem` tema puntosuyla çarpılır; `calc()` ve `vw/vh` React Native'de yoktur
279
- (`MOB-002`).
280
-
281
- ## Görünüm — tipli gruplar
282
-
283
- React Native'de CSS yoktur; tipli stil grupları **derlenir** (web'in `composeTypedStyle` ikizi,
284
- aynı katman sırası: tema taban → gruplar → serbest `style`).
285
-
286
- - `surfaceStyle` → zemin, köşe, kenarlık, gölge (tek katman), opaklık, taşma; döndürme `rotate`
287
- (derece), ölçek `scale` (yüzde, 100 aynı boy), kaydırma `translateX`/`translateY` (px). Sıra web
288
- ile aynı (kaydır → döndür → ölçekle, köken merkez), düğüm çocuklarıyla döner. Değer birimsiz sayıdır
289
- (`'15deg'` yazılmaz); aralık dışı (`rotate` ±360, `scale` 10–500, kaydırma ±1000) yazılmaz ve
290
- `nativeStyle.warnings`'e düşer. Katman ve kabukta (`modal`, `drawer`, `app-bar`) bu dört alan yoktur.
291
- - `typographyStyle` → renk, aile (tek ad), punto, kalınlık, hizalama, satır yüksekliği.
292
- - Tema token'ları (`var(--ng-*)`) sayılara çözülür; proje teması değişince mobil de değişir.
293
-
294
- Çizilmeyen alanlar (`MOB-002`) ve yerine ne:
295
-
296
- | Alan | Yerine |
297
- |---|---|
298
- | `className` | `surfaceStyle` / `typographyStyle` |
299
- | serbest `style` nesnesi (alt seçici `&:hover`, `&__body`) | tipli gruplar; düz anahtarlar (ör. `padding`) çevrilir, alt seçici düşer. İstisna `html`: metin (ya da koda bağlı) `style` kendi belgesinin CSS'idir ve çizilir; statik nesne `style` orada da düşer |
300
- | `hoverStyle` | yok — dokunmatikte üzerine gelme durumu yoktur |
301
- | `tooltip`, `tooltipPosition` | düğümü `tooltip` bileşenine sarın (dokunuşla açılır, yanı `side`) ya da açıklamayı metin olarak koyun |
302
- | `zIndex`, `style.position` | görsel üstüne bindirme (rozet, hap, tarih etiketi, açıklama bandı, arka plan görseli): `stack` — ilk çocuk taban, ötekiler üst katman; her köşe için `fill`×`fill` bir `container` katmanı kendi hizasıyla; görselin altına binen kart: kartın üst boşluğu negatif (`marginValues.top: -28`); ekrana sabit: `floating-container` / `fab`; yapışkan başlık: `scroll-view` çocuğunda `states.isSticky`; örten katman: `modal` / `drawer` (§Ekrana sabit içerik) |
303
- | `surfaceStyle`'ın tanımadığı alt anahtar (ör. CSS `transform` metni, `padding`) | grubun tipli alanları; döndürme/ölçek/kaydırma `rotate`, `scale`, `translateX`/`translateY` |
304
-
305
- Düğümün gerçek stilini görmek: `page_runtime_get({ applicationSlug, pageSlug, resolveStyles: true })`
306
- → her düğümde `nativeStyle: { shell, text, warnings }` (`shell` kutunun, `text` içine akan metnin
307
- stili; RN'de tipografi miras alınmaz). Yanıtta `styleResolver: 'native'`. Temanın katmanı
308
- (`componentStyles[tip]` ← `$preset`) TABANDIR: panel grupları üstüne biner, düğümün serbest `style`'ı son söz — rapor
309
- da onu içerir. Mobilde tasarım sisteminin yolu `componentStyles`'tır (`theme_update`; tipin bütün düğümlerine iner).
310
- Mobil katalogda `style` prop'u olmadığı için düğüme yeni `$preset` başvurusu yazılamaz; kayıtlı (ör. web'den taşınmış)
311
- düğümün işareti çözülür. Katman düğümün kabuğuna çizilir: yüzeyini kendi çizen `button`'da zemin ve köşe kabukta
312
- kalır, düğmenin kendi rengi `kind`'dan gelir (bilinen fark).
313
-
314
- ## Görünüm — shadcn/ui
315
-
316
- Bileşenler shadcn/ui görünümünde çizilir (react-native-reusables ilkelleri, NativeWind). Renk ve
317
- köşe yine **proje temasından** gelir: `--ng-*` değişkenleri shadcn token'larına köprüyle çevrilir
318
- (`--primary` ← `accent.primary`, `--destructive` ← hata rengi, `--border`, `--input`, `--ring`…).
319
- `theme_update` web'i ve mobili birlikte değiştirir; koyu kip aynı köprünün ikinci çözümüdür. Ölçü
320
- (alan yüksekliği, punto, iç boşluk) temanın `--ng-form-*` değişkenlerinden gelir. Yazı **ailesi**
321
- köprüde yoktur: temanın ailesi alanlarda, başlıklarda ve sekme çubuğunda uygulanır; `text` ve düğme
322
- etiketi ailesini `typographyStyle`'dan alır, alan etiketleri platform yazı tipiyle çizilir.
323
-
324
- - `button`: `kind` rengi, `variant` kullanımını seçer — `solid` dolu (`kind: error` → shadcn
325
- `destructive`), `outline` çerçeveli, `text`/`ghost` zeminsiz; mobilde ayrıca `secondary` (nötr
326
- dolgu) ve `link`. `info`/`success`/`warning` → temanın `--status-*` renkleri. Eşlemenin tamamı ve
327
- bilinen sınırlar: `component_get('button')` → `mobileKnowledge.propNotes`.
328
- - `switch` platformun kendi anahtarı DEĞİLDİR: üç barındırıcıda (kanvas, önizleme, cihaz) aynı
329
- shadcn anahtarı çizilir; kanvasta basılamadığı için soluk görünür.
330
- - Web sayfası kendi bileşen ailesiyle çizilir; iki platformun görünüm farkı bilinçlidir, ortak olan
331
- temadır. Yakalama seçicileri (`role="button"`, `__tabs__item-<slug>`, `submit` köprüsü) görünümden
332
- bağımsızdır (§Doğrulama).
333
-
334
- ## Gezinme
335
-
336
- - **Yığın varsayılandır; ayar yoktur.** `redirect` adımı hedef sayfayı yığına iter, geri hareketi
337
- (cihaz geri tuşu, app-bar geri düğmesi, tarayıcı geri) önceki ekrana döner. Göreli yol uygulama
338
- köküne eklenir; tam adres (`https://…`) dışarıda açılır.
339
- - **Sekmeler uygulama ayarıdır, layout'ta değil.** `application_update({ properties: { mobile: { tabs } } })`:
340
-
341
- ```json
342
- {
343
- "mobile": {
344
- "tabs": {
345
- "enabled": true,
346
- "style": "default",
347
- "items": [
348
- { "page": "<page_list id>", "label": "Görevler", "icon": "list" },
349
- { "page": "<page_list id>", "label": "Profil", "icon": "user" }
350
- ],
351
- "showLabels": true
352
- }
353
- }
354
- }
355
- ```
356
-
357
- `items` 1–5 sayfa **id**'si (slug değil), tekrar yok; `style: 'floating'` köşe `pill` + gölge `md`
358
- çizer. Çubuğun rengi ayarda YOKTUR: zemin `surface`, seçili `accent-primary`, seçilmemiş
359
- `text-secondary` — değiştirmek için `theme_update`; eski `appearance` alanı okunmaz; `style: 'custom'` + `customWidgetId` çubuğu kendi widget'ınla çizer. Tutarsız ayar ve
360
- layout/sayfada eski `tab-bar` / `drawer-menu` düğümü `MOB-007` alır. Sekme dışı sayfalar yığına açılır.
361
- - **Çekmece bir bileşendir.** `drawer` widget'ı + `app-bar`'ın `menuTarget` prop'u çekmeceyi açar.
362
- - Kabuk örnekleri: `ngapps://examples/mobile-app-shell-stack` (yığın), `ngapps://examples/mobile-app-shell-tab`
363
- (sekmeler), `ngapps://examples/mobile-app-shell-drawer` (çekmece); üç sayfalık liste → detay → form akışı:
364
- `ngapps://examples/mobile-list-detail-form`.
365
-
366
- ## Çok dil
367
-
368
- Mobil uygulama web ile **aynı sözlüğü ve aynı motoru** kullanır (plans/mobil-coklu-dil, 2026-09-25):
369
- `project_update(languages, defaultLanguage)` → prop'u bağla (`set_prop_type(target, prop, 'translation', ref)`)
370
- → `translation_update`. Kurulum ve fallback zinciri `platform_guide('translation')`.
371
-
372
- - **Dil değiştirici:** `language-selector` mobil katalogdadır (`component_get` → `mobileKnowledge`):
373
- `dropdown`un listesi (az dilde alanın altında, çok dilde alt sayfada), tetikleyici `role="combobox"`,
374
- seçenekler `displayMode`'a göre dilin yerel adıyla (`tr` → Türkçe), koduyla (`TR`) ya da ikisiyle. Seçim `machine.setLanguage` ile bütün prop'ları yerinde çözer ve cihazda uygulama
375
- çapında yayılır: öteki sekmelerin ekranları ve sekme etiketleri de değişir, makine yeniden kurulmaz.
376
- - **Cihazda boot sırası:** uygulama içi seçim → cihazda kayıtlı seçim (`zeyrek:<app>:lang`) → cihaz dili
377
- → projenin varsayılanı. `?lang` CİHAZDA YOKTUR; `/preview`'da vardır, bu yüzden `page_screenshot(language:)`
378
- mobil sayfada da çalışır — kanıt için sayfaya seçici koymak gerekmez.
379
- - **Sekme etiketi:** `properties.mobile.tabs[].label` `t:<anahtar>` ile çevrilir (doğrulama mesajıyla aynı
380
- önek); `mobile_app_create` `tabs[].label` de kabul eder. Sayfa adı fallback'i düz kalır.
381
- - **Çerçeve:** cihazda `alert`/`confirm` düğmeleri (`Tamam`/`Evet`/`Hayır` ↔ `OK`/`Yes`/`No`) uygulama dilini
382
- izler; mesaj gövdesi akışın kendi metnidir.
383
- - **Doğrulama:** `page_screenshot({ language: 'en' })` ikinci dilin karesi;
384
- `page_screenshot({ actions: [{ select: '<seçici elementId>', value: 'en' }] })` seçiciyi sürer
385
- (`optionsSeen` proje dili sayısıdır); seçici sonrası sekme çubuğunun `t:` etiketleri de aynı karede
386
- çevrilir (ölçüldü 2026-09-25: `Ana/Liste`).
387
- - **Doğrulama mesajı:** form alanlarının `t:` doğrulama mesajı web'deki gibi uygulama dilinde çözülür (form
388
- doğrulaması 2026-09-28'den beri mobilde de koşar; akış `validation` adımı da aynı çözümü kullanır).
389
-
390
- ## Akış adımları
391
-
392
- Motorun kendi adımları (`setter`, `condition`, `microservice`, `code`, `function`, `flow-trigger`,
393
- `validation`) iki platformda aynıdır. Barındırıcıya dokunan adımlar:
394
-
395
- | Adım | Mobilde |
396
- |---|---|
397
- | `redirect` | yığına iter (göreli yol) ya da dışarıda açar (tam adres) |
398
- | `navigate` | eski mobil şemaların adı — `redirect`'in takma adıdır; gateway `redirect`'e çevirir |
399
- | `alert` | tipli uyarı (`success`/`error`/`info`/`warning`) toast'tur ve beklemez; düz uyarı onay bekler. Eylem düğmeli bildirim ("Silindi · Geri al") `alert`le kurulmaz: sayfaya bir `toast` bileşeni koyun (`actions: [{ text, flow }]`, gerekirse `keepOpen`), akış setter'la `isOpen: true` yazar; basış eylemin kendi akışını koşar (`actionClick { text, index }`) |
400
- | `confirm` | `yes` / `no` dalları |
401
- | `download` | adres cihazın açma sayfasında açılır; ikili gövde (JSON değil) önbelleğe dosya olarak yazılıp paylaşım sayfasında (`expo-sharing`) açılır, Studio mobil önizlemesi dosyayı indirir (`MOB-005`, bilgi) |
402
- | `storage` | `args.name` `state.page.<key>` / `state.app.<key>` ise o state'i yazar (§Kalıcı state), değilse cihaz deposuna |
403
- | `setcookie` | cihaz deposuna yazar (`MOB-005`, bilgi); Studio paleti mobilde de sunar |
404
- | `share` | RN paylaşım sayfası (metin + bağlantı; Android'de bağlantı metne eklenir, `title` iOS'ta e-posta konusu, Android'de seçici başlığı); akış `always` ile sürer — iOS'ta sayfa kapanınca, Android'de seçici açılır açılmaz (RN kapanışı bildirmez). Argümanlar `platform_guide('page')` §`share` adımı |
405
- | `haptic` | dokunsal geri bildirim (`expo-haptics`, izin istemez). `args.value` stil, **düz metin**: `success` · `warning` · `error` · `light` · `medium` · `heavy` · `selection`; boş → `medium`. Değer yazmaz, hep `always`. Web'de titreşim varsa kısa titreşim, yoksa hiçbir şey (paletten yalnız mobilde sunulur) |
406
- | `location` | cihaz konumu (`expo-location`; ilk kullanımda izin sorulur). `args.value` doğruluk, düz metin: `low` · `balanced` · `high` (boş → `balanced`); `args.isRaw: true` → adres çözülmez. Sonuç `Steps.<adım>.data = { latitude, longitude, accuracy, address }`, `address = { country, region, subregion, city, district, street, postalCode }` ya da `null` (Türkiye'de il `region`, ilçe `subregion`, yoksa `city`). İzin reddi `Steps.<adım>.error = { status: 'denied', message }`, okunamayan konum `unavailable`: adımın `error` dalı bağlıysa o koşar (`always` koşmaz), yoksa akışın hata akışı, o da yoksa `always` (`data: null`). Web'de tarayıcı konumu, adres hep `null` |
407
-
408
- | `notification-permission` | bildirim izni ister (sorulmuşsa yeniden sormaz, kalıcı red yeniden sorulmaz). Sonuç `Steps.<adım>.data.status`: `granted` · `denied` · `undetermined`; red hata değildir, hep `always` |
409
- | `notification-schedule` | yerel bildirim planlar (`expo-notifications`; uzak push değil). `args.name` kimlik (düz metin; aynı kimlik eskisinin yerini alır), `args.title` başlık (düz metin), `args.message` gövde (**ifade**), `args.value` zaman (**ifade**): sonucu `'HH:mm'` → her gün, `{ weekday: 1–7, time: 'HH:mm' }` → her hafta (1 = Pazartesi), ISO tarih-saat → bir kez. `args.path` dokununca açılacak sayfanın slug'ı (+ `args.query` ifade), boşsa uygulama açılır. İzin yoksa `error.status: 'denied'`, geçmiş ya da okunamayan zaman `invalid`: `error` dalı → hata akışı → `always`. Web'de desteklenmez (`unsupported`) — sayfa kapalıyken tarayıcı gösteremez |
410
- | `notification-cancel` | `args.name` kimlikli planlı bildirimi siler, `'*'` hepsini; hep `always` |
411
-
412
- Bildirim adımları paletten yalnız mobil uygulamada sunulur. Tarif — S04 "her gün hatırlat": önce
413
- `notification-permission` (S03 düğmesi), sonra `timepicker`'ın değeriyle `notification-schedule`
414
- (`value: "<saat>.value"`, değer `HH:mm`) ve `error` dalında kullanıcıya mesaj. Çevrimdışı bandı adım değil
415
- ifadedir: `isHidden: {{ Device.isOnline }}` (`platform_guide('expressions')`).
416
-
417
- `style`, `accuracy`, `reverseGeocode` gibi anahtarlar sözleşmede yoktur ve platform onları sessizce düşürür
418
- (`FLOW-029`). "Haritada aç" için adım yoktur: `map`'in `press` olayı düğüme `mapsUrl` yazar, akış
419
- `redirect` `isRaw: true`, `path: '<harita>.mapsUrl'` ile açar. Tarif — L05 "mevcut konumumu kullan":
420
- düğmenin `click`'i → `location` (`always` → setter `il.value = Steps.konum.data.address?.region`, `error` →
421
- setter hata metni). Uzak push bildirimi (sunucudan) bu sürümde yoktur.
422
-
423
- Sayfa ve layout `mount` akışları ilk çizimden sonra, `destroy` akışları sayfa kalkarken koşar.
424
- `Functions.<ad>()` uygulama ve sayfa fonksiyonlarını görür (`platform_guide('functions')`).
425
-
426
- ## Kalıcı state
427
-
428
- State varsayılan olarak **bellektedir**: sayfa her açıldığında `variable_create`'te yazılan `value`'dan
429
- başlar, akışın yazdığı değer ekran kapanınca kaybolur. Uygulama kapanıp açıldığında kaldığı yerden
430
- sürmesi gereken değer için değişkene saklama türü verin:
431
-
432
- | `storage` | Depo | Ne için |
433
- |---|---|---|
434
- | verilmez / `memory` | bellek | ekran ömrü kadar yaşayan değer: seçili satır, açık sekme |
435
- | `device` | cihaz deposu (AsyncStorage karşılığı; `expo-sqlite/kv-store`) | sepet, son filtre, "karşılama görüldü" |
436
- | `secure` | güvenli depo (`expo-secure-store`, anahtarlık) | uygulamanın kendi token'ı gibi gizli ve **küçük** değer |
437
-
438
- ```jsonc
439
- variable_create({ applicationId, pageId, variables: [
440
- { "key": "sepet", "value": { "adet": 0 }, "storage": "device" }
441
- ]})
442
- ```
443
-
444
- - Okuma ve yazma değişmez: `{{ state.page.sepet.adet }}`, kod adımında `state.page.sepet.adet = 3`.
445
- Yazım depoya da gider, ayrı "kaydet" adımı yoktur. İç alana yazınca üst anahtarın (`sepet`) tamamı saklanır.
446
- - Açılışta depodaki değer `value`'nun önüne geçer; depoda değer yoksa `value` kullanılır — `value`
447
- **ilk açılış** değeridir. Saklı değerin biçimi sonradan değiştirdiğiniz `value` ile uyuşmuyorsa saklı
448
- olan kazanır; sıfırlamak için anahtarı yeniden adlandırın.
449
- - `pageId` verilmeden tanımlanan değişken (`state.app`) uygulama kapsamındadır: her sayfa açılışta aynı
450
- saklı değeri okur. Açık iki sekme birbirinin yazdığını canlı görmez — değer sayfa açılırken okunur.
451
- - Çıkışta (kullanıcının çıkışı ya da oturumun düşmesi) iki depodaki state değerleri silinir.
452
- - Ortamlar ayrıdır: `development`'ta saklanan değer `production`'da okunmaz.
453
- - `variable_update` `storage` vermezse kayıttaki tür korunur; belleğe çevirmek için `storage: 'memory'`.
454
- `value` vermezseniz kayıttaki değer de korunur — yalnız türü değiştirmek için `{ key, storage }` yeter.
455
- - Web uygulamasında tür kayda yazılır ama uygulanmaz (`MOB-014`).
456
- - Akıştan kalıcı state yazmanın iki yolu var: kod adımında `state.page.<key> = …`, ya da `storage` adımında
457
- `args.name: 'state.page.<key>'` (ya da `state.app.<key>`) + `args.value` ifadesi — adım state'e yazar, state
458
- kendi saklama türüyle kalıcılaşır ve ekran anında yenilenir. Studio'daki Storage düzenleyicisi anahtarı
459
- state listesinden seçtirir. Başka bir `args.name` eskisi gibi cihaz deposuna adıyla yazar ve ifadeler onu okuyamaz.
460
-
461
- ## Doğrulama
462
-
463
- - `page_screenshot({ applicationSlug, pageSlug })` mobil uygulamada `device: 'phone'` (390x844, kare
464
- 780x1688 px) çeker; `'tablet'` 820x1180 @2 ya da `{ width, height, scale? }`. `viewport` verilirse
465
- cihaz yok sayılır (`deviceNote`). Yanıt `applicationType: 'mobile'` ve `platformNote` taşır: kare
466
- react-native-web çizimidir, cihazdakiyle yapısal olarak (düğüm, sıra, ölçü, renk) aynıdır.
467
- - Eylemler aynı sözlük: `click` basılabilir öğeyi (`role="button"`) bulur; `submit` runtime
468
- köprüsüyle gider (`submitVia: 'bridge'`); sekme öğesi `__tabs__item-<sayfa slug'ı>`, çubuk `__tabs`
469
- özet satırıdır. `select` açılır listeyi açar ve seçeneği değerle ya da görünen metinle seçer
470
- (liste katmanda açılır, `optionsSeen` kaç seçenek görüldüğünü söyler); `tab` bir `tabs`
471
- bileşeninin sekmesini anahtarıyla (`<elementId>__tab-<anahtar>`) bulur.
472
- - `flowRuns: 0` + `requests: 0` bir tıklamada akışın koşmadığını söyler: olay bağını
473
- `page_runtime_get`, akışı `flow_get` ile doğrulayın.
474
- - Kuru doğrulama: `page_schema_validate` mobil kataloğa karşı doğrular (`MOB-003`).
475
- - Kare **donuktur**: bağlam "hareketi azalt" ile açılır, bileşen hareketi (giriş, döngü, geçiş, iskelet parıltısı,
476
- kabuğun yükleme göstergesi) durur, aynı sayfanın iki karesi aynı çıkar. Hareketin kendisini görmek için
477
- `motion: 'play'` (kare çekildiği ana bağlıdır; yanıt `motionNote` taşır).
478
-
479
- ## Cihazda önizleme
480
-
481
- Expo uygulaması (`apps/mobile-runtime`) aynı sayfayı native çizer. Derin bağlantı
482
- `zeyrek://open/{proje}/{uygulama}/{sayfa}?env=<ortam>` **token taşımaz**: cihazdaki uygulama zaten giriş
483
- yapmış olmalıdır. Canlı önizleme sayfa şeması değişikliğini (`/hubs/page-schema`) dinler; yazdığın
484
- yama cihazda yenilenir.
485
-
486
- ## Bilinen farklar
487
-
488
- - Piksel paritesi yoktur: yazı tipi ölçüsü, gölge ve güvenli alan cihaza göre değişir. Parite yapısaldır.
489
- - Bileşen kataloğu dalga dalga gelir; `component_list` ne döndürüyorsa odur.
490
- - Uygulama içi tema seçimi (Sistem / Açık / Koyu) bir ayardır, bileşen değil: akış `storage` adımıyla
491
- `zeyrek:theme-mode` anahtarına `system` · `light` · `dark` yazar (ör. segmentli `choice-chips`'in `change`'i,
492
- `value: '<çipler>.value'`); barındırıcı anahtarı dinler, tema anında döner ve cihazda kalıcıdır — durum çubuğu da
493
- izler. Web'in `theme-toggle`'ı mobilde yoktur. Seçili düğme saklanan seçimi `LocalStorage`'dan okur:
494
- `{{ LocalStorage['zeyrek:theme-mode'] || 'system' }}` (ARC-147).
495
- - Dar ekran kırılımı (`hideOn: 'mobile'`) mobil uygulamada anlamsızdır: ekran zaten tek boydur.
@@ -1,41 +0,0 @@
1
- import { constraintCatalog } from '../knowledge/backendConstraints.js';
2
- import { connectDataRuleCatalog } from '../knowledge/connectDataRules.js';
3
- import { listKnowledgeFiles, readKnowledgeFile } from './knowledge.js';
4
- /** `ngapps://rules/<ad>` kaynakları; docs-lint bu listeyle `ngapps://rules/…` referanslarını denetler. */
5
- export const ruleResourceNames = ['backend-constraints', 'connect-data'];
6
- export function ruleResourceBody(name) {
7
- return name === 'backend-constraints' ? constraintCatalog() : { rules: connectDataRuleCatalog };
8
- }
9
- /**
10
- * 38/M-14 (D-7): rehberler `ngapps://rules/…` ve `ngapps://examples/…` kaynaklarına yönlendiriyor, ama resource
11
- * okuması olmayan MCP istemcisinde (ölçüldü: Claude Code oturumunun araç setinde okuma aracı yoktu) bu yönlendirme
12
- * çıkmaz sokaktı. `platform_guide({ resource })` aynı içeriği araçla verir; kaynak kaydı (`resources/*.ts`) ile bu
13
- * okuyucu aynı dosyaları ve aynı katalogları okur. Rehberler buradan verilmez (page ~120 KB, bölümlü okunur);
14
- * şemalar da verilmez (tek dosya 54 KB'a çıkıyor — araç yanıt sınırı; gövde kısıtları `dto_scheme`/açıklamalarda).
15
- */
16
- export function readToolResource(uri) {
17
- const examples = listKnowledgeFiles('examples').map(file => file.replace(/\.json$/, ''));
18
- const readable = ['ngapps://examples/index', ...examples.map(name => `ngapps://examples/${name}`), 'ngapps://rules/index', ...ruleResourceNames.map(name => `ngapps://rules/${name}`)];
19
- const match = /^ngapps:\/\/([a-z-]+)\/([A-Za-z0-9._-]+)$/.exec(uri.trim());
20
- const json = (value) => ({ uri, mimeType: 'application/json', text: JSON.stringify(value, null, 2) });
21
- if (match?.[1] === 'guides') {
22
- return { error: `Rehberler bu alandan okunmaz: platform_guide({ guide: '${match[2]}' }) bölüm listesini, section ile tek bölümü döner.`, readable };
23
- }
24
- if (match?.[1] === 'schemas') {
25
- return { error: 'Paketlenmiş şemalar araçla okunmaz (tek dosya 54 KB\'a çıkıyor). Gövde şablonu için ilgili *_get çıktısını, kısıtlar için aracın açıklamasındaki constraint özetini ya da ngapps://rules/backend-constraints kullanın.', readable };
26
- }
27
- if (match?.[1] === 'examples') {
28
- if (match[2] === 'index')
29
- return json({ examples: examples.map(name => `ngapps://examples/${name}`) });
30
- if (examples.includes(match[2] ?? ''))
31
- return { uri, mimeType: 'application/json', text: readKnowledgeFile('examples', `${match[2]}.json`) };
32
- }
33
- if (match?.[1] === 'rules') {
34
- if (match[2] === 'index')
35
- return json({ rules: ruleResourceNames.map(name => `ngapps://rules/${name}`) });
36
- const name = ruleResourceNames.find(item => item === match[2]);
37
- if (name)
38
- return json(ruleResourceBody(name));
39
- }
40
- return { error: `'${uri}' okunabilir bir kaynak değil.`, readable };
41
- }