@appaflytech/zeyrek-ai-mcp 0.0.41 → 0.0.43
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/knowledge/componentCatalog.js +27 -97
- package/dist/knowledge/componentEvents.js +1 -18
- package/dist/knowledge/mobileComponentCatalog.js +114 -15
- package/dist/knowledge/mobileComponentEvents.js +41 -0
- package/dist/knowledge/motionResolve.js +252 -0
- package/dist/knowledge/normalize.js +87 -59
- package/dist/knowledge/pageDiscover.js +2 -2
- package/dist/knowledge/platform/batchOps.js +70 -0
- package/dist/knowledge/platform/heroTag.js +153 -0
- package/dist/knowledge/platform/lint.js +128 -6
- package/dist/knowledge/platform/mobile.js +1 -1
- package/dist/knowledge/platform/mobileLayoutLint.js +8 -1
- package/dist/knowledge/platform/mobileRules.js +18 -0
- package/dist/knowledge/platform/pageTransition.js +57 -0
- package/dist/knowledge/platform/web.js +1 -1
- package/dist/knowledge/rules.js +52 -1
- package/dist/knowledge/styleResolveNative.js +88 -4
- package/dist/platform/capture/actions.js +4 -1
- package/dist/platform/capture/capture.js +10 -13
- package/dist/platform/capture/persistent-browser.js +130 -0
- package/dist/resources/examples/flow-list-to-form.json +8 -10
- package/dist/resources/examples/flow-load-table.json +1 -1
- package/dist/resources/examples/mobile-list-detail-form.json +4 -3
- package/dist/resources/examples/mobile-scan-code.json +285 -0
- package/dist/resources/guides/component.md +3 -3
- package/dist/resources/guides/expressions.md +2 -2
- package/dist/resources/guides/merge.md +98 -18
- package/dist/resources/guides/microservice.md +2 -2
- package/dist/resources/guides/mobile-layout.md +2 -1
- package/dist/resources/guides/mobile-publish.md +1 -0
- package/dist/resources/guides/mobile-steps.md +67 -0
- package/dist/resources/guides/mobile.md +27 -55
- package/dist/resources/guides/page.md +182 -121
- package/dist/resources/guides/translation.md +26 -0
- package/dist/resources/schema-fingerprint.json +2 -2
- package/dist/resources/schemas/ResolveMergeConflictsCommand.json +30 -1
- package/dist/tools/activities.js +3 -1
- package/dist/tools/applications.js +16 -2
- package/dist/tools/components.js +12 -6
- package/dist/tools/designSchemaPatch.js +18 -13
- package/dist/tools/layouts.js +7 -2
- package/dist/tools/merges.js +29 -9
- package/dist/tools/pages.js +129 -127
- package/dist/tools/platformInfo.js +3 -2
- package/dist/tools/profileWrite.js +2 -2
- package/dist/tools/schemaOps.js +132 -34
- package/dist/tools/screenWrite.js +1 -1
- package/dist/tools/screens.js +3 -3
- package/package.json +2 -2
|
@@ -189,16 +189,16 @@ Tablonun/listenin satırları şemaya "dataSource" yazarak değil, **flow ile**
|
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
**Event'ler komponent tipine göre değişir; `component_get`'in `events` alanından okunur.**
|
|
192
|
-
Sayfa açılışında veri çekmek için `mount` kullanılır ama tek seçenek o değil — örneğin
|
|
193
|
-
|
|
192
|
+
Sayfa açılışında veri çekmek için `mount` kullanılır ama tek seçenek o değil — örneğin
|
|
193
|
+
`datatable` 7 olay yayar:
|
|
194
194
|
|
|
195
|
-
`mount ·
|
|
195
|
+
`mount · rowClick · rowDoubleClick · save · discard · rowSelectionChange · cellSelectionChange`
|
|
196
196
|
|
|
197
|
-
Yani "
|
|
198
|
-
(`
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
tıklamasını `clickItem` olarak yayar (`component_get` yükü verir).
|
|
197
|
+
Yani "satıra tıklayınca detay getir" (`rowClick`), "satıra çift tıklayınca formu aç"
|
|
198
|
+
(`rowDoubleClick`), "düzenlenen satırları kaydet" (`save`) akışları da aynı `set_event`
|
|
199
|
+
mekanizmasıyla kurulur. Süzme, sıralama ve sayfalamanın AYRI olayı yoktur: `datatable` kendi
|
|
200
|
+
prop'larını yazıp `mount`'u yeniden tetikler (bilinçli — Kural 1e); `page-header` 2026-09-18'den
|
|
201
|
+
beri izdeki öğe tıklamasını `clickItem` olarak yayar (`component_get` yükü verir).
|
|
202
202
|
|
|
203
203
|
**Olay adları `on` ÖNEKİ ALMAZ** (`button` → `click`, `form` → `submit`, `texteditor` → `change`);
|
|
204
204
|
katalogda istisna yok. **Komponentin desteklemediği bir olay adı verirsen bağ
|
|
@@ -239,19 +239,18 @@ aksiyonları (`platform_guide('html')`) ve **`params`'ı da gönderen komponentl
|
|
|
239
239
|
(`eventcalendar` · `importwizard` · `kanban` · `signature` · `stepper` · `tabs` ·
|
|
240
240
|
`tree-view` · `pagination`): bunların yükü `event.data.<anahtar>` ile de okunur; `kanban` ve
|
|
241
241
|
`eventcalendar` yükü `self`'e HİÇ yazmaz (`component_get` çıktısındaki sözleşme notları ayrımı
|
|
242
|
-
söyler). Sessiz hata örneği: **tablonun
|
|
243
|
-
`event.data.
|
|
244
|
-
döndürür; hata yok, sayfalama yok
|
|
245
|
-
|
|
242
|
+
söyler). Sessiz hata örneği: **tablonun** yükleme akışında sayfa değerlerini `event.data.limit` /
|
|
243
|
+
`event.data.offset`'ten okursan sorgu `LIMIT null OFFSET null` ile koşar ve **tüm satırları**
|
|
244
|
+
döndürür; hata yok, sayfalama yok — `datatable` bu değerleri `self.limit` / `self.offset`'e yazar
|
|
245
|
+
(ölçüm 2026-08-25, kaldırılan tablonun sayfalama olayında; kural aynı). (Bağımsız `pagination`
|
|
246
|
+
komponenti bu tuzağa girmez, yükünü `params` ile de gönderir.)
|
|
246
247
|
|
|
247
248
|
| Komponent · olay | Yük (aynı zamanda prop adları) | Akışta nereden okunur |
|
|
248
249
|
|---|---|---|
|
|
249
|
-
| `
|
|
250
|
-
| `
|
|
251
|
-
| `
|
|
252
|
-
| `
|
|
253
|
-
| `table.selectionChange` | — | `self.selectedRows` |
|
|
254
|
-
| `datatable.mount` | — | `self.filters` · `self.sortField` · `self.sortType` · `self.offset` |
|
|
250
|
+
| `datatable.mount` | — | `self.filters` · `self.sortField` · `self.sortType` · `self.offset` · `self.limit` |
|
|
251
|
+
| `datatable.rowClick` · `rowDoubleClick` | — | `self.selectedRow` |
|
|
252
|
+
| `datatable.rowSelectionChange` | — | `self.selectedRows` |
|
|
253
|
+
| `datatable.save` | — | `self.operation` · `self.changeset` · `self.editedRows` · `self.deletedRows` |
|
|
255
254
|
| `pagination.change` | `{ offset, limit }` | `self.offset` · `self.limit` ya da `event.data.offset` · `event.data.limit` |
|
|
256
255
|
| `textinput/textarea/password.change` | `{ value }` | `self.value` |
|
|
257
256
|
| `dropdown.change` · `multi-select.change` | `{ value }` | `self.value` |
|
|
@@ -961,7 +960,8 @@ kapsayıcının kardeşi olarak yaşar (qm `[SY] Profil bilgilerim`: `page_conta
|
|
|
961
960
|
> `gatewayNormalized` ile bildirir. Senin verdiğin `appearance.heightType`'a dokunmaz.
|
|
962
961
|
>
|
|
963
962
|
> Katalogda `isDefaultAutoHeight: false` olan (yani `fixed` damgalanan) tipler: `auth-layout`,
|
|
964
|
-
> `html`, `image`, `layout`, `
|
|
963
|
+
> `html`, `image`, `layout`, `layout-region`, `layout-shell`, `qrcode`, `texteditor`, `video`
|
|
964
|
+
> (katalogdan ölçüldü 2026-10-13). Diğer her tip `auto`'dur.
|
|
965
965
|
> Bu tiplerde `size.h` gerçek yüksekliktir — göz kararı değil, içeriğe göre hesapla
|
|
966
966
|
> (bir satır ≈ 10px; Kural 1f).
|
|
967
967
|
|
|
@@ -985,107 +985,104 @@ sayfasında da reddedilir (web sayfayı her gezinmede baştan kurar, `mount` yet
|
|
|
985
985
|
- Akış kilidi burada da geçerlidir (Kural 3): önce bütün `flow_create`'ler, sonra events bağı.
|
|
986
986
|
- Mevcut bağları `page_get` gösterir (`events[].value` = flow id).
|
|
987
987
|
|
|
988
|
-
## Kural 1e —
|
|
989
|
-
|
|
990
|
-
> **`data-table`
|
|
991
|
-
>
|
|
992
|
-
>
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
988
|
+
## Kural 1e — Tablo komponenti `datatable`'dır
|
|
989
|
+
|
|
990
|
+
> **`table` KALDIRILDI (2026-09-30)**, `data-table` ondan önce (2026-08-17). Katalogda tablo işi
|
|
991
|
+
> gören tek komponent `datatable`'dır. Eski bir sayfada `type: "table"` düğümü görürsen runtime
|
|
992
|
+
> onu `datatable` ile çizer (takma ad), ama o düğümün eski olayları (sayfalama, süzme, sıralama,
|
|
993
|
+
> seçim, çift tık, satır değişimi) ve eski prop'ları (satır seçim kipi, satır bazlı `_columns`
|
|
994
|
+
> ezmesi, `style.thead|th|tr|td`) artık karşılık bulmaz — kurulumu aşağıdaki sözleşmeye çevir.
|
|
995
|
+
>
|
|
996
|
+
> **Kayıt defterinde durmaya devam eder.** Eşitleme kaldırılan bileşeni silmez, gizler (silmek o
|
|
997
|
+
> tipteki kayıtlı düğümleri de silerdi): `component_list` onu yalnız `includeHidden: true` ile ve
|
|
998
|
+
> `retired: true` işaretiyle gösterir — henüz eşitlenmemiş bir ortamda gizlenmeden de listelenebilir —
|
|
999
|
+
> `component_get` eski şemayı `retired` notuyla döner ve PLATFORM o tipte düğümü kabul eder (runtime
|
|
1000
|
+
> `datatable` çizer, eski olaylara kurulan bağ kaydedilir ama ölü kalır). Gateway bu yüzden emekli tipte YENİ
|
|
1001
|
+
> düğümü **PAGE-051** ile istek gitmeden reddeder: `add_component`, `page_create` / `layout_create` /
|
|
1002
|
+
> `component_create` şeması ve `layout_patch`'in eklediği düğüm. O tiple kayıtlı düğüme yazan op'lar
|
|
1003
|
+
> (`replace_prop`, `move_component`…) ve tam şema yazan `page_update` geçer — eski sayfa düzenlenebilir
|
|
1004
|
+
> kalır; düğümü silip aynı tiple yeniden eklemek ise reddedilir. Kayıtlı `table` düğümüne olay
|
|
1005
|
+
> bağlarken `datatable`'ın olay adlarını yaz (`rowDoubleClick`): gateway adı onun listesinden denetler.
|
|
1006
|
+
|
|
1007
|
+
| Ne | Nasıl |
|
|
1008
|
+
|---|---|
|
|
1009
|
+
| Olaylar | 7: `mount · rowClick · rowDoubleClick · save · discard · rowSelectionChange · cellSelectionChange` |
|
|
1010
|
+
| Süzme / sıralama / sayfalama | komponentin İÇİNDE, ayrı olayı yok: `filters`/`sortField`/`sortType`/`offset` prop'larını (hidden) yazıp `mount`'u yeniden tetikler |
|
|
1011
|
+
| Satır | `rowClick` · `rowDoubleClick` ve satır aksiyonları (`actions`) tıklanan satırı `selectedRow`'a yazar (7b) |
|
|
1012
|
+
| Düzenleme | `editMode` (`none` · `row` · `cell` · `batch`); kayıt `save` olayıyla gelir (`self.operation` + `self.changeset`) |
|
|
1013
|
+
| Kolon biçimi | `isFilterable`/`isSortable`/`colorMap`/`prefix`/`suffix`/`precision`/`thousands`/`dateFormat`/`imageShape`, **`progress`** kolon tipi |
|
|
1014
|
+
| Görünüm | `title`, `locale` (tr/en), `tableStyle` (zebra/plain — satır zemini varyantı), **`style`** (parça bazlı CSS: `&__toolbar`/`&__title`/`&__head`/`&__th`/`&__body`/`&__row`/`&__td`) |
|
|
1015
|
+
|
|
1016
|
+
**Süzme/sıralama/sayfalamanın ayrı olayı olmaması eksiklik değil, tasarım.** Filtre paneli,
|
|
1017
|
+
sıralama ve sayfalama komponentin İÇİNDE: kullanıcı süzdüğünde/sıraladığında/sayfa değiştirdiğinde
|
|
1018
|
+
`datatable` önce kendi `filters`/`sortField`/`sortType`/`offset` prop'larını node'a yazar, sonra
|
|
1019
|
+
**`mount`'u yeniden tetikler** (`updateQuery` → `emitMount`). Yani tek bir `mount` akışı yazarsın;
|
|
1020
|
+
o akış tabloya bağlı uca bu prop'ları parametre olarak geçirir ve dönen satırları geri yazar
|
|
1021
|
+
(`ngapps://examples/flow-load-table`).
|
|
1022
|
+
|
|
1023
|
+
Süzme/sıralama sunucu taraflıdır: seçilen filtreler uca `filters` parametresi olarak gider ve
|
|
1024
|
+
ancak `enableDynamicFilters: true` olan bir uçta karşılık bulur
|
|
1010
1025
|
(`platform_guide('microservice')`).
|
|
1011
1026
|
|
|
1012
|
-
**
|
|
1027
|
+
**Kurarken sorulacaklar:**
|
|
1013
1028
|
|
|
1014
|
-
- *Kullanıcı bu listeyi ekrandan süzecek/sıralayacak mı?* Hayır ise
|
|
1015
|
-
|
|
1016
|
-
- *
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
`datatable`'da yok.
|
|
1029
|
+
- *Kullanıcı bu listeyi ekrandan süzecek/sıralayacak mı?* Hayır ise kolonlarda
|
|
1030
|
+
`isFilterable`/`isSortable` açma; `mount` akışı yeterlidir.
|
|
1031
|
+
- *Satıra tıklayınca / çift tıklayınca bir şey olacak mı?* → `rowClick` / `rowDoubleClick` ya da
|
|
1032
|
+
satır aksiyonu (`actions`) — 7b.
|
|
1033
|
+
- *Hücre içi düzenleme gerekiyor mu?* → `editMode`; kaydı `save` akışı yazar, bağlı tabloda
|
|
1034
|
+
(Connect Data) runtime bağlantısı (`component_get('datatable')` → `knowledge`).
|
|
1021
1035
|
- *Sayı/tarih/görsel biçimlendirme (para birimi öneki, ondalık, binlik ayracı, tarih formatı,
|
|
1022
|
-
avatar şekli) gerekiyor mu?* →
|
|
1023
|
-
`dateFormat`/`imageShape
|
|
1024
|
-
- *Renk gerekiyor mu?* →
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
tipi `progress`. `progressVariant` çubuk/halka, `thresholds` yüzdeye göre renk, `captionField`
|
|
1031
|
-
ise BAŞKA bir satır alanını çubuğun üstüne yazar — ad ve çubuk tek hücrede durur. `table`'da
|
|
1032
|
-
böyle bir kolon tipi yok.
|
|
1033
|
-
|
|
1034
|
-
**Bu, katalogdaki her komponent için geçerlidir:** hangi komponenti kullanacağını
|
|
1036
|
+
avatar şekli) gerekiyor mu?* → kolon şemasında `prefix`/`suffix`/`precision`/`thousands`/
|
|
1037
|
+
`dateFormat`/`imageShape`.
|
|
1038
|
+
- *Renk gerekiyor mu?* → Kural 1e-2.
|
|
1039
|
+
- *Hücrenin içinde ilerleme çubuğu ya da yüzde halkası mı istiyorsun?* → kolon tipi `progress`.
|
|
1040
|
+
`progressVariant` çubuk/halka, `thresholds` yüzdeye göre renk, `captionField` ise BAŞKA bir
|
|
1041
|
+
satır alanını çubuğun üstüne yazar — ad ve çubuk tek hücrede durur.
|
|
1042
|
+
|
|
1043
|
+
**Komponent seçimi sana aittir:** hangi komponenti kullanacağını
|
|
1035
1044
|
`component_list`/`component_get` ile keşfedip kendin seçersin, rehberdeki örnekler tercih değil
|
|
1036
1045
|
şablondur.
|
|
1037
1046
|
|
|
1038
|
-
Kaçınılacak tek şey **yarım kurulum**: süzme arayüzünü açıp (`
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1047
|
+
Kaçınılacak tek şey **yarım kurulum**: süzme arayüzünü açıp (`datatable` + `isFilterable`
|
|
1048
|
+
kolonlar) arkasına statik filtreli uç bağlamak. Sayfa çalışır görünür, kullanıcı süzer, hiçbir şey
|
|
1049
|
+
olmaz. Ya süzme arayüzünü kapat, ya ucu `enableDynamicFilters: true` yap ve akışta `filters`
|
|
1050
|
+
parametresini geçir.
|
|
1042
1051
|
|
|
1043
1052
|
> Komponenti sonradan değiştirmek pahalıdır: flow'un `setter` adımı hedefi kayıt anında
|
|
1044
1053
|
> **DesignComponent id**'sine çözer (`StepIterate.component?.Id`), komponenti silip yeniden
|
|
1045
1054
|
> eklersen elementId aynı olsa bile o bağ kopar ve flow'u yeniden kaydetmen gerekir. Tipi
|
|
1046
1055
|
> baştan doğru seç.
|
|
1047
1056
|
|
|
1048
|
-
## Kural 1e-2 — Satır bazlı renk
|
|
1057
|
+
## Kural 1e-2 — Satır bazlı renk: `colorMap` ve satır verisi
|
|
1049
1058
|
|
|
1050
|
-
`
|
|
1051
|
-
|
|
1052
|
-
|
|
1059
|
+
`datatable`'da renk kolonun işidir ve çizim sırası **satır verisindeki `color` → `colorMap` →
|
|
1060
|
+
`autoColor`**'dır (`component_get('datatable')` → `knowledge.propNotes.colorMap`):
|
|
1061
|
+
|
|
1062
|
+
| istenen | yol |
|
|
1063
|
+
|---|---|
|
|
1064
|
+
| Değere göre sabit renk | `tag` kolonu + `colorMap`: `[{ value: 'Active', label: 'Aktif', color: 'success' }]` — hücrenin KENDİ değerine bakar, satırın başka alanına göre hesaplanamaz |
|
|
1065
|
+
| Satıra göre koşullu renk | hücre değerini `{ label, color }` nesnesi olarak yaz: renk satır verisinde taşınır |
|
|
1053
1066
|
|
|
1054
1067
|
```jsonc
|
|
1055
|
-
// setter: rows'a yazmadan önce
|
|
1068
|
+
// setter: rows'a yazmadan önce hücreyi { label, color } nesnesine çevir
|
|
1056
1069
|
{ "type": "change", "element": "tbl", "property": "rows", "source": "component",
|
|
1057
1070
|
"mapping": { "source": "", "mappings": {} },
|
|
1058
|
-
"value": { "type": "code", "ref": "(Steps.listele?.data || []).map(function (r) { return Object.assign({}, r, {
|
|
1071
|
+
"value": { "type": "code", "ref": "(Steps.listele?.data || []).map(function (r) { return Object.assign({}, r, { durum: { label: r.durum, color: r.durum === 'İptal' ? 'error' : 'success' } }); })" } }
|
|
1059
1072
|
```
|
|
1060
1073
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
`
|
|
1064
|
-
tanım sırası**: gizli bir `id` kolonu indeksleri kaydırmaz, kullanıcının kolon menüsünden kolon
|
|
1065
|
-
gizlemesi de kaydırmaz (`hideColumns` `buildViewColumns`'dan SONRA uygulanır).
|
|
1066
|
-
Aynı kalıp `_actions[i]` ile satır bazlı **aksiyon** ezmesinde de çalışır (tek bir satırda "Sil"i
|
|
1067
|
-
`{ "isHidden": true }` ile gizlemek gibi).
|
|
1074
|
+
Renk semantik ad (`primary · info · success · warning · error` — tema token'ına çözülür, tema
|
|
1075
|
+
değişince izler) ya da hex/rgb/CSS renk adıdır; temalarda `info` neredeyse beyazdır, mavi için
|
|
1076
|
+
`primary` yaz. `colorMap` satırının `mode: 'solid'`'i o değeri dolu zemin + beyaz yazıyla çizer.
|
|
1068
1077
|
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1078
|
+
Satır bazlı `_columns` görünüm ezmesi `datatable`'da **yoktur** (kaldırılan tablonun özelliğiydi).
|
|
1079
|
+
Satıra göre değişebilen şey AKSİYONDUR: `rows[i]._actions[<aksiyon indeksi>] = { isHidden,
|
|
1080
|
+
isDisabled, text … }` o satırda aksiyonun üstüne biner; `actions[i].isHidden`/`isDisabled` bir kod
|
|
1081
|
+
ifadesi de olabilir (`{ "type": "code", "ref": "{{ !item.isCustomizable }}" }`, `item` = o satır) —
|
|
1082
|
+
Connect Data'ya bağlı tabloda satırlar `_actions` taşıyamadığı için tek yol budur.
|
|
1073
1083
|
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
| istenen | yol |
|
|
1077
|
-
|---|---|
|
|
1078
|
-
| Hazır palet | `tag` kolonu + `appearance`: `primary · info · success · warning · error`; `_columns` ile satır satır değişir |
|
|
1079
|
-
| Serbest hex | `tags` kolonu + satır verisinde `[{ "value": "kritik", "color": "#da1e28" }]` |
|
|
1080
|
-
|
|
1081
|
-
**`style` yazarken iki ayrı kural geçerli:** `style.root` emotion'dır (camelCase çalışır, iç
|
|
1082
|
-
seçici yazılabilir); `style.thead|th|tr|td` ise satır içi `style` attribute'una basılır
|
|
1083
|
-
(`toStyleString` anahtarı olduğu gibi yazar) — bu dördünde **kebab-case zorunludur**, `fontSize`
|
|
1084
|
-
sessizce düşer, `font-size` çalışır.
|
|
1085
|
-
|
|
1086
|
-
> `datatable`'da `style` prop'u **yoktur** (ne şemada ne `.svelte`'de) ve `_columns` ezmesi de
|
|
1087
|
-
> yoktur; `tableStyle` CSS değil `zebra`/`plain` varyantıdır. Tabloya CSS ya da koşullu satır
|
|
1088
|
-
> rengi gerekiyorsa **`table`**.
|
|
1084
|
+
Tabloya CSS `style` prop'uyla yazılır (parça bazlı, camelCase; `designerCss` her bildirime
|
|
1085
|
+
`!important` ekler); `tableStyle` CSS değil `zebra`/`plain` varyantıdır.
|
|
1089
1086
|
|
|
1090
1087
|
## Kural 1f — Koordinat modeli ve layout-slot yerleşimi
|
|
1091
1088
|
|
|
@@ -1438,6 +1435,75 @@ düşer: sekme yığını kendi geçmişini tutar ve modal onu kırardı. `prese
|
|
|
1438
1435
|
|
|
1439
1436
|
Web uygulamasında alan yok sayılır; gateway web profilinde bu konuda bulgu üretmez.
|
|
1440
1437
|
|
|
1438
|
+
### `redirect.transition`
|
|
1439
|
+
|
|
1440
|
+
`redirect` adımının `args.transition` alanı hedef ekranın NASIL GİRDİĞİNİ söyler — `presentation`'ın
|
|
1441
|
+
yanındaki ikinci seçim, yalnız mobil. Kapalı küme:
|
|
1442
|
+
|
|
1443
|
+
- `default` — işletim sisteminin kendi geçişi
|
|
1444
|
+
- `none` — anında
|
|
1445
|
+
- `fade` — solarak
|
|
1446
|
+
- `slide` — yandan kayarak (iOS'ta sistemin geçişiyle aynı görünür)
|
|
1447
|
+
- `slideUp` — alttan kayarak
|
|
1448
|
+
|
|
1449
|
+
Öncelik: **adımın değeri → uygulamanın varsayılanı → sistem.** Alan yazılmamışsa adım uygulamanın
|
|
1450
|
+
varsayılanını kullanır: `application_update` `properties.mobile.transition` (aynı küme; `properties.mobile.tabs`'in
|
|
1451
|
+
yanındaki anahtar — `properties` yazılırken sekme ayarı da gönderilir, gövde REPLACE'tir). Adımda açıkça yazılmış
|
|
1452
|
+
`default` bir seçimdir ve uygulama varsayılanını ezer. Süre alanı yoktur.
|
|
1453
|
+
|
|
1454
|
+
- Küme dışı ADIM değerini backend 422 ile reddeder (iletisi kümeyi sayar); yazım gitmez. Küme dışı UYGULAMA ayarını
|
|
1455
|
+
backend doğrulamaz ve cihaz sessizce düşürür — onu söyleyen tek yer `application_create` / `application_update`
|
|
1456
|
+
yanıtındaki `platformWarnings`'tir (**MOB-029**).
|
|
1457
|
+
- **`modal` sunumda ve sekme hedefinde geçiş kullanılmaz:** modal sistemin kağıt animasyonuyla açılır, sekme
|
|
1458
|
+
hedefinde sekme değişir ve ekran itilmez. `modal` ile birlikte yazılırsa akış yazımının yanıtına MOB-029 bilgi notu
|
|
1459
|
+
düşer; sekme hedefi için not YOKTUR (lint sekme ayarını görmez) — hedef sayfanın sekme olup olmadığını
|
|
1460
|
+
`application_get` `properties.mobile.tabs.items`'tan kendiniz kontrol edin.
|
|
1461
|
+
- Geri dönüş (başlık çubuğunun geri düğmesi) aynı geçişin tersidir. iOS'ta kenardan geri kaydırma her geçişte
|
|
1462
|
+
sistemin yatay hareketidir.
|
|
1463
|
+
- "Hareketi azalt" açık cihazda seçilmiş geçiş oynamaz; `default` sisteme kalır.
|
|
1464
|
+
- `_transition` sorgu adı kabuğundur: `args.query` içinde bu adı kullanmayın — cihazda adrese yazılmaz ve sayfa onu
|
|
1465
|
+
`Page.queryParams`'ta görmez (web önizleme sorguyu olduğu gibi geçirir; iki yüzey bu adda ayrışır).
|
|
1466
|
+
- Geçiş TELEFONDA oynar. Web önizlemesi (`/dev`, `/preview`) yalnız GELEN sayfanın girişini oynatır — giden sayfa
|
|
1467
|
+
canlanmaz, `modal` ve sekme hedefinde giriş yoktur. `page_screenshot`'ın varsayılan karesi (`motion: 'frozen'`)
|
|
1468
|
+
"hareketi azalt"la alınır: giriş oynamaz, kare son hâli gösterir; `motion: 'play'` karesi girişin ortasına denk
|
|
1469
|
+
gelebilir.
|
|
1470
|
+
|
|
1471
|
+
Web uygulamasında alan yok sayılır; gateway web profilinde bu konuda bulgu üretmez.
|
|
1472
|
+
|
|
1473
|
+
## Kural 1g-3 — Paylaşılan öğe: `heroTag` (liste satırındaki görselden açılan ayrıntı)
|
|
1474
|
+
|
|
1475
|
+
`heroTag` iki sayfada AYNI etiketi taşıyan iki düğümü çift yapar: kaynak sayfadaki öğeye dokunulup hedef sayfaya
|
|
1476
|
+
gidilince hedef sayfa o öğenin kutusundan **büyüyerek** açılır, geri dönüşte o kutuya küçülür. Sayfanın TAMAMI büyür
|
|
1477
|
+
(iOS'un yakınlaşma geçişi) — yalnız öğenin uçtuğu klasik Hero değildir. Alanı `image` ve `container` taşır
|
|
1478
|
+
(`component_get` → `propNotes.heroTag`).
|
|
1479
|
+
|
|
1480
|
+
Liste → ayrıntı, üç adım:
|
|
1481
|
+
|
|
1482
|
+
1. **Kaynak:** satır şablonundaki `image`'a (ya da satırın kabına) `heroTag` yazın — `{ type: 'static', data: 'kapak' }`
|
|
1483
|
+
yeter. Satıra dokunmak (`repeater.itemPress`) satırdaki etiketli düğümden açar; dokunuşun görselin üstünde olması
|
|
1484
|
+
gerekmez. Liste dışında, `click`'i bağlı bir kabın içindeki etiketli düğüm de aynı kuralla kaynak olur. Satıra TEK
|
|
1485
|
+
etiket yazın: iç içe iki etiketli düğümde (kap ⊃ görsel) dokunuş ikisinin de dışındaysa içteki kaynak olur.
|
|
1486
|
+
2. **Hedef:** ayrıntı sayfasında büyük görsele AYNI etiketi yazın. Sayfa ona hizalanarak açılır. Hedefte eş yoksa
|
|
1487
|
+
sayfa yine kaynaktan büyür, yalnız hizalanacak kutu olmaz.
|
|
1488
|
+
3. **Gezinme:** bildiğiniz `redirect` adımı (`pageId`, `query`). Ek alan yok: etiketli öğeden çıkan itme (`push`) ve
|
|
1489
|
+
`modal` sunum yakınlaşır; sekme değişimi ve `replace` yakınlaşmaz.
|
|
1490
|
+
|
|
1491
|
+
- Etiketi satıra özgü yazmak GEREKMEZ (kaynak dokunulan satırdır). Hedef sayfada birden çok etiketli düğüm varsa
|
|
1492
|
+
doğrusunu ifade seçtirir: satırda `{{ 'urun-' + item.id }}`, hedefte `{{ 'urun-' + Page.queryParams.id }}`
|
|
1493
|
+
(`set_binding`). Hedef etiketini SORGU PARAMETRESİNDEN türetin: sonradan yüklenen veriye bağlı etiket ilk çizimde
|
|
1494
|
+
boştur, değer gelince düğüm yeniden kurulur ve `mount` akışları ikinci kez koşar.
|
|
1495
|
+
- **Yalnız iOS 18+ cihazda oynar.** Android'de, eski iOS'ta, `/dev` önizlemesinde, `page_screenshot`'ta ve kanvasta
|
|
1496
|
+
sayfa adımın geçişiyle açılır (`redirect.transition`). Yakınlaşma oynadığında adımın geçişi oynamaz. "Hareketi azalt"
|
|
1497
|
+
açıkken yakınlaşma yoktur. Dokunuşla başlamayan gezinme (zamanlayıcı, dokunuştan 10 sn sonra biten akış) yakınlaşmaz.
|
|
1498
|
+
- Hedef düğümün `motionStyle.enter`'ı oynamaz; hedef olmayan düğümlerinki oynar.
|
|
1499
|
+
- Aynı sayfada aynı statik etiketi iki düğüme yazmak KAYNAK sayfada olağandır (aynı etiketli kartlar). HEDEF sayfada
|
|
1500
|
+
hizalama kutusu tektir: ilk çizilen düğüm hizalanır — yazım bunu **MOB-030** bilgi notuyla söyler. Sayfalar arası
|
|
1501
|
+
eş arama yazımda yapılmaz (hedef sayfa henüz yazılmamış olabilir) ve eşi olmayan etiket için uyarı yoktur: iki
|
|
1502
|
+
sayfanın etiketlerini `page_runtime_get` özetindeki `heroTags`'ten (layout'unkiler dahil) karşılaştırın.
|
|
1503
|
+
- `_hero` sorgu adı kabuğundur (`_transition` gibi): `args.query` içinde kullanmayın.
|
|
1504
|
+
|
|
1505
|
+
Web uygulamasında alan yoktur.
|
|
1506
|
+
|
|
1441
1507
|
## Kural 1h — Tasarım: `style` prop'u ve tema değişkenleri
|
|
1442
1508
|
|
|
1443
1509
|
Her komponentin `style` prop'u vardır ve emotion `css()` bloğudur: iç seçiciler, pseudo-class'lar
|
|
@@ -1460,12 +1526,6 @@ yapmanın yolu budur — ölçülmüş kurallar (anket-doldur, 2026-08-19):
|
|
|
1460
1526
|
> düğümleri silip yeniden kurmaya, o da 20 setter'ın sessizce kopmasına yol açtı. Gateway artık
|
|
1461
1527
|
> kebab-case anahtarı camelCase'e çevirir ve `gatewayNormalized` ile bildirir; seçici anahtarlara
|
|
1462
1528
|
> (`&__body`, `:hover`, `--ng-*`) dokunmaz.
|
|
1463
|
-
>
|
|
1464
|
-
> **İSTİSNA — satır içi stil dalları (TB-129).** Kural `style` prop'unun emotion bloğu olan
|
|
1465
|
-
> dalları içindir. `table.style.thead|th|tr|td` ise DOM'un `style` attribute'una string olarak
|
|
1466
|
-
> basılır ve orada **kebab-case zorunludur**; gateway bu dört alanın altına 2026-09-20'den beri
|
|
1467
|
-
> hiç dokunmaz (`INLINE_STYLE_FIELDS_BY_TYPE`). `table.style.root` ve öteki komponentler eskisi
|
|
1468
|
-
> gibi çevrilir. Çeviri bu dalları da camelCase yapınca stil sessizce düşüyordu (S2-39).
|
|
1469
1529
|
|
|
1470
1530
|
**1. Temayı tek yerden çevir: `page_container.style` içinde `--ng-*` değişkenlerini ez.**
|
|
1471
1531
|
Runtime bütün renk/tipografi/form tokenlarını CSS değişkeni olarak basar
|
|
@@ -2175,7 +2235,7 @@ start → [setter] btn_save.isLoading = true
|
|
|
2175
2235
|
> katalogla sınırlıdır** ama artık neredeyse her komponent tanımlıyor: **101 kaydın 99'u**
|
|
2176
2236
|
> (ölçüm 2026-09-08; 2026-08-26'daki toplu ekleme öncesi 81'de 37 idi). Tanımlamayan yalnız
|
|
2177
2237
|
> iki kap var: **`slot` · `widget-area`** — onların içindekini gizlemek için sarmalayıcı
|
|
2178
|
-
> kullan. Eskiden tanımlamayan `text` · `
|
|
2238
|
+
> kullan. Eskiden tanımlamayan `text` · `datatable` · `dropdown` · `multi-select` ·
|
|
2179
2239
|
> `tag-input` · `tabs` · `notification` · `toast` · `datepicker` ailesi gibi komponentlere
|
|
2180
2240
|
> artık doğrudan `props.isHidden` yazılabilir; sırf gizlemek için `container`'a sarmak
|
|
2181
2241
|
> GEREKMEZ. Tek doğru kaynak `component_get` + `page_schema_validate` kuru koşusudur.
|
|
@@ -2189,26 +2249,27 @@ start → [setter] btn_save.isLoading = true
|
|
|
2189
2249
|
|
|
2190
2250
|
### 7b — Liste → form geçişi
|
|
2191
2251
|
|
|
2192
|
-
|
|
2252
|
+
Tablo `datatable`'dır (Kural 1e). Kaydı açmanın iki yolu var; ikisinde de tıklanan satır, akış
|
|
2253
|
+
koşmadan ÖNCE komponentin `selectedRow` prop'una **komponent tarafından** yazılır
|
|
2254
|
+
(`Table.svelte` → `setNode` + `onEmit`):
|
|
2193
2255
|
|
|
2194
|
-
| |
|
|
2256
|
+
| Yol | Kurulum | Satır akışta |
|
|
2195
2257
|
|---|---|---|
|
|
2196
|
-
|
|
|
2197
|
-
|
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
tarafından** yazılır, sonra akış çalışır (`Table.svelte:72` → `setNode` + `onEmit`): akışta
|
|
2203
|
-
`<elementId>.selectedRow.<alan>` ile okunur. `actions[].kind` sözlüğü **butonunkinden farklıdır**
|
|
2258
|
+
| Satır olayı | `set_event` → `rowDoubleClick` (tek tık için `rowClick`) | `self.selectedRow.<alan>` |
|
|
2259
|
+
| Satır aksiyonu | `actions: [{ text, kind, icon, flow: { type: 'flow', ref: <flowId> } }]` | `<elementId>.selectedRow.<alan>` |
|
|
2260
|
+
|
|
2261
|
+
`rowClick` veri hücresine tıklamada yayılır; onay kutusu, ✏/🗑 ve aksiyon düğmeleri tetiklemez.
|
|
2262
|
+
`editMode` `none` DIŞINDAYKEN çift tık satırı ayrıca düzenlemeye açar — geçiş için `editMode: none`
|
|
2263
|
+
bırak ya da aksiyon kullan. `actions[].kind` sözlüğü **butonunkinden farklıdır**
|
|
2204
2264
|
(`error · information · solid · transparent · dark · danger · warning`; butonda
|
|
2205
2265
|
`success · error · info · primary · warning`) — yanlış sözlükten değer `invalid-enum-value` verir.
|
|
2266
|
+
Kaldırılan tablonun çift tık ve seçim olay adları `datatable`'da yoktur: bağlamak 200 dönüp ölü
|
|
2267
|
+
bağ bırakmaz, gateway PAGE-008 ile istek gitmeden reddeder.
|
|
2206
2268
|
|
|
2207
|
-
|
|
2208
|
-
**`query` bir İFADEDİR**:
|
|
2269
|
+
Geçişi `redirect` yapar ve **`query` bir İFADEDİR** (`ngapps://examples/flow-list-to-form`):
|
|
2209
2270
|
|
|
2210
2271
|
```jsonc
|
|
2211
|
-
// satıra çift tıkla → edit ; self = tetikleyen komponent
|
|
2272
|
+
// satıra çift tıkla (rowDoubleClick) → edit ; self = tetikleyen komponent
|
|
2212
2273
|
{ "stepId": "go_edit", "type": "redirect", "kind": "normal",
|
|
2213
2274
|
"args": { "pageId": "<form sayfası id>", "path": "departman",
|
|
2214
2275
|
"query": "`id=${self.selectedRow.id}`" },
|
|
@@ -2216,7 +2277,7 @@ Aşağıdaki `doubleClick` tarifi **`table`** içindir. Geçişi `redirect` yapa
|
|
|
2216
2277
|
|
|
2217
2278
|
// "Yeni" butonu → create (bağlamı taşıyarak; komponente ADIYLA erişim)
|
|
2218
2279
|
{ "args": { "pageId": "<form sayfası id>", "path": "departman",
|
|
2219
|
-
"query": "
|
|
2280
|
+
"query": "records_table?.selectedRow?.id ? `parent=${records_table.selectedRow.id}` : ''" } }
|
|
2220
2281
|
```
|
|
2221
2282
|
|
|
2222
2283
|
Sayfalar arası veri geçmenin yolu budur: gönderen `query`'ye yazar, alan `Page.queryParams.<ad>`
|
|
@@ -2280,7 +2341,7 @@ bağlanır, filtre `source:'expression'` + `value:'user.id'` olur.
|
|
|
2280
2341
|
| Tarih / saat / aralık | `datepicker` · `datetimepicker` · `daterangepicker` · `datetimerangepicker` · `timepicker` (yalnız HH:mm) |
|
|
2281
2342
|
| Kimlik alanları | `textinput` (e-posta için `inputMask` Email hazır maskesi ya da `regex` kuralı — `email` diye bir bileşen YOK, `add_component` `unknown-type` ile reddedilir) · `password` |
|
|
2282
2343
|
| Dosya | `fileUpload` (dropzone) · `fileInput` · `filebutton` · `file-viewer` |
|
|
2283
|
-
| Liste | `
|
|
2344
|
+
| Liste | `datatable` (Kural 1e) · `repeater` (kart listesi VE dinamik form — Kural 1g) · `tree-view` (hiyerarşi; `isSearchable` ile istemci içi arama) · `timeline` (tarihli olay akışı) |
|
|
2284
2345
|
| Pano / takvim | `kanban` (durum kolonlarında sürüklenebilir kartlar; taşıma `cardMove` ile `event.data`'dan okunur, kalıcılık AKIŞIN işidir) · `eventcalendar` (ay/hafta/gün/ajanda; veri `rows`'a akışla yazılır, `monthChange`/`viewChange` görünen `start`/`end` aralığıyla tazeleme kancasıdır) |
|
|
2285
2346
|
| Kayıt detayı | `detailview` — tek kaydı etiket/değer ızgarası basar (alan başına format, iç içe alan yolu); OLAY YAYMAZ, tıklanabilirlik gerekiyorsa kapsayıcıya sar |
|
|
2286
2347
|
| Adımlı akış | `stepper` — tabs gibi her adım kendi droppable görünümünü taşır; ileri gidiş `canProceed` kapısıyla (`{{ form1.isValid === true }}` biçimi), adım `currentStep` setter'ıyla sürülür |
|
|
@@ -2540,7 +2601,7 @@ micro-op hattına dönün.
|
|
|
2540
2601
|
> 2026-09-20 öncesinde koruma her op'a tek başına baktığı için düğüm taşıyan her yama ikiye
|
|
2541
2602
|
> bölünmek zorundaydı (S2-35). Akışı gerçekten referanssız bırakan yama hâlâ durur.
|
|
2542
2603
|
>
|
|
2543
|
-
> **Satır aksiyonları statik şemada görünmeyebilir (TB-126).** `
|
|
2604
|
+
> **Satır aksiyonları statik şemada görünmeyebilir (TB-126).** `datatable`'ın
|
|
2544
2605
|
> `actions[].flow` bağı `{ type: 'flow', ref }` olarak sayılır — ama bu prop'u çoğu zaman YÜKLEME
|
|
2545
2606
|
> AKIŞI çalışma zamanında yazar (aksiyon role göre eklenip çıkarılıyorsa başka yolu da yok) ve o
|
|
2546
2607
|
> hâlde şemada `actions` BOŞ durur. `flow_list` böyle bir barındırıcıda `unboundFlowIds` yanına
|
|
@@ -127,6 +127,32 @@ Son kullanıcı dili `language-selector` komponentiyle değiştirir (`platform_g
|
|
|
127
127
|
prop'lar sayfa yenilenmeden yeniden çözülür — ayrı bir akış kurmana gerek yok, komponenti sayfaya
|
|
128
128
|
eklemen yeterli. Projede dil tanımlı değilse (`languages` boşsa) liste boş çizilir.
|
|
129
129
|
|
|
130
|
+
**Akıştan dil (2026-10-14 frontend; uzak kurulumda dağıtımdan sonra):** kod adımında ve `{{ }}` bağında
|
|
131
|
+
`Page.language` etkin dil kodunu verir, `Page.setLanguage('en')` dili seçicinin yaptığı gibi değiştirir
|
|
132
|
+
(saklanır, bütün bağlar yeni dilde çözülür; projede olmayan kod yok sayılır). "Girişten sonra
|
|
133
|
+
kullanıcının kayıtlı diline geç" böyle kurulur — sayfayı yenilemek gerekmez. Seçicinin `self.value`'su
|
|
134
|
+
`mount`'ta boştur; dili okumak için `Page.language` kullan.
|
|
135
|
+
|
|
136
|
+
## İfade başka komponentin çeviri bağlı prop'unu okuyunca
|
|
137
|
+
|
|
138
|
+
2026-10-14 frontend'inden (uzak kurulumda dağıtımdan) sonra ifade, kod adımı, `self`, `Widget.x`, setter'ın
|
|
139
|
+
eleman kopyası ve uç argümanının Property kaynağı çeviriye bağlı prop'u **ekranda görünen metinle**
|
|
140
|
+
okur — iç içe dizilerdekiler dahil (`{{ menu.navigations }}` başlıklarla gelir, `drawer.actions.map(a =>
|
|
141
|
+
a.text)` düğme metinlerini verir). Akış okuduğu diziyi geri yazınca, yazılan metin o anki çeviriyle
|
|
142
|
+
aynıysa çeviri bağı korunur ve dil sonradan değişince o metin de değişir; farklı metin yazılırsa bağın
|
|
143
|
+
yerini o metin alır. Bu sürümden önceki kurulumda aynı okuma `null` verir (menü boş, geri yazılan düğme
|
|
144
|
+
yazısı kaybolur) — orada geri okunan diziyi çeviriye bağlama.
|
|
145
|
+
|
|
146
|
+
## html şablonunda çeviri: `{{#t}}anahtar{{/t}}`
|
|
147
|
+
|
|
148
|
+
html bileşeninin `content`'inde `{{#t}}page.x.baslik{{/t}}` sözlükteki metni etkin dilde basar (zincir
|
|
149
|
+
ekrandakiyle aynı), HTML kaçışlıdır ve dil değişince yeniden çizilir. Bölümün içi önce çizildiği için
|
|
150
|
+
anahtar `context`'ten kurulabilir: `{{#t}}common.status.{{durum}}{{/t}}`. `context`'i akışlar baştan
|
|
151
|
+
yazsa da şablondaki metin etkilenmez — birden çok akışın doldurduğu html'deki sabit metni çevirmenin yolu
|
|
152
|
+
budur. Lambda yalnız `{{#t}}` geçen şablona eklenir; `context` kendi `t` alanını taşıyorsa o kazanır; markup taşıyan cümle yine `context` + `{{{…}}}` ile
|
|
153
|
+
basılır; datatable'ın `html` hücresi bu sözdizimini tanımaz. 2026-10-14 frontend'i (frontend ADR 0021),
|
|
154
|
+
uzak kurulumda dağıtımdan sonra.
|
|
155
|
+
|
|
130
156
|
## Kareyi ikinci dilde almak: `page_screenshot(language:)`
|
|
131
157
|
|
|
132
158
|
Dil değiştirici **kanıt için gerekli değildir.** Runtime boot dilini şu sırayla seçer:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"hash": "
|
|
3
|
-
"generatedAt": "2026-10-
|
|
2
|
+
"hash": "ba18a5111614d9b1e63e0d50f1a06a4dce1081b3d482c88e7620ca4bda9a466b",
|
|
3
|
+
"generatedAt": "2026-10-14T08:45:02.944Z",
|
|
4
4
|
"types": 337,
|
|
5
5
|
"files": 167,
|
|
6
6
|
"note": "Şemaları üreten backend kaynaklarının parmak izi. Elle düzenlemeyin: 'npm run generate-schemas' yazar, 'npm run schema:check' denetler.",
|
|
@@ -41,6 +41,9 @@
|
|
|
41
41
|
},
|
|
42
42
|
"choice": {
|
|
43
43
|
"$ref": "#/components/schemas/NgApps.Domain.Contexts.Organization.Merges.MergeChoice"
|
|
44
|
+
},
|
|
45
|
+
"value": {
|
|
46
|
+
"$ref": "#/components/schemas/System.Text.Json.Nodes.JsonNode"
|
|
44
47
|
}
|
|
45
48
|
},
|
|
46
49
|
"additionalProperties": false
|
|
@@ -48,10 +51,36 @@
|
|
|
48
51
|
"NgApps.Domain.Contexts.Organization.Merges.MergeChoice": {
|
|
49
52
|
"enum": [
|
|
50
53
|
"source",
|
|
51
|
-
"target"
|
|
54
|
+
"target",
|
|
55
|
+
"both",
|
|
56
|
+
"custom"
|
|
52
57
|
],
|
|
53
58
|
"type": "string",
|
|
54
59
|
"format": ""
|
|
60
|
+
},
|
|
61
|
+
"System.Text.Json.Nodes.JsonNode": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"properties": {
|
|
64
|
+
"options": {
|
|
65
|
+
"$ref": "#/components/schemas/System.Text.Json.Nodes.JsonNodeOptions"
|
|
66
|
+
},
|
|
67
|
+
"parent": {
|
|
68
|
+
"$ref": "#/components/schemas/System.Text.Json.Nodes.JsonNode"
|
|
69
|
+
},
|
|
70
|
+
"root": {
|
|
71
|
+
"$ref": "#/components/schemas/System.Text.Json.Nodes.JsonNode"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"additionalProperties": false
|
|
75
|
+
},
|
|
76
|
+
"System.Text.Json.Nodes.JsonNodeOptions": {
|
|
77
|
+
"type": "object",
|
|
78
|
+
"properties": {
|
|
79
|
+
"propertyNameCaseInsensitive": {
|
|
80
|
+
"type": "boolean"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"additionalProperties": false
|
|
55
84
|
}
|
|
56
85
|
}
|
|
57
86
|
}
|
package/dist/tools/activities.js
CHANGED
|
@@ -13,6 +13,8 @@ const activityKind = z.enum([
|
|
|
13
13
|
'merge.applied_with_drift',
|
|
14
14
|
'merge.discarded',
|
|
15
15
|
'merge.failed',
|
|
16
|
+
'merge.replanned',
|
|
17
|
+
'merge.resolutions_carried',
|
|
16
18
|
'deployment.started',
|
|
17
19
|
'deployment.completed',
|
|
18
20
|
'deployment.failed',
|
|
@@ -25,7 +27,7 @@ export function registerActivityTools(server, platform) {
|
|
|
25
27
|
const config = platform.config;
|
|
26
28
|
server.registerTool('activity_list', {
|
|
27
29
|
title: 'Proje etkinlik günlüğü',
|
|
28
|
-
description: "Projenin dal, merge ve dağıtım geçmişini en yeniden eskiye listeler: kim, ne zaman, ne yaptı. Her satırda kind, actor, actorSource (human|ai|system), occurredAt ve türe göre değişen bir summary vardır — merge.applied'da message ve counters, environment.created'da branchName, deployment.*'da süre ya da hata. subjectId merge satırlarında plan id'sidir; ayrıntı için merge_get ile okuyun. actorSource='ai' satırları bu gateway üzerinden yapılan işlerdir.",
|
|
30
|
+
description: "Projenin dal, merge ve dağıtım geçmişini en yeniden eskiye listeler: kim, ne zaman, ne yaptı. Her satırda kind, actor, actorSource (human|ai|system), occurredAt ve türe göre değişen bir summary vardır — merge.applied'da message ve counters, merge.resolutions_carried'da carried/dropped (tazelemede korunan ve yeniden sorulan karar sayısı), environment.created'da branchName, deployment.*'da süre ya da hata. subjectId merge satırlarında plan id'sidir; ayrıntı için merge_get ile okuyun. actorSource='ai' satırları bu gateway üzerinden yapılan işlerdir.",
|
|
29
31
|
inputSchema: {
|
|
30
32
|
projectId: guid,
|
|
31
33
|
kind: activityKind,
|
|
@@ -2,6 +2,7 @@ import { guid, pagingParams, readOnly, writes, updates, destructive } from './co
|
|
|
2
2
|
import { handle } from '../platform/responses.js';
|
|
3
3
|
import { forgetApplication, readApplicationPlatform, resolveApplication } from '../knowledge/platform/resolve.js';
|
|
4
4
|
import { mobileTabsProblems, readMobileTabs } from '../knowledge/platform/mobileTabs.js';
|
|
5
|
+
import { mobileTransitionProblems } from '../knowledge/platform/pageTransition.js';
|
|
5
6
|
import { findingLine } from '../knowledge/platform/profile.js';
|
|
6
7
|
import { listComponents } from './components.js';
|
|
7
8
|
import { z } from 'zod';
|
|
@@ -37,6 +38,19 @@ export async function mobileTabsWarnings(platform, applicationId, projectSlug, h
|
|
|
37
38
|
guide: "platform_guide('mobile') §Gezinme"
|
|
38
39
|
}));
|
|
39
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* MOB-029 (varsayılan sayfa geçişi) — `properties.mobile.transition` yazan mobil uygulama çağrısının denetimi.
|
|
43
|
+
* Yazım platforma YİNE gider (backend `properties`'i doğrulamaz); cihaz sözlük dışı değeri sessizce düşürdüğü için
|
|
44
|
+
* bulgunun söylendiği tek yer `platformWarnings`'tir.
|
|
45
|
+
*/
|
|
46
|
+
export function mobileTransitionWarnings(properties) {
|
|
47
|
+
return mobileTransitionProblems(properties).map(message => findingLine({
|
|
48
|
+
code: 'MOB-029',
|
|
49
|
+
severity: 'warn',
|
|
50
|
+
message,
|
|
51
|
+
guide: "platform_guide('page') §Kural 1g-2"
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
40
54
|
function withPlatformWarnings(response, warnings) {
|
|
41
55
|
if (warnings.length === 0 || !response || typeof response !== 'object' || Array.isArray(response))
|
|
42
56
|
return response;
|
|
@@ -77,7 +91,7 @@ export function registerApplicationTools(server, platform) {
|
|
|
77
91
|
annotations: writes
|
|
78
92
|
}, handle(config, async ({ projectId, ...body }) => {
|
|
79
93
|
const warnings = readApplicationPlatform(body.type) === 'mobile'
|
|
80
|
-
? await mobileTabsWarnings(platform, undefined, undefined, undefined, body.properties)
|
|
94
|
+
? [...await mobileTabsWarnings(platform, undefined, undefined, undefined, body.properties), ...mobileTransitionWarnings(body.properties)]
|
|
81
95
|
: [];
|
|
82
96
|
const response = await platform.org('POST', `/applications/${projectId}`, { body });
|
|
83
97
|
forgetApplication(platform);
|
|
@@ -100,7 +114,7 @@ export function registerApplicationTools(server, platform) {
|
|
|
100
114
|
}, handle(config, async ({ id, ...body }) => {
|
|
101
115
|
const current = await resolveApplication(platform, id);
|
|
102
116
|
const warnings = current?.platform === 'mobile'
|
|
103
|
-
? await mobileTabsWarnings(platform, id, current.projectSlug, body.homepageId, body.properties)
|
|
117
|
+
? [...await mobileTabsWarnings(platform, id, current.projectSlug, body.homepageId, body.properties), ...mobileTransitionWarnings(body.properties)]
|
|
104
118
|
: [];
|
|
105
119
|
const response = await platform.org('PUT', `/applications/${id}`, { body });
|
|
106
120
|
forgetApplication(platform, id);
|