@appaflytech/zeyrek-ai-mcp 0.0.23 → 0.0.25

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 (61) hide show
  1. package/dist/config.js +0 -2
  2. package/dist/knowledge/componentCatalog.js +24 -12
  3. package/dist/knowledge/componentEvents.js +6 -13
  4. package/dist/knowledge/normalize.js +11 -52
  5. package/dist/knowledge/rules.js +12 -56
  6. package/dist/knowledge/styleResolve.js +1 -1
  7. package/dist/knowledge/themeResolve.js +3 -3
  8. package/dist/platform/domSummary.js +1 -1
  9. package/dist/platform/{capture/capture.js → screenshot.js} +509 -23
  10. package/dist/resources/examples/workflow-http-step.json +2 -2
  11. package/dist/resources/guides/component.md +1 -6
  12. package/dist/resources/guides/expressions.md +1 -1
  13. package/dist/resources/guides/functions.md +1 -1
  14. package/dist/resources/guides/layout.md +7 -11
  15. package/dist/resources/guides/microservice.md +2 -1
  16. package/dist/resources/guides/page.md +16 -69
  17. package/dist/resources/guides/translation.md +1 -1
  18. package/dist/resources/guides/workflow.md +6 -4
  19. package/dist/resources/schema-fingerprint.json +2 -2
  20. package/dist/resources/schemas/CreateWorkflowCommand.json +3 -0
  21. package/dist/resources/schemas/PreviewWorkflowCommand.json +3 -0
  22. package/dist/resources/schemas/StepDto.json +12 -9
  23. package/dist/resources/schemas/UpdateWorkflowCommand.json +3 -0
  24. package/dist/server.js +0 -2
  25. package/dist/tools/applications.js +3 -60
  26. package/dist/tools/components.js +10 -50
  27. package/dist/tools/designSchemaPatch.js +4 -13
  28. package/dist/tools/externalComponents.js +4 -25
  29. package/dist/tools/flows.js +2 -9
  30. package/dist/tools/layouts.js +9 -41
  31. package/dist/tools/pages.js +35 -115
  32. package/dist/tools/platformInfo.js +1 -2
  33. package/dist/tools/screenWrite.js +2 -2
  34. package/dist/tools/screens.js +3 -9
  35. package/dist/tools/workflows.js +1 -1
  36. package/package.json +1 -1
  37. package/dist/knowledge/mobileComponentCatalog.js +0 -628
  38. package/dist/knowledge/mobileComponentEvents.js +0 -110
  39. package/dist/knowledge/platform/lint.js +0 -205
  40. package/dist/knowledge/platform/mobile.js +0 -78
  41. package/dist/knowledge/platform/mobileRules.js +0 -126
  42. package/dist/knowledge/platform/mobileTabs.js +0 -108
  43. package/dist/knowledge/platform/profile.js +0 -20
  44. package/dist/knowledge/platform/resolve.js +0 -122
  45. package/dist/knowledge/platform/web.js +0 -38
  46. package/dist/knowledge/styleResolveNative.js +0 -410
  47. package/dist/platform/capture/actions.js +0 -333
  48. package/dist/platform/capture/browser.js +0 -1
  49. package/dist/platform/capture/index.js +0 -10
  50. package/dist/platform/capture/readiness.js +0 -103
  51. package/dist/platform/capture/summary.js +0 -77
  52. package/dist/platform/capture/target.js +0 -5
  53. package/dist/platform/capture/targets/studio-mobile.js +0 -15
  54. package/dist/platform/capture/targets/studio-web.js +0 -5
  55. package/dist/resources/examples/mobile-app-shell-drawer.json +0 -209
  56. package/dist/resources/examples/mobile-app-shell-stack.json +0 -123
  57. package/dist/resources/examples/mobile-app-shell-tab.json +0 -174
  58. package/dist/resources/examples/mobile-list-detail-form.json +0 -656
  59. package/dist/resources/guides/mobile.md +0 -283
  60. package/dist/tools/mobile.js +0 -203
  61. package/dist/tools/profileWrite.js +0 -45
@@ -3,11 +3,6 @@
3
3
  Sayfaya konan her şeyin ortak kuralları. Kuruluş sırası ve şema gövdesi için
4
4
  `platform_guide('page')`; HTML kaçış kapısının derin sözleşmesi için `platform_guide('html')`.
5
5
 
6
- > **Mobil uygulamada** katalog ayrıdır: `component_list`/`component_get` mobil satırları okur,
7
- > `component_get` `mobileKnowledge` (bileşenin mobil farkları) ve `mobileNotes` ekler; katalogda
8
- > olmayan tip `MOB-003` alır. Stil CSS değil React Native'dir — `page_runtime_get(resolveStyles)`
9
- > `nativeStyle` döner (`platform_guide('mobile')`).
10
-
11
6
  ## Keşif: iki tool, üç bilgi katmanı
12
7
 
13
8
  ```
@@ -113,7 +108,7 @@ Her şema düğümünde iki sözlük vardır; ikisi de ortak render katmanında
113
108
 
114
109
  | `states` | Anlamı |
115
110
  |---|---|
116
- | `isDroppable` | İçine komponent alır (container/form/repeater true). **Değer kataloğun kararıdır** (`component_list` `droppable` sütunu): Studio kanvası bırakma hedefini bu alandan çözer, bu yüzden gateway yazdığı düğümlerde alanı katalogdan doldurur ve `gatewayNormalized` ile bildirir (PAGE-036). `false` yazılmış bir kabın içine kanvasta bırakma yapılamaz — bilerek kapatmak için `resize_component`/`set_states` |
111
+ | `isDroppable` | İçine komponent alır (container/form/repeater true) |
117
112
  | `isScrollable` | İçeriği kendi alanında kaydırır (sabit yükseklikte `overflow-y: auto`) |
118
113
  | `isWrapper` | Sayfanın/layout'un/widget'ın ANA kabı — salt düzen elemanı: `height:100%` + **`min-height:80vh`**, kap başlığı ÇİZİLMEZ. **Yalnız sayfa boyu kaplaması gereken tek kap için kullan:** iç içe kutuya verirsen 720px'lik pencerede o kutu 36px içerikle bile 576px çizilir (ölçüldü, `platform_guide('page')` Kural 1f). Çerçeve/başlık gizlemek için wrapper değil `style` (`border:'none'`) kullan. Kurulmuş bir düğümün bayrağını `resize_component` micro-op'unun `states` alanı değiştirir — düğümü yeniden kurmak gerekmez |
119
114
  | `isSticky` | Kaydırmada yerinde kalır (header/sidebar; z-index'i otomatik) |
@@ -98,7 +98,7 @@ dalından devam eder.
98
98
  | `Page` | `Page.user`, `Page.variables`, `Page.components`, `Page.properties`, `Page.queryParams`, `Page.authorized(roles)` |
99
99
  | **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
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`) |
101
- | `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) ama **YAPIŞKANDIR**: storage sayfa başına tek `FlowMachine`'de yaşar ve `'error'` anahtarı hiç temizlenmez, yani ilk hatadan sonra o sayfadaki her akışta dolu kalır — normal akışta `Steps.error` okuyan bir ifade bayat hatayı 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 |
101
+ | `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
102
  | `self` · `item` · `Row` / `RowIndex` | Tetikleyen komponent (yazılabilir) · repeater/tablo satırı (yazmak satırı günceller) |
103
103
  | `event` | `{name, data, source: {id, props}}` |
104
104
  | `cookie` | `cookie.get(name)` / `cookie.set(name, value, {expiresInHours, path})` / `cookie.remove(name)` — tarayıcı cookie'si |
@@ -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 uygulama:** mobil runtime (`@ng-apps/ui-native`) `appFunctions`/`pageFunctions`'ı `Functions`'a geçirir, çağrı web'deki gibi çalışır.
276
+ - **Mobil yok** (K11): `apps/mobile` runtime'ı `Functions`'ı boş nesne kurar.
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.
@@ -4,10 +4,6 @@ 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
-
11
7
  ## Karar kuralları
12
8
 
13
9
  **1. Layout, tek `slot` içeren SIRADAN bir komponent ağacıdır.** Ayrı bir dil yoktur:
@@ -65,7 +61,7 @@ yapılan eski numaraya artık gerek yok.
65
61
  NEREDE durduğunu değil, BİÇİMİNİ söyler (dikey kolon / yatay şerit / dolgu yüzeyi). Hem
66
62
  runtime hem Studio tuvali bölgeleri 12 kolonluk ızgarayla yerleştirir.
67
63
 
68
- **7. Dar ekranda flex YIĞILMAZ.** Runtime'ın dar ekran kuralı yalnız ızgara özelliklerini ezer.
64
+ **7. Mobilde flex YIĞILMAZ.** Runtime'ın mobil kuralı yalnız ızgara özelliklerini ezer.
69
65
  Telefonda alt alta düşmesi gereken satırı `layout:'grid'` ile kur; `layout:'flex'` +
70
66
  `direction:'row'` telefonda da yan yana kalır (375px'te ölçüldü: ızgara çocukları 375/375px
71
67
  alt alta, flex çocukları 49/310px yan yana). Not: `wrap` varsayılanı artık açık (2026-09-01) —
@@ -144,8 +140,8 @@ bağlantı nesnesi ya da tam yol).
144
140
  "direction": { "type": "static", "data": "row" } },
145
141
  "blocks": [{ "breakpoint": 1024, "size": { "w": 12, "h": 80 }, "position": { "x": 0, "y": 0 } }] }
146
142
 
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
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
149
145
  // flex anlamının devreye girmemesi.
150
146
  ```
151
147
 
@@ -183,9 +179,9 @@ bunlardan biri olabilir:
183
179
  |---|---|
184
180
  | ~~`heightType` yalnız `auto` \| `fixed`~~ | **28 Ağustos'ta kapandı:** üçüncü değer `fill` (Kural 5b) |
185
181
  | ~~Kök kap viewport'a kilitlenmez~~ | **28 Ağustos'ta kapandı:** `fill` verilmiş kök 100vh (Kural 5b) |
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')`) |
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 |
189
185
 
190
186
  ---
191
187
 
@@ -193,7 +189,7 @@ bunlardan biri olabilir:
193
189
  (`injectPageSchemaIntoSlots`, `getResolvedLayoutViews`), `apps/studio/src/features/page/api/page.mappers.ts`
194
190
  (`mapPageLayoutToPreview`), `packages/ng-apps-ui/src/shared/render/render.functions.ts`
195
191
  (`resolveNodeBoxStyle` — slot'un `y / auto` satırı, flex çocuk genişliği),
196
- `packages/ng-apps-ui/src/shared/render/RenderComponent.svelte` (dar ekran media kuralı),
192
+ `packages/ng-apps-ui/src/shared/render/RenderComponent.svelte` (mobil media kuralı),
197
193
  `packages/ng-apps-screen-builder/src/flex-layout.ts` (`getFlexChildStyle` — `widthType`
198
194
  fill/fixed/auto dalları, `normalizeCssSize` kabul kuralı; tuval ve runtime aynı fonksiyonu okur),
199
195
  `apps/studio/src/features/page/components/appearance/appearance-size.functions.ts` (panelin
@@ -226,7 +226,8 @@ DTO'dan süzülmez (WF-026 — `platform_guide('workflow')` §Hata yolu). Sözle
226
226
  - Adımda tanımlı ama değeri boş bırakılan alanlar gövdeden/expression'dan gelen veriyi
227
227
  **ezmez**; yalnız değeri dolu olan sabitler her satıra uygulanır.
228
228
  - **`count` vardır** — kayıt sayısı için tüm satırları çekip uzunluğuna bakmayın; panel/KPI
229
- sayaçlarının doğru şekli budur.
229
+ sayaçlarının doğru şekli budur. Dönüşü tek bir sayıdır: `isReturnSchemaArray` `isSingle`'dan
230
+ bağımsız `false` okunur (2026-09-28'den önce kaydedilmiş servislerde de).
230
231
  - Gövde kökünde **`entityId` zorunlu**. (Eski "kökte datasourceId zorunlu" bilgisi yanlıştı —
231
232
  komutta öyle bir alan yok, gönderilirse yok sayılır; asıl zorunluluk selectFields'taki fieldId.)
232
233
  - `selectFields[]` / `filters[]` öğelerinde platform **`fieldId`** ister; gateway'e **`fieldSlug`**
@@ -4,10 +4,6 @@ Studio'nun tuval tarafı. Buradaki kurallar controller + komut kodundan doğrula
4
4
  (`zeyrek-mcp/docs/13-faz2-envanter.md` §4); veri/mantık tarafı için
5
5
  `platform_guide('entity')`, `('microservice')`, `('workflow')`.
6
6
 
7
- > **Mobil uygulamada** (`type: 'mobile'`) şema ve micro-op'lar aynıdır ama yerleşim yalnız flex'tir
8
- > (blocks çizilmez), görünüm tipli gruplarla yazılır ve `page_create` kökü flex sütun kurar —
9
- > `platform_guide('mobile')`. Bu rehberdeki "dar ekran" notları WEB uygulamasının telefon kırılımıdır.
10
-
11
7
  ## Kuruluş sırası
12
8
 
13
9
  ```
@@ -390,8 +386,11 @@ göstermek error flow'un işidir.
390
386
  > `errorTasks.some(t => t.type !== 'start')` arar. Start'ın ardına en az bir adım bağla —
391
387
  > gateway `FLOW-021` ile uyarır.
392
388
  >
393
- > **Mobil uygulama:** mobil runtime (`@ng-apps/ui-native` `NativeRuntime`) `errorSteps`'i web gibi
394
- > `errorTasks`'a eşler — hata yolu iki platformda aynı koşar.
389
+ > **Mobilde `errorSteps` diye bir şey YOK.** `ScreenRuntime.tsx` `mapFlowsToMachine` yalnız
390
+ > `tasks` üretir (web `Runtime.svelte` ayrıca `errorTasks` verir), yani mobil uygulamada
391
+ > `hasErrorFlow` her zaman false: hata yolu hiç koşmaz ve akış yukarıdaki 2. yoldan —
392
+ > `always` + hata gövdeli storage — devam eder. Mobil sayfada hata yolunu `condition
393
+ > Steps.<adımAdı>.error` ile kur.
395
394
 
396
395
  > **Hata metni ÜÇ ayrı yerde durur ve ikisi kullanıcıya gösterilecek metin DEĞİLDİR.**
397
396
  > `onError` hata akışını koşturmadan önce `machine.setStorage('error', errorInfo)` yapar
@@ -514,21 +513,21 @@ Tarif: `platform_guide('middleware')`.
514
513
 
515
514
  **Sözlükler** (`StepType.cs`, `StepParameterValueType.cs` — hepsi küçük harf):
516
515
  `start · microservice · setter · setcookie · validation · condition · redirect · alert ·
517
- confirm · flow-trigger · storage · navigate · code · download · function · share · end`
516
+ confirm · flow-trigger · storage · navigate · code · download · function · end`
518
517
  değer tipleri: `static · page · property · storage · variable · code · item · state`
519
518
 
520
519
  > **Sözlükte olmak KOŞACAĞI anlamına gelmez — koşan tipler barındırıcıdan gelir.** Motor yedi
521
520
  > tip register eder, gerisini uygulama ekler. Bir sayfa TEK bir uygulamaya aittir
522
521
  > (`Page.ApplicationId`) ve uygulamanın tipi `web` ya da `mobile`'dır (`ApplicationType.cs`), yani
523
522
  > sayfanın barındırıcısı bellidir — matris "hangi tip sende çalışır"ı söyler, iki barındırıcıda
524
- > birden koşmayı değil (web `Runtime.svelte`, mobil uygulama `@ng-apps/ui-native` `NativeRuntime`):
523
+ > birden koşmayı değil (web `Runtime.svelte`, mobil `ScreenRuntime.tsx`):
525
524
  >
526
- > | Adım tipi | Web | Mobil uygulama | Nerede register ediliyor |
525
+ > | Adım tipi | Web | Mobil | Nerede register ediliyor |
527
526
  > |---|---|---|---|
528
- > | `start` · `setter` · `code` · `condition` · `microservice` · `validation` · `flow-trigger` · `function` | ✅ | ✅ | `flow-engine.ts` — motorun kendisi |
529
- > | `alert` · `redirect` · `setcookie` · `storage` | ✅ | ✅ | barındırıcı; mobilde `setcookie` cihaz deposuna yazar (`MOB-005`) |
530
- > | `confirm` · `download` · `share` | ✅ | ✅ | `Runtime.svelte` · `runtime-tasks.ts` (`download` mobilde açma/paylaşım — `MOB-005`; `share` aşağıda) |
531
- > | `navigate` | ❌ | ✅ (`redirect` takma adı) | web'deki karşılığı `redirect`; gateway `redirect`'e çevirir |
527
+ > | `start` · `setter` · `code` · `condition` · `microservice` · `validation` · `flow-trigger` · `function` | ✅ | ✅ | `flow-engine.ts` — motorun kendisi (`function` mobilde kayıtlıdır ama mobil runtime `Functions`'ı boş kurar — K11, çağrı çalışmaz) |
528
+ > | `alert` · `redirect` · `setcookie` · `storage` | ✅ | ✅ | uygulama; mobilde `redirect` navigate, `setcookie` storage uygulamasına eşlenir |
529
+ > | `confirm` · `download` | ✅ | ❌ | yalnız `Runtime.svelte` |
530
+ > | `navigate` | ❌ | ✅ | yalnız `ScreenRuntime.tsx` — web'deki karşılığı `redirect` |
532
531
  > | `end` · `query` | ❌ | ❌ | hiçbir yerde — üstelik `query` backend sözlüğünde de yok (`StepType.cs` onu saymaz), yalnız frontend enum'unda duruyor |
533
532
  >
534
533
  > **Register edilmemiş bir tipe gelen akış SESSİZCE durur.** `flow-engine.ts` `process()`
@@ -564,19 +563,6 @@ değer tipleri: `static · page · property · storage · variable · code · it
564
563
  > adımında ve `{{ }}` bağlamasında `Functions.<ad>(…)` ile de çağrılır; gateway bilinmeyen adı ve
565
564
  > fazla argümanı FLOW-025 ile uyarır. Tam gövde `ngapps://examples/flow-call-function`, kurallar
566
565
  > **`platform_guide('functions')`**.
567
- >
568
- > **`share` adımı ("Share")** metin ve bağlantı paylaşır: `args: { title, message, path }`. `title`
569
- > DÜZ METİNDİR (ifade yazılırsa FLOW-022 uyarır); `message` ve `path` `storage.value` gibi
570
- > İFADEDİR — düz metin tırnak ister (`"'Şuna bak'"`, `"'https://…/urun/' + Page.queryParams.id"`).
571
- > Bağlantının adı `url` DEĞİL `path`'tir: backend `Title`/`Message`/`Path` alanlarında saklar ve
572
- > tanımadığı anahtarı 200 ile sessizce düşürür (FLOW-027 `url`/`link`/`text`'i ve tırnaksız adresi
573
- > bloklar). Bağlantı ŞEMALI TAM ADRES olmalı (`https://…`, `mailto:…`): şemasız değer (`www.…`,
574
- > `urun/42`) adres sayılmaz, metnin sonuna eklenir. İfadenin sonucu yalnız dize ya da sayıysa
575
- > paylaşılır; `false` (`koşul && 'x'`), `null` ve nesne boş sayılır. Cihazda paylaşım sayfası açılır
576
- > (Android'de bağlantı metnin sonuna eklenir), web'de tarayıcının paylaşım penceresi, yoksa ya da
577
- > reddederse metin + bağlantı panoya yazılır ve bildirim çıkar. Tek dal `always`: iOS'ta sayfa
578
- > kapanınca, Android'de seçici açılır açılmaz (RN seçicinin kapanışını bildirmez) sürer; metin de
579
- > bağlantı da boşsa hiçbir şey açılmaz, akış hemen sürer.
580
566
 
581
567
  > Bir microservice adımı kaydedildiğinde platform `args.microserviceSchema`'yı
582
568
  > (parameterScheme + returnScheme + `isReturnArray`) kendisi doldurur — `flow_get` ile geri
@@ -875,7 +861,7 @@ kullanır: `page.mappers.ts` `mapPageLayoutToPreview` — layout varsa çizilen
875
861
  > `add_component` ile yeniden kurmaktır (sonrasında Kural 2'deki flow yeniden kaydetme adımı
876
862
  > ZORUNLU olur).
877
863
 
878
- Dar ekran notu: <768px'te ızgara tek kolona düşer (`RenderComponent` media query'si) — y sırası
864
+ Mobil not: <768px'te ızgara tek kolona düşer (`RenderComponent` media query'si) — y sırası
879
865
  dikey sıraya dönüşür, x/w yok sayılır. Yerleşimi masaüstü (breakpoint 1024) bloğuyla kur.
880
866
 
881
867
  ## Kural 1f-2 — Kapsayıcı düzeni: `flex` (varsayılan) ↔ `grid`
@@ -964,10 +950,10 @@ Beş şeyi bilmeden flex kurma:
964
950
  4. **`layout: 'grid'` iken diğer altı prop ÖLÜDÜR.** Katalogda tanımlı oldukları için
965
951
  doğrulama duvarı susar, renderer da okumaz: ızgara kapsayıcıya `direction: 'column'` yazmak
966
952
  sessizce hiçbir şey yapmaz. Gateway bunu **PAGE-015 (uyarı)** ile söyler.
967
- 5. **Flex düzeni kırılım BİLMEZ.** `direction`/`gap`/hizalama masaüstü ve dar ekranda AYNIDIR;
968
- sıra ve span'lar Desktop (1024) bloğundandır — Studio, dar ekran kırılımı düzenlenirken flex
953
+ 5. **Flex düzeni kırılım BİLMEZ.** `direction`/`gap`/hizalama masaüstü ve mobilde AYNIDIR;
954
+ sıra ve span'lar Desktop (1024) bloğundandır — Studio, mobil kırılım düzenlenirken flex
969
955
  bölgeyi salt-okunur kilitler. Kırılım bilen yalnız `blocks[]` ve `appearance.hideOn`'dur;
970
- dar ekranda farklı davranış gereken satır için `layout: 'grid'` kullan (Kural 1f dar ekran notu).
956
+ mobilde farklı davranış gereken satır için `layout: 'grid'` kullan (Kural 1f mobil notu).
971
957
 
972
958
  ```jsonc
973
959
  // Ortalanmış giriş kartı — style ile CSS hack'i YOK, kabın kendi düzeni
@@ -1111,45 +1097,6 @@ kendisi nesneye çevirir; Studio tablosunda `[object Object]` görünmesi normal
1111
1097
  (`platform_guide('entity')` → "TEXT kolonunda JSON"). Ekranın görsel tarafı için **Kural 1h**:
1112
1098
  tema `--ng-*` değişkenleriyle tek yerden çevrilir, `html` kaçış kapısına gerek kalmaz.
1113
1099
 
1114
- ## Kural 1g-2 — Mobil davranış: dört ayar, dört ayrı sahip
1115
-
1116
- Mobil listelerin davranışı TEK bileşende toplanmaz. Hangi ayarın kimde olduğunu bilmeden yazılan
1117
- şema sessizce çalışmaz — prop var olmayan bileşene yazılır ve `page_schema_patch` onu düşürmez,
1118
- çizer yok sayar.
1119
-
1120
- | Davranış | Sahip bileşen | Prop / olay |
1121
- |---|---|---|
1122
- | Çekerek yenile | `scroll-view` (listeyi SARAN kap) | `refreshable: true` + `refresh` olayı |
1123
- | Sonsuz kaydırma | `scroll-view` | `scrollEnd` olayı (prop yok) |
1124
- | Kaydırma eylemleri | `repeater` | `swipeActions: [{ key, label, tone, icon }]` + `swipe` olayı, payload `{ key, index, row }` |
1125
- | Satıra dokunma | `repeater` | `itemPressable: true` + `itemPress` olayı, payload `{ index, row }` |
1126
-
1127
- Çekerek yenileyi `repeater`'a yazmak en sık hatadır: liste kendi kaydırmasını yapmaz, onu saran
1128
- `scroll-view` yapar. `repeater` kökteyse (kap yok) yenileme hiç çizilmez.
1129
-
1130
- Satıra dokunmanın kartın `click`'iyle yapılan eski yolu mobilde bırakıldı: `itemPress` satır
1131
- bağlamını payload'da taşır ve seçimi (`selectedIndex`) de yazar, yani akış satırı
1132
- `<tekrarlayıcı>.selectedItem` ile okumaya devam eder.
1133
-
1134
- ### `redirect.presentation`
1135
-
1136
- `redirect` adımının `args.presentation` alanı ekranın NASIL açıldığını söyler ve kapalı bir küme
1137
- alır:
1138
-
1139
- - `push` — yığına ekler, geri düğmesi önceki ekrana döner (**varsayılan**; alan yazılmayabilir)
1140
- - `modal` — alttan açılan ayrı bir sunum; geri onu kapatır, altındaki ekran yerinde kalır
1141
- - `replace` — geçerli ekranı değiştirir, geçmişe girmez (giriş → ana ekran için doğru olan)
1142
-
1143
- Küme dışı bir değer **MOB-008** uyarısıdır ve backend doğrulayıcısı 422 döner. Alanı hiç yazmamak
1144
- kusur değildir.
1145
-
1146
- **Sekme hedefinde `modal` çalışmaz.** Hedef sayfa bir sekmeyse gezinme her zaman `navigate`'e
1147
- düşer: sekme yığını kendi geçmişini tutar ve modal onu kırardı. `presentation`ı yazabilirsiniz,
1148
- çizer sessizce yok sayar — sekme dışı bir sayfaya modal istiyorsanız o sayfayı sekme listesinden
1149
- çıkarın.
1150
-
1151
- Web uygulamasında alan yok sayılır; gateway web profilinde bu konuda bulgu üretmez.
1152
-
1153
1100
  ## Kural 1h — Tasarım: `style` prop'u ve tema değişkenleri
1154
1101
 
1155
1102
  Her komponentin `style` prop'u vardır ve emotion `css()` bloğudur: iç seçiciler, pseudo-class'lar
@@ -208,7 +208,7 @@ gerekmez — `schema.ts`'e dokunulmaz, katalog yeniden yüklenmez.
208
208
  `translation_update` artık uygulamanın bütün sayfalarının önbellek satırlarını düşürüyor
209
209
  (`RefreshPageCacheWhenTranslationChangedCommand`), okuma yolu cache-aside olduğu için bir
210
210
  sonraki `page_runtime_get` taze değeri kurar. Yazmadan hemen sonra okuyabilirsin.
211
- - Mobil uygulama runtime'ı (`@ng-apps/ui-native`, Expo) web ile aynı sözlüğü ve motoru kullanır (2026-09-25, plans/mobil-coklu-dil): `language-selector` mobil katalogda, cihazda dil sırası uygulama içi seçim → kayıtlı seçim → cihaz dili → varsayılan (`?lang` yalnız `/preview`'da), seçim uygulama çapında ve kalıcı, sekme etiketi `t:<anahtar>`, `X-Data-Language` sonraki isteklerle gider. Ayrıntı `platform_guide('mobile')` §Çok dil.
211
+ - Mobil runtime (`apps/mobile`) bu özelliği henüz beslemiyor — yalnız web.
212
212
 
213
213
  ## Backend doğrulama sınırları (TR-001)
214
214
 
@@ -426,13 +426,15 @@ bakar (`HttpStep.cs:32,42,59`).
426
426
  | Yanıt JSON değil | Gövde **sessizce** boş nesne olur (`:92`) — XML dönen uçtan veri de hata da alamazsınız |
427
427
  | Adım adında boşluk | Çıktıya adım adıyla erişilir; ad geçerli JS tanımlayıcısı olmalı (`call_roles`, `Call Roles` değil) |
428
428
 
429
- **Çıktıyı okurken şemaya değil ölçüme güvenin (2026-09-16).** `workflow_step_schema('http')`
430
- `returnScheme`'i kök seviyede `{ httpStatusCode, data }` ilan eder, ama koşumda ifade bağlamındaki
431
- adım `{ data, meta: { elapsedTime, httpStatusCode, totalCount }, error }` şeklindedir:
429
+ **Çıktının şekli (ölçüldü 2026-09-16).** Koşumda ifade bağlamındaki adım
430
+ `{ data, meta: { elapsedTime, httpStatusCode, totalCount }, error }` şeklindedir.
431
+ `workflow_step_schema('http')` `returnScheme`'i yalnız gövdeyi anlatır — adsız, tipsiz
432
+ (`anonymous`) tek girdi, çünkü dış yanıtın şekli bilinmez; zarf her adımda aynıdır ve şemada
433
+ yer almaz:
432
434
 
433
435
  - gövde → **`<adım>.data`**
434
436
  - durum kodu → **`<adım>.meta.httpStatusCode`**
435
- - `<adım>.httpStatusCode` → **undefined** (şemanın vaat ettiği ad çalışmaz)
437
+ - `<adım>.httpStatusCode` → **undefined**
436
438
 
437
439
  Tam örnek ve POST varyantı: `ngapps://examples/workflow-http-step`.
438
440
 
@@ -1,6 +1,6 @@
1
1
  {
2
- "hash": "f37265d598ea468deb2157165891629c2e88c7fd2238e82ec60cda7f58f7de4c",
3
- "generatedAt": "2026-09-18T12:57:15.416Z",
2
+ "hash": "06f7d6b64937424fcbe7a9c8751e90a5224556e0c970199fb199cfa3a147c7d2",
3
+ "generatedAt": "2026-09-28T09:04:34.182Z",
4
4
  "types": 186,
5
5
  "files": 108,
6
6
  "note": "Şemaları üreten backend kaynaklarının parmak izi. Elle düzenlemeyin: 'npm run generate-schemas' yazar, 'npm run schema:check' denetler.",
@@ -134,6 +134,9 @@
134
134
  },
135
135
  "nullable": true
136
136
  },
137
+ "returnBehavior": {
138
+ "$ref": "#/components/schemas/NgApps.Domain.Contexts.Shared.DataTransferObjects.DataTransferObjectBehavior"
139
+ },
137
140
  "relationTree": {
138
141
  "$ref": "#/components/schemas/NgApps.Domain.Contexts.Datastore.Entities.EntityRelationDto"
139
142
  }
@@ -128,6 +128,9 @@
128
128
  },
129
129
  "nullable": true
130
130
  },
131
+ "returnBehavior": {
132
+ "$ref": "#/components/schemas/NgApps.Domain.Contexts.Shared.DataTransferObjects.DataTransferObjectBehavior"
133
+ },
131
134
  "relationTree": {
132
135
  "$ref": "#/components/schemas/NgApps.Domain.Contexts.Datastore.Entities.EntityRelationDto"
133
136
  }
@@ -45,6 +45,9 @@
45
45
  },
46
46
  "nullable": true
47
47
  },
48
+ "returnBehavior": {
49
+ "$ref": "#/components/schemas/NgApps.Domain.Contexts.Shared.DataTransferObjects.DataTransferObjectBehavior"
50
+ },
48
51
  "relationTree": {
49
52
  "$ref": "#/components/schemas/NgApps.Domain.Contexts.Datastore.Entities.EntityRelationDto"
50
53
  }
@@ -413,6 +416,15 @@
413
416
  },
414
417
  "additionalProperties": false
415
418
  },
419
+ "NgApps.Domain.Contexts.Shared.DataTransferObjects.DataTransferObjectBehavior": {
420
+ "enum": [
421
+ "primitive",
422
+ "object",
423
+ "array"
424
+ ],
425
+ "type": "string",
426
+ "format": ""
427
+ },
416
428
  "NgApps.Domain.Contexts.Datastore.Entities.EntityRelationDto": {
417
429
  "type": "object",
418
430
  "properties": {
@@ -804,15 +816,6 @@
804
816
  "type": "string",
805
817
  "format": ""
806
818
  },
807
- "NgApps.Domain.Contexts.Shared.DataTransferObjects.DataTransferObjectBehavior": {
808
- "enum": [
809
- "primitive",
810
- "object",
811
- "array"
812
- ],
813
- "type": "string",
814
- "format": ""
815
- },
816
819
  "NgApps.Domain.Contexts.Datastore.Entities.EntityType": {
817
820
  "enum": [
818
821
  "normal",
@@ -134,6 +134,9 @@
134
134
  },
135
135
  "nullable": true
136
136
  },
137
+ "returnBehavior": {
138
+ "$ref": "#/components/schemas/NgApps.Domain.Contexts.Shared.DataTransferObjects.DataTransferObjectBehavior"
139
+ },
137
140
  "relationTree": {
138
141
  "$ref": "#/components/schemas/NgApps.Domain.Contexts.Datastore.Entities.EntityRelationDto"
139
142
  }
package/dist/server.js CHANGED
@@ -39,7 +39,6 @@ import { registerMergeTools } from "./tools/merges.js";
39
39
  import { registerRevisionTools } from "./tools/revisions.js";
40
40
  import { registerActivityTools } from "./tools/activities.js";
41
41
  import { registerDtoTools } from "./tools/dtos.js";
42
- import { registerMobileTools } from "./tools/mobile.js";
43
42
  const moduleRegistrations = {
44
43
  platform: registerPlatformTools,
45
44
  project: registerProjectTools,
@@ -81,7 +80,6 @@ const moduleRegistrations = {
81
80
  merge: registerMergeTools,
82
81
  activity: registerActivityTools,
83
82
  revision: registerRevisionTools,
84
- mobile: registerMobileTools,
85
83
  };
86
84
  export function createGatewayServer(platform) {
87
85
  const server = rejectUnknownArguments(instrumentServer(new McpServer({ name: "ngapps", version: "0.1.0" }), platform.config));
@@ -1,44 +1,6 @@
1
1
  import { guid, pagingParams, readOnly, writes, updates, destructive } from './common.js';
2
2
  import { handle } from '../platform/responses.js';
3
- import { forgetApplication, readApplicationPlatform, resolveApplication } from '../knowledge/platform/resolve.js';
4
- import { mobileTabsProblems, readMobileTabs } from '../knowledge/platform/mobileTabs.js';
5
- import { findingLine } from '../knowledge/platform/profile.js';
6
3
  import { z } from 'zod';
7
- /**
8
- * MOB-007 (sekme ayarı) — `properties.mobile.tabs` yazan mobil uygulama çağrısının denetimi. Yazım
9
- * platforma YİNE gider (D3; backend `properties`'i doğrulamaz): bulgu `platformWarnings`'e düşer.
10
- * Sayfa ve widget listesi okunamazsa o denetimler atlanır, biçim denetimi yine koşar.
11
- */
12
- export async function mobileTabsWarnings(platform, applicationId, projectSlug, homepageId, properties) {
13
- const tabs = readMobileTabs(properties);
14
- if (tabs === undefined)
15
- return [];
16
- const pages = applicationId && projectSlug
17
- ? await platform.tenant('GET', projectSlug, `/pages/${applicationId}`, { query: { pageIndex: 0, pageLength: 200 } })
18
- .then(response => (response?.data ?? []).map(page => ({ id: String(page.id ?? '') })))
19
- .catch(() => undefined)
20
- : undefined;
21
- const widgetIds = applicationId && projectSlug
22
- ? await platform.tenant('GET', projectSlug, `/components/${applicationId}`, { query: { pageIndex: 0, pageLength: 999 } })
23
- .then(response => new Set((response?.data ?? []).filter(entry => entry.kind === 'widget').map(entry => String(entry.id ?? ''))))
24
- .catch(() => undefined)
25
- : undefined;
26
- return mobileTabsProblems(tabs, {
27
- ...(pages ? { pages } : {}),
28
- ...(homepageId ? { homepageId } : {}),
29
- ...(widgetIds ? { widgetIds } : {})
30
- }).map(message => findingLine({
31
- code: 'MOB-007',
32
- severity: 'warn',
33
- message,
34
- guide: "platform_guide('mobile') §Gezinme"
35
- }));
36
- }
37
- function withPlatformWarnings(response, warnings) {
38
- if (warnings.length === 0 || !response || typeof response !== 'object' || Array.isArray(response))
39
- return response;
40
- return { ...response, platformWarnings: warnings };
41
- }
42
4
  export function registerApplicationTools(server, platform) {
43
5
  const config = platform.config;
44
6
  server.registerTool('application_list', {
@@ -72,14 +34,7 @@ export function registerApplicationTools(server, platform) {
72
34
  notFoundPageId: guid.optional()
73
35
  },
74
36
  annotations: writes
75
- }, handle(config, async ({ projectId, ...body }) => {
76
- const warnings = readApplicationPlatform(body.type) === 'mobile'
77
- ? await mobileTabsWarnings(platform, undefined, undefined, undefined, body.properties)
78
- : [];
79
- const response = await platform.org('POST', `/applications/${projectId}`, { body });
80
- forgetApplication(platform);
81
- return withPlatformWarnings(response, warnings);
82
- }));
37
+ }, handle(config, ({ projectId, ...body }) => platform.org('POST', `/applications/${projectId}`, { body })));
83
38
  server.registerTool('application_update', {
84
39
  title: 'Application güncelle',
85
40
  description: 'Application bilgilerini günceller; homepageId zorunludur (mevcut değeri application_get ile alın).',
@@ -94,23 +49,11 @@ export function registerApplicationTools(server, platform) {
94
49
  notFoundPageId: guid.optional()
95
50
  },
96
51
  annotations: updates
97
- }, handle(config, async ({ id, ...body }) => {
98
- const current = await resolveApplication(platform, id);
99
- const warnings = current?.platform === 'mobile'
100
- ? await mobileTabsWarnings(platform, id, current.projectSlug, body.homepageId, body.properties)
101
- : [];
102
- const response = await platform.org('PUT', `/applications/${id}`, { body });
103
- forgetApplication(platform, id);
104
- return withPlatformWarnings(response, warnings);
105
- }));
52
+ }, handle(config, ({ id, ...body }) => platform.org('PUT', `/applications/${id}`, { body })));
106
53
  server.registerTool('application_delete', {
107
54
  title: 'Application sil',
108
55
  description: 'Application\'ı kalıcı olarak siler.',
109
56
  inputSchema: { id: guid },
110
57
  annotations: destructive
111
- }, handle(config, async (args) => {
112
- const response = await platform.org('DELETE', `/applications/${args.id}`);
113
- forgetApplication(platform, args.id);
114
- return response;
115
- }));
58
+ }, handle(config, args => platform.org('DELETE', `/applications/${args.id}`)));
116
59
  }