@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.
- package/dist/config.js +0 -2
- package/dist/knowledge/componentCatalog.js +24 -12
- package/dist/knowledge/componentEvents.js +6 -13
- package/dist/knowledge/normalize.js +11 -52
- package/dist/knowledge/rules.js +12 -56
- package/dist/knowledge/styleResolve.js +1 -1
- package/dist/knowledge/themeResolve.js +3 -3
- package/dist/platform/domSummary.js +1 -1
- package/dist/platform/{capture/capture.js → screenshot.js} +509 -23
- package/dist/resources/examples/workflow-http-step.json +2 -2
- package/dist/resources/guides/component.md +1 -6
- package/dist/resources/guides/expressions.md +1 -1
- package/dist/resources/guides/functions.md +1 -1
- package/dist/resources/guides/layout.md +7 -11
- package/dist/resources/guides/microservice.md +2 -1
- package/dist/resources/guides/page.md +16 -69
- package/dist/resources/guides/translation.md +1 -1
- package/dist/resources/guides/workflow.md +6 -4
- package/dist/resources/schema-fingerprint.json +2 -2
- package/dist/resources/schemas/CreateWorkflowCommand.json +3 -0
- package/dist/resources/schemas/PreviewWorkflowCommand.json +3 -0
- package/dist/resources/schemas/StepDto.json +12 -9
- package/dist/resources/schemas/UpdateWorkflowCommand.json +3 -0
- package/dist/server.js +0 -2
- package/dist/tools/applications.js +3 -60
- package/dist/tools/components.js +10 -50
- package/dist/tools/designSchemaPatch.js +4 -13
- package/dist/tools/externalComponents.js +4 -25
- package/dist/tools/flows.js +2 -9
- package/dist/tools/layouts.js +9 -41
- package/dist/tools/pages.js +35 -115
- package/dist/tools/platformInfo.js +1 -2
- package/dist/tools/screenWrite.js +2 -2
- package/dist/tools/screens.js +3 -9
- package/dist/tools/workflows.js +1 -1
- package/package.json +1 -1
- package/dist/knowledge/mobileComponentCatalog.js +0 -628
- package/dist/knowledge/mobileComponentEvents.js +0 -110
- package/dist/knowledge/platform/lint.js +0 -205
- package/dist/knowledge/platform/mobile.js +0 -78
- package/dist/knowledge/platform/mobileRules.js +0 -126
- package/dist/knowledge/platform/mobileTabs.js +0 -108
- package/dist/knowledge/platform/profile.js +0 -20
- package/dist/knowledge/platform/resolve.js +0 -122
- package/dist/knowledge/platform/web.js +0 -38
- package/dist/knowledge/styleResolveNative.js +0 -410
- package/dist/platform/capture/actions.js +0 -333
- package/dist/platform/capture/browser.js +0 -1
- package/dist/platform/capture/index.js +0 -10
- package/dist/platform/capture/readiness.js +0 -103
- package/dist/platform/capture/summary.js +0 -77
- package/dist/platform/capture/target.js +0 -5
- package/dist/platform/capture/targets/studio-mobile.js +0 -15
- package/dist/platform/capture/targets/studio-web.js +0 -5
- package/dist/resources/examples/mobile-app-shell-drawer.json +0 -209
- package/dist/resources/examples/mobile-app-shell-stack.json +0 -123
- package/dist/resources/examples/mobile-app-shell-tab.json +0 -174
- package/dist/resources/examples/mobile-list-detail-form.json +0 -656
- package/dist/resources/guides/mobile.md +0 -283
- package/dist/tools/mobile.js +0 -203
- 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)
|
|
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)
|
|
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
|
|
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.
|
|
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
|
|
148
|
-
//
|
|
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
|
|
187
|
-
| Kırılıma duyarlı prop yok | `direction`/`gap` masaüstü ve
|
|
188
|
-
|
|
|
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` (
|
|
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
|
-
> **
|
|
394
|
-
> `
|
|
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 ·
|
|
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
|
|
523
|
+
> birden koşmayı değil (web `Runtime.svelte`, mobil `ScreenRuntime.tsx`):
|
|
525
524
|
>
|
|
526
|
-
> | Adım tipi | Web | Mobil
|
|
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` | ✅ | ✅ |
|
|
530
|
-
> | `confirm` · `download`
|
|
531
|
-
> | `navigate` | ❌ | ✅
|
|
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
|
-
|
|
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
|
|
968
|
-
sıra ve span'lar Desktop (1024) bloğundandır — Studio,
|
|
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
|
-
|
|
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
|
|
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
|
-
**Çı
|
|
430
|
-
`
|
|
431
|
-
|
|
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**
|
|
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": "
|
|
3
|
-
"generatedAt": "2026-09-
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
}
|