@appaflytech/zeyrek-ai-mcp 0.0.28 → 0.0.30
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/.env.example +15 -0
- package/README.md +5 -5
- package/dist/config.js +37 -0
- package/dist/index.js +2 -0
- package/dist/knowledge/access.js +802 -0
- package/dist/knowledge/backendConstraints.js +18 -1
- package/dist/knowledge/case.js +41 -0
- package/dist/knowledge/componentCatalog.js +494 -34
- package/dist/knowledge/componentEvents.js +132 -7
- package/dist/knowledge/connectDataBind.js +819 -0
- package/dist/knowledge/connectDataDefinition.js +341 -0
- package/dist/knowledge/connectDataExecute.js +93 -0
- package/dist/knowledge/connectDataRules.js +128 -0
- package/dist/knowledge/decision.js +121 -0
- package/dist/knowledge/expressionPrelude.js +59 -0
- package/dist/knowledge/layoutSummary.js +140 -2
- package/dist/knowledge/microserviceParameters.js +58 -0
- package/dist/knowledge/mining.js +94 -0
- package/dist/knowledge/mobileComponentCatalog.js +859 -0
- package/dist/knowledge/mobileComponentEvents.js +239 -0
- package/dist/knowledge/normalize.js +236 -67
- package/dist/knowledge/outlines.js +36 -0
- package/dist/knowledge/platform/lint.js +385 -0
- package/dist/knowledge/platform/mobile.js +142 -0
- package/dist/knowledge/platform/mobileLayoutLint.js +324 -0
- package/dist/knowledge/platform/mobileRules.js +231 -0
- package/dist/knowledge/platform/mobileSpacing.js +82 -0
- package/dist/knowledge/platform/mobileTabs.js +108 -0
- package/dist/knowledge/platform/nativeBoxModel.js +44 -0
- package/dist/knowledge/platform/profile.js +25 -0
- package/dist/knowledge/platform/resolve.js +122 -0
- package/dist/knowledge/platform/web.js +39 -0
- package/dist/knowledge/policy.js +18 -4
- package/dist/knowledge/process.js +510 -0
- package/dist/knowledge/reservedTables.js +79 -0
- package/dist/knowledge/rowFilter.js +43 -0
- package/dist/knowledge/rules.js +319 -21
- package/dist/knowledge/schemaGuard.js +11 -0
- package/dist/knowledge/styleResolve.js +50 -4
- package/dist/knowledge/styleResolveNative.js +527 -0
- package/dist/knowledge/themeResolve.js +3 -3
- package/dist/observability/trace.js +6 -3
- package/dist/platform/argumentAliases.js +128 -0
- package/dist/platform/bodyFile.js +103 -0
- package/dist/platform/capture/actions.js +333 -0
- package/dist/platform/capture/browser.js +1 -0
- package/dist/platform/{screenshot.js → capture/capture.js} +105 -519
- package/dist/platform/capture/console-log.js +122 -0
- package/dist/platform/capture/index.js +11 -0
- package/dist/platform/capture/readiness.js +103 -0
- package/dist/platform/capture/summary.js +77 -0
- package/dist/platform/capture/target.js +5 -0
- package/dist/platform/capture/targets/studio-mobile.js +15 -0
- package/dist/platform/capture/targets/studio-web.js +5 -0
- package/dist/platform/diagnostics.js +10 -4
- package/dist/platform/domSummary.js +1 -1
- package/dist/platform/errors.js +162 -10
- package/dist/platform/http.js +29 -8
- package/dist/platform/impersonation.js +45 -0
- package/dist/platform/jsonArray.js +24 -0
- package/dist/platform/responses.js +39 -5
- package/dist/platform/schemaReadMemory.js +60 -0
- package/dist/platform/secrets.js +17 -1
- package/dist/platform/strictArguments.js +68 -12
- package/dist/platform/tokenVault.js +187 -4
- package/dist/resources/examples/bpm-gorev-kontrol.json +294 -0
- package/dist/resources/examples/bpm-iso-dokuman.json +228 -0
- package/dist/resources/examples/bpm-satinalma.json +376 -0
- package/dist/resources/examples/connect-data-convert-verify.json +107 -0
- package/dist/resources/examples/connect-data-dropdown-roles.json +66 -0
- package/dist/resources/examples/connect-data-edit-m2m.json +73 -0
- package/dist/resources/examples/connect-data-query-params.json +50 -0
- package/dist/resources/examples/connect-data-table-entity.json +147 -0
- package/dist/resources/examples/connect-data-workflow-microservice.json +65 -0
- package/dist/resources/examples/mobile-app-shell-drawer.json +243 -0
- package/dist/resources/examples/mobile-app-shell-stack.json +157 -0
- package/dist/resources/examples/mobile-app-shell-tab.json +208 -0
- package/dist/resources/examples/mobile-form-screen.json +365 -0
- package/dist/resources/examples/mobile-list-detail-form.json +672 -0
- package/dist/resources/examples/page-detail-profile.json +2 -1
- package/dist/resources/examples/page-dynamic-form.json +3 -2
- package/dist/resources/examples/page-flex-sections.json +1 -1
- package/dist/resources/examples/page-html-embed.json +1 -1
- package/dist/resources/examples/workflow-basic.json +8 -2
- package/dist/resources/guides/access.md +796 -0
- package/dist/resources/guides/bpm.md +686 -0
- package/dist/resources/guides/case.md +153 -0
- package/dist/resources/guides/component.md +91 -4
- package/dist/resources/guides/decision.md +185 -0
- package/dist/resources/guides/entity.md +50 -8
- package/dist/resources/guides/expressions.md +14 -5
- package/dist/resources/guides/functions.md +1 -1
- package/dist/resources/guides/getting-started.md +38 -1
- package/dist/resources/guides/layout.md +11 -7
- package/dist/resources/guides/microservice.md +81 -2
- package/dist/resources/guides/middleware.md +44 -2
- package/dist/resources/guides/mobile-layout.md +193 -0
- package/dist/resources/guides/mobile.md +495 -0
- package/dist/resources/guides/page.md +454 -75
- package/dist/resources/guides/theme.md +8 -2
- package/dist/resources/guides/translation.md +1 -1
- package/dist/resources/guides/workflow.md +58 -1
- package/dist/resources/read.js +41 -0
- package/dist/resources/rules.js +11 -5
- package/dist/resources/schema-fingerprint.json +7 -5
- package/dist/resources/schemas/AccessExplanationDto.json +144 -0
- package/dist/resources/schemas/AccessMatrixDto.json +170 -0
- package/dist/resources/schemas/AccessPermissionDto.json +57 -0
- package/dist/resources/schemas/AccessPolicyDto.json +223 -0
- package/dist/resources/schemas/AccessResourceDto.json +86 -0
- package/dist/resources/schemas/AppSessionDto.json +53 -0
- package/dist/resources/schemas/ConnectDataDescribeDto.json +344 -0
- package/dist/resources/schemas/ConnectDataRequestModel.json +202 -0
- package/dist/resources/schemas/ConnectDataResultDto.json +421 -0
- package/dist/resources/schemas/ConnectorCredentialDto.json +70 -0
- package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +37 -0
- package/dist/resources/schemas/CreateAccessPolicyCommand.json +209 -0
- package/dist/resources/schemas/CreateDecisionCommand.json +221 -0
- package/dist/resources/schemas/CreateEntityCommand.json +118 -0
- package/dist/resources/schemas/CreateMicroserviceCommand.json +13 -1
- package/dist/resources/schemas/CreateProcessDefinitionCommand.json +1337 -0
- package/dist/resources/schemas/CreateQueryCommand.json +4 -0
- package/dist/resources/schemas/CreateWorkflowCommand.json +143 -1
- package/dist/resources/schemas/DataJobDto.json +6 -1
- package/dist/resources/schemas/DecisionDto.json +302 -0
- package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +28 -0
- package/dist/resources/schemas/ExplainAccessQuery.json +33 -0
- package/dist/resources/schemas/GenerateProcessDocumentCommand.json +116 -0
- package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +21 -1
- package/dist/resources/schemas/MicroserviceDto.json +15 -3
- package/dist/resources/schemas/OrganizationProjectDto.json +335 -0
- package/dist/resources/schemas/OrganizationSchemaDto.json +196 -0
- package/dist/resources/schemas/OrganizationSchemaVersionDto.json +207 -0
- package/dist/resources/schemas/PatchProcessDefinitionCommand.json +76 -0
- package/dist/resources/schemas/PreviewMicroserviceCommand.json +10 -1
- package/dist/resources/schemas/PreviewWorkflowCommand.json +22 -1
- package/dist/resources/schemas/ProcessDefinitionDto.json +1480 -0
- package/dist/resources/schemas/ProcessSimulationDto.json +96 -0
- package/dist/resources/schemas/SaveConnectorCredentialCommand.json +90 -0
- package/dist/resources/schemas/SaveProcessEventSourceCommand.json +61 -0
- package/dist/resources/schemas/SaveProcessMailSourceCommand.json +89 -0
- package/dist/resources/schemas/SignProcessTaskCommand.json +73 -0
- package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +92 -0
- package/dist/resources/schemas/StepDto.json +22 -1
- package/dist/resources/schemas/UpdateAccessPolicyCommand.json +209 -0
- package/dist/resources/schemas/UpdateDecisionCommand.json +216 -0
- package/dist/resources/schemas/UpdateEntityCommand.json +118 -0
- package/dist/resources/schemas/UpdateMicroserviceCommand.json +13 -1
- package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +1357 -0
- package/dist/resources/schemas/UpdateQueryCommand.json +4 -0
- package/dist/resources/schemas/UpdateViewCommand.json +0 -2
- package/dist/resources/schemas/UpdateWorkflowCommand.json +143 -1
- package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +1339 -0
- package/dist/server.js +27 -1
- package/dist/tools/access.js +369 -2
- package/dist/tools/accessOperations.js +135 -0
- package/dist/tools/accessPolicies.js +170 -0
- package/dist/tools/accessRuntime.js +203 -0
- package/dist/tools/applications.js +60 -3
- package/dist/tools/bpm.js +343 -0
- package/dist/tools/bpmGovernance.js +266 -0
- package/dist/tools/bpmOperations.js +230 -0
- package/dist/tools/bpmReporting.js +154 -0
- package/dist/tools/bpmRouting.js +150 -0
- package/dist/tools/bpmRuntime.js +396 -0
- package/dist/tools/case.js +178 -0
- package/dist/tools/caseRuntime.js +89 -0
- package/dist/tools/common.js +7 -0
- package/dist/tools/components.js +118 -14
- package/dist/tools/connectData.js +449 -0
- package/dist/tools/connectors.js +193 -0
- package/dist/tools/datasources.js +3 -3
- package/dist/tools/decisions.js +206 -0
- package/dist/tools/dependencies.js +1 -1
- package/dist/tools/deployments.js +2 -2
- package/dist/tools/designSchemaPatch.js +34 -9
- package/dist/tools/dtos.js +36 -5
- package/dist/tools/entities.js +79 -12
- package/dist/tools/externalComponents.js +26 -5
- package/dist/tools/flows.js +122 -14
- package/dist/tools/folders.js +1 -1
- package/dist/tools/imports.js +5 -2
- package/dist/tools/layouts.js +50 -17
- package/dist/tools/merges.js +1 -1
- package/dist/tools/microservices.js +77 -25
- package/dist/tools/mobile.js +221 -0
- package/dist/tools/modules.js +48 -0
- package/dist/tools/organizationStructure.js +137 -0
- package/dist/tools/pages.js +465 -98
- package/dist/tools/platformInfo.js +27 -8
- package/dist/tools/profileWrite.js +92 -0
- package/dist/tools/projects.js +71 -9
- package/dist/tools/rows.js +69 -13
- package/dist/tools/schemaOps.js +61 -1
- package/dist/tools/screenWrite.js +37 -8
- package/dist/tools/screens.js +95 -5
- package/dist/tools/templates.js +26 -1
- package/dist/tools/translations.js +1 -1
- package/dist/tools/variables.js +11 -5
- package/dist/tools/workflows.js +10 -5
- package/package.json +2 -2
|
@@ -14,8 +14,10 @@ Uydurma fonksiyon adı runtime'da `X is not defined` 500'üdür — yalnız bura
|
|
|
14
14
|
|
|
15
15
|
**Değişkenler:** step çıktıları (`<stepAdı>.data`), middleware değişkenleri (`user`,
|
|
16
16
|
`settings`, `permissions`… — `workflow_middleware_variables` ile keşfet), HTTP bağlamı:
|
|
17
|
-
`cookie`, `header`, `queryString`, `body`, `triggerSource
|
|
18
|
-
type/name/roles/
|
|
17
|
+
`cookie`, `header`, `queryString`, `body`, `triggerSource` (tetikleyen ucun
|
|
18
|
+
type/id/name/slug/roles/pathAndQuery'si — emekliye ayrılacak) ve `context`
|
|
19
|
+
(type/name/roles/path/impersonatedUserId/language). **Kimlik devri yalnız `context.impersonatedUserId`**'dedir;
|
|
20
|
+
`triggerSource`'ta bu alan yoktur (MW-006). Gövde bir JSON **nesnesi** ise `body.alan` diye okunur,
|
|
19
21
|
gövde bir JSON **dizisi** ise `body[0].alan` diye — 2026-09-04 öncesinde nesne gövde de diziye
|
|
20
22
|
sarılıyordu ve `body.alan` sessizce `undefined` dönüyordu, bu yüzden gövdeye bakan yetki kapıları
|
|
21
23
|
açık kalıyordu. Workflow'da istek girdisi `input.`, automation'da
|
|
@@ -97,14 +99,16 @@ dalından devam eder.
|
|
|
97
99
|
|---|---|
|
|
98
100
|
| `Page` | `Page.user`, `Page.variables`, `Page.components`, `Page.properties`, `Page.queryParams`, `Page.authorized(roles)` |
|
|
99
101
|
| **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
|
-
| `state.page` / `state.app` |
|
|
102
|
+
| `state.page` / `state.app` | Sayfa/uygulama state'i (oku/yaz): `state.page.selectedId = row.id`. **Bellekte yaşar** — sayfa her açıldığında tanımlı `value`'dan başlar; mobil uygulamada kalıcı olması için değişkene `storage` verilir (`platform_guide('mobile')` §Kalıcı state). **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
103
|
| `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
|
-
| `self` · `item` · `Row` / `RowIndex` | Tetikleyen komponent (yazılabilir) · repeater/tablo satırı (yazmak satırı günceller) |
|
|
104
|
+
| `self` · `item` · `Row` / `RowIndex` | Tetikleyen komponent (yazılabilir) · repeater/tablo satırı (yazmak YALNIZ o satırı günceller). Satır AKIŞINDA (satırdaki düğümün olayı) ARC-121 düzeltmesini (2026-09-27) taşıyan runtime gerekir, eskisinde boştu — sürümden bağımsız yol `<liste>.selectedItem` / `.selectedIndex`. Tekrarlayıcının KENDİ `change`/`select` akışında satır bağlamı yoktur. `item.x = …` yazımı tekrarlayıcının `change` olayı olarak iletilir: `change`'e bağlı akış her yazımda koşar, o akış da `item`'a yazarsa döngü olur |
|
|
103
105
|
| `event` | `{name, data, source: {id, props}}` |
|
|
104
106
|
| `cookie` | `cookie.get(name)` / `cookie.set(name, value, {expiresInHours, path})` / `cookie.remove(name)` — tarayıcı cookie'si |
|
|
105
107
|
| `setComponentProperty(name, key, value)` / `getComponentProperty(name, key)` | fonksiyon alternatifi |
|
|
106
108
|
| `resetForm(name)` | Formu sıfırlar: alanlar başlangıç değerine döner, form "gönderilmemiş" olur, doğrulama mesajları silinir. Kayıt sonrası "yeni kayıt" için alanları tek tek `null`'a çekme — gönderilmiş formda her biri "zorunlu alan" mesajı çıkarır. Ad ya da komponent değişkeni alır: `resetForm('risk_form')` / `resetForm(risk_form)`. **Yalnız UI flow kodunda** |
|
|
107
|
-
| `LocalStorage` · `Widget` · `params` | yerel veri · widget bağlamı · olay parametreleri |
|
|
109
|
+
| `LocalStorage` · `Widget` · `params` | yerel veri · widget bağlamı · olay parametreleri. `LocalStorage` barındırıcının deposudur, salt okunur ve değerler METİNdir: web'de uygulamanın kökenindeki `localStorage` (Studio önizlemesinde Studio'nun kendi anahtarları da görünür), cihazda akışın `storage` deposu. `storage` adımı düz bir anahtara yazınca `LocalStorage.<anahtar>` aynı akışta yeni değeri verir ve sayfanın bağları yeniden değerlendirilir (`isSelected: {{ LocalStorage['zeyrek:theme-mode'] === 'dark' }}`). `state.page\|app.<key>`'e yazan adım `LocalStorage`'a girmez (ARC-147, 2026-09-29) |
|
|
110
|
+
| `Device` | Salt okunur cihaz durumu, barındırıcı günceller: `Device.isOnline` — ağ bağlantısı var mı (bilinmiyorsa `true`). Değişince sayfanın bütün bağları yeniden değerlendirilir; çevrimdışı bandı: `isHidden: {{ Device.isOnline }}`. Cihazda `expo-network`, web'de tarayıcının `online`/`offline` olayları. `Device` adında komponent ifade bağlamından süzülür (ayrılmış ad) |
|
|
111
|
+
| **Ayrılmış adlar** | Bu tablodaki globallerle (ve önsözün iç adlarıyla: `payload`, `error`, `repeaterId`, `_` ile başlayanlar…) aynı `name`'i taşıyan komponent (runtime yalnız İLK `-`'yi siler: `ite-m` da `item` sayılır) ifadede kendi adıyla GÖRÜNMEZ — süzülür, uyarı loglanır (liste: `@ng-apps/flow` `EXPRESSION_PRELUDE_NAMES`). Eskiden aynı ad sayfanın BÜTÜN ifadelerini `SyntaxError`'la düşürürdü (ARC-143). Gateway artık bu adların HEPSİNİ **PAGE-009** ile sayfa/layout yazma yollarında ve `page_schema_validate`'te istek gitmeden reddeder — komponente `t`, `state`, `event`, `item`, `self`, `Page`, `Row` gibi ad verme |
|
|
108
112
|
| `t(key)` | Çeviri anahtarını çözer: aktif dil → projenin varsayılan dili → anahtarın kendisi. Boş string de "eksik" sayılır. Sözlük `machine.context.state.translations`'tan gelir; dil `language-selector` ile değişince bir sonraki çağrı yeni dili görür. **Yalnız UI flow kodunda vardır** — backend ifadelerinde karşılığı `Loc()`'tur (`platform_guide('workflow')`) | `t('home.welcome')` |
|
|
109
113
|
| `log(...)` | console (proxy'leri temizler) |
|
|
110
114
|
| `Functions` | **Kullanıcı fonksiyonları** (`function_create`): `Functions.toplamHesapla(fiyat, adet)` — uygulama kapsamlılar her sayfada, sayfa kapsamlılar yalnız kendi sayfasında. **Yalnız tarayıcı**; sunucuda bu ad alanı yoktur (2026-09-10, `WF-030`) |
|
|
@@ -125,6 +129,11 @@ dalından devam eder.
|
|
|
125
129
|
> `runtimeErrors` taşır ve hangi komponentin hangi prop'unun yazılamadığını (`element` ·
|
|
126
130
|
> `property`) söyler. Aynı defter hata dönen microservice adımlarını da kaydeder. **Kare
|
|
127
131
|
> "çalışıyor" görünse bile `runtimeErrors` doluysa o adımlar işini YAPMAMIŞTIR.**
|
|
132
|
+
>
|
|
133
|
+
> **Prop'a bağlı ifade patlarsa** (Studio'da "Expression error" toast'ı) `page_screenshot` yanıtı
|
|
134
|
+
> `expressionErrors` taşır: `{ elementId, prop, expression, message, count }`, öğe başına en çok iki.
|
|
135
|
+
> Toast da öğeyi adlandırır (`Expression error · tx_baslik.content`); cihazda geliştirme paketi aynı
|
|
136
|
+
> satırı Metro günlüğüne basar (ZM-05).
|
|
128
137
|
|
|
129
138
|
**Prop'a doğrudan ifade bağlama (`{{ }}`):** akış kurmadan bir prop'u ifadeye bağlamak için
|
|
130
139
|
prop `type: 'code'` olur, **ifade `ref` alanına `{{ }}` içinde** yazılır, `data` tasarım zamanı
|
|
@@ -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 uygulama:** mobil runtime (`@ng-apps/ui-native`) `appFunctions`/`pageFunctions`'ı `Functions`'a geçirir, çağrı web'deki gibi çalışır.
|
|
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.
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
Bağımlılıklar bu sırayı zorunlu kılar; atlama:
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
1. project_create (
|
|
8
|
+
1. project_create (ÖNCE TÜRÜ SEÇ: accessModel 'simple' | 'complex' — aşağıdaki
|
|
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;
|
|
9
12
|
application slug'ı ORG GENELİNDE tekildir — 'web' büyük olasılıkla
|
|
10
13
|
doludur, 409'da project_list ile mevcut slug'ları tara.
|
|
11
14
|
DİL: gateway create'ten sonra projenin dillerini kurar — verirsen
|
|
@@ -68,6 +71,8 @@ Bağımlılıklar bu sırayı zorunlu kılar; atlama:
|
|
|
68
71
|
13. application_update (homepageId — ana sayfa sayfadan değil application'dan seçilir)
|
|
69
72
|
```
|
|
70
73
|
|
|
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
|
+
|
|
71
76
|
## İlk kullanıcıyı kim açar? (tavuk-yumurta kilidi)
|
|
72
77
|
|
|
73
78
|
Kimlik kurulmuş yeni bir projede **giriş yapabilecek hiç kimse yoktur** ve zincir kendi kendini
|
|
@@ -119,6 +124,38 @@ Middleware bir kontrol listesi maddesi değil; **ihtiyaca** kurulur:
|
|
|
119
124
|
`middlewareIds` ile bağlı olmalı. Bir-iki uca bağlayıp gerisini açık bırakmak, hiç kurmamaktan
|
|
120
125
|
kötüdür — sistem güvenli görünür, değildir.
|
|
121
126
|
|
|
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
|
+
|
|
122
159
|
## Örnek arama davranışı
|
|
123
160
|
|
|
124
161
|
Örnek gövde için **mevcut projeleri taramak yerine** önce şunlara bak:
|
|
@@ -4,6 +4,10 @@ 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
|
+
|
|
7
11
|
## Karar kuralları
|
|
8
12
|
|
|
9
13
|
**1. Layout, tek `slot` içeren SIRADAN bir komponent ağacıdır.** Ayrı bir dil yoktur:
|
|
@@ -61,7 +65,7 @@ yapılan eski numaraya artık gerek yok.
|
|
|
61
65
|
NEREDE durduğunu değil, BİÇİMİNİ söyler (dikey kolon / yatay şerit / dolgu yüzeyi). Hem
|
|
62
66
|
runtime hem Studio tuvali bölgeleri 12 kolonluk ızgarayla yerleştirir.
|
|
63
67
|
|
|
64
|
-
**7.
|
|
68
|
+
**7. Dar ekranda flex YIĞILMAZ.** Runtime'ın dar ekran kuralı yalnız ızgara özelliklerini ezer.
|
|
65
69
|
Telefonda alt alta düşmesi gereken satırı `layout:'grid'` ile kur; `layout:'flex'` +
|
|
66
70
|
`direction:'row'` telefonda da yan yana kalır (375px'te ölçüldü: ızgara çocukları 375/375px
|
|
67
71
|
alt alta, flex çocukları 49/310px yan yana). Not: `wrap` varsayılanı artık açık (2026-09-01) —
|
|
@@ -140,8 +144,8 @@ bağlantı nesnesi ya da tam yol).
|
|
|
140
144
|
"direction": { "type": "static", "data": "row" } },
|
|
141
145
|
"blocks": [{ "breakpoint": 1024, "size": { "w": 12, "h": 80 }, "position": { "x": 0, "y": 0 } }] }
|
|
142
146
|
|
|
143
|
-
// KÖTÜ — telefonda 49px'lik yan menü: row flex
|
|
144
|
-
//
|
|
147
|
+
// KÖTÜ — telefonda 49px'lik yan menü: row flex dar ekranda yığılmaz (Kural 7)
|
|
148
|
+
// Dar ekranda alt alta düşmesi gerekiyorsa kökü layout:'grid' kur — bedeli, fill'in
|
|
145
149
|
// flex anlamının devreye girmemesi.
|
|
146
150
|
```
|
|
147
151
|
|
|
@@ -179,9 +183,9 @@ bunlardan biri olabilir:
|
|
|
179
183
|
|---|---|
|
|
180
184
|
| ~~`heightType` yalnız `auto` \| `fixed`~~ | **28 Ağustos'ta kapandı:** üçüncü değer `fill` (Kural 5b) |
|
|
181
185
|
| ~~Kök kap viewport'a kilitlenmez~~ | **28 Ağustos'ta kapandı:** `fill` verilmiş kök 100vh (Kural 5b) |
|
|
182
|
-
| Flex
|
|
183
|
-
| Kırılıma duyarlı prop yok | `direction`/`gap` masaüstü ve
|
|
184
|
-
|
|
|
186
|
+
| Flex dar ekranda yığılmaz | Kural 7 — kabuk bugün bir MASAÜSTÜ kabuğudur |
|
|
187
|
+
| Kırılıma duyarlı prop yok | `direction`/`gap` masaüstü ve dar ekranda AYNI; yalnız `blocks` ve `appearance.hideOn` kırılım bilir |
|
|
188
|
+
| Dar ekranda çekmece (overlay) yok | Telefon genişliğinde içeriğin üstüne binen panel kurulamaz (mobil UYGULAMADA çekmece `drawer` widget'ıdır — `platform_guide('mobile')`) |
|
|
185
189
|
|
|
186
190
|
---
|
|
187
191
|
|
|
@@ -189,7 +193,7 @@ bunlardan biri olabilir:
|
|
|
189
193
|
(`injectPageSchemaIntoSlots`, `getResolvedLayoutViews`), `apps/studio/src/features/page/api/page.mappers.ts`
|
|
190
194
|
(`mapPageLayoutToPreview`), `packages/ng-apps-ui/src/shared/render/render.functions.ts`
|
|
191
195
|
(`resolveNodeBoxStyle` — slot'un `y / auto` satırı, flex çocuk genişliği),
|
|
192
|
-
`packages/ng-apps-ui/src/shared/render/RenderComponent.svelte` (
|
|
196
|
+
`packages/ng-apps-ui/src/shared/render/RenderComponent.svelte` (dar ekran media kuralı),
|
|
193
197
|
`packages/ng-apps-screen-builder/src/flex-layout.ts` (`getFlexChildStyle` — `widthType`
|
|
194
198
|
fill/fixed/auto dalları, `normalizeCssSize` kabul kuralı; tuval ve runtime aynı fonksiyonu okur),
|
|
195
199
|
`apps/studio/src/features/page/components/appearance/appearance-size.functions.ts` (panelin
|
|
@@ -243,9 +243,16 @@ DTO'dan süzülmez (WF-026 — `platform_guide('workflow')` §Hata yolu). Sözle
|
|
|
243
243
|
- **Operatör sözlüğü kapalıdır:** `eq · neq · lt · lte · gt · gte · contains · icontains ·
|
|
244
244
|
in · notin · startswith · endswith · istartswith · iendswith · isnull · isnotnull`.
|
|
245
245
|
**`like` YOKTUR** — metin
|
|
246
|
-
araması `contains`/`icontains` iledir. Kritik tuzak:
|
|
246
|
+
araması `contains`/`icontains` iledir. Kritik tuzak: eski backend bilinmeyen operatörü 400 ile
|
|
247
247
|
reddetmez, **sessizce `eq`'e düşürür** (enum çözümlemesi unknown'da default'a düşer) — uç
|
|
248
|
-
testten geçer ama
|
|
248
|
+
testten geçer ama yanlış sonuç döner (koşuda `ne` böyle geçti). 2026-09-27'den sonraki backend
|
|
249
|
+
uç çağrısının `filters` parametresinde (JSON dizisi) 400 verir; workflow tablo adımının filtresi
|
|
250
|
+
hâlâ sessizce `eq`'e düşer. Ad büyük/küçük harfe duyarlıdır: `NEQ` geçersizdir. Gateway her iki
|
|
251
|
+
sürümde istek gitmeden keser: uç tanımında ve
|
|
252
|
+
workflow tablo adımında MS-012/WF-015 (blok), çalışma anında `row_list` / `row_export` filtresinde ve
|
|
253
|
+
`microservice_execute` / `microservice_debug`'ın `filters` parametresinde hata — sık yanlışlara öneriyle
|
|
254
|
+
(`ne`/`!=` → `neq`, `like` → `contains`, `=` → `eq`). Studio'nun filtre ARAYÜZÜNDEKİ adlar
|
|
255
|
+
(`notContains`, `between`…) ayrı bir sözlüktür; arayüz onları bu işleçlere çevirir.
|
|
249
256
|
- **Write operasyonunda (`create`/`update`) yanıt yalnız primary key'dir** — platform sonucu
|
|
250
257
|
PK'ya indirger ve `selectFields`'ı kaydederken sessizce boşaltır. Yanıtın başka alan da
|
|
251
258
|
dönmesi gerekiyorsa **`returnFields`** kullanılır (öğeler `selectFields` ile aynı şekildedir:
|
|
@@ -337,6 +344,25 @@ kart doğru sütuna geçer, başlığı ve sorumlusu silinir.
|
|
|
337
344
|
> ifadeden gelir ve `undefined` dönen ifade de `null` yazar —
|
|
338
345
|
> `platform_guide('workflow')` §"Table update adımı".
|
|
339
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
|
+
|
|
340
366
|
## İlişki alanı: `row_list` NESNE döner, uç/step JOIN'siz DÜZ FK döner
|
|
341
367
|
|
|
342
368
|
Aynı alan iki yoldan farklı şekilde gelir ve bu fark sessizce yanlış sonuç üretir:
|
|
@@ -678,6 +704,20 @@ Rol listesini **değiştirmek** için yukarıdaki §"Patch belgesi OKUMA şeklid
|
|
|
678
704
|
> rota `/{project}/m/{application}/{microservice SLUG'ı}`'dır ( `url` alanı rotaya GİRMEZ) ve
|
|
679
705
|
> `Host: <org>.<suffix>` + `X-Environment` başlıkları zorunludur.
|
|
680
706
|
|
|
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
|
+
|
|
681
721
|
## Alias nerede geçerli
|
|
682
722
|
|
|
683
723
|
Alias bir **SQL tablo takma adıdır**: yalnız okunan tarafta anlamı vardır. Sözleşme iki ayrı
|
|
@@ -698,6 +738,29 @@ Yazma alanına `alias` koyarsan istek **hata vermez**, alan model bağlamada dü
|
|
|
698
738
|
istek gitmeden gövdeden çıkarır ve `gatewayNormalized` ile bildirir — böylece `silentlyDropped`
|
|
699
739
|
listesi yalnız gerçek kayıpları gösterir.
|
|
700
740
|
|
|
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
|
+
|
|
701
764
|
## Zamanlanmış iş (`type: 'schedule-job'`) — `typeParameters.schedule`
|
|
702
765
|
|
|
703
766
|
Zamanlama tek bir tanımdır; `cronExpression` tek başına verilirse **UTC cron** sayılır (eski gövde).
|
|
@@ -813,3 +876,19 @@ Dört gerçek daha:
|
|
|
813
876
|
(`{ "op": "add", "path": "/description", "value": "…" }`). Patch yanıtındaki `silentlyDropped`
|
|
814
877
|
alanı, gönderilen ama kaydedilmeyen alanları listeler — boş değilse platform bir alanı yutmuş
|
|
815
878
|
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
|
+
- **Tablo ucunda `enableDynamicFilters: true`** alanları `canFilter`/`sortable` yapar (kullanıcı filtresi tanım filtresiyle
|
|
888
|
+
AND'lenir); `sort`/`limit` query-string parametreleri offset sayfalama açar. Dinamik filtresiz ya da query kaynaklı uç
|
|
889
|
+
`pageMode: client` kalır (CD-007) ve süzmez.
|
|
890
|
+
- Uç parametreleri bağlantının `params`'ından gelir (`source.parameters`; CD-013).
|
|
891
|
+
- `connect_data_convert` bir bağlantıyı `source: connectData` bir uca çevirir: `m/{app}/{slug}` `POST { op: 'list' }` aynı
|
|
892
|
+
kabiliyet damgalı `{ data, meta, errors }` zarfını döner. Kompleks projede `microservice_execute { asUserId }` ile
|
|
893
|
+
kullanıcı gözüyle doğrulayın; `microservice_preview` Studio ucudur (ROLLBACK'li, kapıları koşmaz).
|
|
894
|
+
- Örnekler: `ngapps://examples/connect-data-workflow-microservice`, `ngapps://examples/connect-data-convert-verify`.
|
|
@@ -19,6 +19,16 @@ 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
|
+
|
|
22
32
|
## Açıklama zorunlu
|
|
23
33
|
|
|
24
34
|
Middleware de bir workflow'dur: her adımı ve middleware'in kendisi `description` taşımak
|
|
@@ -56,8 +66,15 @@ cevabı adımın ifadesinde gizlidir. Ayrıntı ve yazım ölçütü: `platform_
|
|
|
56
66
|
kuracaksan ifadeyi guard'la: `typeof user === 'undefined' ? false : Authorized(user.roles)`.
|
|
57
67
|
Gateway `set-user` adımı olmadan `user` okuyan middleware'i **MW-003** ile uyarır.
|
|
58
68
|
4. **`input` YOKTUR.** Middleware girdisini HTTP bağlamından okur: `cookie`, `header`,
|
|
59
|
-
`queryString`, `body`, `triggerSource` (hangi microservice/sayfa tetikledi: type, name,
|
|
60
|
-
slug, roles,
|
|
69
|
+
`queryString`, `body`, `triggerSource` (hangi microservice/sayfa tetikledi: type, id, name,
|
|
70
|
+
slug, roles, pathAndQuery — emekliye ayrılacak) ve `context` (type, name, roles, path,
|
|
71
|
+
**impersonatedUserId**, language). Kimlik devri **yalnız `context.impersonatedUserId`**'dedir;
|
|
72
|
+
`triggerSource.impersonatedUserId` diye bir alan yoktur, hep `undefined` okunur (MW-006).
|
|
73
|
+
`context.impersonatedUserId` ve start adımının `impersonation` dalı yalnız Studio önizlemesinde
|
|
74
|
+
seçilen uygulama kullanıcısı için dolar; kimlik devrini yalnız super-admin yapabilir, anonim ya da
|
|
75
|
+
yetkisiz istekte başlık platformda silinir. `impersonation` dalı bağlı değilse start
|
|
76
|
+
`success`'e düşer — uygulamanın kendi auth yolu koşar (ZM-22, 2026-09-26). Tarif: 1c. Hazır
|
|
77
|
+
fonksiyonlar: `system.validateToken(...)`,
|
|
61
78
|
`system.generateToken(...)`, `crypto.JWT.encode/validate`, `Authorized(user.roles)`,
|
|
62
79
|
`request.url.searchParams`, `GenerateGuid()`, `UtcNow()`, `system.getPageUrl(slug)` —
|
|
63
80
|
**tam sözlük ve gerçek örnekler: `platform_guide('expressions')`**.
|
|
@@ -197,6 +214,31 @@ guard → [condition] triggerSource.type === 'page'
|
|
|
197
214
|
Korumalı her sayfada yukarıdaki `redirect → response` zinciri kurulmalı ve **tokensız bir
|
|
198
215
|
istekle 401 verdiği görülerek** kabul edilmeli. Karşılığı: `platform_guide('page')` Kural 8.
|
|
199
216
|
|
|
217
|
+
## Tarif 1c — Studio önizlemesinde seçilen kullanıcıyla açılış (`impersonation` dalı)
|
|
218
|
+
|
|
219
|
+
Özel auth middleware'li bir uygulamada Studio'nun Preview alt çubuğundaki kullanıcı seçici
|
|
220
|
+
(`impersonated-user-id` başlığı) jeton taşımaz; yalnız jeton yolu olan middleware bu istekte 401
|
|
221
|
+
döner ya da `user` kurmadan biter ve korumalı her uç `user is not defined` ile 500 verir (ZM-22).
|
|
222
|
+
Seçilen kullanıcıyla açılmak için start adımının **`impersonation` dalını** bağlayın:
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
start ─ success → token → token_check → userTable → setUser → response 200 (normal yol)
|
|
226
|
+
─ impersonation → kimlik [table get: users, filtre id eq context.impersonatedUserId]
|
|
227
|
+
→ var_mi [condition] ─ else → response 401
|
|
228
|
+
→ setUser (aynı set-user ifadesi) → response 200
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
```jsonc
|
|
232
|
+
// start adımının dalları — impersonation dalının adı ve tipi 'impersonation'
|
|
233
|
+
{ "id": "<GUID>", "name": "impersonation", "type": "impersonation", "nextStepId": "<kimlik adımının id'si>" }
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
- Dal **yalnız** platform kimlik devrini doğruladığında seçilir (Studio önizlemesi, super-admin);
|
|
237
|
+
başlığı elle ekleyen istek normal `success` yolundan geçer. Bu yüzden değer yalnız bu dalda anlamlıdır:
|
|
238
|
+
**`context.impersonatedUserId`'yi dal dışında yetki kararı için okumayın.**
|
|
239
|
+
- Kullanıcı satırını yine tablodan okuyun; değerin kendisi yalnız bir kimliktir, rol ya da sahiplik
|
|
240
|
+
taşımaz. `set-user` ifadesi normal yolla aynı şekli üretmelidir (kapsam workflow'ları `user.id` okur).
|
|
241
|
+
|
|
200
242
|
## Tarif 3b — Rol kapısı: `microservice.roles` TEK BAŞINA hiçbir şeyi kapatmaz
|
|
201
243
|
|
|
202
244
|
**Ölçüm (2026-08-19):** `roleIds: ['<admin rol id>']` verilmiş ama `middlewareIds` **boş** bir
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Mobil mizanpaj — uygulamanın her yeri tek dil
|
|
2
|
+
|
|
3
|
+
Bir mobil ekran kurmadan önce bunu okuyun. Buradaki kurallar zevk meselesi değildir, **ölçülür**:
|
|
4
|
+
|
|
5
|
+
- **Doğru varsayılan.** Gateway iskeleti kendisi doğru kurar (`mobile_app_create`, `page_create`, yeni
|
|
6
|
+
düğümlerin boşluğu).
|
|
7
|
+
- **Yazımda uyarı.** Yazım yanıtında sözleşme dışı durum `MOB-015…021` olarak gelir (`layoutWarnings`).
|
|
8
|
+
- **Çizimde ölçüm.** `page_screenshot({ layoutReport: true })` sonucu sayıyla ölçer (`layoutSummary.alignment`).
|
|
9
|
+
|
|
10
|
+
Temel mobil bilgi (flex-only yerleşim, tipli stil, gezinme, adımlar) için `platform_guide('mobile')`.
|
|
11
|
+
Altın örnek: `ngapps://examples/mobile-form-screen`.
|
|
12
|
+
|
|
13
|
+
## Sözleşme
|
|
14
|
+
|
|
15
|
+
Birim dp. Ölçek **4 · 8 · 16 · 24 · 32**. `gap` jetonları `small` 8, `medium` 16, `large` 24.
|
|
16
|
+
|
|
17
|
+
| # | Konu | Kural | Bulgu |
|
|
18
|
+
|---|---|---|---|
|
|
19
|
+
| S1 | Üst güvenli alan | Tek yerde. Kabuklu uygulamada kabukta (`safe-area` `edges: 'top'` içinde app-bar). Kabuksuz sayfada ilk öğe `safe-area` `top`. Sayfa kabuğun payını ikinci kez vermez | MOB-015 |
|
|
20
|
+
| S2 | Alt güvenli alan | Formun gönder düğmesi akışta, formun sonunda durur. Ekrana sabit alt eylem gerekiyorsa `floating-container` (`respectSafeArea`) kullanılır, ayrıntısı §Bileşen dizgisi'nde. Akışın sonunda pay gerekiyorsa `safe-area` `bottom` (`all` değil) | — |
|
|
21
|
+
| S3 | Kaydırma | Sayfa kökü kaydırır, `size: 'shrink'`. `scroll-view` yalnız gerekçeyle; iç içe dikey kaydırıcı yok | MOB-016 |
|
|
22
|
+
| S4 | Ekran kenarı | Yatayda ve üstte **16**, tek yerde. Kabuklu sayfada slot'un margin'i verir. Kabuksuz sayfada yatayı kökün padding'i verir; üstteki 16, tepedeki `safe-area`'dan sonraki `gap`tir. Bileşenlere yazılmaz | ölçüm `gutter` |
|
|
23
|
+
| S5 | Aralık | Kardeşler arası boşluk yalnız ebeveynin `gap`'i; çocuklar `marginType: 'none'`. Bölümler arası `large`, bölüm içi alanlar `medium`, satır içi öğeler `small` | MOB-019, MOB-021 |
|
|
24
|
+
| S6 | Saydam sarmalayıcı | Yalnız davranış ekleyen kap (`tooltip`, zeminsiz grup kabı) içeriği içeri itmez: `paddingType: 'none'`, `marginType: 'none'`, `widthType: 'fill'` | MOB-019 |
|
|
25
|
+
| S7 | Yüzey | Görünen grup (kart) iç boşluğu 16, yarıçap `lg`, 1 dp kenarlık ya da zemin (ikisi birden değil). Yüzeyin içeriği bilerek içeride durur | MOB-021 |
|
|
26
|
+
| S8 | Genişlik | Tam genişlik öğesi (alan, birincil düğme, yüzey) `widthType: 'fill'`. Aynı sütundaki kardeşlerin sol ve sağ kenarı eşittir | MOB-019, MOB-020 |
|
|
27
|
+
| S9 | Kap yönü | Dikey grup `direction: 'column'` + `horizontalAlign: 'stretch'`. **Yönü yazılmamış container/form satırdır.** Satır yalnız gerçekten yan yana dizilen öğeler için | MOB-020 |
|
|
28
|
+
| S10 | Bileşen içi | Alan yüksekliği, iç boşluk, etiket aralığı ve yarıçap temadan (`--ng-form-*`) gelir; alanlara padding ya da yarıçap yazılmaz | — |
|
|
29
|
+
| S11 | Yarıçap, renk, yazı | Yarıçap ölçek adıyla (`sm`, `md`, `lg`, `pill`), renk tanımlı jetonla, yazı boyu `text`'in `type` seviyesiyle (`h1`…`h4`, `p`, `small`, `label`). Ham px yok | MOB-021 |
|
|
30
|
+
| S12 | App-bar | Ekranda tek app-bar, ilk çizilen öğe. Kabuk veriyorsa sayfa eklemez; başlık kabuğun app-bar'ına bağlanır | MOB-017 |
|
|
31
|
+
| S13 | Boş kap | Çalışma anında boş kalan kap bırakılmaz (tepedeki `safe-area` payı hariç) | MOB-018 |
|
|
32
|
+
|
|
33
|
+
## İskelet ağaçları
|
|
34
|
+
|
|
35
|
+
Aşağıdaki iskeleti `mobile_app_create` ile mobil `page_create` kendisi kurar. Elle kuruyorsanız bu biçimi
|
|
36
|
+
kullanın.
|
|
37
|
+
|
|
38
|
+
**Kabuk (layout).** `shell_root` düz bir `container`'dır. Padding tipi yazılmazsa runtime ona 10 dp verir ve
|
|
39
|
+
app-bar kenardan kopar.
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
container shell_root direction:column gap:none size:shrink appearance.paddingType:none heightType:fill
|
|
43
|
+
├─ safe-area edges:top
|
|
44
|
+
│ └─ app-bar (başlık, leading, menuTarget)
|
|
45
|
+
├─ slot appearance.marginType:custom marginValues:{ top:16, right:16, bottom:0, left:16 } heightType:fill
|
|
46
|
+
└─ drawer (çekmeceli kabukta)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Kabuklu sayfa.** Pay ve kenar boşluğu kabuktan gelir.
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
container page_container direction:column horizontalAlign:stretch size:shrink gap:medium paddingType:none
|
|
53
|
+
└─ … içerik
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Kabuksuz sayfa** (giriş, karşılama, izin). `isWrapper` yalnız margin'i sıfırlar, kökün padding'i çizilir.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
container page_container direction:column horizontalAlign:stretch size:shrink gap:medium
|
|
60
|
+
appearance.paddingType:custom paddingValues:{ top:0, right:16, bottom:0, left:16 }
|
|
61
|
+
├─ safe-area edges:top (boş: durum çubuğu payı + gap kadar üst boşluk)
|
|
62
|
+
└─ … içerik
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Form ekranı.** Gönder düğmesi formun içinde, akışın sonundadır. Form doğrulaması yalnız bu yolda koşar.
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
page_container
|
|
69
|
+
├─ text type:h2 (başlık)
|
|
70
|
+
└─ form direction:column horizontalAlign:stretch gap:large paddingType:none marginType:none widthType:fill
|
|
71
|
+
├─ … bölümler
|
|
72
|
+
└─ button type:submit widthType:fill
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Bileşen dizgisi
|
|
76
|
+
|
|
77
|
+
Bir ekran yukarıdan aşağıya şu sırayla kurulur: **başlık → bölümler → eylem.**
|
|
78
|
+
|
|
79
|
+
- **Başlık:** `text` `type: 'h2'`, bölüm başlığı `type: 'h4'`. `typographyStyle.fontSize` yazılmaz.
|
|
80
|
+
- **Bölüm iki türlüdür:**
|
|
81
|
+
- *Görünen grup (yüzey kabı):* `container` + `surfaceStyle` (zemin ya da kenarlık, `radius: 'lg'`) +
|
|
82
|
+
`paddingType: 'custom'` ve `paddingValue: 16`. İçeriği bilerek 16 içeride durur; kabın kendisi kardeşleriyle
|
|
83
|
+
hizalıdır.
|
|
84
|
+
- *Görünmeyen grup (saydam kap):* `container` `direction: 'column'`, `paddingType: 'none'`,
|
|
85
|
+
`marginType: 'none'`. İçerik kardeşleriyle aynı kenarda başlar.
|
|
86
|
+
|
|
87
|
+
Başlığı (`title`) olan ama zemini olmayan kap saydam kap gibi davranmalıdır. Varsayılan 10 dp padding'i
|
|
88
|
+
içeriği kaydırır (MOB-019). Ya yüzey verin ya da padding'i `none` yapın.
|
|
89
|
+
- **`card` çocuk almaz.** Kart görünümlü alan grubu `container` + `surfaceStyle` ile kurulur.
|
|
90
|
+
- **`tooltip`** dokunulan içeriği sarar ve saydamdır. Runtime ona varsayılan boşluk vermez; gateway yine de yeni
|
|
91
|
+
tooltip'e `paddingType: 'none'` ve `widthType: 'fill'` yazar. 2026-09-29'dan önce derlenmiş uygulamada
|
|
92
|
+
boşluksuz tooltip'in içeriği 14 dp içeri kayar ve 28 dp daralır; açık değer onu da korur.
|
|
93
|
+
- **Satır (`direction: 'row'`)** yan yana dizilen öğeler içindir: arama kutusu + düğme, ikon + metin,
|
|
94
|
+
"Ekle / Sil" düğmeleri. Form alanlarını alt alta dizmek için satır kullanılmaz.
|
|
95
|
+
- **Eylem:** birincil düğme tam genişlik (`widthType: 'fill'`). İkincil eylem `variant: 'text'` ya da
|
|
96
|
+
`'outline'`; metin görünümlü düğme içerik genişliğinde durabilir.
|
|
97
|
+
- **Ekrana sabit eylem** (`floating-container`, `anchor: 'bottom-center'`, `fullWidth`, `respectSafeArea`) iki
|
|
98
|
+
şeye dikkat ister:
|
|
99
|
+
- *Yerleşim.* `fullWidth` ekran kenarına dayanır; S4 kenarı için içine `paddingType: 'custom'` +
|
|
100
|
+
`paddingValues` yatay 16 olan bir kap koyun, `floating-container`'ın kendisine `paddingType: 'none'`
|
|
101
|
+
yazın (yoksa akışta 20 dp boş şerit kalır). Sabit düğme uzun formun son alanını örter; akışın sonuna
|
|
102
|
+
düğme boyu kadar boşluk bırakın.
|
|
103
|
+
- *Gönderim.* Formun dışındaki `type: 'submit'` + `formId` düğmesi formun olayını tetikler ama **form
|
|
104
|
+
doğrulamasını koşmaz** (bilinen açık). Doğrulanan form için gönder düğmesi formun içinde kalmalı.
|
|
105
|
+
|
|
106
|
+
## Boşluk
|
|
107
|
+
|
|
108
|
+
Aralığın tek kaynağı ebeveynin `gap`'idir. Runtime'ın varsayılanları katmanlarda birikir: margin tipi
|
|
109
|
+
yazılmamış her düğüm 4 dp, bırakılabilir düğüm ayrıca 10 dp padding alır. İki kat iç içe zeminsiz kap, içeriği
|
|
110
|
+
28 dp kaydırır.
|
|
111
|
+
|
|
112
|
+
- **Gateway yeni düğüme `marginType: 'none'` yazar** (`page_create`, `page_schema_patch`,
|
|
113
|
+
`page_schema_validate`) ve bunu `gatewayNormalized`'da söyler.
|
|
114
|
+
- Kardeşleri varsayılan margin'le duran eski bir kaba eklenen düğüme dokunulmaz; yeni düğüm eskilerden
|
|
115
|
+
4 dp kayardı. Kabı sözleşmeye taşımak için bütün çocuklarına `marginType: 'none'` yazın.
|
|
116
|
+
- `layout_schema_patch` ve `component_schema_patch` bu varsayılanı yazmaz. Kabukta ya da widget'ta eklenen
|
|
117
|
+
düğüme boşluğu siz yazın.
|
|
118
|
+
- **Ritim:**
|
|
119
|
+
- bölümler arası `gap: 'large'` (24);
|
|
120
|
+
- bölüm içi alanlar `gap: 'medium'` (16);
|
|
121
|
+
- satır içi öğeler `gap: 'small'` (8).
|
|
122
|
+
|
|
123
|
+
- **Özel değer** (`custom`) ve sayısal `gap` yalnız ölçekten seçilir: 0, 4, 8, 16, 24, 32 (MOB-021).
|
|
124
|
+
|
|
125
|
+
## Genişlik ve hiza
|
|
126
|
+
|
|
127
|
+
- **`horizontalAlign: 'stretch'`** olan sütun, çocuklarını `widthType` yazılmasa da tam genişlik gerer. Öteki
|
|
128
|
+
hizalarda tam genişlik öğesine `widthType: 'fill'` yazın. Aynı sütunda bir kısmı `fill`, bir kısmı değilse
|
|
129
|
+
sağ kenar hizadan kopar (MOB-020).
|
|
130
|
+
- **Yönü yazılmamış `container` ve `form` satırdır.** Alanlar yan yana sıkışır; `direction: 'column'` yazın.
|
|
131
|
+
`safe-area` ve `scroll-view` sütun doğar.
|
|
132
|
+
- **Ortalanmış ekran** (giriş, boş durum) için sütuna `horizontalAlign: 'center'` verin. Bu kapsamda kenar
|
|
133
|
+
eşitliği aranmaz.
|
|
134
|
+
|
|
135
|
+
## Kenarlık, yarıçap, yazı
|
|
136
|
+
|
|
137
|
+
- **Yüzey:** `surfaceStyle` ile verilir.
|
|
138
|
+
- zemin `background: 'var(--ng-…)'` (temada tanımlı jeton);
|
|
139
|
+
- kenarlık `borderTop…borderLeft` 1 dp, renk `border` jetonu;
|
|
140
|
+
- yarıçap `radius: 'lg'`.
|
|
141
|
+
|
|
142
|
+
Zemin ve kenarlığı birlikte kullanmayın; biri yeter.
|
|
143
|
+
- **Yarıçap ölçeği:** kartlar `lg`, çip ve rozetler `pill`, alan ve düğmeler temadan. Ham `'10px'` yazılmaz.
|
|
144
|
+
- **Yazı:** `text` `type` seviyesi.
|
|
145
|
+
- **Tasarım sistemi çapında görünüm** (bütün kartlar, bütün düğmeler) temadan yönetilir. Ölçekler, adlı ön
|
|
146
|
+
ayarlar ve yeni düğümlerin başlangıç değerleri `platform_guide('theme')`'dadır. Aynı değer tek tek düğümlere
|
|
147
|
+
kopyalanmaz. Temanın eski `componentStyles` alanı emeklidir.
|
|
148
|
+
|
|
149
|
+
## Kaydırma
|
|
150
|
+
|
|
151
|
+
Sayfa kökü her zaman kaydırır: barındırıcı sayfayı bir kaydırıcı içinde çizer.
|
|
152
|
+
|
|
153
|
+
`scroll-view` yalnız şu gerekçelerle eklenir:
|
|
154
|
+
|
|
155
|
+
- `refreshable` (çekerek yenile);
|
|
156
|
+
- `stickyHeader` ya da `states.isSticky` çocuk (yapışkan başlık);
|
|
157
|
+
- `horizontal` (yatay şerit);
|
|
158
|
+
- `heightType: 'fixed'` (sabit boylu iç liste).
|
|
159
|
+
|
|
160
|
+
Gerekçesiz ya da iç içe dikey kaydırıcı jestleri çakıştırır (MOB-016). Kökün `size: 'grow'`'u çocukları ekran
|
|
161
|
+
boyunca eşit böler ve kısa içerik üst üste biner. Yapışkan başlık ve ekrana sabit içerik için
|
|
162
|
+
`platform_guide('mobile')` §Ekrana sabit içerik.
|
|
163
|
+
|
|
164
|
+
## Doğrulama
|
|
165
|
+
|
|
166
|
+
Bir ekranı bitirince iki çağrı yapın:
|
|
167
|
+
|
|
168
|
+
1. **`page_schema_validate`** (kuru koşu): `layoutWarnings`'te MOB-015…021 bulgusu olmamalı.
|
|
169
|
+
- Yazım araçları (`page_schema_patch`, `layout_schema_patch`) yalnız o yazımın **getirdiği** bulguyu söyler.
|
|
170
|
+
- Sayfanın bütün durumunu kuru koşu verir.
|
|
171
|
+
2. **`page_screenshot({ layoutReport: true })`:** `layoutSummary.alignment` şu değerleri vermeli.
|
|
172
|
+
|
|
173
|
+
| Alan | Temiz değer | Anlamı |
|
|
174
|
+
|---|---|---|
|
|
175
|
+
| `gutter` | 16 | ekran kenarı boşluğu (sol = sağ) |
|
|
176
|
+
| `leftEdges` | tek küme | aynı kapsamdaki geniş içeriğin sol kenarları |
|
|
177
|
+
| `surfaces` | `[]` | iç hizası bozuk yüzey kabı yok |
|
|
178
|
+
| `widthOutliers` | `[]` | sağ kenarı sapan geniş öğe yok (`insetLeft`/`insetRight` dp) |
|
|
179
|
+
| `offScaleGaps` | `[]` | ardışık öğeler arası boşluk ölçekte |
|
|
180
|
+
|
|
181
|
+
İki kaynak aynı şeyi söyler. MOB-019'un şemadan öngördüğü dp farkı, `leftEdges` kümeleri arasındaki farktır.
|
|
182
|
+
|
|
183
|
+
## Bulgu → reçete
|
|
184
|
+
|
|
185
|
+
| Kod | Ne diyor | Ne yapılır |
|
|
186
|
+
|---|---|---|
|
|
187
|
+
| MOB-015 | Üst pay eksik ya da çift | Kabuksuz sayfaya `safe-area` `top`. Kabuğu payı vermiyorsa kabukta app-bar'ı `safe-area` `top` içine alın. Kabuk veriyorsa sayfadaki `top`/`all` güvenli alanı kaldırın |
|
|
188
|
+
| MOB-016 | Kaydırma tek yerde değil | Kök `size: 'shrink'`. Gerekçesiz `scroll-view`'ı kaldırın ya da gerekçesini verin. İç içe olanda içtekine `fixed` boy verin |
|
|
189
|
+
| MOB-017 | İkinci ya da yanlış yerde app-bar | Kabuk veriyorsa sayfadakini silin, başlığı kabuğa bağlayın. Kabuksuzda app-bar'ı ilk sıraya (ya da tepedeki `safe-area`'nın içine) taşıyın |
|
|
190
|
+
| MOB-018 | Boş kap | İçeriğini ekleyin ya da silin |
|
|
191
|
+
| MOB-019 | Kenar kayması (dp) | Bulgunun hedefi içeriği iten kaptır. Görünen grup olacaksa yüzey verin, olmayacaksa `paddingType: 'none'` + `marginType: 'none'`. Hedef öğenin kendisiyse margin'ini kardeşleriyle aynı yapın |
|
|
192
|
+
| MOB-020 | Genişlik tutarsız | Öğeye `widthType: 'fill'`. Yönü yazılmamış kaba `direction: 'column'` + `horizontalAlign: 'stretch'` |
|
|
193
|
+
| MOB-021 | Ölçek dışı değer | Boşluğu ve sayısal gap'i 0/4/8/16/24/32'den, yarıçapı `sm`/`md`/`lg`/`pill`'den, yazı boyunu `text` `type`'tan seçin |
|