@appaflytech/zeyrek-ai-mcp 0.0.30 → 0.0.32
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 +0 -15
- package/README.md +5 -5
- package/dist/config.js +0 -37
- package/dist/index.js +0 -2
- package/dist/knowledge/backendConstraints.js +1 -18
- package/dist/knowledge/boxSections.js +184 -0
- package/dist/knowledge/componentCatalog.js +232 -562
- package/dist/knowledge/componentEvents.js +21 -141
- package/dist/knowledge/layoutSummary.js +2 -140
- package/dist/knowledge/normalize.js +67 -236
- package/dist/knowledge/outlines.js +0 -36
- package/dist/knowledge/policy.js +4 -18
- package/dist/knowledge/reservedTables.js +0 -79
- package/dist/knowledge/rules.js +21 -319
- package/dist/knowledge/schemaGuard.js +0 -11
- package/dist/knowledge/styleResolve.js +38 -55
- package/dist/knowledge/themeResolve.js +3 -3
- package/dist/observability/trace.js +3 -6
- package/dist/platform/diagnostics.js +4 -10
- package/dist/platform/domSummary.js +1 -1
- package/dist/platform/errors.js +10 -162
- package/dist/platform/http.js +8 -29
- package/dist/platform/responses.js +5 -39
- package/dist/platform/{capture/capture.js → screenshot.js} +519 -105
- package/dist/platform/secrets.js +1 -17
- package/dist/platform/strictArguments.js +12 -68
- package/dist/platform/tokenVault.js +4 -187
- package/dist/resources/examples/layout-app-shell.json +707 -229
- package/dist/resources/examples/page-detail-profile.json +1 -2
- package/dist/resources/examples/page-dynamic-form.json +2 -3
- package/dist/resources/examples/page-flex-sections.json +1 -1
- package/dist/resources/examples/page-html-embed.json +1 -1
- package/dist/resources/examples/workflow-basic.json +2 -8
- package/dist/resources/guides/component.md +4 -91
- package/dist/resources/guides/entity.md +8 -50
- package/dist/resources/guides/expressions.md +5 -14
- package/dist/resources/guides/functions.md +1 -1
- package/dist/resources/guides/getting-started.md +1 -38
- package/dist/resources/guides/layout.md +58 -55
- package/dist/resources/guides/microservice.md +2 -81
- package/dist/resources/guides/middleware.md +2 -44
- package/dist/resources/guides/page.md +75 -454
- package/dist/resources/guides/theme.md +2 -8
- package/dist/resources/guides/translation.md +1 -1
- package/dist/resources/guides/workflow.md +1 -58
- package/dist/resources/rules.js +5 -11
- package/dist/resources/schema-fingerprint.json +5 -7
- package/dist/resources/schemas/CreateEntityCommand.json +0 -118
- package/dist/resources/schemas/CreateMicroserviceCommand.json +1 -13
- package/dist/resources/schemas/CreateQueryCommand.json +0 -4
- package/dist/resources/schemas/CreateWorkflowCommand.json +1 -143
- package/dist/resources/schemas/DataJobDto.json +1 -6
- package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +1 -21
- package/dist/resources/schemas/MicroserviceDto.json +3 -15
- package/dist/resources/schemas/PreviewMicroserviceCommand.json +1 -10
- package/dist/resources/schemas/PreviewWorkflowCommand.json +1 -22
- package/dist/resources/schemas/StepDto.json +1 -22
- package/dist/resources/schemas/UpdateEntityCommand.json +0 -118
- package/dist/resources/schemas/UpdateMicroserviceCommand.json +1 -13
- package/dist/resources/schemas/UpdateQueryCommand.json +0 -4
- package/dist/resources/schemas/UpdateViewCommand.json +2 -0
- package/dist/resources/schemas/UpdateWorkflowCommand.json +1 -143
- package/dist/server.js +1 -27
- package/dist/tools/access.js +2 -369
- package/dist/tools/applications.js +3 -60
- package/dist/tools/common.js +0 -7
- package/dist/tools/components.js +14 -118
- package/dist/tools/datasources.js +3 -3
- package/dist/tools/dependencies.js +1 -1
- package/dist/tools/deployments.js +2 -2
- package/dist/tools/designSchemaPatch.js +18 -34
- package/dist/tools/dtos.js +5 -36
- package/dist/tools/entities.js +12 -79
- package/dist/tools/externalComponents.js +5 -26
- package/dist/tools/flows.js +14 -122
- package/dist/tools/folders.js +1 -1
- package/dist/tools/imports.js +2 -5
- package/dist/tools/layouts.js +17 -50
- package/dist/tools/merges.js +1 -1
- package/dist/tools/microservices.js +25 -77
- package/dist/tools/pages.js +112 -465
- package/dist/tools/platformInfo.js +8 -27
- package/dist/tools/projects.js +9 -71
- package/dist/tools/rows.js +13 -69
- package/dist/tools/schemaOps.js +1 -61
- package/dist/tools/screenWrite.js +8 -37
- package/dist/tools/screens.js +5 -95
- package/dist/tools/templates.js +1 -26
- package/dist/tools/translations.js +1 -1
- package/dist/tools/variables.js +5 -11
- package/dist/tools/workflows.js +5 -10
- package/package.json +2 -2
- package/dist/knowledge/access.js +0 -802
- package/dist/knowledge/case.js +0 -41
- package/dist/knowledge/connectDataBind.js +0 -819
- package/dist/knowledge/connectDataDefinition.js +0 -341
- package/dist/knowledge/connectDataExecute.js +0 -93
- package/dist/knowledge/connectDataRules.js +0 -128
- package/dist/knowledge/decision.js +0 -121
- package/dist/knowledge/expressionPrelude.js +0 -59
- package/dist/knowledge/microserviceParameters.js +0 -58
- package/dist/knowledge/mining.js +0 -94
- package/dist/knowledge/mobileComponentCatalog.js +0 -859
- package/dist/knowledge/mobileComponentEvents.js +0 -239
- package/dist/knowledge/platform/lint.js +0 -385
- package/dist/knowledge/platform/mobile.js +0 -142
- package/dist/knowledge/platform/mobileLayoutLint.js +0 -324
- package/dist/knowledge/platform/mobileRules.js +0 -231
- package/dist/knowledge/platform/mobileSpacing.js +0 -82
- package/dist/knowledge/platform/mobileTabs.js +0 -108
- package/dist/knowledge/platform/nativeBoxModel.js +0 -44
- package/dist/knowledge/platform/profile.js +0 -25
- package/dist/knowledge/platform/resolve.js +0 -122
- package/dist/knowledge/platform/web.js +0 -39
- package/dist/knowledge/process.js +0 -510
- package/dist/knowledge/rowFilter.js +0 -43
- package/dist/knowledge/styleResolveNative.js +0 -527
- package/dist/platform/argumentAliases.js +0 -128
- package/dist/platform/bodyFile.js +0 -103
- package/dist/platform/capture/actions.js +0 -333
- package/dist/platform/capture/browser.js +0 -1
- package/dist/platform/capture/console-log.js +0 -122
- package/dist/platform/capture/index.js +0 -11
- package/dist/platform/capture/readiness.js +0 -103
- package/dist/platform/capture/summary.js +0 -77
- package/dist/platform/capture/target.js +0 -5
- package/dist/platform/capture/targets/studio-mobile.js +0 -15
- package/dist/platform/capture/targets/studio-web.js +0 -5
- package/dist/platform/impersonation.js +0 -45
- package/dist/platform/jsonArray.js +0 -24
- package/dist/platform/schemaReadMemory.js +0 -60
- package/dist/resources/examples/bpm-gorev-kontrol.json +0 -294
- package/dist/resources/examples/bpm-iso-dokuman.json +0 -228
- package/dist/resources/examples/bpm-satinalma.json +0 -376
- package/dist/resources/examples/connect-data-convert-verify.json +0 -107
- package/dist/resources/examples/connect-data-dropdown-roles.json +0 -66
- package/dist/resources/examples/connect-data-edit-m2m.json +0 -73
- package/dist/resources/examples/connect-data-query-params.json +0 -50
- package/dist/resources/examples/connect-data-table-entity.json +0 -147
- package/dist/resources/examples/connect-data-workflow-microservice.json +0 -65
- package/dist/resources/examples/mobile-app-shell-drawer.json +0 -243
- package/dist/resources/examples/mobile-app-shell-stack.json +0 -157
- package/dist/resources/examples/mobile-app-shell-tab.json +0 -208
- package/dist/resources/examples/mobile-form-screen.json +0 -365
- package/dist/resources/examples/mobile-list-detail-form.json +0 -672
- package/dist/resources/guides/access.md +0 -796
- package/dist/resources/guides/bpm.md +0 -686
- package/dist/resources/guides/case.md +0 -153
- package/dist/resources/guides/decision.md +0 -185
- package/dist/resources/guides/mobile-layout.md +0 -193
- package/dist/resources/guides/mobile.md +0 -495
- package/dist/resources/read.js +0 -41
- package/dist/resources/schemas/AccessExplanationDto.json +0 -144
- package/dist/resources/schemas/AccessMatrixDto.json +0 -170
- package/dist/resources/schemas/AccessPermissionDto.json +0 -57
- package/dist/resources/schemas/AccessPolicyDto.json +0 -223
- package/dist/resources/schemas/AccessResourceDto.json +0 -86
- package/dist/resources/schemas/AppSessionDto.json +0 -53
- package/dist/resources/schemas/ConnectDataDescribeDto.json +0 -344
- package/dist/resources/schemas/ConnectDataRequestModel.json +0 -202
- package/dist/resources/schemas/ConnectDataResultDto.json +0 -421
- package/dist/resources/schemas/ConnectorCredentialDto.json +0 -70
- package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +0 -37
- package/dist/resources/schemas/CreateAccessPolicyCommand.json +0 -209
- package/dist/resources/schemas/CreateDecisionCommand.json +0 -221
- package/dist/resources/schemas/CreateProcessDefinitionCommand.json +0 -1337
- package/dist/resources/schemas/DecisionDto.json +0 -302
- package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +0 -28
- package/dist/resources/schemas/ExplainAccessQuery.json +0 -33
- package/dist/resources/schemas/GenerateProcessDocumentCommand.json +0 -116
- package/dist/resources/schemas/OrganizationProjectDto.json +0 -335
- package/dist/resources/schemas/OrganizationSchemaDto.json +0 -196
- package/dist/resources/schemas/OrganizationSchemaVersionDto.json +0 -207
- package/dist/resources/schemas/PatchProcessDefinitionCommand.json +0 -76
- package/dist/resources/schemas/ProcessDefinitionDto.json +0 -1480
- package/dist/resources/schemas/ProcessSimulationDto.json +0 -96
- package/dist/resources/schemas/SaveConnectorCredentialCommand.json +0 -90
- package/dist/resources/schemas/SaveProcessEventSourceCommand.json +0 -61
- package/dist/resources/schemas/SaveProcessMailSourceCommand.json +0 -89
- package/dist/resources/schemas/SignProcessTaskCommand.json +0 -73
- package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +0 -92
- package/dist/resources/schemas/UpdateAccessPolicyCommand.json +0 -209
- package/dist/resources/schemas/UpdateDecisionCommand.json +0 -216
- package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +0 -1357
- package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +0 -1339
- package/dist/tools/accessOperations.js +0 -135
- package/dist/tools/accessPolicies.js +0 -170
- package/dist/tools/accessRuntime.js +0 -203
- package/dist/tools/bpm.js +0 -343
- package/dist/tools/bpmGovernance.js +0 -266
- package/dist/tools/bpmOperations.js +0 -230
- package/dist/tools/bpmReporting.js +0 -154
- package/dist/tools/bpmRouting.js +0 -150
- package/dist/tools/bpmRuntime.js +0 -396
- package/dist/tools/case.js +0 -178
- package/dist/tools/caseRuntime.js +0 -89
- package/dist/tools/connectData.js +0 -449
- package/dist/tools/connectors.js +0 -193
- package/dist/tools/decisions.js +0 -206
- package/dist/tools/mobile.js +0 -221
- package/dist/tools/modules.js +0 -48
- package/dist/tools/organizationStructure.js +0 -137
- package/dist/tools/profileWrite.js +0 -92
|
@@ -4,10 +4,6 @@ Studio'nun tuval tarafı. Buradaki kurallar controller + komut kodundan doğrula
|
|
|
4
4
|
(`zeyrek-mcp/docs/13-faz2-envanter.md` §4); veri/mantık tarafı için
|
|
5
5
|
`platform_guide('entity')`, `('microservice')`, `('workflow')`.
|
|
6
6
|
|
|
7
|
-
> **Mobil uygulamada** (`type: 'mobile'`) şema ve micro-op'lar aynıdır ama yerleşim yalnız flex'tir
|
|
8
|
-
> (blocks çizilmez), görünüm tipli gruplarla yazılır ve `page_create` kökü flex sütun kurar —
|
|
9
|
-
> `platform_guide('mobile')`. Bu rehberdeki "dar ekran" notları WEB uygulamasının telefon kırılımıdır.
|
|
10
|
-
|
|
11
7
|
## Kuruluş sırası
|
|
12
8
|
|
|
13
9
|
```
|
|
@@ -31,14 +27,8 @@ blokları 1h-3'te).
|
|
|
31
27
|
|
|
32
28
|
## Kural 1 — Komponent gövdesinin şekli (`DesignComponentManagementSchema`)
|
|
33
29
|
|
|
34
|
-
Sayfa şeması **micro-op hattından** kurulur; `page_create
|
|
35
|
-
|
|
36
|
-
gateway geçersiz enum değerini `invalid-enum-value`, olmayan prop'u `unknown-prop`, geçersiz
|
|
37
|
-
`appearance` jetonunu `invalid-appearance` ile **istek gitmeden** reddeder — platformun micro-op
|
|
38
|
-
ucundaki duvarıyla aynı kural kimlikleri. Micro-op hattının hâlâ iki üstünlüğü var: **canlı
|
|
39
|
-
canvas** (SignalR) ve ATOMİK op listesi. Gateway'in tam şema denetimi ÜST DÜZEY prop'lara ve
|
|
40
|
-
`appearance` jetonlarına bakar (platformun duvarı da öyle: `surfaceStyle.contentOverflow` gibi iç
|
|
41
|
-
alanlar denetlenmez); katalog okunamazsa denetim susar ve yazma eskisi gibi geçer.
|
|
30
|
+
Sayfa şeması **micro-op hattından** kurulur; `page_create`'e satır içi `schema` vermek de
|
|
31
|
+
mümkündür ama doğrulama duvarı ve canlı canvas yalnız `page_schema_patch`'te çalışır.
|
|
42
32
|
|
|
43
33
|
```jsonc
|
|
44
34
|
{ "elementId": "page_header_1", "kind": "component", "type": "<component_list slug'ı>",
|
|
@@ -232,7 +222,7 @@ döndürür; hata yok, sayfalama yok. (Bağımsız `pagination` komponenti bu tu
|
|
|
232
222
|
| `dropdown.search` · `multi-select.search` | `{ searchText }` | `self.searchText` |
|
|
233
223
|
| `tabs.tab` | `{ selected }` | `self.selected` ya da `event.data.selected` |
|
|
234
224
|
| `chart.dataPointClick` | `{ name, seriesName, value, dataIndex, row }` | `self.row` (kaynak satırın tamamı) |
|
|
235
|
-
| `repeater.change` · `repeater.select` | `{ selectedIndex }` | `self.selectedIndex` · `self.selectedItem` (akış satır bağlamında koşmaz, `item`/`Row` boş)
|
|
225
|
+
| `repeater.change` · `repeater.select` | `{ selectedIndex }` | `self.selectedIndex` · `self.selectedItem` (akış satır bağlamında koşmaz, `item`/`Row` boş) |
|
|
236
226
|
| `html` aksiyonu (`fireEvent`) | ikinci argüman | **`event.data`** |
|
|
237
227
|
| `kanban.cardMove` | `{ id, row, from, to }` | **`event.data`** (self'e yazılmaz) |
|
|
238
228
|
| `kanban.cardAdd` · `kanban.cardRemove` | `{ column }` · `{ id, row, column }` | **`event.data`** (self'e yazılmaz; kart eklenmez/gizlenmez, akış yazıp `rows`'u tazeler) |
|
|
@@ -255,8 +245,7 @@ dalı bulamaz ve akışı **sessizce durdurur** (`flow-engine.ts:79`); Studio da
|
|
|
255
245
|
`sourceBranch === 'always'` ile çizdiği için panelde **Start kartından sonrası boş görünür**.
|
|
256
246
|
İstisnalar: `condition` → dal adı rule id'sidir (ve o id bir **GUID**'dir — aşağıdaki tuzak 6),
|
|
257
247
|
`confirm` → `yes|no|always`, `microservice` →
|
|
258
|
-
`always` (eski akışlarda `success` de çalışır)
|
|
259
|
-
yerine ondan sürer (2026-09-26, ADR 0004; ayrıntı aşağıdaki §"4xx de hatadır").
|
|
248
|
+
`always` (eski akışlarda `success` de çalışır).
|
|
260
249
|
|
|
261
250
|
**2. `iteratees[].type` yalnız `change` | `fill`.** `setter.ts` başka değerde hiçbir dala
|
|
262
251
|
girmez — adım çalışır, hiçbir şey yapmaz. `change` tek prop'a değer yazar, `fill` diziyi
|
|
@@ -382,42 +371,36 @@ Satır eşlemeli tablo yüklemesinin tam şekli (yükleniyor bayrağı → uç
|
|
|
382
371
|
göstermek error flow'un işidir.
|
|
383
372
|
|
|
384
373
|
> **4xx de hatadır ve `always` dalı seni KURTARMAZ.** `microservice.ts` `.catch` bloğu
|
|
385
|
-
> reddedilen her istekte koşar — 401/403/404/422 dâhil
|
|
386
|
-
>
|
|
387
|
-
> 2026-09-26 — eskiden hata gövdesi `data`'ya yazılıyordu). `.finally` sonra ÜÇ yoldan birini
|
|
388
|
-
> dener, SIRAYLA:
|
|
374
|
+
> reddedilen her istekte koşar — 401/403/404/422 dâhil. Sonrası iki yoldan biridir ve ikisi de
|
|
375
|
+
> "ekranda hiçbir şey olmadı" ile biter:
|
|
389
376
|
>
|
|
390
|
-
> 1. **
|
|
391
|
-
>
|
|
392
|
-
>
|
|
393
|
-
>
|
|
394
|
-
>
|
|
395
|
-
>
|
|
396
|
-
>
|
|
397
|
-
> akış sessizce diğer dala düşer — `else` dalı bağlı değilse akış orada biter. `data`yı bir
|
|
398
|
-
> liste prop'una yazan bir setter artık patlayan bir nesne değil `null` görür (repeater/table
|
|
399
|
-
> `null`'ı boş liste sayar), ama hata OLDUĞUNU fark etmeden geçer — gateway bunu **FLOW-036**
|
|
400
|
-
> ile uyarır.
|
|
377
|
+
> 1. **Hata yolu VARSA** `engine.onError` true döner ve `.finally` `return` eder —
|
|
378
|
+
> `engine.next('always')` **hiç çağrılmaz**. Yani `always` ile `errorSteps` birbirini dışlar;
|
|
379
|
+
> ikisini birden kuramazsın, hata yolu ana akışın devamını devralır.
|
|
380
|
+
> 2. **Hata yolu YOKSA** `always` koşar, ama storage artık `{ error, data }`'dır ve
|
|
381
|
+
> `Steps.<ad>.data` başarı gövdesi değil **hata gövdesidir**. Sıradaki `condition`
|
|
382
|
+
> `!!Steps.signIn.data.token` gibi bir ifadeyi `undefined` üzerinden değerlendirir, sessizce
|
|
383
|
+
> diğer dala düşer ve `else` dalı bağlı değilse akış orada biter.
|
|
401
384
|
>
|
|
402
385
|
> **`errorSteps` yalnız `start` taşıyorsa hata yolu YOKTUR:** `hasErrorFlow`
|
|
403
386
|
> `errorTasks.some(t => t.type !== 'start')` arar. Start'ın ardına en az bir adım bağla —
|
|
404
387
|
> gateway `FLOW-021` ile uyarır.
|
|
405
388
|
>
|
|
406
|
-
> **
|
|
407
|
-
> `
|
|
389
|
+
> **Mobilde `errorSteps` diye bir şey YOK.** `ScreenRuntime.tsx` `mapFlowsToMachine` yalnız
|
|
390
|
+
> `tasks` üretir (web `Runtime.svelte` ayrıca `errorTasks` verir), yani mobil uygulamada
|
|
391
|
+
> `hasErrorFlow` her zaman false: hata yolu hiç koşmaz ve akış yukarıdaki 2. yoldan —
|
|
392
|
+
> `always` + hata gövdeli storage — devam eder. Mobil sayfada hata yolunu `condition
|
|
393
|
+
> Steps.<adımAdı>.error` ile kur.
|
|
408
394
|
|
|
409
|
-
> **Hata metni
|
|
395
|
+
> **Hata metni ÜÇ ayrı yerde durur ve ikisi kullanıcıya gösterilecek metin DEĞİLDİR.**
|
|
410
396
|
> `onError` hata akışını koşturmadan önce `machine.setStorage('error', errorInfo)` yapar
|
|
411
|
-
> (`flow-engine.ts`), yani hata akışının adımları `Steps.error`'ı okuyabilir
|
|
412
|
-
> KENDİ storage'ı ise (bağlı `error` dalı da `always` da) `Steps.<adımAdı>.error` nesnesini taşır:
|
|
397
|
+
> (`flow-engine.ts`), yani hata akışının adımları `Steps.error`'ı okuyabilir:
|
|
413
398
|
>
|
|
414
399
|
> | İfade | Ne taşır | Kaynak |
|
|
415
400
|
> |---|---|---|
|
|
416
|
-
> | **`Steps.error.message`** | **
|
|
417
|
-
> | `Steps.<adımAdı>.error
|
|
418
|
-
> | `Steps.<adımAdı>.
|
|
419
|
-
> | `Steps.<adımAdı>.error.body` | Ucun hata gövdesi — eski `Steps.<adımAdı>.data`'nın taşındığı yer | `microservice.ts` `.catch` |
|
|
420
|
-
> | `Steps.<adımAdı>.data` | **HER ZAMAN `null`**'dır — başarı gövdesi değil, hiçbir gövde değil (eskiden hata gövdesiydi) | `microservice.ts` `.catch` |
|
|
401
|
+
> | **`Steps.error.message`** | **Ucun kendi mesajı** — `err.response.data.message`; boşsa HTTP durum metnine düşer. **Kullanıcıya gösterilecek metin budur.** Yanında `Steps.error.code` · `Steps.error.step.name` (patlayan adım) · `Steps.error.step.data` (ucun gövdesi) gelir | `microservice.ts` `err.reason \|\| HttpStatusText[err.code]` → `flow-engine.ts` `onError` |
|
|
402
|
+
> | `Steps.<adımAdı>.error` | Yalnız HTTP **durum metni** — 401 için `'Unauthorized'`. Hata OLDUĞUNU anlamaya yarar, göstermeye değil | `microservice.ts` `.catch` `HttpStatusText[err.code]` |
|
|
403
|
+
> | `Steps.<adımAdı>.data` | Ucun **hata gövdesi** (`err.response.data`) — başarı gövdesi değil. `.message` alanı burada da vardır | `microservice.ts` `.catch` |
|
|
421
404
|
>
|
|
422
405
|
> **`alert` adımının `message`'ı DÜZ METİNDİR — ifade yazarsan ekranda o ifade görünür.**
|
|
423
406
|
> `alert.ts` `task.argument.message`'ı doğrudan `toast.error()`'a geçirir ve `args` hiçbir yerde
|
|
@@ -445,24 +428,15 @@ göstermek error flow'un işidir.
|
|
|
445
428
|
> `{ "type": "confirm", "args": { "message": "Bu risk ve 4 aksiyonu silinecek.", "title": "Riski sil",
|
|
446
429
|
> "confirmText": "Sil", "cancelText": "Vazgeç" } }`.
|
|
447
430
|
|
|
448
|
-
> **Hangi yolu seçeceksin —
|
|
449
|
-
>
|
|
450
|
-
> olabilir ama aynı anda yalnız biri koşar: **`error` dalı bağlıysa o kazanır**, yoksa
|
|
451
|
-
> `errorSteps`, ikisi de yoksa `always` + `condition`:
|
|
452
|
-
>
|
|
453
|
-
> | | adımın kendi `error` dalı (g-02) | `errorSteps` | ana akışta `condition !!Steps.<adımAdı>.error` |
|
|
454
|
-
> |---|---|---|---|
|
|
455
|
-
> | Kapsam | yalnız BU adımın hatası | akıştaki HERHANGİ bir adımın hatası | yalnız BU adımın hatası |
|
|
456
|
-
> | Ana akışın kalanı | **koşmaz** — bu dal devralır | **koşmaz** — hata akışı devralır | koşar, dalı sen seçersin |
|
|
457
|
-
> | Yükleniyor bayrağı · modal kapatma · tablo tazeleme | dalda **yeniden kurmak zorundasın** | hata akışında **yeniden kurmak zorundasın**; kurmazsan bayrak açık kalır | zaten ana akışta duruyor |
|
|
458
|
-
> | Hata metni | `Steps.<adımAdı>.error.message` | `Steps.error.message` (yukarıdaki tablo) | `Steps.<adımAdı>.error.message`; hata olduğunu `!!Steps.<adımAdı>.error` söyler — `.error.status` parametre ifadesi patladıysa `null`dur, o yolu KAÇIRIR |
|
|
459
|
-
> | Ne zaman doğru | hata anında BU adımın sonrası **tamamen başka bir yola** sapacaksa | hata anında akış **tamamen başka bir yola** sapacaksa (başarısız giriş, yetkisiz sayfa) | kalan adımların çoğu hata hâlinde de koşacaksa — **form gönderimlerinin varsayılanı budur** (Kural 7) |
|
|
431
|
+
> **Hangi yolu seçeceksin — `errorSteps` mi, ana akışta `condition` mı?** İkisi birden
|
|
432
|
+
> kurulamaz (yukarıdaki 1. madde), yani bu bir tercih değil bir karar:
|
|
460
433
|
>
|
|
461
|
-
>
|
|
462
|
-
>
|
|
463
|
-
>
|
|
464
|
-
>
|
|
465
|
-
>
|
|
434
|
+
> | | `errorSteps` | ana akışta `condition Steps.<adımAdı>.error` |
|
|
435
|
+
> |---|---|---|
|
|
436
|
+
> | Ana akışın kalanı | **koşmaz** — hata akışı devralır | koşar, dalı sen seçersin |
|
|
437
|
+
> | Yükleniyor bayrağı · modal kapatma · tablo tazeleme | hata akışında **yeniden kurmak zorundasın**; kurmazsan bayrak açık kalır | zaten ana akışta duruyor |
|
|
438
|
+
> | Hata metni | `Steps.error.message` (yukarıdaki tablo) | `Steps.<adımAdı>.data.message`, hata olduğunu `Steps.<adımAdı>.error` söyler |
|
|
439
|
+
> | Ne zaman doğru | hata anında akış **tamamen başka bir yola** sapacaksa (başarısız giriş, yetkisiz sayfa) | kalan adımların çoğu hata hâlinde de koşacaksa — **form gönderimlerinin varsayılanı budur** (Kural 7) |
|
|
466
440
|
|
|
467
441
|
Zorunlu filtresi olan uçlarda (`patient-*`, `doctor-appointments` gibi `isRequired: true`
|
|
468
442
|
filtreli microservice'ler) parametreyi adımda ver, yoksa uç `MissingParameterException` atar:
|
|
@@ -539,22 +513,21 @@ Tarif: `platform_guide('middleware')`.
|
|
|
539
513
|
|
|
540
514
|
**Sözlükler** (`StepType.cs`, `StepParameterValueType.cs` — hepsi küçük harf):
|
|
541
515
|
`start · microservice · setter · setcookie · validation · condition · redirect · alert ·
|
|
542
|
-
confirm · flow-trigger · storage · navigate · code · download · function ·
|
|
543
|
-
(`bpm` argümanı `value` içinde JSON metnidir — `platform_guide('bpm')` §Yürütme ve kutu)
|
|
516
|
+
confirm · flow-trigger · storage · navigate · code · download · function · end`
|
|
544
517
|
değer tipleri: `static · page · property · storage · variable · code · item · state`
|
|
545
518
|
|
|
546
519
|
> **Sözlükte olmak KOŞACAĞI anlamına gelmez — koşan tipler barındırıcıdan gelir.** Motor yedi
|
|
547
520
|
> tip register eder, gerisini uygulama ekler. Bir sayfa TEK bir uygulamaya aittir
|
|
548
521
|
> (`Page.ApplicationId`) ve uygulamanın tipi `web` ya da `mobile`'dır (`ApplicationType.cs`), yani
|
|
549
522
|
> sayfanın barındırıcısı bellidir — matris "hangi tip sende çalışır"ı söyler, iki barındırıcıda
|
|
550
|
-
> birden koşmayı değil (web `Runtime.svelte`, mobil
|
|
523
|
+
> birden koşmayı değil (web `Runtime.svelte`, mobil `ScreenRuntime.tsx`):
|
|
551
524
|
>
|
|
552
|
-
> | Adım tipi | Web | Mobil
|
|
525
|
+
> | Adım tipi | Web | Mobil | Nerede register ediliyor |
|
|
553
526
|
> |---|---|---|---|
|
|
554
|
-
> | `start` · `setter` · `code` · `condition` · `microservice` · `validation` · `flow-trigger` · `function`
|
|
555
|
-
> | `alert` · `redirect` · `setcookie` · `storage` | ✅ | ✅ |
|
|
556
|
-
> | `confirm` · `download`
|
|
557
|
-
> | `navigate` | ❌ | ✅
|
|
527
|
+
> | `start` · `setter` · `code` · `condition` · `microservice` · `validation` · `flow-trigger` · `function` | ✅ | ✅ | `flow-engine.ts` — motorun kendisi (`function` mobilde kayıtlıdır ama mobil runtime `Functions`'ı boş kurar — K11, çağrı çalışmaz) |
|
|
528
|
+
> | `alert` · `redirect` · `setcookie` · `storage` | ✅ | ✅ | uygulama; mobilde `redirect` navigate, `setcookie` storage uygulamasına eşlenir |
|
|
529
|
+
> | `confirm` · `download` | ✅ | ❌ | yalnız `Runtime.svelte` |
|
|
530
|
+
> | `navigate` | ❌ | ✅ | yalnız `ScreenRuntime.tsx` — web'deki karşılığı `redirect` |
|
|
558
531
|
> | `end` · `query` | ❌ | ❌ | hiçbir yerde — üstelik `query` backend sözlüğünde de yok (`StepType.cs` onu saymaz), yalnız frontend enum'unda duruyor |
|
|
559
532
|
>
|
|
560
533
|
> **Register edilmemiş bir tipe gelen akış SESSİZCE durur.** `flow-engine.ts` `process()`
|
|
@@ -590,19 +563,6 @@ değer tipleri: `static · page · property · storage · variable · code · it
|
|
|
590
563
|
> adımında ve `{{ }}` bağlamasında `Functions.<ad>(…)` ile de çağrılır; gateway bilinmeyen adı ve
|
|
591
564
|
> fazla argümanı FLOW-025 ile uyarır. Tam gövde `ngapps://examples/flow-call-function`, kurallar
|
|
592
565
|
> **`platform_guide('functions')`**.
|
|
593
|
-
>
|
|
594
|
-
> **`share` adımı ("Share")** metin ve bağlantı paylaşır: `args: { title, message, path }`. `title`
|
|
595
|
-
> DÜZ METİNDİR (ifade yazılırsa FLOW-022 uyarır); `message` ve `path` `storage.value` gibi
|
|
596
|
-
> İFADEDİR — düz metin tırnak ister (`"'Şuna bak'"`, `"'https://…/urun/' + Page.queryParams.id"`).
|
|
597
|
-
> Bağlantının adı `url` DEĞİL `path`'tir: backend `Title`/`Message`/`Path` alanlarında saklar ve
|
|
598
|
-
> tanımadığı anahtarı 200 ile sessizce düşürür (FLOW-035 `url`/`link`/`text`'i ve tırnaksız adresi
|
|
599
|
-
> bloklar). Bağlantı ŞEMALI TAM ADRES olmalı (`https://…`, `mailto:…`): şemasız değer (`www.…`,
|
|
600
|
-
> `urun/42`) adres sayılmaz, metnin sonuna eklenir. İfadenin sonucu yalnız dize ya da sayıysa
|
|
601
|
-
> paylaşılır; `false` (`koşul && 'x'`), `null` ve nesne boş sayılır. Cihazda paylaşım sayfası açılır
|
|
602
|
-
> (Android'de bağlantı metnin sonuna eklenir), web'de tarayıcının paylaşım penceresi, yoksa ya da
|
|
603
|
-
> reddederse metin + bağlantı panoya yazılır ve bildirim çıkar. Tek dal `always`: iOS'ta sayfa
|
|
604
|
-
> kapanınca, Android'de seçici açılır açılmaz (RN seçicinin kapanışını bildirmez) sürer; metin de
|
|
605
|
-
> bağlantı da boşsa hiçbir şey açılmaz, akış hemen sürer.
|
|
606
566
|
|
|
607
567
|
> Bir microservice adımı kaydedildiğinde platform `args.microserviceSchema`'yı
|
|
608
568
|
> (parameterScheme + returnScheme + `isReturnArray`) kendisi doldurur — `flow_get` ile geri
|
|
@@ -642,166 +602,6 @@ verilmemiş bir tablo kaynağı vardır ve sayfa göstergesi `NaN / N` olur (öl
|
|
|
642
602
|
> bildirir, ama ham HTTP'de bu kural sana ait.) `add_component`'te ise sarmal ZORUNLUdur — iki
|
|
643
603
|
> op'un şekli birbirinin tersidir, karıştırma.
|
|
644
604
|
|
|
645
|
-
## Kural 1c-3 — Prop'u veri kaynağına BAĞLAMA (`connectData`)
|
|
646
|
-
|
|
647
|
-
Liste, seçenek, grafik serisi ya da ağaç verisi bir TABLODAN geliyorsa akış yazılmaz: prop veri kaynağına bağlanır.
|
|
648
|
-
Değer `{ type: 'connectData', ref: <tanım>, data: <son satırlar> }` olur; runtime satırları
|
|
649
|
-
`POST /connect-data/{uygulama}/{sayfa}/{element}/{prop}` ucundan okur, politika her istekte uygulanır.
|
|
650
|
-
|
|
651
|
-
| İş | Yol |
|
|
652
|
-
|---|---|
|
|
653
|
-
| Tablo/datatable satırları, dropdown/select seçenekleri, grafik serisi, kanban kartları — kaynak tablo, okuyan query, **liste dönen workflow (dönüş DTO'su array) ya da okuyan microservice** olsa da | **Bağla** (bu kural) |
|
|
654
|
-
| Tek kayıt yükleyip forma doldurmak, bir düğmeyle tetiklenen yazma/işlem, çıktısı birden çok bileşene dağıtılan sonuç | **Akış** (Kural 1c) |
|
|
655
|
-
|
|
656
|
-
**Tek çağrı.** `connect_data_bind` bileşenin bağlanabilir prop kaydını ve kaynağın kabiliyetini
|
|
657
|
-
okur, tanımı kurar, bulguları istek gitmeden verir ve tek atomik yamayla yazar:
|
|
658
|
-
|
|
659
|
-
```json
|
|
660
|
-
{ "applicationId": "<app>", "pageId": "<sayfa>", "element": "tbl_musteri", "prop": "rows",
|
|
661
|
-
"source": { "kind": "entity", "id": "<entity id>" },
|
|
662
|
-
"fields": ["ad", "soyad", "tckn", "puan", "sube"], "expand": { "sube": ["ad"] },
|
|
663
|
-
"filterable": ["ad", "tckn", "puan"], "searchable": ["ad", "soyad"], "pageSize": 25 }
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
Layout'taki bileşende `pageId` yerine `layoutId`, widget içindekinde `componentId`. Yanıt `touched`, `newVersion` ve `runtime.propType: 'connectData'` döner. Önce `dryRun: true` ile
|
|
667
|
-
tanımı, op'ları ve bulguları görebilirsiniz. **Var olan bağlantıyı değiştirmek** için aynı prop ve kaynakla
|
|
668
|
-
yalnız değişen parçayı verin (`{ …, pageSize: 50 }`): verilmeyen parçalar kayıtlı tanımdan taşınır, alan
|
|
669
|
-
listesi değişmediyse kolonlar (genişlik, biçim, başlık) yeniden yazılmaz. Kolonların filtre düğmesi (`isFilterable`)
|
|
670
|
-
yalnız `filterable` listesindeki alanlarda açılır. Tam örnekler: `ngapps://examples/connect-data-table-entity`,
|
|
671
|
-
`ngapps://examples/connect-data-dropdown-roles`, `ngapps://examples/connect-data-query-params` (parametreli query +
|
|
672
|
-
`$ad`), `ngapps://examples/connect-data-workflow-microservice`, `ngapps://examples/connect-data-edit-m2m`,
|
|
673
|
-
`ngapps://examples/connect-data-convert-verify` (convert/detach + kullanıcı gözüyle doğrulama). Resource okuyamayan
|
|
674
|
-
istemcide: `platform_guide({ resource: 'ngapps://examples/<ad>' })`.
|
|
675
|
-
|
|
676
|
-
**Keşif sırası.**
|
|
677
|
-
|
|
678
|
-
1. `component_get` → `connectData.props`: hangi prop bağlanır (`rows`, `options`, `series[].data`).
|
|
679
|
-
Kayıt yoksa bileşen bağlanamaz (CD-001).
|
|
680
|
-
2. `connect_data_sources` → kaynak listesi: `entity` · `query` (yalnız okuyan) · `view` · `workflow` · `microservice`.
|
|
681
|
-
Entity dışı kaynak yazmaz. Query, view ve workflow tanımı filtre/sıralama/searchable taşımaz (CD-013); microservice
|
|
682
|
-
yalnız dinamik filtreli tablo ucunda süzer ve parametreli sıralamada sıralar (describe `canFilter`/`sortable`, CD-002).
|
|
683
|
-
Describe `source.pageMode: client` ise sunucu sayfalamaz, runtime ilk 1000 satırı alıp tarayıcıda süzer (CD-007); view
|
|
684
|
-
`textSearch`: arama istekteki `search` ile, aramasız liste boş. `isSchemaSampled`: DTO'suz query ilk satırdan okundu.
|
|
685
|
-
3. `connect_data_describe { source }` → alan başına efektif kabiliyet (`access` · `operators` · `sortable` · `canWrite` ·
|
|
686
|
-
`relation` · `enum`). İşleci ve sıralamayı alan tipinden tahmin etmeyin, buradan okuyun.
|
|
687
|
-
|
|
688
|
-
**İki bağlanma biçimi.**
|
|
689
|
-
|
|
690
|
-
- **Alan listesi (`fieldsFrom`)** — `datatable.rows`, `table.rows`, `repeater.rows`. Kolon listesi (`columns`) bileşenin
|
|
691
|
-
KENDİ kolon şemasından üretilir (metin → `text`, sayı → `number`, boolean → `switch`, ilişki → `relation` yoksa `tag`,
|
|
692
|
-
enum → `tag`); `expand` yolu (`sube.ad`) satıra okunur ama kolon OLMAZ — hedefte gösterilecek alanlar `lookup`'a yazılır.
|
|
693
|
-
Yeniden bağlamada kolonların sırası ve ayarları korunur.
|
|
694
|
-
- **Roller** — dropdown/radio `{ label, value, … }`, grafik `{ category, value, series, … }`. Verilmezse
|
|
695
|
-
yalnız ZORUNLU roller önerilir: `value` ← birincil anahtar, `label` ← görünen alan, diğer zorunlu rol
|
|
696
|
-
türündeki ilk alan. İsteğe bağlı roller (`caption`, `color`, `isDisabled`, `series`…) açıkça verilmedikçe
|
|
697
|
-
boş kalır. Zorunlu rol doldurulamazsa bind aday listesiyle durur; rolü besleyemeyen alan tipi uyarıdır
|
|
698
|
-
(CD-016). Runtime satırları rol adlarına da yazar (`option.label ← ad`). Kaydında `fields` olan bileşende
|
|
699
|
-
(grafik `categoryField`, kanban `titleField`) alan adı o prop'lara aynı yamada yazılır; kanban `columns`
|
|
700
|
-
kolon rolünün enum değerlerinden üretilir (yeniden bağlamada elle girilen `wipLimit` korunur). Grafiğin
|
|
701
|
-
`aggregate`'i yazılmaz — satır başına tekrar eden kategori için elle ayarlayın (CD-015).
|
|
702
|
-
**Role ilişki alanının kendisi** (`category: 'kategori'`, o2m/self) eşlenirse runtime ve kanvas satırda o alanı
|
|
703
|
-
hedefin görünen alanına (`relation.targetDisplay`, datatable hücresindeki metin) çevirir — hem rolde hem alanın
|
|
704
|
-
kendisinde, çünkü `categoryField` satırı alan adıyla okur (39/03 U-3; önce eksen `[object Object]` çiziyordu). Kimlik
|
|
705
|
-
gerekiyorsa alt yolu eşleyin (`value: 'kategori.id'`); m2m dizisi çevrilmez.
|
|
706
|
-
- **Sayfalamayan bileşen bütün sonucu okur** (bileşen tanımında `isPaginated` yok — grafik, dropdown, stat card,
|
|
707
|
-
kanban…; 39/03 U-5): `pageSize` verilmezse tanımın sayfa boyu **1000** (motorun tek okuma tavanı) yazılır, kayıtlı eski
|
|
708
|
-
25 de ezilir. Kaynak 1000'i aşarsa satırlar kesilir ve runtime bunu `runtimeErrors`'a `ConnectDataRowsTruncated` olarak
|
|
709
|
-
yazar; kanvas şeridi "Sayfalamıyor: N satırın M satırını gösterir" der.
|
|
710
|
-
- **Stat Card ana değeri** (39/03 U-13): birincil bağlanabilir prop `rows` (rol `value: number`); kart `valueAggregate`
|
|
711
|
-
(`first` · `count` · `sum` · `avg` · `min` · `max`) özetini basar, `count` kaynağın `meta.total`'ıdır. `sparkline`
|
|
712
|
-
ikincil prop olarak bağlanır. Bağlama `valueAggregate`'i yazmaz — `page_schema_patch set_prop` ile seçin.
|
|
713
|
-
|
|
714
|
-
**Alan kimliği kalıcıdır.** `slug` sayfanın gördüğü ad, `id` fiziksel alan: kaynakta ad değişse de yanıt kayıtlı adla
|
|
715
|
-
gelir, sayfa kırılmaz. Elle yazılan tanımda her alana `id` koyun (`connect_data_bind` kendisi yazar).
|
|
716
|
-
|
|
717
|
-
**Tanımın şekli (kısa).** `version: 1` · `source { kind, id, slug? }` · `fields [{ id, slug, expand? }]` ·
|
|
718
|
-
`filter` (backend Filter ağacı) · `sort [{ field, ascending }]` · `page { mode: 'offset'|'cursor'|'client', limit }` ·
|
|
719
|
-
`language` (`request` · `default` · `xx`) · `mapping { roles, columns? }` ·
|
|
720
|
-
`behavior { filterable, searchable, edit { create, update, delete, bulk, saveMode, editable, defaults, writeMode }, refresh }`.
|
|
721
|
-
Davranış, rol ve sıralama yalnız SEÇİLİ alanlardan olur; `editable` yalnız seçili kök alanlardan (CD-004).
|
|
722
|
-
Tanım filtresinde `"$ad"` yazılan değer istekteki `params.ad`'dan bağlanır. `cursor` (keyset) yalnız entity'de, tek
|
|
723
|
-
sıralama anahtarıyla; sonraki sayfa `page.after` ← `meta.page.nextCursor`.
|
|
724
|
-
|
|
725
|
-
**Politika arayüzü ezer.** Politikanın gizlediği alan yanıtta YOKTUR ve kolonu çizilmez, maskeli alan maskeli gelir —
|
|
726
|
-
ayrıca gizlemeye gerek yok. **Maske önkoşulu:** maske alanın depolama korumasından gelir — alan önce
|
|
727
|
-
`entity_protection_update { field, protection: { mode: 'masked', mask } }` ile korunmalı; korumasız alana politika
|
|
728
|
-
`fieldAccess: 'masked'` verilirse değer DÜZ döner (ACC-017 warn). Maskeli gören özne o alanı SÜZEMEZ (describe
|
|
729
|
-
`canFilter: false`, `operators: []` — koruma varsayılanı maskelidir, yetkili kullanıcı için de; 39/05). Açık (`plain`) gören
|
|
730
|
-
öznede korumalı alanda yalnız `eq` · `neq` · `in` · `notin`,
|
|
731
|
-
sıralama yok; `contains` istek gitmeden durur (CD-002).
|
|
732
|
-
|
|
733
|
-
### İlişki, enum, dosya ve Lookup
|
|
734
|
-
|
|
735
|
-
- İlişki alanı satırda hedef nesnesi olarak gelir: `sube: { id, ad }` (hangi hedef alanların geleceği
|
|
736
|
-
`expand` ile seçilir). `datatable`'da kolon tipi `relation`, hücre görünen alanı basar; m2m ilk üç
|
|
737
|
-
chip + `+N`; kullanıcı hedef tabloyu okuyamıyorsa hücre kilitli `—` (lookup ayarı etkisiz, CD-011 warn).
|
|
738
|
-
- Enum alanı `tag` kolonunda seçeneğin etiketi ve rengiyle çizilir.
|
|
739
|
-
- İlişki alanının seçim listesi aynı motordan gelir: runtime `op: 'lookup'` (hedefin anahtarı, görünen
|
|
740
|
-
alanı ve ilk düz alanları türetilir). Özelleştirmek için alanın `lookup` alt tanımı:
|
|
741
|
-
`{ slug: 'sube', lookup: { fields: [{ slug: 'ad' }, { slug: 'kod' }], behavior: { filterable: ['kod'], searchable: ['ad'] }, sort, page, mode: 'drawer' } }`.
|
|
742
|
-
`lookup` yalnız ilişki alanında olur ve içinde ikinci `lookup` olmaz (CD-011).
|
|
743
|
-
- `datatable`'da ilişki hücresi ve filtre değeri lookup panelinden seçilir (o2m tekil, m2m çoklu) — akış yazılmaz.
|
|
744
|
-
- Dosya alanı (describe `type: 'file'`, `operators: [isnull, isnotnull]`, sıralanmaz) satırda dosya nesnesi olarak gelir:
|
|
745
|
-
`{ id, display_name, path, size, extension, content_type, folder_id, absolute_path, … }`; boş dosya/ilişki alanı `null` ya da satırda hiç yok (runtime `list` anahtarı atar — ikisini de boş sayın; 39/05)
|
|
746
|
-
(38/M-6 backend düzeltmesiyle; eski imaj `{ absolute_path: '', type: 'ref' }` döndürüyordu). Dosya alanı
|
|
747
|
-
`edit.editable`'a KONAMAZ — bağlı bileşen dosyayı satır içinde yazmaz, platform kaydı 422
|
|
748
|
-
`connect-data-editable-file` ile reddeder (CD-018, bind dryRun'da block). Dosyayı `file_upload` + `row_update` yazar.
|
|
749
|
-
|
|
750
|
-
### Yazma (`edit`)
|
|
751
|
-
|
|
752
|
-
- Tanım: `edit { create, update, delete, bulk, saveMode: 'row'|'cell'|'batch', editable: [kök alanlar], defaults, writeMode: 'atomic'|'partial' }`.
|
|
753
|
-
`row` satırı ✓ ile kaydeder; `cell` var olan satırda yalnız çift tıklanan hücreyi açar, ✓/✕ hücrenin içindedir ve
|
|
754
|
-
✓ yalnız o alanı yazar (yeni satır yine bütün olarak kaydedilir); `batch` değişiklikleri taslakta biriktirip birlikte kaydeder.
|
|
755
|
-
Bağlı `datatable`'ın düzenleme prop'larını runtime tanım ∧ politikadan yazar; hücre yalnız `editable` ∧ `canWrite`
|
|
756
|
-
alanda açılır. Kaydetmek için akış YOK: `save` bağlantı uca gider (create → update → delete).
|
|
757
|
-
- Yazmayı önden denemek: `connect_data_execute { applicationId, pageId, element, prop, op: 'update', rows: [{ id, durum: 'pasif' }], asUserId }`
|
|
758
|
-
— bileşenin isteğinin aynısı, GERÇEKTEN yazar; tanımın izin vermediği istek gitmeden durur (CD-012). İlişki alanı
|
|
759
|
-
`'<id>'`, m2m `['<id>', …]` (tam liste); hedefte olmayan kimlik 404 `ConnectDataRelationTargetNotFound` (`field`).
|
|
760
|
-
`atomic` (varsayılan) TEK transaction'dır: `rowIndex` gönderilen dizinin indeksi — HİÇBİR satır yazılmadı.
|
|
761
|
-
`writeMode: 'partial'` (yalnız built-in veritabanı): yazılabilenler yazılır, yanıt `errors[{ row, field, code, message }]`.
|
|
762
|
-
- **Zorunlu alan** (describe `isRequired`) create'te boş/eksik, update'te `null`/boş gönderilirse istek gitmeden kaynağa
|
|
763
|
-
değil motorda düşer: `422 BulkRowFailed`, `field` alanın slug'ı, `rowIndex` satır, iç neden `ConnectDataFieldRequired`
|
|
764
|
-
("Başlık alanı zorunludur."); `partial`'da yalnız o satır `errors[]`'a (39/03 U-8 — önce veritabanının NOT NULL'u
|
|
765
|
-
alan adsız `400 RowValidationFailed` veriyordu). `defaults` create'te eksik alanı doldurur.
|
|
766
|
-
- `defaults` yalnız create'te, istemci değeri ezer. Politikanın vermediği eylem ya da alan etkisizdir (CD-006).
|
|
767
|
-
Anonim sayfada açık yazma oturumsuz ziyaretçiye yazma verir (CD-017). Denetim izinde kaynak `CONNECT_DATA`.
|
|
768
|
-
|
|
769
|
-
**Doğrulama tarifi.** `connect_data_get` (tanım + drift) → `page_screenshot` (satırlar çizildi mi, `runtimeErrors`
|
|
770
|
-
boş mu; bağlama hatası `flowId: 'connect-data'`) → `connect_data_execute { op: 'list' }` (runtime yanıtı;
|
|
771
|
-
`connect_data_preview` Studio ucudur, sayfa kapısını koşmaz). **Kompleks + `enforce` projede** gateway kimliği uygulama
|
|
772
|
-
öznesi değildir: runtime araçları (`connect_data_execute`, `microservice_execute`/`_debug`, `page_runtime_get`,
|
|
773
|
-
`page_screenshot`) kimliksiz 401 `AppSessionRequired` alır. **Parolasız kullanıcı gözü:** aynı çağrıya
|
|
774
|
-
`asUserId: '<users satır id'si>'` — istek gateway kimliği + `impersonated-user-id` başlığıyla gider, özne o kullanıcıdır
|
|
775
|
-
(politika, satır kapsamı, maske); `page_screenshot` sayfanın bütün isteklerine başlığı ekler (Studio "View as user"
|
|
776
|
-
seçicisinin aynısı). Yalnız development/dal: production'da platform başlığı düşürür, gateway isteği göndermez.
|
|
777
|
-
Oturum açılmış üye gerekiyorsa `access_session_create` + `asUser`. **Kaynağın kendi grant'i** (kompleks + `enforce`,
|
|
778
|
-
ölçüldü 39/05): entity kaynağı `entity.read` (+ yazmada `entity.create/update/delete`, ilişki hedefi için hedefin `entity.read`)
|
|
779
|
-
ister; workflow kaynağı `workflow.execute` (`workflow:<id>`), microservice kaynağı `microservice.execute` (`microservice:<id>`)
|
|
780
|
-
ister — yoksa bağlantı 403 `ForbiddenException`. Query kaynağı (ve query kaynaklı uç) kapsamlı tabloya dokunuyorsa her
|
|
781
|
-
kullanıcıda 403 `AccessQueryNotScoped` (ACC-005): kullanıcıya özel liste için entity ya da tablo ucu, özet rapor için sorguyu
|
|
782
|
-
`isUnrestricted` yapın. `connect_data_convert`'in açtığı uç da ayrı `microservice.execute` ister (sayfanın bağlantısı istemez).
|
|
783
|
-
Kullanıcıda `page.view` yoksa sayfa ve bağlantı 403
|
|
784
|
-
döner — politikaya `page:<sayfa>` grant'i ekleyin. `connect_data_bind { asUserId }` CD-006/CD-011 uyarılarını o
|
|
785
|
-
kullanıcının gözüyle üretir (gateway kimliği yöneticidir, bu iki uyarıyı hiç görmez).
|
|
786
|
-
|
|
787
|
-
**Yasaklar.**
|
|
788
|
-
|
|
789
|
-
- Bağlı prop'a `set_binding`, `set_prop_type` ya da `{ type: … }` sarmallı `replace_prop` yazılmaz;
|
|
790
|
-
flow setter bağlı prop'u hedeflemez. Runtime setter'ı atlar ve bileşene hiçbir şey yazılmaz (CD-005).
|
|
791
|
-
Yalnız örnek satırları değiştirmek için `replace_prop { value: [ham satırlar] }`.
|
|
792
|
-
- Bağlantıyı kaldırmak `remove_connect_data { target, path }`: son satırlar static veri olarak kalır.
|
|
793
|
-
- Platformun yönettiği tabloda (organizasyon, rol tabloları) düzenleme açılamaz (CD-003); `users` sistem tablosu
|
|
794
|
-
değildir, `password` alanı kabiliyette hiç yoktur.
|
|
795
|
-
- Kaynaktan silinmiş alan tanımda kalırsa uyarı; `connect_data_bind { fixDrift: true }` her yerden (filtre, expand dahil) düşürür (CD-008).
|
|
796
|
-
- Aynı sayfada aynı kaynağa 5+ bağlantı uyarıdır (CD-010).
|
|
797
|
-
- **Parametreli kaynak** (query/workflow/microservice): `connect_data_describe` `source.parameters` bağlantının doldurabileceği parametreleri verir; `connect_data_bind { params: { yil: 2026, sube: '$secilenSube' } }` sabit değer ya da sayfa değişkeni yazar. Bilinmeyen ad block (CD-013); `$ad` `page_state`'te yoksa warn (CD-014, runtime `null` gönderir). Önizleme `$ad`'ı sayfa durumundan DOLDURMAZ:
|
|
798
|
-
`connect_data_preview { request: { params: { yil: 2026 } } }` verin — verilmezse null bağlanır, sonuç sessizce boş döner — ya da null'da filtresini düşüren workflow'da TÜM satırlar döner (39/05)
|
|
799
|
-
(CD-014 warn, sayfa değişkeninin başlangıç değerini önerir). Entity/view parametre almaz — filtre değerinde `$ad` kullanın.
|
|
800
|
-
- **Microservice'e çevirmek** (`connect_data_convert { …, name, slug }`, yalnız sayfa): tanım microservice'e taşınır, prop `{ version: 1, microserviceId }` olur; flow aynı veriyi `microservice_execute { body: { op: 'list' } }` ile alır. Çevrilmiş prop'u bind reddeder: önce `connect_data_detach` (başka yerde kullanılıyorsa 409).
|
|
801
|
-
|
|
802
|
-
Kuralların tamamı, uygulandığı yer ve kaynağıyla: `ngapps://rules/connect-data` (resource okuyamayan istemcide
|
|
803
|
-
`platform_guide({ resource: 'ngapps://rules/connect-data' })`).
|
|
804
|
-
|
|
805
605
|
## Kural 1c-2 — Komponentin `name`'i JS TANIMLAYICISI olmalı (yoksa sayfadaki tüm ifadeler ölür)
|
|
806
606
|
|
|
807
607
|
Runtime, ifade çalıştırmadan önce sayfadaki **her** komponent için bir değişken üretir:
|
|
@@ -851,10 +651,9 @@ Türkçe başlık `props.title` / `props.text` / `props.label` / `props.pageTitl
|
|
|
851
651
|
`isScrollable: true`, `appearance.heightType: 'auto'`). `container`, `form` ve `repeater` de aynı
|
|
852
652
|
şekilde kapsayıcıdır — onların içine de `parent` vererek eklenir.
|
|
853
653
|
|
|
854
|
-
Sayfa düzeyi olaylar (page load vb.) **bu kapsayıcıya
|
|
855
|
-
|
|
856
|
-
`page_container`
|
|
857
|
-
tasarımcıda hiçbir yerden bulunamaz. `page_container`'ın kendi `isLoading` prop'u vardır — sayfa açılış akışında yükleniyor bayrağı olarak
|
|
654
|
+
Sayfa düzeyi olaylar (page load vb.) **bu kapsayıcıya** bağlanır:
|
|
655
|
+
`set_event { target: 'page_container', event: 'mount', eventValue: <flow id> }`.
|
|
656
|
+
`page_container`'ın kendi `isLoading` prop'u vardır — sayfa açılış akışında yükleniyor bayrağı olarak
|
|
858
657
|
onu kullan. Bir `container` olduğu için **düzen prop'larını da alır**: çocuklarını ızgara yerine
|
|
859
658
|
akışla (ortalama, sağa yaslama, aralık) dizmek istiyorsan `layout: 'flex'` — Kural 1f-2.
|
|
860
659
|
|
|
@@ -897,10 +696,9 @@ gateway **PAGE-011 / LAY-004** ile istek gitmeden reddeder.
|
|
|
897
696
|
|
|
898
697
|
- Bağlama yolu `set_event` DEĞİLDİR (o komponent hedefler): sayfada `page_create` /
|
|
899
698
|
`page_update`'in `events` parametresi, layout'ta `layout_create/update`'in `events`'i.
|
|
900
|
-
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
"ayrılmadan kaydet" uyarısı gibi işler).
|
|
699
|
+
- Sayfa açılış akışı için yerleşik desen `page_container.mount`'tur (Kural 1d) — ikisi de
|
|
700
|
+
çalışır; **`destroy` için tek yol buradaki sayfa olayıdır** (interval temizliği, "ayrılmadan
|
|
701
|
+
kaydet" uyarısı gibi işler).
|
|
904
702
|
- Akış kilidi burada da geçerlidir (Kural 3): önce bütün `flow_create`'ler, sonra events bağı.
|
|
905
703
|
- Mevcut bağları `page_get` gösterir (`events[].value` = flow id).
|
|
906
704
|
|
|
@@ -1056,15 +854,14 @@ kullanır: `page.mappers.ts` `mapPageLayoutToPreview` — layout varsa çizilen
|
|
|
1056
854
|
>
|
|
1057
855
|
> Kural: **`isWrapper` yalnız gerçekten sayfa boyu kaplaması gereken kap içindir**
|
|
1058
856
|
> (`page_container` böyledir ve öyle kalmalı). Sadece "başlık/çerçeve çizilmesin" diye wrapper
|
|
1059
|
-
> yapma —
|
|
1060
|
-
>
|
|
1061
|
-
> `style` ile (`background:'transparent'`, `border:'none'`, `padding:0`). `form`'un eski `hideBorders`/`hidePadding` prop'ları
|
|
857
|
+
> yapma — o iş `container` için de `form` için de `style` ile yapılır (`background:'transparent'`,
|
|
858
|
+
> `border:'none'`, `padding:0`). `form`'un eski `hideBorders`/`hidePadding` prop'ları
|
|
1062
859
|
> 2026-09-09'da şemadan kaldırıldı — bileşen onları hiçbir zaman okumuyordu, no-op'tu. **`states` için micro-op
|
|
1063
860
|
> YOKTUR:** yanlış `isWrapper`'ı düzeltmenin tek yolu düğümü `remove_component` +
|
|
1064
861
|
> `add_component` ile yeniden kurmaktır (sonrasında Kural 2'deki flow yeniden kaydetme adımı
|
|
1065
862
|
> ZORUNLU olur).
|
|
1066
863
|
|
|
1067
|
-
|
|
864
|
+
Mobil not: <768px'te ızgara tek kolona düşer (`RenderComponent` media query'si) — y sırası
|
|
1068
865
|
dikey sıraya dönüşür, x/w yok sayılır. Yerleşimi masaüstü (breakpoint 1024) bloğuyla kur.
|
|
1069
866
|
|
|
1070
867
|
## Kural 1f-2 — Kapsayıcı düzeni: `flex` (varsayılan) ↔ `grid`
|
|
@@ -1082,7 +879,7 @@ aynı prop grubunu o da alır. Grup katalogda tanımlıdır, yani şemadan kurul
|
|
|
1082
879
|
| `horizontalAlign` | **`left`** · `center` · `right` · `stretch` | `row`'da ana eksen (`justify-content`), `column`'da çapraz eksen (`align-items`). |
|
|
1083
880
|
| `verticalAlign` | **`top`** · `middle` · `bottom` · `stretch` | `row`'da çapraz eksen, `column`'da ana eksen (rolleri `horizontalAlign` ile takas). |
|
|
1084
881
|
| `size` | **`shrink`** · `grow` | Çocuklara `flex: 0 1 auto` / `1 1 auto`. |
|
|
1085
|
-
| `gap` | `none` · `small` · **`medium`** · `large` | Preset'ler tema değişkenidir: 0 / `var(--ng-spacing-sm)` / `--ng-spacing-md` / `--ng-spacing-lg` (varsayılan temada 8/16/32px).
|
|
882
|
+
| `gap` | `none` · `small` · **`medium`** · `large` **ya da ham CSS** | Preset'ler tema değişkenidir: 0 / `var(--ng-spacing-sm)` / `--ng-spacing-md` / `--ng-spacing-lg` (varsayılan temada 8/16/32px). Alan `allowCustom`'dır: `"18px"` ya da `"var(--ng-spacing-xl)"` gibi ham değer de geçer. `box-section`/`aibox`'taki sayısal `gapCustom` doluysa preset'i ezer. |
|
|
1086
883
|
| `wrap` | kapalı · **açık** | `flex-wrap`. **Varsayılan 2026-09-01'de açık oldu:** `row` + `w:12` çocuklar artık alt satıra sararak dikey akar. Kapatırsan taşan çocuklar tek satıra sıkışır. |
|
|
1087
884
|
|
|
1088
885
|
**`form` da bu grubun tamamını taşır (2026-09-01):** varsayılanları container ile aynı
|
|
@@ -1153,10 +950,10 @@ Beş şeyi bilmeden flex kurma:
|
|
|
1153
950
|
4. **`layout: 'grid'` iken diğer altı prop ÖLÜDÜR.** Katalogda tanımlı oldukları için
|
|
1154
951
|
doğrulama duvarı susar, renderer da okumaz: ızgara kapsayıcıya `direction: 'column'` yazmak
|
|
1155
952
|
sessizce hiçbir şey yapmaz. Gateway bunu **PAGE-015 (uyarı)** ile söyler.
|
|
1156
|
-
5. **Flex düzeni kırılım BİLMEZ.** `direction`/`gap`/hizalama masaüstü ve
|
|
1157
|
-
sıra ve span'lar Desktop (1024) bloğundandır — Studio,
|
|
953
|
+
5. **Flex düzeni kırılım BİLMEZ.** `direction`/`gap`/hizalama masaüstü ve mobilde AYNIDIR;
|
|
954
|
+
sıra ve span'lar Desktop (1024) bloğundandır — Studio, mobil kırılım düzenlenirken flex
|
|
1158
955
|
bölgeyi salt-okunur kilitler. Kırılım bilen yalnız `blocks[]` ve `appearance.hideOn`'dur;
|
|
1159
|
-
|
|
956
|
+
mobilde farklı davranış gereken satır için `layout: 'grid'` kullan (Kural 1f mobil notu).
|
|
1160
957
|
|
|
1161
958
|
```jsonc
|
|
1162
959
|
// Ortalanmış giriş kartı — style ile CSS hack'i YOK, kabın kendi düzeni
|
|
@@ -1179,7 +976,7 @@ gibi bitişik duracak elemanlar için ÜÇ şart birden gerekir; biri eksikse ar
|
|
|
1179
976
|
|
|
1180
977
|
1. Her çocuğa **`appearance.widthType: 'auto'`** — içerik kadar yer kaplar (`flex: 0 1 auto`).
|
|
1181
978
|
Yazılmazsa eski 12 kolon payı geçerlidir ve çocuk kolonunu doldurur, bitişemez.
|
|
1182
|
-
2. Kaba **`gap: 'none'`** (ham ince değer
|
|
979
|
+
2. Kaba **`gap: 'none'`** (ya da ham ince değer: `"2px"`, `"4px"` — alan `allowCustom`).
|
|
1183
980
|
3. Her çocuğa **`appearance.marginType: 'none'`** — en çok atlanan şart: `marginType`
|
|
1184
981
|
yazılmamış düğüm `normal` sayılır ve her kenara 4px basar (`spacing.ts`
|
|
1185
982
|
`CANVAS_NORMAL_MARGIN`), yani `gap:'none'` olsa bile komşular arasında 8px kalır.
|
|
@@ -1255,9 +1052,8 @@ UYGULAMAZ** — koordinatları aynen kaydeder (aşağı itme yalnız `page_creat
|
|
|
1255
1052
|
> Ölçüm: `radio`, `textarea`, `container`, `form`, `button` **var**; `text` ve `multi-select`
|
|
1256
1053
|
> **yok**. Çözüm: gizlenecek komponenti `isHidden`'ı olan bir `container`'a sar ve koşulu
|
|
1257
1054
|
> sarmalayıcıya bağla (yukarıdaki `box_multi`). Sarmalayıcıyı **`isWrapper:false`** kur
|
|
1258
|
-
> (Kural 1f: wrapper = `min-height:80vh`) ve çerçevesini `
|
|
1259
|
-
> `
|
|
1260
|
-
> `style`'da kalır: `{ '&__body': { padding:'0px' } }`.
|
|
1055
|
+
> (Kural 1f: wrapper = `min-height:80vh`) ve çerçevesini `style` ile kapat:
|
|
1056
|
+
> `{ background:'transparent', border:'none', '&__body': { padding:'0px' } }`.
|
|
1261
1057
|
> `appearance.isHidden` diye bir alan YOKTUR (2026-09-15'te platformdan kaldırıldı, S-16) —
|
|
1262
1058
|
> görünürlük yalnız `props.isHidden`'dır.
|
|
1263
1059
|
|
|
@@ -1284,22 +1080,15 @@ UYGULAMAZ** — koordinatları aynen kaydeder (aşağı itme yalnız `page_creat
|
|
|
1284
1080
|
> SONRAKİ ağaca bakarak. Layout'ta da geçerlidir: kırılma
|
|
1285
1081
|
> `_repeaterValues` geri yazmasındadır, barındıranın sayfa mı layout mu olduğuna bakmaz.
|
|
1286
1082
|
>
|
|
1287
|
-
> **Mobil uygulamada** başlıklar altında gruplu liste (güne/kategoriye göre) iç içe repeater
|
|
1288
|
-
> gerektirmez: tek `grouped-list` (`groupBy` + başlık `{{ Section.title }}` + öğe şablonu) —
|
|
1289
|
-
> `platform_guide('mobile')` §Güne göre görev listesi. PAGE-013 mesajı mobilde bunu önerir.
|
|
1290
|
-
>
|
|
1291
1083
|
> **Yapılacak:** satır içi listeyi tek bir `textarea`'da **satır başına bir öğe** olarak topla
|
|
1292
1084
|
> (`options_text`), kaydederken `split('\n')`'le böl. Ölçülmüş çalışan sürüm: anket editörü
|
|
1293
1085
|
> (`anket-admin/anket-duzenle`). Gerçekten satır satır düzenleme gerekiyorsa iç listeyi AYRI bir
|
|
1294
1086
|
> sayfada/modalda yönet — iç içe repeater bunu karşılamıyor.
|
|
1295
1087
|
|
|
1296
1088
|
> **Repeater satırını akıştan silmek/eklemek:** repeater ÇOCUĞUNDAKİ bir butonun click akışında
|
|
1297
|
-
>
|
|
1298
|
-
>
|
|
1299
|
-
>
|
|
1300
|
-
> `q_list.rows = (q_list.rows || []).filter(function(r, i){ return i !== q_list.selectedIndex; })`.
|
|
1301
|
-
> `RowIndex` de aynı satırı verir, ama yalnız ARC-121 düzeltmesini (2026-09-27) taşıyan runtime'da;
|
|
1302
|
-
> eskisinde akışta tanımsızdı.
|
|
1089
|
+
> `RowIndex` doğru satırı verir, ve hedef repeater'ın KENDİSİ olduğu için `rows`'a yazmak serbesttir
|
|
1090
|
+
> (`isRepeaterSelf` dalı satır-değeri yoluna girmez). Ölçülmüş desen:
|
|
1091
|
+
> `q_list.rows = (q_list.rows || []).filter(function(r, i){ return i !== RowIndex; })`.
|
|
1303
1092
|
> Ekleme aynı şekilde `.slice()` + `push` ile yapılır; satır numarasını ekledikten sonra yeniden ata.
|
|
1304
1093
|
|
|
1305
1094
|
**Gönderimi saklamak:** satır başına normalize kayıt yerine tek `TEXT` kolonda anlık görüntü
|
|
@@ -1308,45 +1097,6 @@ kendisi nesneye çevirir; Studio tablosunda `[object Object]` görünmesi normal
|
|
|
1308
1097
|
(`platform_guide('entity')` → "TEXT kolonunda JSON"). Ekranın görsel tarafı için **Kural 1h**:
|
|
1309
1098
|
tema `--ng-*` değişkenleriyle tek yerden çevrilir, `html` kaçış kapısına gerek kalmaz.
|
|
1310
1099
|
|
|
1311
|
-
## Kural 1g-2 — Mobil davranış: dört ayar, dört ayrı sahip
|
|
1312
|
-
|
|
1313
|
-
Mobil listelerin davranışı TEK bileşende toplanmaz. Hangi ayarın kimde olduğunu bilmeden yazılan
|
|
1314
|
-
şema sessizce çalışmaz — prop var olmayan bileşene yazılır ve `page_schema_patch` onu düşürmez,
|
|
1315
|
-
çizer yok sayar.
|
|
1316
|
-
|
|
1317
|
-
| Davranış | Sahip bileşen | Prop / olay |
|
|
1318
|
-
|---|---|---|
|
|
1319
|
-
| Çekerek yenile | `scroll-view` (listeyi SARAN kap) | `refreshable: true` + `refresh` olayı |
|
|
1320
|
-
| Sonsuz kaydırma | `scroll-view` | `scrollEnd` olayı (prop yok) |
|
|
1321
|
-
| Kaydırma eylemleri | `repeater` | `swipeActions: [{ key, label, tone, icon }]` + `swipe` olayı, payload `{ key, index, row }` |
|
|
1322
|
-
| Satıra dokunma | `repeater` | `itemPressable: true` + `itemPress` olayı, payload `{ index, row }` |
|
|
1323
|
-
|
|
1324
|
-
Çekerek yenileyi `repeater`'a yazmak en sık hatadır: liste kendi kaydırmasını yapmaz, onu saran
|
|
1325
|
-
`scroll-view` yapar. `repeater` kökteyse (kap yok) yenileme hiç çizilmez.
|
|
1326
|
-
|
|
1327
|
-
Satıra dokunmanın kartın `click`'iyle yapılan eski yolu mobilde bırakıldı: `itemPress` satır
|
|
1328
|
-
bağlamını payload'da taşır ve seçimi (`selectedIndex`) de yazar, yani akış satırı
|
|
1329
|
-
`<tekrarlayıcı>.selectedItem` ile okumaya devam eder.
|
|
1330
|
-
|
|
1331
|
-
### `redirect.presentation`
|
|
1332
|
-
|
|
1333
|
-
`redirect` adımının `args.presentation` alanı ekranın NASIL açıldığını söyler ve kapalı bir küme
|
|
1334
|
-
alır:
|
|
1335
|
-
|
|
1336
|
-
- `push` — yığına ekler, geri düğmesi önceki ekrana döner (**varsayılan**; alan yazılmayabilir)
|
|
1337
|
-
- `modal` — alttan açılan ayrı bir sunum; geri onu kapatır, altındaki ekran yerinde kalır
|
|
1338
|
-
- `replace` — geçerli ekranı değiştirir, geçmişe girmez (giriş → ana ekran için doğru olan)
|
|
1339
|
-
|
|
1340
|
-
Küme dışı bir değer **MOB-008** uyarısıdır ve backend doğrulayıcısı 422 döner. Alanı hiç yazmamak
|
|
1341
|
-
kusur değildir.
|
|
1342
|
-
|
|
1343
|
-
**Sekme hedefinde `modal` çalışmaz.** Hedef sayfa bir sekmeyse gezinme her zaman `navigate`'e
|
|
1344
|
-
düşer: sekme yığını kendi geçmişini tutar ve modal onu kırardı. `presentation`ı yazabilirsiniz,
|
|
1345
|
-
çizer sessizce yok sayar — sekme dışı bir sayfaya modal istiyorsanız o sayfayı sekme listesinden
|
|
1346
|
-
çıkarın.
|
|
1347
|
-
|
|
1348
|
-
Web uygulamasında alan yok sayılır; gateway web profilinde bu konuda bulgu üretmez.
|
|
1349
|
-
|
|
1350
1100
|
## Kural 1h — Tasarım: `style` prop'u ve tema değişkenleri
|
|
1351
1101
|
|
|
1352
1102
|
Her komponentin `style` prop'u vardır ve emotion `css()` bloğudur: iç seçiciler, pseudo-class'lar
|
|
@@ -1369,12 +1119,6 @@ yapmanın yolu budur — ölçülmüş kurallar (anket-doldur, 2026-08-19):
|
|
|
1369
1119
|
> düğümleri silip yeniden kurmaya, o da 20 setter'ın sessizce kopmasına yol açtı. Gateway artık
|
|
1370
1120
|
> kebab-case anahtarı camelCase'e çevirir ve `gatewayNormalized` ile bildirir; seçici anahtarlara
|
|
1371
1121
|
> (`&__body`, `:hover`, `--ng-*`) dokunmaz.
|
|
1372
|
-
>
|
|
1373
|
-
> **İSTİSNA — satır içi stil dalları (TB-129).** Kural `style` prop'unun emotion bloğu olan
|
|
1374
|
-
> dalları içindir. `table.style.thead|th|tr|td` ise DOM'un `style` attribute'una string olarak
|
|
1375
|
-
> basılır ve orada **kebab-case zorunludur**; gateway bu dört alanın altına 2026-09-20'den beri
|
|
1376
|
-
> hiç dokunmaz (`INLINE_STYLE_FIELDS_BY_TYPE`). `table.style.root` ve öteki komponentler eskisi
|
|
1377
|
-
> gibi çevrilir. Çeviri bu dalları da camelCase yapınca stil sessizce düşüyordu (S2-39).
|
|
1378
1122
|
|
|
1379
1123
|
**1. Temayı tek yerden çevir: `page_container.style` içinde `--ng-*` değişkenlerini ez.**
|
|
1380
1124
|
Runtime bütün renk/tipografi/form tokenlarını CSS değişkeni olarak basar
|
|
@@ -1534,20 +1278,6 @@ kullanacağını bilmek gereksiz CSS yazmayı önler:
|
|
|
1534
1278
|
| Şema prop'ları | yerleşim (`layout`/`direction`/`gap`/`gridColumns`), semantik renkler, boyut (`size`) | `replace_prop` |
|
|
1535
1279
|
| `style` prop'u | geri kalan her şey; iç seçiciler, pseudo-class, `--ng-*` token ezme | `replace_prop` / `set_binding` |
|
|
1536
1280
|
|
|
1537
|
-
**Kap seçimi — çerçeve tasarımdan gelir, kaptan değil.** `container`'ın tabanı kart yüzeyidir:
|
|
1538
|
-
tema her `container`'a 1px `--ng-border-primary` çerçeve verir. Salt düzen için açılan kaplar
|
|
1539
|
-
(satır, sütun, başlık şeridi, buton grubu, gövde/iki sütun kabuğu) bu yüzden ekranda iç içe
|
|
1540
|
-
çerçeveler olarak görünür — kullanıcı bunu hata olarak bildirdi (qm `qms-dokumanlar`,
|
|
1541
|
-
2026-09-30: başlık şeridi, buton grubu ve içerik sütunu çerçeveli çizildi).
|
|
1542
|
-
|
|
1543
|
-
1. Tasarımda o kutunun **çerçevesi yoksa `box` kullan** — `box`'ın tabanında çerçeve yoktur.
|
|
1544
|
-
2. `container` kullanmak zorundaysan (başlık bandı, `isLoading`, `page_container`, mevcut düğüm)
|
|
1545
|
-
çerçeveyi **`surfaceStyle` ile kapat**, `style`'a ham `border` yazma:
|
|
1546
|
-
`replace_prop { target, prop: 'surfaceStyle', value: { borderTop: 'none', borderRight: 'none', borderBottom: 'none', borderLeft: 'none' } }`.
|
|
1547
|
-
Tek yön kalacaksa (ör. ayraç çizgisi) yalnız o yönü boş bırak. Zemin de istenmiyorsa
|
|
1548
|
-
aynı gruba `background: 'transparent'`.
|
|
1549
|
-
3. Çerçeveyi yalnız tasarımda **gerçekten kart olan** kutu taşır (tablo kartı, özet kartı).
|
|
1550
|
-
|
|
1551
1281
|
**Dikkat — `appearance` kutunun İÇİNİ boyamaz.** Yüzey stili düğüm sarmalayıcısına
|
|
1552
1282
|
(`.ng-app__node-item`) yazılır; `box` gibi kendi zeminini çizen bir komponentin içi bundan
|
|
1553
1283
|
etkilenmez. Tipli stil modeline göçen komponentler bu boşluğu kapatır: `box` (ve emekli
|
|
@@ -1607,16 +1337,6 @@ alanları silinir. Gateway bu yüzden `page_update`'te sayfayı önce okur, yaln
|
|
|
1607
1337
|
alanları değiştirip tam gövdeyi geri yazar (`layout_update` ve `component_update` de aynı).
|
|
1608
1338
|
Yine de `schema` parametresini elle doldurursan okuduğun hâli değil, **verdiğin liste** yazılır.
|
|
1609
1339
|
|
|
1610
|
-
**`page_update` sürümsüz yazmaz (PAGE-043).** Platform sayfa PUT'unu `baseVersion` olmadan reddeder.
|
|
1611
|
-
`baseVersion` vermezsen gateway bu sayfada en son gördüğü sürümü gönderir: `page_get` ya da
|
|
1612
|
-
`page_schema_get` yanıtındaki `version`, `page_schema_patch`'in `newVersion`'ı ya da önceki
|
|
1613
|
-
`page_update`'in yazdığı sürüm. Hiçbiri yoksa istek **gönderilmez** — önce oku. Sayfa o sürümden beri
|
|
1614
|
-
değiştiyse (Studio'da açık sekme, başka ajan) 409 döner; mesaj güncel sürümü ve son yazmayı (zaman,
|
|
1615
|
-
kullanıcı, kaynak, revizyon) söyler ve hiçbir şey yazılmaz. Doğru yol yeniden okuyup değişikliği
|
|
1616
|
-
`page_schema_patch` ile yapmaktır; aradaki değişikliği bilerek ezmek için `force: true` son sürümü
|
|
1617
|
-
okuyup onun üstüne yazar ve yanıt `forced: true` taşır. Sebep: Bitki Bakım koşusunda sürümsüz bir
|
|
1618
|
-
tam gövde yazımı ana sayfayı ve profili boşalttı, akışları sildirdi (14:02).
|
|
1619
|
-
|
|
1620
1340
|
### Atomiklik: 500 KB'lık şemada tek komponente dokunmak
|
|
1621
1341
|
|
|
1622
1342
|
`page_schema_patch` şemanın tamamını göndermez — yalnız op'ları gönderir. Tam gövde ne LLM
|
|
@@ -1626,8 +1346,7 @@ ve geri yazar. Sözleşme (`PatchPageSchemaCommandHandler`):
|
|
|
1626
1346
|
| Aşama | Ne yapar |
|
|
1627
1347
|
|---|---|
|
|
1628
1348
|
| Kilit | Sayfa başına 60 sn'lik dağıtık kilit; başka bir aktör yazıyorsa istek `PageSchemaLockedException` ile döner (409) |
|
|
1629
|
-
| Sürüm | `baseVersion` verdiysen `UpdatedAt.Ticks` ile karşılaştırılır; tutmazsa `PageSchemaVersionConflictException` (409) ve **hiçbir op uygulanmaz**
|
|
1630
|
-
| Tekrar | `add_component`'in `elementId`'si zaten varsa ve düğüm istenen ebeveynde, istenen içerikle duruyorsa op **etkisizdir** (hata değil; konum karşılaştırılmaz). Hedef düğümü değiştirmeyen `replace_prop`/`set_*`/`add_event` da etkisizdir. Bütün op'lar etkisizse yama yazılmaz, sürüm artmaz ve eski `baseVersion`'a rağmen 200 `noop: true` döner; sürüm eskiyse `stale: true` ve `newVersion` sizin gönderdiğinizdir. Aynı id'de farklı düğüm hâlâ 422 `duplicate-id`'dir |
|
|
1349
|
+
| Sürüm | `baseVersion` verdiysen `UpdatedAt.Ticks` ile karşılaştırılır; tutmazsa `PageSchemaVersionConflictException` (409) ve **hiçbir op uygulanmaz** |
|
|
1631
1350
|
| Uygulama | Her op hedefini ağaçta arar (`Find` → JSON Pointer) ve **yalnız o düğüme** dokunur; kardeşler, üst düğümler ve diğer alt ağaçlar bit düzeyinde korunur |
|
|
1632
1351
|
| Hep-ya-hiç | Op'lar önce bellekte uygulanır; **tek bir hata** (bilinmeyen op, bulunamayan hedef, tekrar eden elementId, doğrulama) tüm komutu düşürür — kısmi yazma yoktur |
|
|
1633
1352
|
| Doğrulama | Tam şema `PageSchemaValidator`'dan geçer (422 + alan bazlı `errors`) |
|
|
@@ -1636,18 +1355,7 @@ ve geri yazar. Sözleşme (`PatchPageSchemaCommandHandler`):
|
|
|
1636
1355
|
|
|
1637
1356
|
Yanıt üç alan döner: `applied` (uygulanan op sayısı), **`appliedPatch`** (her op'un şemada tam
|
|
1638
1357
|
olarak hangi JSON Pointer'a ne yaptığı — RFC 6902 biçiminde; "gerçekten yalnız o komponente mi
|
|
1639
|
-
dokunuldu" sorusunun kanıtı) ve **`newVersion`** (`UpdatedAt.Ticks`).
|
|
1640
|
-
(elementId listesi) ve `alreadyApplied` cümlesi gelir; hepsi etkisizse `noop: true`.
|
|
1641
|
-
|
|
1642
|
-
**Yanıt kaybolursa aynı gövdeyle tekrarla.** Ağ koptu, zaman aşımı oldu ve yamanın uygulanıp
|
|
1643
|
-
uygulanmadığını bilmiyorsan aynı `page_schema_patch`'i **aynı gövde ve aynı `baseVersion`** ile
|
|
1644
|
-
yeniden gönder. Uygulanmışsa `noop: true` + `alreadyApplied` döner, hiçbir şey ikinci kez yazılmaz;
|
|
1645
|
-
uygulanmamışsa yama şimdi uygulanır. `add_component` (gövdede `id` verme — platform her istekte yeni
|
|
1646
|
-
`id` üretir, karşılaştırma onu yok sayar), aynı değeri yazan `replace_prop`/`set_*` ve aynı bağı kuran
|
|
1647
|
-
`add_event` tekrarda etkisizdir. İki istisna: `remove_component` ikinci kez `unknown-target` döner — o
|
|
1648
|
-
durumda `page_schema_get` ile bak; eklediğin düğümün bir prop'unu aynı yamanın sonraki op'u
|
|
1649
|
-
değiştirdiyse tekrar `duplicate-id` alır. Yanıt `stale: true` taşıyorsa sayfa sürümünden beri başka bir
|
|
1650
|
-
yazımla da değişmiştir: devam etmeden önce yeniden oku. `idempotencyKey` yoktur ve gerekmez.
|
|
1358
|
+
dokunuldu" sorusunun kanıtı) ve **`newVersion`** (`UpdatedAt.Ticks`).
|
|
1651
1359
|
|
|
1652
1360
|
> **`appliedPatch` gövdesi VARSAYILAN OLARAK iskelettir.** Girdi `{ op, path }` döner; eklenen
|
|
1653
1361
|
> düğüm `component` altında yalnız `id`/`elementId`/`name`/`type`/`children` taşır. Kanıt zaten
|
|
@@ -1667,29 +1375,12 @@ yamanın `baseVersion`'ıdır. Kontrol platformda atomiktir (satır kilidi + sü
|
|
|
1667
1375
|
`UPDATE`'te), yani iki çağrı arasına giren yazarı da yakalar. `baseVersion` vermezsen gateway yalnız
|
|
1668
1376
|
bu çağrıda zaten okuduğu sayfanın sürümünü gönderir; hiç okumadıysa yama sürümsüz gider ve son
|
|
1669
1377
|
yazan kazanır. Eski `expectedUpdatedAt` hâlâ çalışır ama `baseVersion`'ın yerini tutmaz.
|
|
1670
|
-
|
|
1671
|
-
**Studio da sürüm gönderir (2026-09-26, ZM-27).** Önceden Studio'da açık kalan bir sekme, yayını
|
|
1672
|
-
kaçırdığı yamalarının üstüne kendi eski (bir kez boş) şemasını yazıyor ve bağı kalmayan akışları
|
|
1673
|
-
sildiriyordu. Artık Studio'nun her kaydı sürüm taşır: eski sekme 409 alır ve taslağını senin
|
|
1674
|
-
yazdığının üstüne birleştirir. `revision_list`'te yamandan sonra `source: studio` satırı görürsen bu
|
|
1675
|
-
artık bir üzerine yazma değil, birleştirilmiş bir kayıttır — yine de `revision_diff` ile bak.
|
|
1676
1378
|
Yanıttaki `touched`, kaydı değişen elementId'leri listeler (eklenen alt ağaç dâhil).
|
|
1677
1379
|
|
|
1678
1380
|
> **Büyük şemada çalışma sırası:** `mode:'summary'` ile ağacı çıkar (props yok, 500 KB'lık sayfada
|
|
1679
1381
|
> bile küçük) → hedefin `elementId`'sini al → gerekiyorsa `mode:'subtree'` ile yalnız o dalı oku →
|
|
1680
1382
|
> op'ları `page_schema_validate` ile kuru koştur → `page_schema_patch`. `mode:'full'` yalnız
|
|
1681
1383
|
> gerçekten tüm şema gerektiğinde çağrılır.
|
|
1682
|
-
>
|
|
1683
|
-
> **`full` sığmazsa hata verir, kırpmaz.** Yanıt boyut sınırını aşan şemada `mode:'full'` hata döner
|
|
1684
|
-
> ve düğüm sayısını söyler. Tamamı gerekiyorsa `cursor:'0'` ile oku ve `nextCursor` gelmeyene kadar
|
|
1685
|
-
> sür: her parça `items[]` taşır, kalem `parentElementId` düğümünün `children[index]`'inin yerine
|
|
1686
|
-
> geçer (`parentElementId` yoksa kök dizinin `[index]`'i); alt ağacı sığmayan düğüm kabuk gelir
|
|
1687
|
-
> (`children: [{ elementId, deferred: true }]`) ve sonraki kalemler onu doldurur. Toplanan düğüm sayısı
|
|
1688
|
-
> `nodeCount`'a eşit değilse okuma eksiktir. Okuma arasında sayfa değişirse 409 — baştan başla.
|
|
1689
|
-
> `allowTruncated:true` kırpılmış gövdeyi açıkça verir (`truncated: true`); o gövdeye dayanan
|
|
1690
|
-
> `page_schema_patch` PAGE-042 uyarısı taşır. **`page_update`'e kırpık ya da yarım şema gönderme:**
|
|
1691
|
-
> PUT tam REPLACE'tir, eksik düğümler geri dönüşsüz silinir — gateway düğüm eksilten şemayı
|
|
1692
|
-
> `allowNodeLoss:true` olmadan PAGE-041 ile reddeder.
|
|
1693
1384
|
|
|
1694
1385
|
> **`remove_component`'in yan etkisi — tek istisna.** Sayfa kaydedilirken artık hiçbir komponent
|
|
1695
1386
|
> olayının, prop'unun ya da sayfa olayının referans vermediği akışlar platformca **kalıcı olarak
|
|
@@ -1735,24 +1426,19 @@ patch'te bütün `set_event`'ler:
|
|
|
1735
1426
|
```
|
|
1736
1427
|
page_create → page_schema_patch (tüm add_component)
|
|
1737
1428
|
→ TÜM flow_create'ler
|
|
1738
|
-
→ TEK page_schema_patch (bütün set_event'ler)
|
|
1429
|
+
→ TEK page_schema_patch (bütün set_event'ler)
|
|
1739
1430
|
```
|
|
1740
1431
|
|
|
1741
1432
|
Sonradan akış eklemen gerekirse sayfayı baştan kurmana gerek yok — **bağı geçici olarak çöz**:
|
|
1742
1433
|
|
|
1743
1434
|
```jsonc
|
|
1744
|
-
1) page_schema_patch [{ "op":"set_event", "target":"
|
|
1745
|
-
page_update { events: [] } // sayfanın kendi mount/destroy bağları
|
|
1435
|
+
1) page_schema_patch [{ "op":"set_event", "target":"page_container", "event":"mount", "eventValue": null }]
|
|
1746
1436
|
2) flow_create × N
|
|
1747
|
-
3) page_schema_patch [ bütün set_event'ler tek seferde ]
|
|
1437
|
+
3) page_schema_patch [ bütün set_event'ler tek seferde ]
|
|
1748
1438
|
```
|
|
1749
1439
|
|
|
1750
1440
|
`eventValue: null` olay kaydını bırakıp değerini boşaltır ve kilidi açar.
|
|
1751
1441
|
|
|
1752
|
-
> Ölçüm 2026-09-25 (`egitim-portali` › `surecler`, Studio'nun `POST pages/<id>/flows` çağrısı):
|
|
1753
|
-
> sayfada `page_container.mount` ve komponent olayları bağlıyken yeni akış **reddedilmeden**
|
|
1754
|
-
> oluştu. Kilit artık her durumda devrede olmayabilir; yine de sıralı kuruluş güvenli yoldur.
|
|
1755
|
-
|
|
1756
1442
|
> **Aynı kilit LAYOUT'ta da vardır** (ölçüm 2026-08-18: menüye yeni bağlantı eklerken
|
|
1757
1443
|
> `POST /layouts/<id>/flows` aynı hatayı verdi). Layout'ta sıra sayfadakiyle aynıdır ve bağlar
|
|
1758
1444
|
> `layout_schema_patch` ile yazılır: `flow_create × N` → TEK `layout_schema_patch` (bütün
|
|
@@ -1805,9 +1491,7 @@ isimlerine bağlanır.
|
|
|
1805
1491
|
|
|
1806
1492
|
**Platform değişkenleri tek tek değil SET olarak tutar:** uygulama başına bir kayıt, sayfa başına
|
|
1807
1493
|
bir kayıt (`variable_create` `pageId` verirsen sayfa, vermezsen uygulama düzeyi). Kayıt zaten varsa
|
|
1808
|
-
create update'e döner. Şekil `[{ key, value
|
|
1809
|
-
State **bellektedir** — sayfa her açıldığında `value`'dan başlar; `storage: 'device' | 'secure'` yalnız
|
|
1810
|
-
mobil uygulamada değeri cihazda saklar (`platform_guide('mobile')` §Kalıcı state, `MOB-014`):
|
|
1494
|
+
create update'e döner. Şekil `[{ key, value }]`; `value` **herhangi bir JSON** olabilir:
|
|
1811
1495
|
|
|
1812
1496
|
```jsonc
|
|
1813
1497
|
variable_create({ applicationId, pageId, variables: [
|
|
@@ -1819,7 +1503,7 @@ variable_create({ applicationId, pageId, variables: [
|
|
|
1819
1503
|
- Uç seti **komple değiştirir**; gateway mevcut seti okuyup anahtar bazında birleştirir. Kasten
|
|
1820
1504
|
silmek için `replace: true`. `variable_delete` **setin tamamını** siler.
|
|
1821
1505
|
- Platform `data`'yı JSON **string** olarak saklar (`"[{\"key\":…}]"`); gateway çeviriyi iki yönde
|
|
1822
|
-
de yapar — `variable_list` sana `[{key, value
|
|
1506
|
+
de yapar — `variable_list` sana `[{key, value}]` döndürür. Ham HTTP kullanıyorsan string
|
|
1823
1507
|
zorunludur: gövdede yalnız `data` alanı okunur, `name`/`type`/`defaultValue` gibi alanlar
|
|
1824
1508
|
**sessizce yok sayılır** ve kayıt boş yazılır (istek yine 200 döner).
|
|
1825
1509
|
|
|
@@ -1978,8 +1662,7 @@ ya da `set_binding { prop: 'isHidden' }` (Kural 7a'daki `isHidden` notu).
|
|
|
1978
1662
|
|
|
1979
1663
|
**Kip ayrımı query parametresidir:** aynı sayfa `?id=<kayıt>` ile edit, parametresiz create.
|
|
1980
1664
|
|
|
1981
|
-
`mount` akışı (
|
|
1982
|
-
`page_container`'a değil, Kural 1d-2):
|
|
1665
|
+
`mount` akışı (`page_container` ya da `form` üzerine bağlanır):
|
|
1983
1666
|
|
|
1984
1667
|
```
|
|
1985
1668
|
start → [setter] page_container.isLoading = true
|
|
@@ -2141,24 +1824,15 @@ page_container
|
|
|
2141
1824
|
```
|
|
2142
1825
|
start → [setter] btn.isLoading = true, btn.isDisabled = true, notification gizle
|
|
2143
1826
|
→ [microservice] sign-in (POST; email + password body'den)
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
│ → [redirect] hedef sayfaya
|
|
2152
|
-
└─ else → [setter] notification.content =
|
|
2153
|
-
{ type:'code', ref:'Steps.signIn.error?.message ?? "Giriş başarısız"' }
|
|
1827
|
+
→ [condition] !!Steps.signIn.data.token
|
|
1828
|
+
├─ always → [setter] buton durumunu sıfırla
|
|
1829
|
+
├─ if → [setcookie] { name:'APP_Token', value:'Steps.signIn.data.token',
|
|
1830
|
+
│ expiresInHours: 240 }
|
|
1831
|
+
│ → [redirect] hedef sayfaya
|
|
1832
|
+
└─ else → [setter] notification.content =
|
|
1833
|
+
{ type:'code', ref:'Steps.signIn.data.message || "Giriş başarısız"' }
|
|
2154
1834
|
```
|
|
2155
1835
|
|
|
2156
|
-
- **`sign-in` adımının `error` dalı burada ZORUNLUDUR, süs değil.** Dal bağlı değilken bu şablonun
|
|
2157
|
-
`condition`'ı `Steps.signIn.data.token`'ı okur ve gateway'i **FLOW-036** ile uyarır (yukarıdaki
|
|
2158
|
-
"Hangi yolu seçeceksin" notu): hata anında `data` `null`'dur, token okuması sessizce `undefined`
|
|
2159
|
-
döner. Dal bağlanınca hata onun üzerinden sürer — `always`/`condition` yalnız BAŞARIDA çalışır,
|
|
2160
|
-
yani `data.token` orada gerçek bir iş kuralıdır (uç 200 dönüp token'sız yanıt verirse), hata
|
|
2161
|
-
algılama YÖNTEMİ değil.
|
|
2162
1836
|
- **Cookie adı middleware'in okuduğu adla birebir aynı olmalı** (`cookie.APP_Token` —
|
|
2163
1837
|
`platform_guide('middleware')` Tarif 1). Uyuşmazlık sessizce "hep 401" demektir.
|
|
2164
1838
|
- `redirect` adımı `isRaw: true` iken `path` **çok satırlı JS bloğudur** (son ifade değeri döner) —
|
|
@@ -2348,14 +2022,9 @@ hiçbiri** bağlı değildi; üç portalın da rol menüsü boş çıkıyor, pan
|
|
|
2348
2022
|
> (`dto_get` ile bak: genelde `role`, `role_name`, `roles_csv` vardır). Sayfa tarafında CSV
|
|
2349
2023
|
> kullan — ayrıntı ve şablon `platform_guide('expressions')` §2.
|
|
2350
2024
|
>
|
|
2351
|
-
> **Uç hata dönerse `.data`
|
|
2352
|
-
>
|
|
2353
|
-
>
|
|
2354
|
-
> dönünce `data` **null**'dur ve bu adım boş veriyle koşar — `rows` gibi bir listeye bağlarsan
|
|
2355
|
-
> bileşen `null`'ı boş liste sayar, `Array.isArray(...) ? ... : []` sarmalamaya artık gerek yok.
|
|
2356
|
-
> Hata OLDUĞUNU fark etmeden geçmemek için `error` dalı bağlayın (yukarıdaki §"4xx de hatadır",
|
|
2357
|
-
> gateway bunu bağlı değilken **FLOW-036** ile uyarır); hata gövdesini görmek istiyorsan
|
|
2358
|
-
> `Steps.x.error.body`'yi okuyun.
|
|
2025
|
+
> **Uç hata dönerse `.data` dizi değildir.** 401/404 sonrası `Steps.x.data` bir nesnedir ve
|
|
2026
|
+
> `rows || []` bunu yakalamaz (nesne truthy) → `rows.filter is not a function` /
|
|
2027
|
+
> `(items ?? []).map is not a function`. `Array.isArray(Steps.x?.data) ? Steps.x.data : []` yaz.
|
|
2359
2028
|
|
|
2360
2029
|
## ⚠️ `page_schema_patch` `html` komponentini reddediyor — katalogda mükerrer kayıt (2026-08-19)
|
|
2361
2030
|
|
|
@@ -2418,44 +2087,6 @@ micro-op hattına dönün.
|
|
|
2418
2087
|
> uyarı yoktu. Silinmesini bilerek istiyorsanız çağrıyı `allowFlowDeletion: true` ile tekrarlayın;
|
|
2419
2088
|
> yanıt `deletedFlows` ile hangi akışların gittiğini listeler.
|
|
2420
2089
|
>
|
|
2421
|
-
> **Silinen akış geri kurulabilir (2026-09-26, ZM-27).** Sayfa kaydının sildiği akış artık revizyon
|
|
2422
|
-
> defterine `operation: delete` satırı olarak düşer (kaynağı `studio` ya da `mcp`). `flow_restore`
|
|
2423
|
-
> akışı son revizyonundaki ad, slug ve adımlarla AYNI id ile yeniden kurar; olaya bağlamaz —
|
|
2424
|
-
> geri geldikten sonra `set_event`. İki sınır: revizyon saklama süresi (budanan akış 404) ve
|
|
2425
|
-
> adımların hedeflediği komponentler — akış bir komponenti tetikleyen/parametre olarak
|
|
2426
|
-
> gösteriyorsa o komponent şemada durmalıdır (canlı ölçüldü: `flow_restore` "Trigger Element Id"
|
|
2427
|
-
> dış anahtarına çarpar).
|
|
2428
|
-
>
|
|
2429
|
-
> **Boşalan sayfa: `page_restore` (2026-09-26).** Sayfayı ve akışlarını birlikte geri kurar:
|
|
2430
|
-
> `revision_list(module: 'page', recordId: <pageId>)` → boşalmadan önceki revizyonu bul (`source` ve
|
|
2431
|
-
> `correlationId` yardım eder; `revision_get` ile içeriğine bak) → `page_restore({ revisionNo })`.
|
|
2432
|
-
> Platform önce eksik akışları adımsız kurar, sonra şemayı eski komponent id'leriyle yazar, sonra
|
|
2433
|
-
> adımları yazar — akış→komponent ve olay→akış dış anahtarları bu sırayla tek transaction'da çözülür.
|
|
2434
|
-
> Yanıt `restoredFlows` ve `deletedFlows` (N'den sonra bağlanmış, şimdi yetim kalan) döner.
|
|
2435
|
-
> Revizyonu kalmamış bir akış varsa 409 ve hiçbir şey yazılmaz.
|
|
2436
|
-
>
|
|
2437
|
-
> **Doğru revizyonu seç.** Şemayı yüklemeyen komutların (`UpdateProjectCommand`,
|
|
2438
|
-
> `UpdateApplicationCommand`…) yazdığı sayfa revizyonları komponent taşımaz; komponenti olan sayfayı
|
|
2439
|
-
> böyle bir revizyona döndürmek 409 `PageRevisionEmptyException` ile reddedilir (bilerek boşaltmak için
|
|
2440
|
-
> `allowEmpty: true`). `correlationId`'si `PatchPageSchemaCommand` ya da `UpdatePageCommand` olan
|
|
2441
|
-
> revizyonu seç. İki sınır daha: N'den beri silinen layout/rol/middleware/özel komponent ya da başka
|
|
2442
|
-
> sayfanın aldığı slug geri yüklemeyi dış anahtar/benzersizlik hatasıyla düşürür (transaction geri
|
|
2443
|
-
> alınır, veri kaybı yok); yalnız başka bir akışın adımından çağrılan (olaya bağlı olmayan) akışlar
|
|
2444
|
-
> geri kurulmaz — onlar için `flow_restore`.
|
|
2445
|
-
>
|
|
2446
|
-
> **Koruma op listesinin SONUCUNA bakar (TB-125).** İstek atomik olduğu için doğru soru tektir:
|
|
2447
|
-
> yama bittiğinde bu akışa referans kalıyor mu? Aynı yamada akışı başka bir düğüme bağlayıp
|
|
2448
|
-
> eskisini silmek (`add_component` + `set_event` + `remove_component`) artık TEK çağrıda geçer;
|
|
2449
|
-
> 2026-09-20 öncesinde koruma her op'a tek başına baktığı için düğüm taşıyan her yama ikiye
|
|
2450
|
-
> bölünmek zorundaydı (S2-35). Akışı gerçekten referanssız bırakan yama hâlâ durur.
|
|
2451
|
-
>
|
|
2452
|
-
> **Satır aksiyonları statik şemada görünmeyebilir (TB-126).** `table`/`datatable`'ın
|
|
2453
|
-
> `actions[].flow` bağı `{ type: 'flow', ref }` olarak sayılır — ama bu prop'u çoğu zaman YÜKLEME
|
|
2454
|
-
> AKIŞI çalışma zamanında yazar (aksiyon role göre eklenip çıkarılıyorsa başka yolu da yok) ve o
|
|
2455
|
-
> hâlde şemada `actions` BOŞ durur. `flow_list` böyle bir barındırıcıda `unboundFlowIds` yanına
|
|
2456
|
-
> `mayBeBoundAtRuntime: true` koyar: "bağsız akışları temizle" refleksinden önce akışın gerçekten
|
|
2457
|
-
> sahipsiz olduğunu doğrulayın (S2-36).
|
|
2458
|
-
>
|
|
2459
2090
|
> **FLOW-018 artık silinen düğümün ALT AĞACINI da görüyor.** Eskiden yalnız op'un kendi
|
|
2460
2091
|
> `target`'ına bakılıyordu: bir kapsayıcı silinince ÇOCUĞUNA yazan setter sessizce kopuyor ve
|
|
2461
2092
|
> uyarı hiç çıkmıyordu (09-05, `sign_in_form` → `btn_sign_in`).
|
|
@@ -2499,9 +2130,6 @@ micro-op hattına dönün.
|
|
|
2499
2130
|
style + Kural 1h deseniyle yeniden kurulunca kart 400px'e ve ortaya oturdu. Gateway bunu **PAGE-014 (uyarı)** ile
|
|
2500
2131
|
yanıtın `layoutWarnings` alanında bildirir. **Düzeni `style` ile kurmaya hiç kalkışma:**
|
|
2501
2132
|
ortalama/yaslama/aralık işi kapsayıcının kendi `layout: 'flex'` prop grubuna aittir (Kural 1f-2).
|
|
2502
|
-
**İstisna `html`:** onun `style`'ı yazarın işaretlemesine kapsamlı giren CSS metnidir (web'de iç
|
|
2503
|
-
seçicili sınıf, mobilde belgenin stil bloğu) — string asıl biçimdir ve PAGE-014 onda susar. Mobilde
|
|
2504
|
-
`html`'e nesne `style` verme: çizilmez (MOB-002).
|
|
2505
2133
|
- **Menüde "bulunduğun sayfa" vurgusu: `sidebar`/`layout`'ta `activeHref`, `header`'da
|
|
2506
2134
|
`activeNavHref`.** `sidebar` ve `layout` menü ağacını ortak renderer'la çizer: `activeHref` boşken
|
|
2507
2135
|
tarayıcıdaki adrese uyan satırı kendileri vurgular, prop yazılırsa o satır vurgulanır (akıştan
|
|
@@ -2551,13 +2179,6 @@ micro-op hattına dönün.
|
|
|
2551
2179
|
elemanıdır; başlığı da `__header` bloğunu da render etmez (klinik ölçümü: `__header` sayısı 0).
|
|
2552
2180
|
`isWrapper: false` olan ve başlığı açıkça verilen kapta başlık normal çizilir. Kart başlığını garantiye almak istiyorsan kabın
|
|
2553
2181
|
`title`'ına güvenme, **içine bir `text` komponenti** koy.
|
|
2554
|
-
- **`selectedRow`'un ALANLARI sarmalı korur.** `tbl.selectedRow` prop olarak çözülür ama içindeki
|
|
2555
|
-
alanlar `{data, type}` nesneleri olarak kalır: `mapSchemaPropToRawProp` yalnız üst düzey prop'u
|
|
2556
|
-
açar, satırın iç alanlarını açmaz. `tbl.selectedRow.id` bu yüzden bir **nesnedir**, ham değer
|
|
2557
|
-
değil — uca öyle gidince güncelleme hiçbir satırı tutmaz ve sonuç sessizdir (ölçüldü 2026-09-19:
|
|
2558
|
-
`PUT kredi-onayla` → **404**). İfadede `tbl.selectedRow?.id?.data ?? tbl.selectedRow?.id` yazın;
|
|
2559
|
-
aynısı satır eşlemesinden gelen her alan için geçerlidir (S-22).
|
|
2560
|
-
|
|
2561
2182
|
- **Kod prop'unun ifadesi `ref`'te ve `{{ }}` sarılı olmalı.** `{type:'code', ref:"'' + Row.value"}`
|
|
2562
2183
|
(süssüz) ekrana ifadenin **kendisini** basar; ifade yalnız `data`'da olursa prop **boş**
|
|
2563
2184
|
render edilir. `set_binding` micro-op'u eski sürümlerde `data`'ya yazıyordu — bu davranış
|