@appaflytech/zeyrek-ai-mcp 0.0.32 → 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/.env.example +15 -0
- package/dist/config.js +11 -0
- package/dist/index.js +2 -0
- package/dist/knowledge/access.js +802 -0
- package/dist/knowledge/case.js +41 -0
- package/dist/knowledge/componentCatalog.js +82 -213
- package/dist/knowledge/componentEvents.js +21 -19
- 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 +864 -0
- package/dist/knowledge/mobileComponentEvents.js +239 -0
- package/dist/knowledge/mobileStore.js +227 -0
- package/dist/knowledge/normalize.js +121 -35
- 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/process.js +510 -0
- package/dist/knowledge/rowFilter.js +43 -0
- package/dist/knowledge/rules.js +291 -19
- package/dist/knowledge/styleResolve.js +55 -38
- package/dist/knowledge/styleResolveNative.js +527 -0
- package/dist/knowledge/themeResolve.js +3 -3
- package/dist/observability/trace.js +1 -1
- 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} +81 -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/http.js +23 -7
- package/dist/platform/impersonation.js +45 -0
- package/dist/platform/jsonArray.js +24 -0
- package/dist/platform/responses.js +6 -2
- package/dist/platform/schemaReadMemory.js +60 -0
- package/dist/platform/secrets.js +9 -0
- 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/layout-app-shell.json +229 -707
- package/dist/resources/examples/mobile-app-shell-drawer.json +244 -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 +703 -0
- package/dist/resources/examples/page-flex-sections.json +1 -1
- 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 +10 -2
- package/dist/resources/guides/decision.md +185 -0
- package/dist/resources/guides/expressions.md +14 -5
- package/dist/resources/guides/functions.md +1 -1
- package/dist/resources/guides/layout.md +55 -58
- package/dist/resources/guides/microservice.md +9 -2
- package/dist/resources/guides/middleware.md +34 -2
- package/dist/resources/guides/mobile-layout.md +193 -0
- package/dist/resources/guides/mobile.md +578 -0
- package/dist/resources/guides/page.md +221 -92
- package/dist/resources/guides/theme.md +8 -2
- package/dist/resources/guides/translation.md +1 -1
- package/dist/resources/guides/workflow.md +7 -1
- package/dist/resources/read.js +41 -0
- package/dist/resources/schema-fingerprint.json +4 -4
- 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/CreateProcessDefinitionCommand.json +1337 -0
- 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 +3 -1
- package/dist/resources/schemas/MicroserviceDto.json +2 -2
- 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/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/StartMobileBuildCommand.json +54 -0
- package/dist/resources/schemas/UpdateAccessPolicyCommand.json +209 -0
- package/dist/resources/schemas/UpdateDecisionCommand.json +216 -0
- package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +1357 -0
- package/dist/resources/schemas/UpsertMobileStoreSettingsCommand.json +259 -0
- package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +1339 -0
- package/dist/server.js +7 -1
- 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/components.js +103 -12
- package/dist/tools/connectData.js +449 -0
- package/dist/tools/connectors.js +193 -0
- package/dist/tools/datasources.js +1 -1
- package/dist/tools/decisions.js +206 -0
- package/dist/tools/designSchemaPatch.js +22 -16
- package/dist/tools/externalComponents.js +25 -4
- package/dist/tools/flows.js +79 -6
- package/dist/tools/layouts.js +44 -12
- package/dist/tools/microservices.js +32 -10
- package/dist/tools/mobile.js +221 -0
- package/dist/tools/mobileStore.js +268 -0
- package/dist/tools/modules.js +48 -0
- package/dist/tools/organizationStructure.js +137 -0
- package/dist/tools/pages.js +391 -92
- package/dist/tools/platformInfo.js +7 -2
- package/dist/tools/profileWrite.js +92 -0
- package/dist/tools/rows.js +7 -1
- package/dist/tools/schemaOps.js +33 -1
- package/dist/tools/screenWrite.js +15 -7
- package/dist/tools/screens.js +90 -3
- package/dist/tools/variables.js +11 -5
- package/package.json +2 -2
- package/dist/knowledge/boxSections.js +0 -184
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Vaka Rehberi — CMMN 1.1 vaka yönetimi
|
|
2
|
+
|
|
3
|
+
Adımları önceden bilinmeyen işler içindir: müşteri şikâyeti, soruşturma, hasar dosyası, uygunsuzluk incelemesi. Süreç tanımı
|
|
4
|
+
(`process_definition_*`) sırayı çizer; **vaka** ise aşamaları, isteğe bağlı görevleri ve "şu olunca şu açılır" koşullarını
|
|
5
|
+
(sentry) tanımlar, sırayı olaylar ve kişiler belirler. İnsan görevleri süreç görevleriyle **aynı kutuya** düşer
|
|
6
|
+
(`kind: case-task`) ve `process_task_update` ile tamamlanır. Süreçten vaka `case` düğümüyle başlatılır (§Süreçten vaka).
|
|
7
|
+
|
|
8
|
+
Modüller: `case` (tanım: `case_definition_*`, `case_cmmn_*`) ve `caseRuntime` (`case_execute`, `case_instance_*`).
|
|
9
|
+
|
|
10
|
+
## Başlangıç
|
|
11
|
+
|
|
12
|
+
1. **Modeli yazın** — `case_definition_create { case }`. Taslak sürüm oluşur. Gateway yazmadan önce CASE-001'i denetler
|
|
13
|
+
(§Lint); `case_definition_preview { case }` aynı denetimi istek göndermeden yapar.
|
|
14
|
+
2. **Yayınlayın** — `case_definition_publish { id }`. Çalışan vakalar başladıkları sürümde kalır; production'a yayın yok (BPM-001).
|
|
15
|
+
3. **Başlatın** — `case_execute { slug, subjectRowId, caseFile, asUser }`. Yanıt `planItems[]` ve `availableActions[]` taşır.
|
|
16
|
+
4. **Yürütün** — `case_instance_get` → `availableActions` → `case_instance_update { operation, planItemId }`; insan görevleri
|
|
17
|
+
`process_task_list` / `process_task_update`.
|
|
18
|
+
|
|
19
|
+
Düzeltmede tam modeli yeniden göndermeyin: `case_definition_get` → `case_definition_patch` (`/planItems[id=<öğe>]/…`).
|
|
20
|
+
Başka modelleyiciden gelen CMMN için `case_cmmn_update { filePath }`; dışa aktarma `case_cmmn_get { outPath }`.
|
|
21
|
+
|
|
22
|
+
## Model
|
|
23
|
+
|
|
24
|
+
```jsonc
|
|
25
|
+
{
|
|
26
|
+
"slug": "musteri-sikayeti", "name": { "tr": "Müşteri şikâyeti" }, "description": { "tr": "Şikâyeti inceler ve kapatır." },
|
|
27
|
+
"caseFile": [{ "id": "musteriCevabi" }, { "id": "oncelik", "default": "normal" }],
|
|
28
|
+
"planItems": [
|
|
29
|
+
{ "id": "inceleme", "type": "stage", "required": true, "autoComplete": true },
|
|
30
|
+
{ "id": "sikayeti-incele", "type": "human-task", "parent": "inceleme", "required": true, "assignee": { "rule": "user", "arg": "<kullanıcı id>" } },
|
|
31
|
+
{ "id": "hukuk-gorusu", "type": "human-task", "parent": "inceleme", "discretionary": true, "assignee": { "rule": "role", "arg": "hukuk" } },
|
|
32
|
+
{ "id": "yanit-alindi", "type": "milestone", "entry": ["musteri-cevapladi"] },
|
|
33
|
+
{ "id": "kapanis", "type": "stage", "required": true, "manualActivation": true, "autoComplete": true, "entry": ["musteri-cevapladi"] }
|
|
34
|
+
],
|
|
35
|
+
"sentries": [
|
|
36
|
+
{ "id": "musteri-cevapladi",
|
|
37
|
+
"onParts": [{ "source": "inceleme", "event": "complete" }, { "source": "musteriCevabi", "event": "update" }],
|
|
38
|
+
"ifPart": "caseFile.musteriCevabi != 'yok'" }
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| Alan | Kural (backend `CaseValidator`, hata 422 `CaseInvalid` + bulgu yolu `/planItems[id=x]/alan`) |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `slug`, plan öğesi ve sentry `id` | kebab-case, benzersiz; ilk yayından sonra slug değişmez (400) |
|
|
46
|
+
| `caseFile[].id` | harf, rakam, alt çizgi; `default` herhangi bir JSON |
|
|
47
|
+
| `planItems[].type` | `stage` · `human-task` · `milestone` |
|
|
48
|
+
| `parent` | yalnız bir `stage`; döngü yasak. `parent` yoksa öğe vaka planının köküdür |
|
|
49
|
+
| `required` | aşama tamamlanmadan önce bitmesi gereken öğe; `disable` edilemez |
|
|
50
|
+
| `repeatable` | tamamlanınca yeni `occurrence` açılır; giriş sentry'si ister, kilometre taşında olmaz |
|
|
51
|
+
| `manualActivation` | koşul sağlanınca `enabled` olur, biri `start` edene kadar bekler |
|
|
52
|
+
| `discretionary` | tanımda durur, kişi `add-discretionary` ile ekleyene kadar oluşmaz |
|
|
53
|
+
| `autoComplete` | yalnız `stage`: etkin çocuk kalmayınca ve zorunlular bitince kendiliğinden kapanır |
|
|
54
|
+
| `assignee` | `human-task` için zorunlu: `user` (`arg` kullanıcı id), `role` (`arg` rol slug'ı, aday kaydı), `initiator` |
|
|
55
|
+
| `entry` / `exit` | sentry kimlikleri; girişlerden biri yeter, çıkış öğeyi ve alt ağacını `terminated` yapar |
|
|
56
|
+
| `onParts[].event` | kaynak kilometre taşıysa yalnız `occur`; başka plan öğesiyse `complete` · `start` · `terminate`; vaka dosyası öğesiyse `update` |
|
|
57
|
+
| `ifPart` | Jint; `caseFile.x` (ya da `vars.x`) vaka dosyasını, `initiator` başlatanı okur |
|
|
58
|
+
|
|
59
|
+
Süreç tanımındaki `assignee` sözlüğü (`unit-manager of …`, `position:`) vakada **yoktur**; yalnız üç kural.
|
|
60
|
+
|
|
61
|
+
## Yaşam döngüsü
|
|
62
|
+
|
|
63
|
+
Plan öğesi: `available → enabled → active → completed | terminated | disabled`. Vaka: `active → completed | terminated`.
|
|
64
|
+
|
|
65
|
+
Her değişiklikten sonra platform yerleşimi sabitlenene kadar yeniden çalıştırır: çıkış sentry'si sağlanan öğe `terminated`;
|
|
66
|
+
ebeveyni etkin ve giriş koşulu sağlanan öğe `manualActivation` ise `enabled`, değilse etkin olur (insan görevi görev açar,
|
|
67
|
+
kilometre taşı doğrudan `completed`); kökteki her şey bitince vaka `completed`.
|
|
68
|
+
|
|
69
|
+
Aşama kapanışı **turun sonunda ve yalnız o turda başka hiçbir öğe hareket etmediyse** denenir — bir çocuk daha açılabiliyorken
|
|
70
|
+
aşama kapatılmaz. `autoComplete` aşama etkin çocuğu yokken ve zorunlu çocukları bitmişken kapanır, bekleyen çocuklarını
|
|
71
|
+
`terminated` eder. `autoComplete` **olmayan** aşama da kendiliğinden kapanır ama **bütün** çocukları terminal olmalıdır;
|
|
72
|
+
bekleyen çocuğu varken bekler ve onları terminale çekmez. Çocuğu olmayan aşama yalnız `autoComplete` ise kendiliğinden kapanır,
|
|
73
|
+
değilse elle `complete` bekler (elle `complete` her zaman gevşek koşulu kullanır: etkin çocuk yok + zorunlular bitmiş).
|
|
74
|
+
|
|
75
|
+
Sentry **durum tabanlıdır**: `onPart` kaynağın şu anki durumuna bakar (`complete`/`occur` → tamamlanmış, `start` → etkin ya da
|
|
76
|
+
tamamlanmış, `update` → vaka dosyası öğesi dolu) ve `ifPart` her turda yeniden çalışır. Bu yüzden vaka dosyasını değiştirmek
|
|
77
|
+
(`update-case-file`) bekleyen öğeyi açabilir.
|
|
78
|
+
|
|
79
|
+
## Eylemler
|
|
80
|
+
|
|
81
|
+
`case_instance_get` yanıtındaki `availableActions[] { action, itemId, planItemId }` o an yapılabilecekleri listeler:
|
|
82
|
+
|
|
83
|
+
| `case_instance_update { operation }` | Ne yapar | Hata |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `start` (`planItemId`) | `enabled` öğeyi başlatır | yanlış durum 409 `InstanceStateTransitionNotAllowed` |
|
|
86
|
+
| `complete` (`planItemId`) | etkin aşamayı kapatır (etkin çocuk yok, zorunlular bitmiş); insan görevi görev ucundan kapanır | 409 |
|
|
87
|
+
| `disable` (`planItemId`) | zorunlu olmayan `enabled` öğeyi devre dışı bırakır | 409 |
|
|
88
|
+
| `enable` (`planItemId`) | `available` öğeyi elle açar; giriş sentry'si **varsa** biri sağlanmalı (sentry'si olmayan öğe koşulsuz açılır) | sentry sağlanmıyorsa **422 `CaseSentryNotSatisfied`**, `available` değilse 409 |
|
|
89
|
+
| `add-discretionary` (`itemDefinitionId`) | isteğe bağlı öğeyi ebeveyn aşaması etkinken ekler | aynı öğenin bitmemiş örneği varsa 409 |
|
|
90
|
+
| `update-case-file` (`itemId`, `value`) | vaka dosyasına yazar, yerleşimi yeniden çalıştırır | tanımsız öğe 400 |
|
|
91
|
+
|
|
92
|
+
`enable` `availableActions`'ta **listelenmez**: yerleşim, giriş sentry'si sağlanan ya da hiç sentry'si olmayan öğeyi zaten açar,
|
|
93
|
+
dolayısıyla listede kalan `available` öğe sentry'sini bekliyordur ve ona `enable` 422 döner. Bu bir lint değil çalışma zamanı
|
|
94
|
+
kuralıdır — koşulu sağlamak için vaka dosyasını güncelleyin ya da kaynak öğeyi bitirin. Kapanmış vakada her değişiklik 409.
|
|
95
|
+
|
|
96
|
+
## Görevler
|
|
97
|
+
|
|
98
|
+
`human-task` etkinleşince `ProcessTask` açılır: `kind: case-task`, `instanceId` = vaka kimliği, `nodeId` = plan öğesi `id`,
|
|
99
|
+
`definitionSlug` = vaka slug'ı. `user` ve `initiator` doğrudan atanır; `role` aday kaydı açar ve görev `claim` ister. Tamamlama
|
|
100
|
+
`process_task_update { action: complete, payload, asUser }` — plan öğesi `completed` olur, yük vaka defterine yazılır. Vaka
|
|
101
|
+
görevi süreç defterine yazmaz; görev yardımcısı (`process_task_get { view: 'assistant' }`) çalışır ama `ai-suggestion` satırı
|
|
102
|
+
yalnız öneri tablosuna düşer.
|
|
103
|
+
|
|
104
|
+
Görünürlük: vakayı başlatan, görevi atanan ya da tamamlayan kişi `case_instance_get` ile okur; liste (`case_instance_list`)
|
|
105
|
+
ve başkalarının vakaları `process.view-all` ister. Başlatma `process.start`, tanım yazımı `process.manage` ister.
|
|
106
|
+
|
|
107
|
+
## Süreçten vaka
|
|
108
|
+
|
|
109
|
+
Süreç tanımında `case` düğümü yayındaki vakayı başlatır ve **beklemez** (akış devam eder):
|
|
110
|
+
|
|
111
|
+
```jsonc
|
|
112
|
+
{ "id": "sikayet-ac", "type": "case", "description": "Şikâyet vakasını açar.", "caseSlug": "musteri-sikayeti",
|
|
113
|
+
"input": { "musteriCevabi": "'yok'" }, "output": "vars.sikayetVakasi" }
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Başlatan süreç örneğinin başlatanı, iş satırı süreç konusudur; `output` yoluna vaka kimliği yazılır, süreç defterine
|
|
117
|
+
`case-started`. Bilinmeyen ya da yayınlanmamış slug tanım doğrulamasında `CaseUnknown`, çalışma anında düğüm hatası.
|
|
118
|
+
|
|
119
|
+
## CMMN XML
|
|
120
|
+
|
|
121
|
+
`case_cmmn_get` CMMN 1.1 XML üretir (`zeyrek:` uzantısı atamayı, çok dilli ad/açıklamayı, varsayılanı ve sırayı taşır);
|
|
122
|
+
`case_cmmn_update { xml | filePath }` içe aktarır: aynı slug varsa taslağına yazar, yoksa yeni tanım açar. `stage`, `humanTask`,
|
|
123
|
+
`milestone` dışındaki öğeler (`processTask`, `caseTask`, olay dinleyicileri) ve DTD içeren XML 400'dür. Başka araçta
|
|
124
|
+
çizilmiş vakanın atamaları uzantı taşımıyorsa içe aktarma sonrası `case_definition_patch` ile ekleyin.
|
|
125
|
+
|
|
126
|
+
## Lint
|
|
127
|
+
|
|
128
|
+
| Kural | Ne zaman | Önem |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| CASE-001 | `onParts[].source` bir plan öğesi ya da vaka dosyası öğesi değil; `entry`/`exit` tanımsız sentry'ye bakıyor | block |
|
|
131
|
+
|
|
132
|
+
Denetim `case_definition_create`, `case_definition_update`, `case_definition_patch`, `case_definition_publish` öncesinde ve
|
|
133
|
+
`case_definition_preview`'da çalışır. Diğer model kuralları backend'dedir (422 `CaseInvalid` bulgu listesi).
|
|
134
|
+
|
|
135
|
+
## Hata sözlüğü
|
|
136
|
+
|
|
137
|
+
| Kod | Anlamı | Ne yapılır |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| `CaseInvalid` (422) | Model kuralı ihlali; `errors[]` yol ve mesaj taşır | yolu `case_definition_patch` ile düzeltin |
|
|
140
|
+
| `CaseSentryNotSatisfied` (422) | `enable` edilen öğenin giriş koşulu sağlanmıyor | kaynak öğeyi bitirin ya da `update-case-file` |
|
|
141
|
+
| `InstanceStateTransitionNotAllowed` (409) | öğe ya da vaka bu eyleme uygun durumda değil | `case_instance_get` ile `availableActions`'a bakın |
|
|
142
|
+
| `CaseUnknown` (422) | süreçteki `case` düğümü yayında olmayan vakaya bakıyor | vakayı yayınlayın |
|
|
143
|
+
| `ReferencedByProcess` (422) | silinen vaka tanımına bir süreç `case` düğümüyle başvuruyor | önce süreci güncelleyin |
|
|
144
|
+
| `InvalidOperation` (400) | vakası olan tanım silinemez | tanımı yerinde bırakın |
|
|
145
|
+
|
|
146
|
+
## Sık tuzaklar
|
|
147
|
+
|
|
148
|
+
- **Sırayı vaka ile çizmek.** Adımlar belliyse süreç tanımı kullanın; vaka bekleme ve dallanmayı sentry'ye çevirir, okunması zorlaşır.
|
|
149
|
+
- **`enable`'ı düzeltme sanmak.** 422 aldıysanız koşul sağlanmamıştır; tekrar denemek değil koşulu sağlamak gerekir.
|
|
150
|
+
- **`repeatable` öğeyi giriş sentry'siz yazmak.** Model reddedilir; tekrar tetikleyicisiz sonsuz döngü olurdu.
|
|
151
|
+
- **Vaka görevini `case_instance_update { complete }` ile kapatmaya çalışmak.** `complete` yalnız aşama içindir; görev
|
|
152
|
+
`process_task_update` ile kapanır.
|
|
153
|
+
- **`caseFile` öğesini tanımlamadan `ifPart`'ta kullanmak.** Tanımsız değer `undefined` okunur; öğeyi `caseFile[]`'a ekleyin.
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
Sayfaya konan her şeyin ortak kuralları. Kuruluş sırası ve şema gövdesi için
|
|
4
4
|
`platform_guide('page')`; HTML kaçış kapısının derin sözleşmesi için `platform_guide('html')`.
|
|
5
5
|
|
|
6
|
+
> **Mobil uygulamada** katalog ayrıdır: `component_list`/`component_get` mobil satırları okur,
|
|
7
|
+
> `component_get` `mobileKnowledge` (bileşenin mobil farkları) ve `mobileNotes` ekler; katalogda
|
|
8
|
+
> olmayan tip `MOB-003` alır. Stil CSS değil React Native'dir — `page_runtime_get(resolveStyles)`
|
|
9
|
+
> `nativeStyle` döner (`platform_guide('mobile')`).
|
|
10
|
+
|
|
6
11
|
## Keşif: iki tool, üç bilgi katmanı
|
|
7
12
|
|
|
8
13
|
```
|
|
@@ -88,7 +93,10 @@ Widget, kendi komponent ağacını taşıyan yeniden kullanılabilir pakettir (`
|
|
|
88
93
|
|
|
89
94
|
1. **Kayıt:** `component_create` — `kind:'widget'`, `widgetType`, `schema` (widget'ın kendi
|
|
90
95
|
ağacı; `name = elementId` kuralı burada da geçerli — layout gibi widget adları da kullanan
|
|
91
|
-
sayfaya sızar).
|
|
96
|
+
sayfaya sızar). Ağacın KÖKÜ tiplidir: `container` → `widget-area`, `modal`/`drawer` → kendi
|
|
97
|
+
tipi (+ düğümde `widgetType`). Runtime widget'ı yalnız bu kökten çizer; düz `container` kökle
|
|
98
|
+
kayıt 200 döner ama boş çizilir. Kök vermezsen gateway düğümlerini Studio'nun kurduğu köke
|
|
99
|
+
sarar ve `gatewayNormalized`'da CMP-002 ile bildirir (`component_update` şemada da aynı).
|
|
92
100
|
2. **Sayfaya koyma:** `add_component` düğümünde `kind:'widget'` ve **`type` = widget KAYDININ
|
|
93
101
|
ID'si** — slug DEĞİL (runtime widget'ı `widget.id === node.type` ile çözer; slug yazarsan
|
|
94
102
|
kayıt 200 döner, render sessizce boş kalır — gateway **PAGE-012/LAY-005** ile reddeder).
|
|
@@ -108,7 +116,7 @@ Her şema düğümünde iki sözlük vardır; ikisi de ortak render katmanında
|
|
|
108
116
|
|
|
109
117
|
| `states` | Anlamı |
|
|
110
118
|
|---|---|
|
|
111
|
-
| `isDroppable` | İçine komponent alır (container/form/repeater true) |
|
|
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` |
|
|
112
120
|
| `isScrollable` | İçeriği kendi alanında kaydırır (sabit yükseklikte `overflow-y: auto`) |
|
|
113
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 |
|
|
114
122
|
| `isSticky` | Kaydırmada yerinde kalır (header/sidebar; z-index'i otomatik) |
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Karar Rehberi — DMN karar tabloları
|
|
2
|
+
|
|
3
|
+
Eşik, seviye, oran, uygunluk gibi **kuralları süreç tanımından ayırır**: iş birimi tabloyu değiştirir, süreç
|
|
4
|
+
yeniden yayınlanmaz. Karar bir DMN 1.3 karar tablosu (`kind: table`) ya da tek bir FEEL ifadesidir
|
|
5
|
+
(`kind: literal`). Süreçte `decision` düğümüyle çağrılır; tek başına `decision_preview` ile değerlendirilir.
|
|
6
|
+
Karar **workflow değildir** (yan etkisi yoktur, veri okumaz — girdileri çağıran verir) ve **süreç değildir**
|
|
7
|
+
(beklemez).
|
|
8
|
+
|
|
9
|
+
## Başlangıç
|
|
10
|
+
|
|
11
|
+
1. **Tabloyu yazın** — `decision_create { decision }`. Taslak sürüm oluşur. Gateway yazmadan önce DMN-001 ve
|
|
12
|
+
DMN-002 denetimini çalıştırır (§Lint).
|
|
13
|
+
2. **Deneyin** — `decision_preview { id, inputs }`. Her sınır değerini ayrı deneyin (§Deneme).
|
|
14
|
+
3. **Yayınlayın** — `decision_publish { id }`. Motor yalnız aktif sürümü kullanır; production'a yayın yoktur
|
|
15
|
+
(BPM-001).
|
|
16
|
+
4. **Süreçte kullanın** — `decision` düğümü (§Süreçte kullanım); tanımı `process_definition_preview` ile doğrulayın
|
|
17
|
+
(bilinmeyen `decisionSlug` → `DecisionUnknown`).
|
|
18
|
+
|
|
19
|
+
Düzeltmede tam modeli yeniden göndermeyin: `decision_get` → `decision_patch` (`/rules[id=<kural>]/…`).
|
|
20
|
+
Başka modelleyiciden (Camunda Modeler, Trisotech) gelen tablo için `decision_dmn_update { filePath }`.
|
|
21
|
+
|
|
22
|
+
## Karar modeli
|
|
23
|
+
|
|
24
|
+
```jsonc
|
|
25
|
+
{
|
|
26
|
+
"slug": "siparis-onay-limitleri", // tekil; yayından sonra değişmez
|
|
27
|
+
"name": { "tr": "Sipariş onay limitleri" },
|
|
28
|
+
"variable": "siparisOnayLimitleri", // üst kararların gördüğü ad; yoksa slug'daki '-' → '_'
|
|
29
|
+
"kind": "table", // table | literal
|
|
30
|
+
"hitPolicy": "unique", // §İsabet politikaları
|
|
31
|
+
"aggregation": null, // collect + tek çıktı: sum | min | max | count
|
|
32
|
+
"requires": [], // DRD: önce değerlendirilecek alt kararlar (slug)
|
|
33
|
+
"inputData": [], // { name, typeRef, source: "authority-limits", category }
|
|
34
|
+
"inputs": [
|
|
35
|
+
{ "id": "tutar", "label": "Tutar", "expression": "tutar", "typeRef": "number" },
|
|
36
|
+
{ "id": "kategori", "label": "Kategori", "expression": "kategori", "typeRef": "string", "allowedValues": "\"makine\", \"sarf\"" }
|
|
37
|
+
],
|
|
38
|
+
"outputs": [
|
|
39
|
+
{ "id": "seviye", "name": "seviye", "typeRef": "number", "allowedValues": "3, 2, 1", "defaultOutputEntry": "1" }
|
|
40
|
+
],
|
|
41
|
+
"rules": [
|
|
42
|
+
{ "id": "kucuk", "description": "10 binin altı", "inputEntries": ["< 10000", "-"], "outputEntries": ["1"] },
|
|
43
|
+
{ "id": "orta", "inputEntries": ["[10000..100000)", "-"], "outputEntries": ["2"] },
|
|
44
|
+
{ "id": "buyuk", "inputEntries": [">= 100000", "-"], "outputEntries": ["3"] }
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- `inputEntries[i]` `inputs[i]`'nin **tekli testidir**, `outputEntries[j]` `outputs[j]`'nin **FEEL ifadesidir**.
|
|
50
|
+
Sütun sayısı eşleşmezse 422 `DecisionInvalid` (yol `/rules/{i}/inputEntries`).
|
|
51
|
+
- `inputs[].expression` girdinin bağlamdaki adıdır ya da ifadesidir (`siparis.tutar`, `tutar * 1.2`).
|
|
52
|
+
- Metin değerler FEEL'de **çift tırnaklıdır**: `"makine"`. Tırnaksız `makine` bir değişken adıdır ve `null` olur.
|
|
53
|
+
- `typeRef`: `number`, `string`, `boolean`, `date`, `time`, `dateTime`, `dayTimeDuration`,
|
|
54
|
+
`yearMonthDuration`, `list`, `context`. Dönüştürme yalnız metin girdiye uygulanır (`"2026-09-17"` → tarih).
|
|
55
|
+
- Literal karar: `{ "kind": "literal", "literalExpression": "tutar * oran", "typeRef": "number" }`.
|
|
56
|
+
|
|
57
|
+
## İsabet politikaları
|
|
58
|
+
|
|
59
|
+
| Politika | Ne döner | Ne zaman |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `unique` | En çok bir kural; ikisi eşleşirse 422 `DecisionHitPolicyViolated` | Kurallar kesin ayrık (varsayılan) |
|
|
62
|
+
| `any` | Eşleşenlerin çıktıları aynı olmalı, yoksa 422 | Aynı sonucu farklı yollardan veren kurallar |
|
|
63
|
+
| `first` | Kural sırasındaki ilk eşleşme | "Özel durum önce, genel en sonda" |
|
|
64
|
+
| `priority` | Çıktının `allowedValues` sırasına göre en yüksek (ilk yazılan) | Birden çok eşleşmede en katısı kazanır |
|
|
65
|
+
| `collect` | Eşleşenlerin listesi; `aggregation` ile tek sayı | Puanlama, kontrol listesi |
|
|
66
|
+
| `rule-order` | Eşleşenler kural sırasıyla | Sıralı öneriler |
|
|
67
|
+
| `output-order` | Eşleşenler `priority` sırasıyla | Önceliğe göre sıralı liste |
|
|
68
|
+
|
|
69
|
+
Tek çıktılı tabloda karar değeri çıktının kendisidir; çok çıktılıda `{ çıktıAdı: değer }`. Çok isabetli
|
|
70
|
+
politikada değer listedir. Hiç kural eşleşmezse `defaultOutputEntry` olan çıktılar varsayılanı alır, yoksa `null`
|
|
71
|
+
— `null` sonucu süreçte gateway koşulunu sessizce yanlış dala gönderebilir; ya varsayılan verin ya da son kurala
|
|
72
|
+
joker (`-`) koyup `first` kullanın.
|
|
73
|
+
|
|
74
|
+
## FEEL
|
|
75
|
+
|
|
76
|
+
**Tekli testler** (`inputEntries`):
|
|
77
|
+
|
|
78
|
+
| Yazım | Anlamı |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `-` ya da boş | her şey |
|
|
81
|
+
| `< 100` · `>= 5` | karşılaştırma |
|
|
82
|
+
| `[10..20)` · `]1..5]` | aralık; `[` `]` dahil, `(` `)` ya da ters köşe hariç |
|
|
83
|
+
| `"makine"` · `3` · `null` · `esik` | eşitlik (değer ya da bağlamdaki ad) |
|
|
84
|
+
| `"makine", "sarf"` | virgül = VEYA |
|
|
85
|
+
| `not("makine", "sarf")` | hiçbiri |
|
|
86
|
+
| `? > esik * 2` | `?` girdinin kendisi; ifade mantıksal döner |
|
|
87
|
+
|
|
88
|
+
**İfadeler** (`outputEntries`, `expression`, `literalExpression`): `+ - * / **`; `= != < <= > >=`;
|
|
89
|
+
`and`/`or` üç değerli (`true and null` → `null`); `x between 1 and 5`; `x in [1..5]`;
|
|
90
|
+
`if … then … else …`; `for x in liste return x * 2`; `some x in liste satisfies x > 3`; liste filtresi
|
|
91
|
+
`kalemler[tutar > 100]`, indeks `liste[1]` (1'den başlar), `liste[-1]` (son); yol `siparis.musteri.ad`; bağlam
|
|
92
|
+
`{ ad: "x", tutar: 5 }`; zamansal değişmez `@"2026-09-17"`, `@"P3D"`.
|
|
93
|
+
|
|
94
|
+
**Yerleşik işlevler** (tam liste; başkası DMN-002):
|
|
95
|
+
`date`, `time`, `date and time`, `duration`, `years and months duration`, `string length`, `substring`,
|
|
96
|
+
`substring before`, `substring after`, `upper case`, `lower case`, `contains`, `starts with`, `ends with`,
|
|
97
|
+
`matches`, `replace`, `string`, `number`, `not`, `list contains`, `count`, `sum`, `product`, `min`, `max`, `mean`,
|
|
98
|
+
`all`, `any`, `append`, `concatenate`, `flatten`, `reverse`, `distinct values`, `index of`, `get value`, `abs`,
|
|
99
|
+
`floor`, `ceiling`, `decimal` (yarıdan çifte yuvarlar), `modulo`, `sqrt`, `odd`, `even`.
|
|
100
|
+
|
|
101
|
+
Özellikler: tarihte `year month day weekday`, zamanda `hour minute second`, sürede `days hours minutes seconds`
|
|
102
|
+
ve `years months`, aralıkta `start end`.
|
|
103
|
+
|
|
104
|
+
**Yok:** `round up/down/half`, `sort`, `now()`/`today()` (bugünü girdi olarak verin), işlev tanımı, adlı
|
|
105
|
+
argüman, `instance of`, BKM çağrısı, saat dilimli zaman. Sözdizimi hatası 422 `ExpressionInvalid`; tür uyuşmazlığı,
|
|
106
|
+
sıfıra bölme ve tanımsız ad hata değil `null`'dır.
|
|
107
|
+
|
|
108
|
+
## DRD ve girdi verisi
|
|
109
|
+
|
|
110
|
+
`requires: ["risk-skoru"]` alt kararı önce değerlendirir ve sonucunu `variable` adıyla (yoksa `risk_skoru`)
|
|
111
|
+
bağlama ekler; üst tablonun sütunu `{ "expression": "risk_skoru" }` olur. Döngü yayında 422 `DecisionInvalid`;
|
|
112
|
+
alt kararın aktif sürümü yoksa 422 `DecisionUnknown`. Silme: süreç başvuruyorsa 422 `ReferencedByProcess`,
|
|
113
|
+
başka karar `requires` ile başvuruyorsa 422 `DecisionInvalid`.
|
|
114
|
+
|
|
115
|
+
**Yetki limitleri:** `inputData: [{ "name": "limitler", "typeRef": "list", "source": "authority-limits",
|
|
116
|
+
"category": "makine" }]` — girdi verilmezse `process_authority_limit_list` satırları
|
|
117
|
+
`[{ subjectKind, subjectId, category, limit, currency }]` listesi olarak yüklenir. Tabloda
|
|
118
|
+
`count(limitler[limit >= tutar])` gibi kullanılır.
|
|
119
|
+
|
|
120
|
+
## Süreçte kullanım
|
|
121
|
+
|
|
122
|
+
```jsonc
|
|
123
|
+
{ "id": "limit", "type": "decision", "description": "Onay seviyesini belirler",
|
|
124
|
+
"decisionSlug": "siparis-onay-limitleri",
|
|
125
|
+
"binding": "latest", // latest | deployed | "v:2" (sabit sürüm)
|
|
126
|
+
"input": { "tutar": "vars.tutar", "kategori": "row.kategori" }, // Jint; yoksa vars + row
|
|
127
|
+
"output": "vars.onay" } // yoksa her çıktı vars'a kendi adıyla
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Sonraki gateway'de `vars.onay.seviye >= 2` (çok çıktılı) ya da `vars.onay >= 2` (tek çıktılı). Değerlendirme
|
|
131
|
+
hatası örneği `faulted` yapar; `process_instance_get { view: 'timeline' }` → `decision-evaluated`
|
|
132
|
+
`{ decisionSlug, version, inputs, matchedRules, outputs }`. Tanım yayını karar yayınını beklemez ama motor
|
|
133
|
+
aktif sürüm ister: önce kararı yayınlayın.
|
|
134
|
+
|
|
135
|
+
## Deneme
|
|
136
|
+
|
|
137
|
+
`decision_preview { id, inputs, version? }` yan etkisizdir; `version` yoksa taslak (yoksa aktif), alt kararlar da
|
|
138
|
+
taslak/son modelle çalışır. Yanıt `{ value, outputs, matchedRules, decisions[] }` — `decisions[]` DRD'deki her
|
|
139
|
+
kararın girdisini ve eşleşen kuralını gösterir.
|
|
140
|
+
|
|
141
|
+
Her kuralı en az bir kez tetikleyin ve **sınırları** ayrı deneyin: `[10000..100000)` için 9999, 10000, 99999,
|
|
142
|
+
100000. Aralık uçlarındaki `[`/`)` hatası en sık kusurdur; DMN-001 bunu yakalamaz (§Lint).
|
|
143
|
+
|
|
144
|
+
## DMN XML
|
|
145
|
+
|
|
146
|
+
- `decision_dmn_get { id, outPath? }` kararı ve alt kararlarını DMN 1.3 XML'e yazar; çok dilli ad, `kind`,
|
|
147
|
+
`variable`, `inputData` kaynağı `zeyrek:` uzantısıyla (`https://zeyrek.dev/dmn`) gidiş-dönüş kayıpsızdır.
|
|
148
|
+
- `decision_dmn_update { xml | filePath }` DMN 1.3/1.2/1.1 içe aktarır: `decision id` → slug (küçük harf),
|
|
149
|
+
var olan slug yeni taslak alır, yoksa oluşturulur; bir karar geçersizse hiçbiri yazılmaz. Kutulu bağlam/ilişki,
|
|
150
|
+
BKM ve DMNDI desteklenmez. İçe aktardıktan sonra `decision_preview` — başka motorun FEEL işlevleri (ör.
|
|
151
|
+
Camunda `round up`) içe aktarmada 422 ile reddedilir.
|
|
152
|
+
- Ortamlar arası taşıma: kararlar deployment/merge zincirinde **yoktur**; dışa aktarıp hedef dalda içe aktarın.
|
|
153
|
+
|
|
154
|
+
## Lint
|
|
155
|
+
|
|
156
|
+
| Kural | Ne | Şiddet |
|
|
157
|
+
|---|---|---|
|
|
158
|
+
| DMN-001 | `unique` tabloda iki kural her girdi sütununda aynı testi ya da `-` taşıyor → aynı girdi ikisini eşler | block (istek gitmez) |
|
|
159
|
+
| DMN-002 | FEEL alt kümesinde olmayan işlev çağrısı | warn (istek gider; backend yazımı 422 ile reddeder) |
|
|
160
|
+
|
|
161
|
+
DMN-001 temkinlidir: yalnız **kesin** çakışmayı yakalar. `< 20` ile `< 10` ya da `[1..5]` ile `[5..9]` kesişir ama
|
|
162
|
+
yakalanmaz — `decision_preview` ile sınır değeri deneyin. Bilinçli istisna `policyOverride: true`.
|
|
163
|
+
|
|
164
|
+
## Hata sözlüğü
|
|
165
|
+
|
|
166
|
+
| Kod | Anlamı | Ne yapılır |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| 422 `DecisionHitPolicyViolated` | unique/any tabloda çakışan kurallar (yanıtta kural kimlikleri) | Kuralları ayırın ya da politikayı değiştirin |
|
|
169
|
+
| 422 `ExpressionInvalid` | FEEL sözdizimi ya da bilinmeyen işlev (yol `/rules/{i}/…`) | §FEEL listesine bakın |
|
|
170
|
+
| 422 `DecisionInvalid` | Model hatası (sütun sayısı, politika, döngü) | Yoldaki alanı düzeltin |
|
|
171
|
+
| 422 `DecisionUnknown` | `requires` ya da süreç `decisionSlug`'ı aktif kararı bulamadı | Alt kararı yayınlayın |
|
|
172
|
+
| 422 `ReferencedByProcess` | Silinmek istenen karara süreç başvuruyor | Önce süreci değiştirin |
|
|
173
|
+
|
|
174
|
+
## Sık tuzaklar
|
|
175
|
+
|
|
176
|
+
- **Tırnaksız metin:** `inputEntries: ["makine"]` değil `["\"makine\""]`. Tırnaksız ad bağlamda aranır, `null` olur ve
|
|
177
|
+
kural hiç eşleşmez.
|
|
178
|
+
- **Sayı metin geliyor:** satırdaki `"180000"` metni `number` sütunda karşılaştırılamaz; `typeRef: "number"` verin ya da
|
|
179
|
+
düğüm girdisinde `Number(row.tutar)`.
|
|
180
|
+
- **Boşluk bırakan aralıklar:** `< 10000` ve `(10000..100000)` → tam 10000 hiçbir kurala düşmez.
|
|
181
|
+
- **`null` sonuç:** eşleşme yoksa varsayılan yoksa `null` döner; süreçte koşul `vars.onay.seviye >= 2` `false`
|
|
182
|
+
olur, hata vermez.
|
|
183
|
+
- **Bugünün tarihi:** FEEL'de `today()` yok; süreç düğümü girdisinde `{ "bugun": "new Date().toISOString().slice(0, 10)" }`.
|
|
184
|
+
- **Taslakla çalıştığını sanmak:** `decision_preview` taslağı, süreç motoru aktif sürümü kullanır — yayınlamayı unutmak
|
|
185
|
+
"önizlemede doğruydu, süreçte eski sonuç" demektir.
|
|
@@ -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.
|
|
@@ -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:
|
|
@@ -39,20 +43,16 @@ göre kurmaktır. `version` bir **string**tir (mikrosaniye zaman damgası) — s
|
|
|
39
43
|
**4. TEK slot.** Sayfa şeması **her** slot'a ayrı ayrı kopyalanır — iki slot, sayfayı iki
|
|
40
44
|
kez çizer ve `elementId`'leri tekrarlar. (LAY-002 / LAY-006)
|
|
41
45
|
|
|
42
|
-
**5.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
`
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
**5a. Kök, sayfanın `page_container`'ının yerleşim ikizidir.** Varsayılan kabuk kökü şöyle
|
|
53
|
-
kurar ve sen de aynısını yazmalısın: `states.isWrapper: true` (çerçevesiz, başlıksız,
|
|
54
|
-
saydam) + `appearance.heightType: 'fill'` + `blocks` x0/w12. Sarmalayıcı olmayan bir kök,
|
|
55
|
-
kenarlıklı beyaz bir kart olarak çizilir.
|
|
46
|
+
**5. Kabuğu `container` + `slot` ile kur.** `layout` monoliti (sabit logo/menü/kullanıcı
|
|
47
|
+
bandı — yalnız doldurulur) ve `layout-shell` + `layout-region` ikilisi **emekliye
|
|
48
|
+
ayrıldı**; kayıtlı kalırlar ve mevcut layout'lar çalışır, ama yeni kabuk `container` ile
|
|
49
|
+
kurulur. Sebebi: `container` zaten `layout-region`'ın yaptığının üstünü yapıyor (flex/ızgara
|
|
50
|
+
düzeni, hizalama, gap, wrap), region'ın kattığı tek şey `dock` sözlüğüydü.
|
|
51
|
+
|
|
52
|
+
**5a. Kök, sayfanın `page_container`'ının yerleşim ikizidir.** Studio'nun yeni layout
|
|
53
|
+
iskeleti (`getDefaultLayout`) tam olarak şunu kurar ve sen de aynısını yazmalısın:
|
|
54
|
+
`states.isWrapper: true` (çerçevesiz, başlıksız, saydam) + `appearance.heightType: 'fill'`
|
|
55
|
+
+ `blocks` x0/w12. Sarmalayıcı olmayan bir kök, kenarlıklı beyaz bir kart olarak çizilir.
|
|
56
56
|
|
|
57
57
|
**5b. Tam ekran kabuk `heightType: 'fill'` ile kurulur (2026-08-28).** Yükseklik ne
|
|
58
58
|
içerikten (`auto`) ne satır sayısından (`fixed`) gelir — ebeveynin bıraktığı yerden gelir:
|
|
@@ -65,7 +65,7 @@ yapılan eski numaraya artık gerek yok.
|
|
|
65
65
|
NEREDE durduğunu değil, BİÇİMİNİ söyler (dikey kolon / yatay şerit / dolgu yüzeyi). Hem
|
|
66
66
|
runtime hem Studio tuvali bölgeleri 12 kolonluk ızgarayla yerleştirir.
|
|
67
67
|
|
|
68
|
-
**7.
|
|
68
|
+
**7. Dar ekranda flex YIĞILMAZ.** Runtime'ın dar ekran kuralı yalnız ızgara özelliklerini ezer.
|
|
69
69
|
Telefonda alt alta düşmesi gereken satırı `layout:'grid'` ile kur; `layout:'flex'` +
|
|
70
70
|
`direction:'row'` telefonda da yan yana kalır (375px'te ölçüldü: ızgara çocukları 375/375px
|
|
71
71
|
alt alta, flex çocukları 49/310px yan yana). Not: `wrap` varsayılanı artık açık (2026-09-01) —
|
|
@@ -76,48 +76,45 @@ yana kalmaya devam eder.
|
|
|
76
76
|
gerçek çıktıyı, layout'a bağlı bir sayfanın runtime paketinde görürsün (slot yerleşimi
|
|
77
77
|
dahil). Slot kurgusu için ayrıca `page_state` → `layoutSlots`.
|
|
78
78
|
|
|
79
|
-
## Mini tarif — uygulama kabuğu
|
|
79
|
+
## Mini tarif — uygulama kabuğu
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
(`resource: layout-app-shell`).
|
|
81
|
+
Yan menü + üst şerit + içerik. Studio'nun `getDefaultLayout` iskeletiyle birebir aynı ağaç;
|
|
82
|
+
`layout_create`'in `views` alanına doğrudan verilebilir (`resource: layout-app-shell`).
|
|
84
83
|
|
|
85
84
|
```
|
|
86
|
-
container
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
└ container shell_content fill · isScrollable · isWrapper · dolgu 28/32/32/32
|
|
95
|
-
└ container shell_page fill · en fazla 1600px · ortalı
|
|
96
|
-
└ slot shell_slot fill
|
|
85
|
+
container isWrapper:true heightType:'fill' layout:'flex' direction:'row' gap:'none'
|
|
86
|
+
│ verticalAlign:'stretch' block w12 x0
|
|
87
|
+
├ container heightType:'fill' layout:'flex' direction:'column' block w2 ← yan menü
|
|
88
|
+
│ └ navigations block w12
|
|
89
|
+
└ container heightType:'fill' layout:'flex' direction:'column' block w10 x2
|
|
90
|
+
├ container layout:'flex' direction:'row' states.isSticky block w12 h6
|
|
91
|
+
│ └ breadcrumb block w12 h3
|
|
92
|
+
└ slot heightType:'fill' block w12 y6
|
|
97
93
|
```
|
|
98
94
|
|
|
99
|
-
- **
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
`
|
|
112
|
-
`
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
`
|
|
116
|
-
- **
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
95
|
+
- **Genişlik `appearance.widthType`'tan gelir (2026-09-01); kolon payı fallback'tir.**
|
|
96
|
+
Yan menü için `widthType: 'fixed'` + `widthString: "240px"` (serbest CSS uzunluğu:
|
|
97
|
+
`"50%"`, `"10vw"`, `calc(...)` de geçer; yalnız flex kabın çocuğunda okunur, mutlak
|
|
98
|
+
ızgara kabında okunmaz). `'fill'` kabın tüm genişliğini alır, `'auto'` içeriğe oturur;
|
|
99
|
+
`widthType` HİÇ yazılmazsa `w:2` = 12'de 2 → 1440px tasarım genişliğinde 240px payı
|
|
100
|
+
geçerlidir. String yalnız `'fixed'` modda okunur — tek başına `widthString` ölüdür.
|
|
101
|
+
- **Yükseklik `fill`'dir**, `size.h` değil: kök ekranı doldurur, yan menü ve içerik sütunu
|
|
102
|
+
kökün bıraktığını, slot da üst şeritten artanı alır. Slot'un grid satırı ayrıca açık
|
|
103
|
+
uçludur (`y / auto`), yani sayfa uzadıkça slot uzar.
|
|
104
|
+
- **Kaydırma:** `fill` + `states.isScrollable:true` verilen düğüm büyümek yerine İÇİNDE
|
|
105
|
+
kaydırır — uzun içerikte kabuğu sabit tutmanın yolu budur.
|
|
106
|
+
- **Slot'un kenar boşluğu margin'dir, padding değil.** Slot droppable değildir; ona yazılan
|
|
107
|
+
`paddingType`/`paddingValue` hiçbir kutuya çizilmez (LAY-010). Her sayfanın kenardan uzak
|
|
108
|
+
durmasını tek yerden istiyorsan slot'a `appearance.marginType: 'custom'` + `marginValue: 24`
|
|
109
|
+
yaz — margin slot'un sarmalayıcısına iç boşluk olarak iner ve slot'un zemini olmadığı için
|
|
110
|
+
sonuç padding'le aynıdır. Studio iskeleti slot'a zaten 8px custom margin verir. Değer SAYIDIR
|
|
111
|
+
(`24`, `"24px"` değil — LAY-011). Her sayfaya sarmalayıcı container eklemek gerekmez.
|
|
112
|
+
- **MOBİL UYARISI:** bu ağaç `flex` olduğu için telefonda YIĞILMAZ (Kural 7) — 375px'te yan
|
|
113
|
+
menü ince bir şerite iner. Telefonda alt alta düşmesi gereken bir kabuk için kökü
|
|
114
|
+
`layout:'grid'` kur; o zaman `fill`'in flex anlamı (`flex:1 1 auto`) devreye girmez,
|
|
115
|
+
yükseklik yine `blocks` satırlarından gelir. İkisini aynı anda veren bir yol bugün yok.
|
|
116
|
+
- Menü satırlarını biçimlendirme: **bugün mümkün değil.** `navigations`'ın `style` prop'u
|
|
117
|
+
ölüdür (bkz. `component_get('navigations')`).
|
|
121
118
|
|
|
122
119
|
## Mini tarif — menüde aktif satır
|
|
123
120
|
|
|
@@ -147,8 +144,8 @@ bağlantı nesnesi ya da tam yol).
|
|
|
147
144
|
"direction": { "type": "static", "data": "row" } },
|
|
148
145
|
"blocks": [{ "breakpoint": 1024, "size": { "w": 12, "h": 80 }, "position": { "x": 0, "y": 0 } }] }
|
|
149
146
|
|
|
150
|
-
// KÖTÜ — telefonda 49px'lik yan menü: row flex
|
|
151
|
-
//
|
|
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
|
|
152
149
|
// flex anlamının devreye girmemesi.
|
|
153
150
|
```
|
|
154
151
|
|
|
@@ -186,9 +183,9 @@ bunlardan biri olabilir:
|
|
|
186
183
|
|---|---|
|
|
187
184
|
| ~~`heightType` yalnız `auto` \| `fixed`~~ | **28 Ağustos'ta kapandı:** üçüncü değer `fill` (Kural 5b) |
|
|
188
185
|
| ~~Kök kap viewport'a kilitlenmez~~ | **28 Ağustos'ta kapandı:** `fill` verilmiş kök 100vh (Kural 5b) |
|
|
189
|
-
| Flex
|
|
190
|
-
| Kırılıma duyarlı prop yok | `direction`/`gap` masaüstü ve
|
|
191
|
-
|
|
|
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')`) |
|
|
192
189
|
|
|
193
190
|
---
|
|
194
191
|
|
|
@@ -196,7 +193,7 @@ bunlardan biri olabilir:
|
|
|
196
193
|
(`injectPageSchemaIntoSlots`, `getResolvedLayoutViews`), `apps/studio/src/features/page/api/page.mappers.ts`
|
|
197
194
|
(`mapPageLayoutToPreview`), `packages/ng-apps-ui/src/shared/render/render.functions.ts`
|
|
198
195
|
(`resolveNodeBoxStyle` — slot'un `y / auto` satırı, flex çocuk genişliği),
|
|
199
|
-
`packages/ng-apps-ui/src/shared/render/RenderComponent.svelte` (
|
|
196
|
+
`packages/ng-apps-ui/src/shared/render/RenderComponent.svelte` (dar ekran media kuralı),
|
|
200
197
|
`packages/ng-apps-screen-builder/src/flex-layout.ts` (`getFlexChildStyle` — `widthType`
|
|
201
198
|
fill/fixed/auto dalları, `normalizeCssSize` kabul kuralı; tuval ve runtime aynı fonksiyonu okur),
|
|
202
199
|
`apps/studio/src/features/page/components/appearance/appearance-size.functions.ts` (panelin
|