@appaflytech/zeyrek-ai-mcp 0.0.31 → 0.0.33
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/README.md +5 -5
- package/dist/config.js +0 -26
- package/dist/knowledge/backendConstraints.js +1 -18
- package/dist/knowledge/componentCatalog.js +27 -493
- package/dist/knowledge/componentEvents.js +2 -120
- package/dist/knowledge/connectDataDefinition.js +4 -4
- package/dist/knowledge/connectDataRules.js +1 -1
- package/dist/knowledge/mobileComponentCatalog.js +13 -8
- package/dist/knowledge/mobileStore.js +227 -0
- package/dist/knowledge/normalize.js +48 -131
- package/dist/knowledge/outlines.js +0 -36
- package/dist/knowledge/platform/lint.js +1 -1
- package/dist/knowledge/platform/nativeBoxModel.js +1 -1
- package/dist/knowledge/policy.js +4 -18
- package/dist/knowledge/process.js +1 -1
- package/dist/knowledge/reservedTables.js +0 -79
- package/dist/knowledge/rules.js +10 -83
- package/dist/knowledge/schemaGuard.js +0 -11
- package/dist/observability/trace.js +2 -5
- package/dist/platform/capture/capture.js +1 -25
- package/dist/platform/errors.js +10 -162
- package/dist/platform/http.js +1 -6
- package/dist/platform/responses.js +4 -34
- package/dist/platform/schemaReadMemory.js +2 -2
- package/dist/platform/secrets.js +1 -8
- package/dist/resources/examples/middleware-authenticate.json +1 -1
- package/dist/resources/examples/mobile-app-shell-drawer.json +62 -61
- package/dist/resources/examples/mobile-list-detail-form.json +51 -20
- package/dist/resources/examples/page-detail-profile.json +1 -2
- package/dist/resources/examples/page-dynamic-form.json +2 -3
- package/dist/resources/examples/page-html-embed.json +1 -1
- package/dist/resources/examples/workflow-basic.json +2 -8
- package/dist/resources/guides/access.md +4 -18
- package/dist/resources/guides/bpm.md +1 -6
- package/dist/resources/guides/component.md +4 -83
- package/dist/resources/guides/entity.md +8 -50
- package/dist/resources/guides/getting-started.md +1 -38
- package/dist/resources/guides/merge.md +3 -37
- package/dist/resources/guides/microservice.md +0 -78
- package/dist/resources/guides/middleware.md +3 -35
- package/dist/resources/guides/mobile.md +85 -2
- package/dist/resources/guides/page.md +26 -278
- package/dist/resources/guides/workflow.md +0 -51
- package/dist/resources/rules.js +5 -11
- package/dist/resources/schema-fingerprint.json +5 -7
- package/dist/resources/schemas/CreateEntityCommand.json +0 -118
- package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
- package/dist/resources/schemas/CreateQueryCommand.json +0 -4
- package/dist/resources/schemas/CreateWorkflowCommand.json +1 -146
- package/dist/resources/schemas/DataJobDto.json +1 -6
- package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +2 -20
- package/dist/resources/schemas/MicroserviceDto.json +1 -13
- package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
- package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -25
- package/dist/resources/schemas/StartMobileBuildCommand.json +54 -0
- package/dist/resources/schemas/StepDto.json +1 -25
- package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
- package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
- package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
- package/dist/resources/schemas/UpdateViewCommand.json +2 -0
- package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -146
- package/dist/resources/schemas/UpsertMobileStoreSettingsCommand.json +259 -0
- package/dist/server.js +5 -25
- package/dist/tools/access.js +2 -369
- package/dist/tools/common.js +0 -7
- package/dist/tools/components.js +2 -15
- package/dist/tools/datasources.js +2 -2
- package/dist/tools/dependencies.js +1 -1
- package/dist/tools/deployments.js +3 -38
- package/dist/tools/designSchemaPatch.js +3 -13
- package/dist/tools/dtos.js +5 -36
- package/dist/tools/entities.js +12 -79
- package/dist/tools/externalComponents.js +1 -1
- package/dist/tools/flows.js +10 -45
- package/dist/tools/folders.js +1 -1
- package/dist/tools/imports.js +2 -5
- package/dist/tools/layouts.js +5 -6
- package/dist/tools/merges.js +2 -2
- package/dist/tools/microservices.js +20 -50
- package/dist/tools/mobileStore.js +268 -0
- package/dist/tools/pages.js +35 -89
- package/dist/tools/platformInfo.js +6 -20
- package/dist/tools/projects.js +9 -71
- package/dist/tools/rows.js +12 -62
- package/dist/tools/schemaOps.js +1 -29
- package/dist/tools/screenWrite.js +1 -22
- package/dist/tools/screens.js +3 -6
- package/dist/tools/templates.js +1 -26
- package/dist/tools/translations.js +1 -1
- package/dist/tools/workflows.js +5 -10
- package/package.json +2 -2
|
@@ -28,9 +28,7 @@ component_get → tek tipin TAM sözleşmesi, üç katman birleşik:
|
|
|
28
28
|
- **`isHidden`** her komponenti gizler; setter ile yazmak katalogda listelenmeyen tiplerde de
|
|
29
29
|
çalışır. Gizli komponent `mount` olayını görünür olana dek TETİKLEMEZ.
|
|
30
30
|
- **`mount`** olayını komponentin kendisi değil ortak katman yayar: komponent ilk kez
|
|
31
|
-
görünür olduğunda bir kez. Sayfa açılış akışı `page_container.mount`'a
|
|
32
|
-
`mount` olayına bağlanır (`page_update { events }`, `platform_guide('page')` Kural 1d-2) —
|
|
33
|
-
`page_container` Studio'nun Layers ağacında görünmez.
|
|
31
|
+
görünür olduğunda bir kez. Sayfa açılış akışı `page_container.mount`'a bağlanır.
|
|
34
32
|
- **`name` = `elementId`** kuralı: runtime her komponent için `const <name> = Components[...]`
|
|
35
33
|
üretir; bozuk ad sayfadaki BÜTÜN ifadeleri öldürür (`platform_guide('page')` Kural 1c-2).
|
|
36
34
|
- **Boyut:** `blocks[].size` katalogdaki `maxSize`'ı aşamaz; yükseklikte
|
|
@@ -81,51 +79,6 @@ Doğrulama mesajını çeviriye bağlamak ayrı bir sözleşmedir (`t:` öneki,
|
|
|
81
79
|
İstisna: `html` komponentinin
|
|
82
80
|
aksiyonları kendi `flow` prop'uyla bağlanır (`platform_guide('html')`).
|
|
83
81
|
|
|
84
|
-
## Korumalı değer ve arayüz yetkisi (kompleks proje)
|
|
85
|
-
|
|
86
|
-
Kompleks projede ortamın zorlama modu `enforce` iken runtime iki şey taşır; ikisi de **yalnız
|
|
87
|
-
arayüzdür**, yetkiyi backend her istekte yeniden denetler.
|
|
88
|
-
|
|
89
|
-
- **Satır metası.** Table-source uçtan dönen satırda korumalı alan varsa
|
|
90
|
-
`__protected: { <alanSlug>: 'masked' | 'plain' }` bulunur; `hidden` alan satırda hiç yoktur.
|
|
91
|
-
`table` · `datatable` · `detailview` · `text` (`record` + `recordField` ile) `masked` alanı
|
|
92
|
-
kilitli maske olarak çizer; "Göster" → gerekçe → değer 30 sn görünür, sonra yeniden maskelenir.
|
|
93
|
-
"Göster" yalnız erişim özeti yüklüyken çıkar: `off`'ta (basit proje hep `off`) hiç çıkmaz —
|
|
94
|
-
backend her reveal'i reddeder; `shadow`'da çıkar — backend reveal'i yine denetler, yetkisiz
|
|
95
|
-
kullanıcı ret mesajını görür; `enforce`'ta yalnız entity'nin `actions`'ında `reveal` varsa.
|
|
96
|
-
Değeri boş maskeli hücrede "Göster" çıkmaz. Tasarımcı kanvasında (**View as user**) düğme seçilen
|
|
97
|
-
kullanıcıya sunulacağı yerde etkisiz çizilir (kullanıcı seçili değilken tasarımcının
|
|
98
|
-
`project.data.reveal` izni karar verir); gerçek açma önizlemededir.
|
|
99
|
-
Açılan değer prop'a, akışa, olaya yazılmaz. Entity `revealEntity` prop'undan (slug ya da id) ya
|
|
100
|
-
da boşsa erişim özetinden çözülür (`component_get` → `knowledge.propNotes.revealEntity`).
|
|
101
|
-
- **Maske forma bağlanmaz.** Güncelleme formunda korumalı alanın `textinput`'u her zamanki gibi
|
|
102
|
-
`value` ile kaydın alanına bağlanır, yanına `isMasked` eklenir:
|
|
103
|
-
`{{ Steps.<adım>.data.__protected?.tckn === 'masked' }}`. `isMasked` açıkken bağlı değer maske
|
|
104
|
-
metni sayılır ve gösterilmez: alan boş başlar, "Değiştirmek için yeni değer girin" yer tutucusunu
|
|
105
|
-
gösterir, mount sonrası düğüm değerini `null`'a çeker ve `required`'a takılmaz. Kullanıcı yazınca
|
|
106
|
-
sıradan girdidir; değer girdinin yazmadığı bir değere dönerse (forma başka satır seçildi, akış
|
|
107
|
-
alanı sıfırladı) yeni kaydın maskesi yine gizlenir ve temizlenir.
|
|
108
|
-
- **Izgarada kör üzerine yazma (ADR 0007).** Bağlı `datatable`'da `capability.canWrite` politikadan gelir;
|
|
109
|
-
maskeli okumak yazmayı kapatmaz. Maskeli hücre düzenlemeye **boş** açılır, yazılan değer gider, boş bırakılan
|
|
110
|
-
maske gitmez; hücre seçimine girmez, toplu düzenleme maskeli kolonu sunmaz. Korumalı alanı güncellemek için
|
|
111
|
-
form kurmak zorunlu değildir. Eski değeri görerek düzeltmek gerekiyorsa önce "Göster" (30 sn, editöre ön
|
|
112
|
-
doldurulmaz). Bağlı olmayan tabloda ve `table` bileşeninde maskeli hücre düzenlenmez.
|
|
113
|
-
- **Boş değerin gönderilmemesi isteğin kuruluşuna bağlıdır.** Microservice çağrısının parametre
|
|
114
|
-
bağı boş (`null`/`''`) değeri gövdeye koymaz → saklı değer korunur. Gövdeyi akış kodunda ya da
|
|
115
|
-
setter göreviyle elle kuruyorsan (`{ tckn: TextInput1.value }`) `null` gider: `canWrite` yoksa
|
|
116
|
-
403 `AccessFieldWriteDeniedException`, varsa saklı değer **silinir**. Boş maskeli alanı böyle bir
|
|
117
|
-
gövdeye koyma.
|
|
118
|
-
- **`Page.can(permission, resourceKey)`** her ifadede (görünürlük bağı, akış kodu) kullanılır:
|
|
119
|
-
`Page.can('reveal', 'entity:musteriler')` · `Page.can('entity.update', 'entity:<id>')` ·
|
|
120
|
-
`Page.can('view', 'page:musteri/detay')` · `Page.can('execute', 'microservice:musteri-listesi')`.
|
|
121
|
-
İzin kısa eylem adı ya da katalog slug'ıdır; anahtar `entity:<slug|id>` · `page:<slug>` ·
|
|
122
|
-
`microservice:<slug>`. `enforce` dışında (ya da özet yüklenmemişken) HER ZAMAN `true`; okunamayan
|
|
123
|
-
anahtar ya da başka kaynak tipinin izni `enforce`'ta `false`.
|
|
124
|
-
- **Oturum.** `/view` runtime isteklerinde oturum çerezi gider, durum değiştiren isteğe `X-ZY-CSRF`
|
|
125
|
-
eklenir; oturum 401'i bir kez yenilenir (`auth/refresh`) ve istek tekrarlanır. Yenilenemezse
|
|
126
|
-
uygulamanın giriş sayfasına gidilir — sayfa yükü bugün giriş sayfasını taşımadığı için yönlendirme
|
|
127
|
-
backend bunu gönderene dek olmaz (teknik borç). Özetin listelemediği sayfa ana sayfaya döner.
|
|
128
|
-
|
|
129
82
|
## Stil
|
|
130
83
|
|
|
131
84
|
Her komponentin `style` prop'u vardır ve iç parçalara iner (`textinput.style`: `&__label` ·
|
|
@@ -157,30 +110,15 @@ Widget, kendi komponent ağacını taşıyan yeniden kullanılabilir pakettir (`
|
|
|
157
110
|
micro-op'ları `PATCH /components/{app}/{id}/schema`'ya yazar; `component_update` ise slug alan
|
|
158
111
|
tam gövde PUT'tur. Widget'ın düzey olayı yoktur, `remove_event` yalnız komponent hedefler.
|
|
159
112
|
|
|
160
|
-
## Satır başına çizilen çocuklar ve `item`
|
|
161
|
-
|
|
162
|
-
İki komponent çocuklarını VERİ SATIRI başına çizer; çocukların kod bağlamalarında o satır `item`'dır
|
|
163
|
-
(`{{ item.title }}`):
|
|
164
|
-
|
|
165
|
-
| Host | Hangi çocuklar | `item` |
|
|
166
|
-
|---|---|---|
|
|
167
|
-
| `repeater` | Bütün çocukları, `rows`'un her satırında | Satır; `item.x = …` satıra geri YAZAR |
|
|
168
|
-
| `datatable` | Yalnız `datatable-cell` çocukları: her biri `column` prop'undaki kolonun hücresine, her satırda | Satır; SALT OKUNUR |
|
|
169
|
-
|
|
170
|
-
`datatable`'ın kendisi `isDroppable` DEĞİLDİR: çocuğu yalnız `datatable-cell` olabilir
|
|
171
|
-
(`props.column = <columns[].name>`), asıl içerik onun içine konur. Şablonu olan kolonda kolonun
|
|
172
|
-
`type`/format ayarı çizilmez; sıralama, filtre ve dışa aktarma ham değerle çalışır. Hangi türün host
|
|
173
|
-
olduğu tek kayıttadır: `zeyrek-frontend/packages/ng-apps-ui/src/shared/render/row-scope.ts`.
|
|
174
|
-
|
|
175
113
|
## `states` ve `appearance` sözlükleri
|
|
176
114
|
|
|
177
115
|
Her şema düğümünde iki sözlük vardır; ikisi de ortak render katmanında çözülür:
|
|
178
116
|
|
|
179
117
|
| `states` | Anlamı |
|
|
180
118
|
|---|---|
|
|
181
|
-
| `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-
|
|
119
|
+
| `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` |
|
|
182
120
|
| `isScrollable` | İçeriği kendi alanında kaydırır (sabit yükseklikte `overflow-y: auto`) |
|
|
183
|
-
| `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
|
|
121
|
+
| `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 |
|
|
184
122
|
| `isSticky` | Kaydırmada yerinde kalır (header/sidebar; z-index'i otomatik) |
|
|
185
123
|
| `isFloating` | Düğümü akıştan çıkarıp yüzdürür (katman davranışı; nadir) |
|
|
186
124
|
| `isQuickStack` | Studio'nun Quick Stack iskelet hücresi işareti — editörde kesikli çerçeve çizer, **runtime'da hiçbir etkisi yoktur**. MCP'den iskelet kurarken yazmak serbesttir ama gerekmez |
|
|
@@ -202,7 +140,7 @@ Her şema düğümünde iki sözlük vardır; ikisi de ortak render katmanında
|
|
|
202
140
|
| `widthString` / `heightString` | CSS uzunluğu | Sabit ölçü; **yalnız ilgili `*Type: 'fixed'` iken okunur** (aksi PAGE-017 uyarısı). Kabul: çıplak sayı (px sayılır) · `px % vw vh vmin vmax rem em ch` birimli değer · `calc(...)`. Negatif/`pt`/`fr`/`auto` GEÇMEZ — platform kaydeder ama panel ve runtime sessizce düşürür (PAGE-018). Eski `widthPx` alanı 2026-09-01'de kaldırıldı |
|
|
203
141
|
| `marginType` / `marginValue` | `normal` · `none` · `custom` + px | Dış boşluk: **yazılmazsa `normal` sayılır** = her kenara 4px (`spacing.ts` `CANVAS_NORMAL_MARGIN`); custom=`marginValue`. Bileşenleri dip dibe dizmek için `none` ŞART — `gap:'none'` olsa bile normal margin komşular arasında 8px bırakır (sıkı dizilim tarifi: `platform_guide('page')` Kural 1f-2) |
|
|
204
142
|
| `paddingType` / `paddingValue` | `normal` · `none` · `custom` + px | İç boşluk: normal=10px. **Yalnız droppable kaplarda ve tipli stil modelindeki yapraklarda (box · text · container · statcard · icon · form) çizilir**; `slot`, kabuk kökleri (`layout`/`layout-shell`) ve `modal`/`drawer`/`auth-layout` hiç almaz — platform 200 döner, ekran değişmez (PAGE-029). Değerler piksel SAYISIDIR: `24`, `"24px"` değil (PAGE-030) |
|
|
205
|
-
| `alignType` | `left` · `center` · `right` | İçerik hizalama (destekleyen komponentlerde)
|
|
143
|
+
| `alignType` | `left` · `center` · `right` | İçerik hizalama (destekleyen komponentlerde) |
|
|
206
144
|
| `aspectRatio` | sayı | En-boy oranı kilidi (medya komponentleri) |
|
|
207
145
|
|
|
208
146
|
`isHidden` bu sözlüklerde değil PROP'tur ve her komponentte çalışır; flow'lar `margin` /
|
|
@@ -259,23 +197,6 @@ ve `layout` grubundaki adlar giremez. **MCP tarafında karşılığı yoktur:**
|
|
|
259
197
|
bir prop'tur, `set_prop` ile aynı şekilde yazılır. Bu bilgi yalnız "studio'da neden o
|
|
260
198
|
düğmeler var" sorusuna cevaptır.
|
|
261
199
|
|
|
262
|
-
## Bağlanabilir prop'lar (`connectData`)
|
|
263
|
-
|
|
264
|
-
`component_get` yanıtındaki `connectData` bileşenin hangi prop'unun veri kaynağına bağlanabileceğini
|
|
265
|
-
söyler; alan yoksa bileşen bağlanamaz (`connectDataNote`). Kaynak platform kataloğudur.
|
|
266
|
-
|
|
267
|
-
| Alan | Anlamı |
|
|
268
|
-
|---|---|
|
|
269
|
-
| `primary` | Birincil bağlanabilir prop (`rows`, `options`); Studio "Veriye bağla" düğmesi bunu açar |
|
|
270
|
-
| `trigger` | "Veriye bağla" düğmesinin yeri: `toolbar` (bileşen araç çubuğu) · `canvas` (kanvastaki bileşenin üstü) |
|
|
271
|
-
| `props.<yol>.roles` | Rol → tür (`any` · `string` · `number` · `boolean` · `date` · `parent`); dropdown `{ label, value }`, grafik `{ category, value }` |
|
|
272
|
-
| `props.<yol>.required` | Doldurulmadan bağlanamayan roller |
|
|
273
|
-
| `props.<yol>.fields` | Rol → bileşenin alan ADI prop'u (grafik `category → categoryField`, kanban `title → titleField`); bağlama o prop'lara seçilen alanın slug'ını yazar. Kaydında `fields` olmayan bileşen (dropdown) satırı rol adlarıyla okur |
|
|
274
|
-
| `props.<yol>.fieldsFrom` | Satırların alanlarını tanımlayan liste prop'u (`datatable.rows → columns`); rol yerine kolon listesi üretilir |
|
|
275
|
-
|
|
276
|
-
Yol joker olabilir: `series[].data` kaydı `series.1.data` prop'unu kapsar. Bağlamanın kendisi, tanım
|
|
277
|
-
şekli ve kurallar: `platform_guide('page')` §Kural 1c-3.
|
|
278
|
-
|
|
279
200
|
## Komponent seçimi
|
|
280
201
|
|
|
281
202
|
"Hangi işe hangi komponent" tablosu ve `table` / `datatable` karşılaştırması:
|
|
@@ -15,9 +15,7 @@ uzayındadır. Çakışan slug `Migration failed … relation "X" already exists
|
|
|
15
15
|
kaydı hiç oluşmaz**. Rezerve adlardan bilinenler: `branches`, `applications`, `caches`,
|
|
16
16
|
`components`, `datasources`, `entities`, `fields`, `files`, `flows`, `folders`, `layouts`,
|
|
17
17
|
`microservices`, `pages`, `permissions`, `projects`, `queries`, `queued_events`, `roles`,
|
|
18
|
-
`steps`, `users`, `variables`, `views`, `workflows
|
|
19
|
-
`organization_units`, `organization_positions`, `user_positions`, `access_policies`, `access_grants`
|
|
20
|
-
(tam liste gateway'in rezerve ad kontrolündedir). Alan adı bunlardan biriyse eş anlamlısını
|
|
18
|
+
`steps`, `users`, `variables`, `views`, `workflows`. Alan adı bunlardan biriyse eş anlamlısını
|
|
21
19
|
seç (ör. şube/branş için `branches` değil `specialties`).
|
|
22
20
|
|
|
23
21
|
> **Ama `users`/`roles`/`files`/`folders` bir istisna:** bunlar "dolu olduğu için kaçınılacak"
|
|
@@ -26,7 +24,7 @@ seç (ör. şube/branş için `branches` değil `specialties`).
|
|
|
26
24
|
|
|
27
25
|
## Hazır entity'ler — kimlik tablosu ZATEN VAR
|
|
28
26
|
|
|
29
|
-
Her projeye seed sırasında
|
|
27
|
+
Her projeye seed sırasında 9 entity açılır ve **id'leri her kurulumda aynı sabitlerdir**
|
|
30
28
|
(`Defaults` sınıfı) — aramana gerek yok, doğrudan `entity_get` ile çekebilirsin:
|
|
31
29
|
|
|
32
30
|
| slug | id | Ne için |
|
|
@@ -37,33 +35,12 @@ Her projeye seed sırasında hazır entity'ler açılır ve **id'leri her kurulu
|
|
|
37
35
|
| `permissions` · `role_permissions` | `01917ede-a457-…` · `01917ede-d450-…` | yetki matrisi |
|
|
38
36
|
| `files` · `folders` | `0191dbf2-39c4-…` · `0191df94-f635-…` | Drive; `FILE` alanları buraya bağlanır (`entity_list`'te GİZLİ) |
|
|
39
37
|
| `audit_trails` · `audit_trail_values` | `01961f53-25c3-…` · `01961f53-3552-…` | denetim izi |
|
|
40
|
-
| `organization_units` · `organization_unit_closure` | `01a0a05e-1c9a-7022-a0c7-6b8320756a4c` · `01a0a05e-1ca3-7b6a-9f1b-7f1633f7f05a` | **Organizasyon ağacı** (yalnız okunur, aşağıda): birimler — `parent_id` · `unit_type` (holding/company/branch/region/department/team/other) · `function_code` · `name` · `code` · `manager_position_id` · `origin` · `is_active` — ve ata/torun kapanışı |
|
|
41
|
-
| `organization_positions` · `organization_position_closure` | `01a0a05e-1ca3-700f-95c6-18fe1e30079c` · `01a0a05e-1ca4-7b73-b90e-4aa7d8eeeeef` | birimdeki koltuklar — `unit_id` · `parent_position_id` (idari hat) · `functional_parent_position_id` (işlevsel hat) · `role_id` · `name` · `code`; kapanışta `line_type` |
|
|
42
|
-
| `user_positions` | `01a0a05e-1ca4-7841-b6b3-45c5892d5501` | kullanıcı ↔ pozisyon — `user_id` · `position_id` · `is_primary` · `assignment_type` · `starts_at` · `ends_at` |
|
|
43
38
|
|
|
44
39
|
**`users` gerçek bir entity'dir**, sahte bir sistem tablosu değil: `entity_get` alanlarını verir,
|
|
45
40
|
`RELATION` alanı hedef alabilir, table step / microservice okur, `row_create` yazar, kendi default
|
|
46
41
|
DTO'su vardır. Auth middleware tarifi zaten bunu okur — `ngapps://examples/middleware-authenticate`
|
|
47
42
|
`entityId` olarak `users`'ı kullanır.
|
|
48
43
|
|
|
49
|
-
### Organizasyon ağacı tabloları — okunur, genel yolla YAZILMAZ (ORG-001 · ORG-002)
|
|
50
|
-
|
|
51
|
-
Beş organizasyon tablosu **her projede vardır**; basit projede boştur, kompleks projede
|
|
52
|
-
(`project_create` `accessModel: 'complex'`) organizasyonun rol yönetim şemasının kopyasını taşır.
|
|
53
|
-
|
|
54
|
-
- **Yazma kapalı (ORG-001, block).** `row_create` / `row_update` / `row_delete`, table kaynaklı uç
|
|
55
|
-
ve table step bu tablolara platformda `400 SystemEntityWriteNotAllowed` alır; gateway isteği hiç
|
|
56
|
-
göndermez. Ağaç organizasyon şemasından **senkronla** gelir (yönetim konsolunda yayın → abone
|
|
57
|
-
projenin her ortamı); projeye özel birim/pozisyon ve kullanıcı ataması Studio › Organizasyon
|
|
58
|
-
ekranındadır — MCP'de bu yazma yolu bilinçli olarak yoktur: projede yapı değişikliği aboneliği
|
|
59
|
-
kapatır (`receiveUpdates = false`) ve dal ortamında 409 döner.
|
|
60
|
-
- **Kompleks proje yayınlı son şemayla doğar (ORG-002).** Organizasyonda yayın yoksa tablolar boş
|
|
61
|
-
kalır; önce `organization_schema_get` ile `publishedVersion`'a bak. Abonelik ve özelleştirme
|
|
62
|
-
durumu `project_get` → `organizationSchema`.
|
|
63
|
-
- **Okuma serbest:** `row_list('organization_units')`, pozisyonlar için `row_list('organization_positions')`.
|
|
64
|
-
Alt ağaç sorusu (bir birimin bütün torunları) kapanış tablosundan `ancestor_id` filtresiyle
|
|
65
|
-
okunur; `depth` 0 düğümün kendisidir.
|
|
66
|
-
|
|
67
44
|
### Neden gözden kaçıyor
|
|
68
45
|
|
|
69
46
|
`entity_list`'i **`applicationId` ile** çağırdığında hazır entity'ler listede **görünmez**: seed
|
|
@@ -117,12 +94,6 @@ yapıyorsan devam et).
|
|
|
117
94
|
uygulamanın rol açması/düzenlemesi gerekiyorsa yol her domain tablosuyla aynıdır: entity + kendi
|
|
118
95
|
microservice ucun + sayfa. `role_list` yalnız okur.
|
|
119
96
|
|
|
120
|
-
> **Kompleks projede roller organizasyon şemasından gelir** (`roles.origin = 'organization'`;
|
|
121
|
-
> `role_list` bu alanı döndürmez, `row_list('roles')` okur). Şemadan gelen rol MCP'den yazılmaz,
|
|
122
|
-
> yönetim konsolunda düzenlenir; yetki `page.roleIds` ile değil erişim politikasıyla verilir.
|
|
123
|
-
> Aşağıdaki reçete basit proje içindir — kompleks projede kendi rolünü açan uç yine uyarı alır
|
|
124
|
-
> (ROL-002 warn), dikey çözümün açtığı rol projeye özgü kalır.
|
|
125
|
-
|
|
126
97
|
`roles` entity'sinin açtığı alanlar — fiziksel tabloda ayrıca `template_*` kolonları var, hepsi
|
|
127
98
|
nullable, gateway'den görünmez:
|
|
128
99
|
|
|
@@ -163,15 +134,6 @@ Rol açma reçetesi:
|
|
|
163
134
|
`permissions` / `role_permissions` **Studio'nun yetki matrisidir**, uygulama sayfasının yetkisi
|
|
164
135
|
değil; uygulama tarafında yetkiyi `page.roleIds` ve middleware ifadesi kurar.
|
|
165
136
|
|
|
166
|
-
## Veri koruma — maskeli, şifreli ve türetilmiş alan
|
|
167
|
-
|
|
168
|
-
TCKN, telefon gibi alanlar `fields[].protection` ile maskeli ve/veya şifreli saklanır; telefonun
|
|
169
|
-
operatör kodu gibi sorgulanabilir parça `derivedFromFieldId` + `derivationRule` ile türetilmiş alan
|
|
170
|
-
olur. Koruma yalnız düz metin alana konur (display, birincil anahtar, ilişki, çok dilli değil —
|
|
171
|
-
PROT-003), korumalı alanda metin araması ve sıralama yoktur (PROT-001, PROT-002). Modlar, maske
|
|
172
|
-
türleri, dolu kolonda geçiş ve hatalar: `platform_guide('access')` §'Alan koruması'. Satırları bir
|
|
173
|
-
bileşene bağlamak (liste, dropdown, grafik) akış değil `connect_data_bind`: `platform_guide('page')` §Kural 1c-3.
|
|
174
|
-
|
|
175
137
|
## Alan tipleri (dbType + commonType İKİSİ birden verilir)
|
|
176
138
|
|
|
177
139
|
| dbType (BÜYÜK HARF zorunlu) | commonType |
|
|
@@ -197,9 +159,6 @@ bileşene bağlamak (liste, dropdown, grafik) akış değil `connect_data_bind`:
|
|
|
197
159
|
`description`'a yaz: para → `INT8` kuruş (`*_minor`), süre → `INT4` dakika, yüzde →
|
|
198
160
|
`INT4` ×100, puan → `INT4` ×10.
|
|
199
161
|
- `commonType`'sız `UUID`/`BOOL` "isn't a supported database type" hatasıyla reddedilir.
|
|
200
|
-
- Birincil anahtar `properties.generationType` taşımak ZORUNDADIR: `properties` hiç verilmezse create
|
|
201
|
-
`Please select a valid generation type for 'id'` ile düşer (38/U-14). `0` (Always) ve `1` (ByDefault) ikisi de
|
|
202
|
-
geçerlidir — `UUID` anahtarda ikisiyle de satır id'si üretildi (ölçüldü 2026-09-21, 39/05 D-15).
|
|
203
162
|
- **Katalogu okumak gerekiyorsa** (bu datasource'ta hangi `dbType` var, hangisi varsayılan, tip
|
|
204
163
|
hangi seçenekleri kabul ediyor, hangi tipe dönüştürülebilir) `datasource_configuration_options`
|
|
205
164
|
çağır: varsayılan yanıt ~5 KB'lık **özettir**; 816 kayıtlık collation DEĞER listesi yalnız
|
|
@@ -721,13 +680,12 @@ orada `undefined` alır.
|
|
|
721
680
|
> `Sequence contains no **elements**` (satır yok — genelde preview rollback'i) **farklı**
|
|
722
681
|
> sorunlardır; karıştırmak teşhisi saptırır.
|
|
723
682
|
|
|
724
|
-
- **Audit izi ne zaman gerçekten yazılır?**
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
(`AuditTrailType.cs`); `advanced` diye bir değer **yoktur**, gönderirsen bağlama hatası alırsın.
|
|
683
|
+
- **Audit izi ne zaman gerçekten yazılır?** `CreateAuditTrailCommandHandler` şu üç durumda
|
|
684
|
+
**hiç kayıt açmaz**: `IsAuditTrailActive == false`, `AuditTrailType == null`, ya da
|
|
685
|
+
`AuditTrailType == simple`. Yani iz tutulması için `isAuditTrailActive: true` **ve**
|
|
686
|
+
`auditTrailType: "basic" | "detailed"` birlikte gerekir. Enum yalnız üç değer tanır —
|
|
687
|
+
`simple` · `basic` · `detailed` (`AuditTrailType.cs`); `advanced` diye bir değer **yoktur**,
|
|
688
|
+
gönderirsen bağlama hatası alırsın.
|
|
731
689
|
- **Audit izi IP adresi tutar.** `audit_trails.IpAddress`, isteğin
|
|
732
690
|
`HttpContext.Connection.RemoteIpAddress` değerinden doldurulur (`UserContext.cs`) ve satır
|
|
733
691
|
olaylarıyla (`Row.Created/Updated/Deleted` → `UserIpAddress`) audit consumer'a taşınır; kullanıcı
|
|
@@ -5,10 +5,7 @@
|
|
|
5
5
|
Bağımlılıklar bu sırayı zorunlu kılar; atlama:
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
1. project_create (
|
|
9
|
-
'Basit mi kompleks mi?' tablosu; sonradan değiştirmek ayrı bir dönüşüm
|
|
10
|
-
işidir.
|
|
11
|
-
application zorunlu: ilk application projeyle birlikte açılır;
|
|
8
|
+
1. project_create (application zorunlu: ilk application projeyle birlikte açılır;
|
|
12
9
|
application slug'ı ORG GENELİNDE tekildir — 'web' büyük olasılıkla
|
|
13
10
|
doludur, 409'da project_list ile mevcut slug'ları tara.
|
|
14
11
|
DİL: gateway create'ten sonra projenin dillerini kurar — verirsen
|
|
@@ -71,8 +68,6 @@ Bağımlılıklar bu sırayı zorunlu kılar; atlama:
|
|
|
71
68
|
13. application_update (homepageId — ana sayfa sayfadan değil application'dan seçilir)
|
|
72
69
|
```
|
|
73
70
|
|
|
74
|
-
Onay zinciri, görev kutusu, SLA gibi insanı bekleyen işler workflow'a sıkıştırılmaz: entity ve (gerekiyorsa) servis workflow'ları hazır olduktan sonra süreç tanımı yazılır — `platform_guide('bpm')`.
|
|
75
|
-
|
|
76
71
|
## İlk kullanıcıyı kim açar? (tavuk-yumurta kilidi)
|
|
77
72
|
|
|
78
73
|
Kimlik kurulmuş yeni bir projede **giriş yapabilecek hiç kimse yoktur** ve zincir kendi kendini
|
|
@@ -124,38 +119,6 @@ Middleware bir kontrol listesi maddesi değil; **ihtiyaca** kurulur:
|
|
|
124
119
|
`middlewareIds` ile bağlı olmalı. Bir-iki uca bağlayıp gerisini açık bırakmak, hiç kurmamaktan
|
|
125
120
|
kötüdür — sistem güvenli görünür, değildir.
|
|
126
121
|
|
|
127
|
-
## Basit mi kompleks mi? (proje türü)
|
|
128
|
-
|
|
129
|
-
Tür `project_create` `accessModel` ile proje açılırken seçilir; varsayılan `simple`'dır.
|
|
130
|
-
|
|
131
|
-
| Durum | Tür |
|
|
132
|
-
|---|---|
|
|
133
|
-
| Kimlik ve yetki uygulamanın kendi işi; birkaç rol yeter, satır kapsamı elle yazılan `user.id` filtresi | **simple** — bugünkü davranış, aşağıdaki middleware tablosu geçerli |
|
|
134
|
-
| Kurumun birim/pozisyon ağacı var (holding → şirket → bölge → departman), "müdür ekibinin kayıtlarını görür", maskeli/şifreli alan (TCKN) | **complex** |
|
|
135
|
-
|
|
136
|
-
Kompleks projede fark edilmesi gerekenler:
|
|
137
|
-
|
|
138
|
-
- Proje organizasyonun **yayınlı son** rol şemasının kopyasıyla doğar; yayın yoksa organizasyon
|
|
139
|
-
tabloları boştur (ORG-002). Açmadan önce `organization_schema_get` → `publishedVersion`.
|
|
140
|
-
- Ağaç tabloları (`organization_units`, `organization_positions`, `user_positions`) yalnız
|
|
141
|
-
okunur; `row_*` ile yazılmaz (ORG-001).
|
|
142
|
-
- Abonelik `project_get` → `organizationSchema`: `customizedAt` görünüyorsa proje ayrışmıştır ve
|
|
143
|
-
yeni sürümler artık gelmez.
|
|
144
|
-
|
|
145
|
-
### Kompleks projede ilk kullanıcı
|
|
146
|
-
|
|
147
|
-
`users` kompleks projede de boş doğar ve yukarıdaki bootstrap deseni **`enforce` ortamda çalışmaz**:
|
|
148
|
-
anonim uç işareti olmadığı için oturumsuz her microservice isteği — bootstrap ucu da — `401` döner.
|
|
149
|
-
Yeni kompleks proje `enforce` başlar. Sıra:
|
|
150
|
-
|
|
151
|
-
1. Kullanıcıya söyle: development ortamının zorlama modu Studio › Ayarlar › Ortamlar'dan geçici olarak
|
|
152
|
-
`shadow` yapılsın (insan işi, ACC-007; production'a dokunulmaz). `shadow` engellemez.
|
|
153
|
-
2. Bootstrap desenini uygula (geçici uç → kullanıcı → ucu hemen sil).
|
|
154
|
-
3. Kullanıcının koltuğu Studio › Organizasyon ekranında atanır (`user_positions`); politika pozisyona ya da
|
|
155
|
-
role atanmışsa yetki buradan gelir.
|
|
156
|
-
4. Mod `enforce`'a döner; `access_session_create` ile giriş yap, `asUser` ile uçları sına, reddi
|
|
157
|
-
`access_preview` ile açıkla (`platform_guide('access')`).
|
|
158
|
-
|
|
159
122
|
## Örnek arama davranışı
|
|
160
123
|
|
|
161
124
|
Örnek gövde için **mevcut projeleri taramak yerine** önce şunlara bak:
|
|
@@ -39,16 +39,6 @@ trail tabloları hariç, dış datasource'lara dokunulmaz). Kayıt taşıması a
|
|
|
39
39
|
(`promote`) kuralıdır ve orada aynen geçerlidir. **Satırlar merge'de geri taşınmaz** — merge yalnız
|
|
40
40
|
tanım işidir.
|
|
41
41
|
|
|
42
|
-
Tanım sayılan ve merge'in taşıdığı üç şey 2026-09-25'ten beri listede: **çeviriler**
|
|
43
|
-
(translation kalemi, adı çeviri anahtarı), **microfunction'lar** (kod ve arşiv; hedefte **taslak**
|
|
44
|
-
kalır, yayını kullanıcı yapar) ve zamanlanmış işin **duraklatma durumu**. Öncesinde dalda
|
|
45
|
-
eklenen çeviri ve microfunction development'a hiç gelmiyordu.
|
|
46
|
-
|
|
47
|
-
- Aynı çeviri anahtarını (uygulama, dil, anahtar) dal da development da kendi başına eklediyse plan
|
|
48
|
-
yalnız dalınkini `add` gösterir; apply development'ın satırına **dalın değerini** yazar.
|
|
49
|
-
- Microfunction **runtime**'ı merge'de taşınmaz (kimlik bilgisi taşır). Dalda yeni bir runtime kurup
|
|
50
|
-
microfunction'ı ona bağlarsanız apply `23503` ile düşer — runtime'ı önce development'ta kurun.
|
|
51
|
-
|
|
52
42
|
Dalda `page_screenshot` **çalışır** (2026-09-09'dan beri); ayrıntısı bir sonraki bölümde.
|
|
53
43
|
|
|
54
44
|
## Dalda görsel doğrulama
|
|
@@ -95,7 +85,7 @@ değişkenler, çözülen ref'ler) kareyi tamamlar: kare ne çizildiğini, bu ik
|
|
|
95
85
|
- `derivedFromKey`: kalem OTOMATİK ÜRETİLMİŞ bir kayıtsa (varsayılan DTO) kaynağının anahtarı
|
|
96
86
|
- `elements[]`: `path`, `kind`, `base`, `source` (dal), `target` (development), `resolution`
|
|
97
87
|
|
|
98
|
-
`dataRisk` bir **uyarıdır, apply'ı bloklamaz**;
|
|
88
|
+
`dataRisk` bir **uyarıdır, apply'ı bloklamaz**; üç sebepten biriyle doğrudur:
|
|
99
89
|
|
|
100
90
|
| `dataRiskReasons` | Ne demek |
|
|
101
91
|
|---|---|
|
|
@@ -103,32 +93,8 @@ değişkenler, çözülen ref'ler) kareyi tamamlar: kare ne çizildiğini, bu ik
|
|
|
103
93
|
| `field-narrowed` | Tip / `nullable` / `unique` daraltılıyor |
|
|
104
94
|
| `not-null-without-default-on-populated-table` | **Hedefte satır varken** varsayılansız zorunlu alan ekleniyor — bu apply'ı DDL aşamasında düşürür. Alanı `nullable` yapın ya da `defaultValueType: "default-value"` + `defaultValue` verin |
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
`not-null-…` satırı 2026-09-09'da eklendi; öncesinde bu durum `dataRisk: 0` diyordu ve risk ancak
|
|
109
|
-
apply denenerek öğreniliyordu. Hedef tablo **boşsa** aynı alan riskli sayılmaz.
|
|
110
|
-
|
|
111
|
-
Aynı denetimin sert hâli promote'tadır: deploy başlamadan production verisine karşı koşar ve veri
|
|
112
|
-
bozacak değişikliği 400 ile reddeder (`deployment_start` açıklaması).
|
|
113
|
-
|
|
114
|
-
### Silinen kaydın yeni bağımlısı: `dependents[]`
|
|
115
|
-
|
|
116
|
-
Dal bir kaydı sildi, development ise dal açıldıktan **sonra** o kaydı kullanmaya başladıysa
|
|
117
|
-
(bir sayfa sorguyu bağladı, bir akış servisi çağırdı) silme `delete` olarak değil **`conflict`**
|
|
118
|
-
olarak gelir ve kalemde `dependents[]` (`{ id, name, module }`) dolar:
|
|
119
|
-
|
|
120
|
-
- `choice: "target"` kaydı ve bağımlısını korur,
|
|
121
|
-
- `choice: "source"` siler — bağımlı FK ile düşebilir ya da kırık bağla kalır.
|
|
122
|
-
|
|
123
|
-
Sorgunun çıktı DTO'su ve alanları **aynı çakışma grubundadır**: biri çözülünce diğerleri de o
|
|
124
|
-
tarafa gider. Dal açılmadan önce var olan ve development'ta değişmeyen bağımlı çakışma üretmez —
|
|
125
|
-
onu dal zaten görmüştü.
|
|
126
|
-
|
|
127
|
-
### Süreç kenarlarında çakışma
|
|
128
|
-
|
|
129
|
-
`versions[…].model.edges` listesinde iki taraf **aynı geçidin** çıkışlarına dokunduysa tek bir
|
|
130
|
-
çakışma gelir, yolu `versions[id=…].model.edges{from=<düğüm>}` biçimindedir — o geçidin bütün
|
|
131
|
-
çıkışları bir karar olarak çözülür. Farklı geçitlere yapılan değişiklikler kendiliğinden birleşir.
|
|
96
|
+
Son satır 2026-09-09'da eklendi; öncesinde bu durum `dataRisk: 0` diyordu ve risk ancak apply
|
|
97
|
+
denenerek öğreniliyordu. Hedef tablo **boşsa** aynı alan riskli sayılmaz.
|
|
132
98
|
|
|
133
99
|
`derivedFromKey` dolu olan kalemi ayrıca çözmeye çalışmayın: kaynağını (entity ya da query)
|
|
134
100
|
çözdüğünüzde aynı yoldaki çakışması **kendiliğinden** aynı tarafa çözülür. Entity adını değiştiren
|
|
@@ -344,25 +344,6 @@ kart doğru sütuna geçer, başlığı ve sorumlusu silinir.
|
|
|
344
344
|
> ifadeden gelir ve `undefined` dönen ifade de `null` yazar —
|
|
345
345
|
> `platform_guide('workflow')` §"Table update adımı".
|
|
346
346
|
|
|
347
|
-
### Toplu güncelleme FİLTREYLE kurulmaz
|
|
348
|
-
|
|
349
|
-
"Bekleyen bütün başvuruları onayla" bir table-source `update` ucuyla YAZILAMAZ. `update`
|
|
350
|
-
operasyonu tam olarak **bir tekil alan filtresi** ister: birden çok filtre
|
|
351
|
-
`InvalidFilterCountException`, tekil olmayan alanla filtre `FilterFieldMustUniqueException`
|
|
352
|
-
döndürür (ölçüldü 2026-09-20, S2-22). Yani hedef kümeyi bir KOŞUL belirleyemez, yalnız bir ANAHTAR
|
|
353
|
-
belirler. İki doğru yol var:
|
|
354
|
-
|
|
355
|
-
| Ne istiyorsun | Yol |
|
|
356
|
-
|---|---|
|
|
357
|
-
| Anahtarlar elinde, hepsi ya hep ya hiç yazılsın | **`bulk-update` ucu** — gövde satır dizisi, filtre yok, tek çağrı, tek transaction (yukarıdaki §"Toplu yazma"). En fazla 1000 satır; bir satır düşerse hiçbiri yazılmaz |
|
|
358
|
-
| Satır başına SONUÇ ve satır başına YETKİ kararı gerekiyor | **İş akışı + döngü** (BK-05 deseni): liste ucunu çağır → her satır için `microservice` adımı → sayaçları topla → özet döndür |
|
|
359
|
-
|
|
360
|
-
Kapsam ve politika koşulu her iki yolda da satır satır uygulanır; fark sonucun şeklidir. Toplu
|
|
361
|
-
onay gibi işlerde ikinci yol tercih edilir çünkü yetkisi yetmeyen satır ötekileri geri almaz:
|
|
362
|
-
çağıran "N onaylandı · M reddedildi" özetini alır (ölçülen koşu: iki satır da 403 ile reddedildi,
|
|
363
|
-
akış "0 onaylandı · 2 reddedildi" döndürdü). Döngüdeki uç, çağıranın kimliğiyle denetlenir —
|
|
364
|
-
akış içinden yazmak yetki YÜKSELTMEZ.
|
|
365
|
-
|
|
366
347
|
## İlişki alanı: `row_list` NESNE döner, uç/step JOIN'siz DÜZ FK döner
|
|
367
348
|
|
|
368
349
|
Aynı alan iki yoldan farklı şekilde gelir ve bu fark sessizce yanlış sonuç üretir:
|
|
@@ -704,20 +685,6 @@ Rol listesini **değiştirmek** için yukarıdaki §"Patch belgesi OKUMA şeklid
|
|
|
704
685
|
> rota `/{project}/m/{application}/{microservice SLUG'ı}`'dır ( `url` alanı rotaya GİRMEZ) ve
|
|
705
686
|
> `Host: <org>.<suffix>` + `X-Environment` başlıkları zorunludur.
|
|
706
687
|
|
|
707
|
-
### Kompleks projede
|
|
708
|
-
|
|
709
|
-
- `enforce` ortamda **anonim uç yoktur**: oturumsuz her istek `401 AppSessionRequired` döner; yukarıdaki
|
|
710
|
-
anonim veri toplama deseni kompleks projede kurulamaz. Uç izni erişim politikasıyla gelir
|
|
711
|
-
(`microservice.execute`); platform `roleIds`'i hiçbir modda karar için kullanmaz.
|
|
712
|
-
- `middlewareIds`'e bağlı middleware **her modda koşar** ve reddedebilir; set-user adımı ya da yanıttaki
|
|
713
|
-
`user` platformun doldurduğu `user`'ı ezer. Kimlik middleware'ini uçtan çıkarın (ACC-006).
|
|
714
|
-
- Table kaynaklı uç satırları kapsamla SQL'de süzer (kapsam dışı id 404), gizli alanı çıkarır, korumalı
|
|
715
|
-
alanı `__protected` ile işaretler; yetkisiz alana yazma ya da filtre 403.
|
|
716
|
-
- Query kaynaklı uç kapsamlı ya da korumalı tabloya dokunuyorsa sorgu `isUnrestricted` olmadıkça
|
|
717
|
-
`403 AccessQueryNotScoped` (ACC-005).
|
|
718
|
-
- Sınama: `access_session_create` → `asUser`; ret nedeni `access_preview` ve `microservice_debug`
|
|
719
|
-
yanıtındaki `accessDecision`. Kurallar: `platform_guide('access')`.
|
|
720
|
-
|
|
721
688
|
## Alias nerede geçerli
|
|
722
689
|
|
|
723
690
|
Alias bir **SQL tablo takma adıdır**: yalnız okunan tarafta anlamı vardır. Sözleşme iki ayrı
|
|
@@ -738,29 +705,6 @@ Yazma alanına `alias` koyarsan istek **hata vermez**, alan model bağlamada dü
|
|
|
738
705
|
istek gitmeden gövdeden çıkarır ve `gatewayNormalized` ile bildirir — böylece `silentlyDropped`
|
|
739
706
|
listesi yalnız gerçek kayıpları gösterir.
|
|
740
707
|
|
|
741
|
-
### Kök filtrenin alias'ı entity SLUG'ı olmak zorundadır (MS-023)
|
|
742
|
-
|
|
743
|
-
`filters[].alias` runtime'da iki şeyden birine eşlenir: **ana entity'nin slug'ı** ya da bir **join
|
|
744
|
-
alias'ı** (`PostgreSqlRelationHandler.GetField`). Üçüncü bir seçenek yoktur — `sourceParameters.alias`
|
|
745
|
-
alanına yazdığın kök takma ad da dâhil. Eşleşmeyen alias'lı **zorunlu** filtre isteği 400
|
|
746
|
-
`FilterFieldNotResolvedException` ile düşürür ve parametreyi hangi adla gönderirsen gönder değişmez.
|
|
747
|
-
|
|
748
|
-
Çağrı parametresinin adı aynı kuraldan çıkar:
|
|
749
|
-
|
|
750
|
-
| Filtrenin alias'ı | Çağrı parametresi (`parameterScheme[].name`) | Çalışır mı |
|
|
751
|
-
|---|---|---|
|
|
752
|
-
| entity slug'ı (`kredi_basvurusu`) | `id` — **nitelenmemiş** alan slug'ı | evet |
|
|
753
|
-
| join alias'ı (`musteri`) | `musteri.id` | evet |
|
|
754
|
-
| başka bir şey (`kredi`) | `kredi.id` | **hayır** — 400 `FilterFieldNotResolvedException` |
|
|
755
|
-
|
|
756
|
-
Yani şemadaki ad, uç çalışabildiği sürece runtime'ın beklediği addır; nitelikli bir ad görüyorsan
|
|
757
|
-
alias'ın bir JOIN alias'ı olduğundan emin ol. `microservice_get` join olmayan nitelikli adı
|
|
758
|
-
**MS-023** uyarısıyla işaretler. Düzeltme:
|
|
759
|
-
`microservice_patch { op: 'replace', path: '/sourceParameters/filters/0/alias', value: '<entity slug>' }`.
|
|
760
|
-
|
|
761
|
-
Ölçüldü 2026-09-20 (`rehber-basit/tb119-get`, entity slug `tb119_urun`): alias `u` → parametre
|
|
762
|
-
`u.kod`, çağrı 400; alias `tb119_urun` → parametre `kod`, çağrı 200.
|
|
763
|
-
|
|
764
708
|
## Zamanlanmış iş (`type: 'schedule-job'`) — `typeParameters.schedule`
|
|
765
709
|
|
|
766
710
|
Zamanlama tek bir tanımdır; `cronExpression` tek başına verilirse **UTC cron** sayılır (eski gövde).
|
|
@@ -876,25 +820,3 @@ Dört gerçek daha:
|
|
|
876
820
|
(`{ "op": "add", "path": "/description", "value": "…" }`). Patch yanıtındaki `silentlyDropped`
|
|
877
821
|
alanı, gönderilen ama kaydedilmeyen alanları listeler — boş değilse platform bir alanı yutmuş
|
|
878
822
|
demektir.
|
|
879
|
-
|
|
880
|
-
## Connect Data kaynağı olarak uç
|
|
881
|
-
|
|
882
|
-
Okuyan bir uç prop'a **akışsız** bağlanabilir (`connect_data_bind`, `platform_guide('page')` §Kural 1c-3). Şartlar
|
|
883
|
-
(ölçüldü 2026-09-21, koşu 38):
|
|
884
|
-
|
|
885
|
-
- Uç **okur** (GET tablo `get`, query ya da view kaynağı), **middleware'siz** ve **dönüş şeması** vardır; yazan tablo/sistem
|
|
886
|
-
ucu, middleware'li uç ve şemasız uç `connect_data_describe`'da 422 `ConnectDataSourceUnsupported`.
|
|
887
|
-
**Middleware'li uç bilinçli olarak dışarıda (karar 2026-10-02, qm madde 5C):** connectData yolu ucun middleware
|
|
888
|
-
zincirini koşmaz; kaynak olarak kabul edilseydi ucun korumaları (kimlik, rol, setter değişkenleri) atlanırdı.
|
|
889
|
-
Korumalı ucu listeye bağlamanın yolu **akıştır**: bileşenin `mount` (ve arama/sayfa) akışında microservice adımı
|
|
890
|
-
ucu çağırır — middleware'ler koşar —, setter dönen satırları `rows`'a yazar. Uç projedeki başka bir uygulamada
|
|
891
|
-
olabilir (microservice adımı servisin kendi uygulamasının adresine gider). Middleware'i kaldırıp ucu açmak çözüm
|
|
892
|
-
değildir.
|
|
893
|
-
- **Tablo ucunda `enableDynamicFilters: true`** alanları `canFilter`/`sortable` yapar (kullanıcı filtresi tanım filtresiyle
|
|
894
|
-
AND'lenir); `sort`/`limit` query-string parametreleri offset sayfalama açar. Dinamik filtresiz ya da query kaynaklı uç
|
|
895
|
-
`pageMode: client` kalır (CD-007) ve süzmez.
|
|
896
|
-
- Uç parametreleri bağlantının `params`'ından gelir (`source.parameters`; CD-013).
|
|
897
|
-
- `connect_data_convert` bir bağlantıyı `source: connectData` bir uca çevirir: `m/{app}/{slug}` `POST { op: 'list' }` aynı
|
|
898
|
-
kabiliyet damgalı `{ data, meta, errors }` zarfını döner. Kompleks projede `microservice_execute { asUserId }` ile
|
|
899
|
-
kullanıcı gözüyle doğrulayın; `microservice_preview` Studio ucudur (ROLLBACK'li, kapıları koşmaz).
|
|
900
|
-
- Örnekler: `ngapps://examples/connect-data-workflow-microservice`, `ngapps://examples/connect-data-convert-verify`.
|
|
@@ -19,16 +19,6 @@ kavramı olmayan bir üründe auth middleware'i, ayar tablosu olmayan bir ürün
|
|
|
19
19
|
kur** — giriş sayfası + korunacak her uç ve her sayfa `middlewareIds`'e bağlı. Kısmi koruma,
|
|
20
20
|
sistemi güvenli gösterip açık bırakır.
|
|
21
21
|
|
|
22
|
-
> **Kompleks projede (`accessModel: 'complex'`) kimlik tarifleri gerekmez — bağlı kalırsa da etkisiz
|
|
23
|
-
> değildir.** Platform uygulama oturumunu kendisi yönetir (`POST /{proje}/runtime/{app}/auth/sign-in`), uç
|
|
24
|
-
> yolunda `user` değişkenini güvenilir özneyle önceden doldurur ve yetkiyi erişim politikasıyla verir. Bağlı
|
|
25
|
-
> middleware'ler ise zorlama modundan bağımsız **her modda koşar** ve reddedebilir; set-user adımı ya da
|
|
26
|
-
> yanıttaki `user` platformun `user`'ını **ezer**. Kimlik middleware'ini uçların ve sayfaların
|
|
27
|
-
> `middlewareIds`'inden çıkarın (ACC-006, warn). Rol listesini (`microservice.roles`, `page.roleIds`)
|
|
28
|
-
> platform hiçbir modda karar için kullanmaz; yalnız `Authorized(user.roles)` çağıran middleware okur.
|
|
29
|
-
> Kompleks projenin yolu `platform_guide('access')` §Runtime; bu rehberin tarifleri basit projede aynen
|
|
30
|
-
> geçerlidir.
|
|
31
|
-
|
|
32
22
|
## Açıklama zorunlu
|
|
33
23
|
|
|
34
24
|
Middleware de bir workflow'dur: her adımı ve middleware'in kendisi `description` taşımak
|
|
@@ -68,12 +58,7 @@ cevabı adımın ifadesinde gizlidir. Ayrıntı ve yazım ölçütü: `platform_
|
|
|
68
58
|
4. **`input` YOKTUR.** Middleware girdisini HTTP bağlamından okur: `cookie`, `header`,
|
|
69
59
|
`queryString`, `body`, `triggerSource` (hangi microservice/sayfa tetikledi: type, id, name,
|
|
70
60
|
slug, roles, pathAndQuery — emekliye ayrılacak) ve `context` (type, name, roles, path,
|
|
71
|
-
**impersonatedUserId**, language). `context.
|
|
72
|
-
(`/view|dev|branch/{ortam}/{proje}/{uygulama}/{sayfa}`): mobil runtime onu `X-Page-Path`
|
|
73
|
-
başlığıyla yollar, web'de tarayıcının `Referer`'ından okunur. Doğrudan API çağrısında,
|
|
74
|
-
zamanlanmış/otomasyon koşusunda ve sayfası olmayan istekte **`null`'dır** — `split` gibi bir
|
|
75
|
-
metot çağırmadan önce koru: `(context.path || '').split('/')[1]`. İstemci beyanıdır, yetki kararı
|
|
76
|
-
için okunmaz. Kimlik devri **yalnız `context.impersonatedUserId`**'dedir;
|
|
61
|
+
**impersonatedUserId**, language). Kimlik devri **yalnız `context.impersonatedUserId`**'dedir;
|
|
77
62
|
`triggerSource.impersonatedUserId` diye bir alan yoktur, hep `undefined` okunur (MW-006).
|
|
78
63
|
`context.impersonatedUserId` ve start adımının `impersonation` dalı yalnız Studio önizlemesinde
|
|
79
64
|
seçilen uygulama kullanıcısı için dolar; kimlik devrini yalnız super-admin yapabilir, anonim ya da
|
|
@@ -281,29 +266,12 @@ kurulur.** Her projenin ayar middleware'ine ihtiyacı yoktur; okunmayan bir `set
|
|
|
281
266
|
sadece fazladan parça demektir. Karar tablosu: `platform_guide('getting-started')`.
|
|
282
267
|
|
|
283
268
|
```
|
|
284
|
-
start → settings [table get: ayarlar tablosu]
|
|
285
|
-
|
|
286
|
-
dataTransferObjectId: <ayarlar DTO>, isPrivate: true]
|
|
287
|
-
→ setPublic [variable name:'settings',
|
|
288
|
-
expression: '({ app_name: settings.data.app_name, theme: settings.data.theme })']
|
|
269
|
+
start → settings [table get: ayarlar tablosu] → setVar [variable name:'settings',
|
|
270
|
+
expression: '{ ...settings.data }', dataTransferObjectId: <ayarlar DTO>]
|
|
289
271
|
```
|
|
290
272
|
|
|
291
273
|
Response yok — tek işi değişken kurmak; bağlandığı her uçta `settings.<alan>` okunur.
|
|
292
274
|
|
|
293
|
-
**Sayfaya bağlanan middleware'in değişkeni istemciye gider.** Sayfa yanıtı middleware
|
|
294
|
-
değişkenlerini `Page.variables` olarak taşır; tarayıcıda ve cihazda okunur. Bu yüzden:
|
|
295
|
-
|
|
296
|
-
- Gizli değer taşıyan (şifre, `client_secret`, API anahtarı) ya da bütün bir kaydı yayan değişkene
|
|
297
|
-
**`rule.isPrivate: true`** ver (Studio: "Sunucuda tut"). Aynı istekteki sonraki middleware'ler
|
|
298
|
-
onu okumaya devam eder; istemciye gitmez. Sayfanın akışları istemcide koşar ve `Page.variables`'ı
|
|
299
|
-
okur — işaretli değişken orada `undefined`'dır; akışın ihtiyaç duyduğu alanı işaretleme.
|
|
300
|
-
- İstemcinin gerçekten ihtiyaç duyduğu alanları ayrı, işaretsiz bir değişkende **izin listesiyle**
|
|
301
|
-
kur (yukarıdaki `settings`). Aynı ad sonra işaretsiz bir adımla yeniden yazılırsa istemciye açılır.
|
|
302
|
-
- Yalnız microservice uçlarına bağlı middleware'de değişken yanıtla dönmez; işaret yine de zararsızdır.
|
|
303
|
-
- Lint: `MW-007` (işaretsiz değişken bir kaydı yayıyor ya da gizli değer adı taşıyor → warn).
|
|
304
|
-
Ölçüm: qm `[SY] Settings Setter` `{ ...settings.data }` ile `sso_client_secret`'ı istemciye
|
|
305
|
-
veriyordu (2026-10-02).
|
|
306
|
-
|
|
307
275
|
## Tarif 3 — Kimlik kapsaması: "sadece benim kayıtlarım" ucu
|
|
308
276
|
|
|
309
277
|
Kullanıcıya özel veri dönen uçlarda kimliği **istemci parametresinden alma** (sahtelenir);
|