Low Code Platform Dokümantasyon

This commit is contained in:
Sedat ÖZTÜRK 2026-09-24 10:24:48 +03:00
parent c79cee0df7
commit c102114a3a
11 changed files with 599 additions and 377 deletions

View file

@ -232,12 +232,9 @@ Supported component families:
Runtime UI capabilities: Runtime UI capabilities:
- Per-list layout switching: - Per-list layout switching:
- Grid - Grid, Card, Pivot, Chart — on by default for every generated list screen; turn one off only
- Pivot when the request explicitly excludes it (`lowcode.instructions.md` §9.8)
- Tree - Tree, Gantt, Scheduler, Todo — off by default; opened on request with their required `*Expr` fields
- Chart
- Gantt
- Scheduler
- Per-user layout persistence - Per-user layout persistence
- Lazy loading and view preloading - Lazy loading and view preloading
- Shared dynamic datasource pipeline across layouts - Shared dynamic datasource pipeline across layouts

View file

@ -10,8 +10,10 @@ gelen bütün ekranları** ve bunların yeni bir komponentte nasıl kullanılaca
Bir istek geldiğinde önce ana dosyadaki karar sırasını işlet; "hangi anahtarı yazacağım?" Bir istek geldiğinde önce ana dosyadaki karar sırasını işlet; "hangi anahtarı yazacağım?"
sorusunda buraya bak. sorusunda buraya bak.
**Kaynak:** Buradaki her tablo `api/src/Sozsoft.Platform.Application.Contracts/ListForms/**` ve **Kaynak:** Buradaki her tablo `api/src/Sozsoft.Platform.Application.Contracts/ListForms/**`
`api/src/Sozsoft.Platform.Domain/Entities/Tenant/ListForm/ListForm.cs` dosyalarından çıkarılmıştır. (DTO), `api/src/Sozsoft.Platform.Domain/Entities/Tenant/ListForm/ListForm{,Field}.cs` (entity),
`ui/src/views/{list,form}/**` (alanın gerçekten okunup okunmadığı) ve §12 için
`configs/seeds/host/data/App.Menus.*.json` + `ListFormSeeder_*.cs` dosyalarından çıkarılmıştır.
Çelişki hâlinde **kod esastır**; bu dosya güncellenir. Çelişki hâlinde **kod esastır**; bu dosya güncellenir.
**Ortak kurallar** **Ortak kurallar**
@ -23,11 +25,16 @@ sorusunda buraya bak.
`LookupQuery` gibi gerçekten metin olan alanlar içindir. `LookupQuery` gibi gerçekten metin olan alanlar içindir.
- Varsayılan değeri olan bir alanı tekrar yazmak zorunda değilsin; yalnızca farklı olanı yaz. - Varsayılan değeri olan bir alanı tekrar yazmak zorunda değilsin; yalnızca farklı olanı yaz.
- `Accepted Values` yazan yerlerde değer birebir eşleşmelidir (büyük/küçük harf dahil). - `Accepted Values` yazan yerlerde değer birebir eşleşmelidir (büyük/küçük harf dahil).
- **Bilinmeyen anahtar sessizce düşer — tarayıcıya hiç ulaşmaz.** `GridOptionsDto` bu 47 - **Bilinmeyen anahtar sessizce düşer — tarayıcıya hiç ulaşmaz.** `GridOptionsDto` (ekran) ve
kolonun ham metnini `[JsonIgnore]` ile gizler ve istemciye yalnızca tipli DTO'ya `ColumnFormatDto` (alan) `*Json` kolonlarının ham metnini `[JsonIgnore]` ile gizler ve istemciye
(`SchedulerOptionJson` → `SchedulerOptionDto`) çözülmüş hâlini yollar. Dolayısıyla: yalnızca tipli DTO'ya (`SchedulerOptionJson` → `SchedulerOptionDto`) çözülmüş hâlini yollar.
Dolayısıyla:
- DTO'da olmayan bir DevExtreme seçeneğini `*Json`'a yazmak **işe yaramaz**; kalıcı olarak - DTO'da olmayan bir DevExtreme seçeneğini `*Json`'a yazmak **işe yaramaz**; kalıcı olarak
gerekiyorsa önce ilgili DTO'ya alan eklenir (ve bu dosya güncellenir). gerekiyorsa önce ilgili DTO'ya alan eklenir (ve bu dosya güncellenir).
- Çözme `JsonSerializer`'ın varsayılan ayarlarıyla yapılır: anahtarlar **PascalCase ve
büyük/küçük harfe duyarlıdır**. `"visible"` yazılan yerde `"Visible"` beklenir; küçük harfli
anahtar hata vermez, sessizce düşer. İstemcinin gördüğü camelCase hâl API çıktısıdır, seed'e
yazılmaz.
- Yanlış **tipte** yazılan değer (`"3"` yerine `3`, dizi yerine metin) `JsonSerializer` - Yanlış **tipte** yazılan değer (`"3"` yerine `3`, dizi yerine metin) `JsonSerializer`
tarafında `JsonException` fırlatır ve ekranın metadata isteği tamamen düşer — sessiz tarafında `JsonException` fırlatır ve ekranın metadata isteği tamamen düşer — sessiz
değil, gürültülü bir hatadır. Tipleri tablodaki gibi yaz. değil, gürültülü bir hatadır. Tipleri tablodaki gibi yaz.
@ -51,7 +58,7 @@ ama hiçbirini görmeden bırakma; kullanıcı "şunu da yapabilir miydik?" dedi
| 4 | **Lookup** | Sabit liste mi, sorgu mu, servis mi? Cascade var mı? | `lowcode` §4.3.4 | | 4 | **Lookup** | Sabit liste mi, sorgu mu, servis mi? Cascade var mı? | `lowcode` §4.3.4 |
| 5 | **Varsayılanlar** | Kullanıcı/tarih/tenant/sequence/sorgu ile otomatik dolacak alanlar | `lowcode` §4.3.5 · §9.9 | | 5 | **Varsayılanlar** | Kullanıcı/tarih/tenant/sequence/sorgu ile otomatik dolacak alanlar | `lowcode` §4.3.5 · §9.9 |
| 6 | **Alan davranışı** | Hesap, kopyalama, temizleme, koşullu kilit, uyarı, servis çağrısı | `lowcode` §5 | | 6 | **Alan davranışı** | Hesap, kopyalama, temizleme, koşullu kilit, uyarı, servis çağrısı | `lowcode` §5 |
| 7 | **Editör görünümü** | Maske, ondalık, tarih biçimi, arama, çoklu seçim, görsel yükleme | `lowcode` §6 | | 7 | **Editör görünümü** | Maske, ondalık, tarih biçimi, arama, çoklu seçim, görsel yükleme, kamera/barkod/konum | `lowcode` §6 · §9.8 |
| 8 | **Doğrulama** | Zorunluluk, aralık, desen, karşılaştırma + sunucu tarafı kontrol | `lowcode` §4.3.6 · §4 | | 8 | **Doğrulama** | Zorunluluk, aralık, desen, karşılaştırma + sunucu tarafı kontrol | `lowcode` §4.3.6 · §4 |
| 9 | **Filtre/arama** | Filtre satırı, başlık filtresi, arama paneli, ek filtre çubuğu, grup paneli | §2.6 · `lowcode` §4.3.8 | | 9 | **Filtre/arama** | Filtre satırı, başlık filtresi, arama paneli, ek filtre çubuğu, grup paneli | §2.6 · `lowcode` §4.3.8 |
| 10 | **Özet** | Toplam/adet satırı, grup özetleri, pivot | §9.5 · §6 | | 10 | **Özet** | Toplam/adet satırı, grup özetleri, pivot | §9.5 · §6 |
@ -65,7 +72,7 @@ ama hiçbirini görmeden bırakma; kullanıcı "şunu da yapabilir miydik?" dedi
| 18 | **Otomasyon** | Zamanlanmış iş, zamanlanmış e-posta, bildirim kuralı | `lowcode` §9.10–§9.11 · §11 | | 18 | **Otomasyon** | Zamanlanmış iş, zamanlanmış e-posta, bildirim kuralı | `lowcode` §9.10–§9.11 · §11 |
| 19 | **Çıktı** | Hazır grid raporu ya da rapor şablonu | `lowcode` §9.12 | | 19 | **Çıktı** | Hazır grid raporu ya da rapor şablonu | `lowcode` §9.12 |
| 20 | **Yetki** | Ekran, alan, komut ve buton yetkileri; menü görünürlüğü | §5.1 · `lowcode` §4.2 | | 20 | **Yetki** | Ekran, alan, komut ve buton yetkileri; menü görünürlüğü | §5.1 · `lowcode` §4.2 |
| 21 | **Tenant/şube** | `IsTenant`, `IsBranch`, `IsOrganizationUnit`, sorgularda kırılım | `lowcode` §4.2 | | 21 | **Tenant/şube/satır kısıtı** | `IsTenant`, `IsBranch`, `IsOrganizationUnit`, sorgularda kırılım, rol/kullanıcıya `ServerWhere` | `lowcode` §4.2 · §2.5 |
| 22 | **Dil** | Menü, başlık, alan, buton, mesaj metinleri EN + TR | `lowcode` §4.2 | | 22 | **Dil** | Menü, başlık, alan, buton, mesaj metinleri EN + TR | `lowcode` §4.2 |
| 23 | **Kullanıcı tercihi** | Grid durumunun saklanması, kullanıcı/rol/dil varyantı | §2.5 · §5.7 | | 23 | **Kullanıcı tercihi** | Grid durumunun saklanması, kullanıcı/rol/dil varyantı | §2.5 · §5.7 |
| 24 | **Seed** | Üretilen her artefaktın dosyası + yalnızca DB'de yaşayan kayıtların geri getirici script'i | `lowcode` §0.2 · §9.14 | | 24 | **Seed** | Üretilen her artefaktın dosyası + yalnızca DB'de yaşayan kayıtların geri getirici script'i | `lowcode` §0.2 · §9.14 |
@ -100,10 +107,11 @@ ve çoğu isteğin cevabı aslında oradadır:
| `KeyFieldName` · `KeyFieldDbSourceType` | — · `16` String | Anahtar kolon ve `System.Data.DbType` karşılığı | | `KeyFieldName` · `KeyFieldDbSourceType` | — · `16` String | Anahtar kolon ve `System.Data.DbType` karşılığı |
| `SelectFieldsDefaultValueJson` | — | **Okuma** sorgusuna parametre olarak katılan değerler (`FieldsDefaultValueDto[]`) — `@USERID`, `@TENANTID` gibi | | `SelectFieldsDefaultValueJson` | — | **Okuma** sorgusuna parametre olarak katılan değerler (`FieldsDefaultValueDto[]`) — `@USERID`, `@TENANTID` gibi |
| `DefaultFilter` | — | Her sorgunun sonuna `AND` ile eklenen sabit `WHERE` koşulu. `DefaultValueHelper` üzerinden geçer, yani `@USERID`/`@TENANTID`/`@NOW` gibi token'lar çözülür. Soft delete'li tabloda (`IsDeletedField: true`) wizard buraya `"IsDeleted" = 'false'` yazar | | `DefaultFilter` | — | Her sorgunun sonuna `AND` ile eklenen sabit `WHERE` koşulu. `DefaultValueHelper` üzerinden geçer, yani `@USERID`/`@TENANTID`/`@NOW` gibi token'lar çözülür. Soft delete'li tabloda (`IsDeletedField: true`) wizard buraya `"IsDeleted" = 'false'` yazar |
| `SortMode` | — | `UiGridSortModeEnum`: `1` Single · `2` Multiple · `3` None | | `SortMode` | — | **Metin**: `"single"` \| `"multiple"` \| `"none"` (`PlatformConsts.GridOptions.SortMode*`; wizard `single` yazar) |
| `PageSize` | — | Sayfa başına kayıt; `0` = tümü | | `PageSize` | — | Sayfa başına kayıt; `0` = tümü |
| `Name` · `Title` · `Description` | — | Ekran adı, başlığı, açıklaması — **dil anahtarı** yazılır | | `Name` · `Title` · `Description` | — | Ekran adı, başlığı, açıklaması — **dil anahtarı** yazılır |
| `IsTenant` · `IsBranch` · `IsOrganizationUnit` | `IsMultiTenant` · `false` · `false` | Otomatik kırılım filtresi | | `IsTenant` · `IsBranch` · `IsOrganizationUnit` | `IsMultiTenant` · `false` · `false` | Otomatik kırılım filtresi; `IsTenant` ayrıca bağlantı çözümünü belirler (`lowcode` §9.3.3) |
| `SeedFilePath` · `SeedSyncInsert` · `SeedSyncUpdate` · `SeedSyncDelete` | — · `false` | Ekranın verisini `data/` altındaki dosyaya aynalar; `.json` uzantılı değer tek dosya, uzantısız değer klasör (`lowcode` §9.15) |
| Kolon | Ne yapılandırır | Bölüm | | Kolon | Ne yapılandırır | Bölüm |
| --- | --- | --- | | --- | --- | --- |
@ -127,10 +135,8 @@ ve çoğu isteğin cevabı aslında oradadır:
| `LayoutJson` | Açık görünümler ve varsayılan | §5.4 | | `LayoutJson` | Açık görünümler ve varsayılan | §5.4 |
| `PivotOptionJson` | Pivot görünümü | §6 | | `PivotOptionJson` | Pivot görünümü | §6 |
| `TreeOptionJson` · `GanttOptionJson` · `SchedulerOptionJson` · `TodoOptionJson` | Ağaç/Gantt/Takvim/Kanban eşlemeleri | §7 | | `TreeOptionJson` · `GanttOptionJson` · `SchedulerOptionJson` · `TodoOptionJson` | Ağaç/Gantt/Takvim/Kanban eşlemeleri | §7 |
| `SeriesJson` ve diğer 21 grafik kolonu | Chart görünümü | §8 | | `SeriesJson`, `CommonJson` ve diğer 19 grafik kolonu | Chart görünümü (21 kolon; `DataSourceJson` okunmaz) | §8 |
| `CustomJsSourcesJson` · `CustomStyleSourcesJson` | Sayfaya enjekte edilen JS/CSS | §5.5 | | `CustomJsSourcesJson` · `CustomStyleSourcesJson` | Sayfaya enjekte edilen JS/CSS | §5.5 |
| `AdaptiveLayoutJson` | Dar ekranda öğe gizleme (grafik) | §8.4 |
| `CommonJson` · `DataSourceJson` | Grafik geneli ve grafik sorgusu | §8.2 · §8.3 |
| `Width` · `Height` · `FullHeight` | Ekran boyutu. `Height > 0` sabit piksel yüksekliği verir. Grid/Tree/Gantt/Scheduler'da `FullHeight` bayrağı görünümü `calc(100vh - …)` ile sayfaya yayar; **TodoBoard** bayrağa bakmaz, `Height` verilmediyse panoyu her zaman sayfanın kalan yüksekliğine yayar (kolonlar kendi içinde kayar), alt form olarak açıldığında ise içeriği kadar yer kaplar. | — | | `Width` · `Height` · `FullHeight` | Ekran boyutu. `Height > 0` sabit piksel yüksekliği verir. Grid/Tree/Gantt/Scheduler'da `FullHeight` bayrağı görünümü `calc(100vh - …)` ile sayfaya yayar; **TodoBoard** bayrağa bakmaz, `Height` verilmediyse panoyu her zaman sayfanın kalan yüksekliğine yayar (kolonlar kendi içinde kayar), alt form olarak açıldığında ise içeriği kadar yer kaplar. | — |
| `ListFormType` · `IsSubForm` · `SubFormsListFormType` · `ShowNote` | Ekranın türü ve alt form davranışı | §5.6 | | `ListFormType` · `IsSubForm` · `SubFormsListFormType` · `ShowNote` | Ekranın türü ve alt form davranışı | §5.6 |
| `CultureName` · `UserId` · `RoleId` | Aynı ekranın dil/kullanıcı/rol varyantı | §5.7 | | `CultureName` · `UserId` · `RoleId` | Aynı ekranın dil/kullanıcı/rol varyantı | §5.7 |
@ -206,12 +212,17 @@ Toolbar butonları seçili satırlarla çalışır (`lowcode` §4.9); onay akı
| --- | --- | --- | | --- | --- | --- |
| `Enabled` | `true` | Kullanıcının kolon/filtre/sıralama tercihleri saklansın mı | | `Enabled` | `true` | Kullanıcının kolon/filtre/sıralama tercihleri saklansın mı |
| `Type` | `"custom"` | `custom` (sunucuda kullanıcı bazlı) \| `localStorage` \| `sessionStorage` | | `Type` | `"custom"` | `custom` (sunucuda kullanıcı bazlı) \| `localStorage` \| `sessionStorage` |
| `StorageKey` | — | Anahtar; boşsa ekran kodundan türer | | `StorageKey` | — | Anahtar; boşsa sunucu `listFormGridStorage-{ListFormCode}` üretir |
| `SavingTimeout` | `5000` | Değişiklikten kaç ms sonra yazılacağı — **`[Range(1500, 5000)]`**, dışına çıkan değer doğrulamada reddedilir | | `SavingTimeout` | `5000` | Değişiklikten kaç ms sonra yazılacağı — **`[Range(1500, 5000)]`**, dışına çıkan değer doğrulamada reddedilir |
`Type: "custom"` tercih edilir: tercih sunucuda `ListFormCustomization` kaydı olarak `Type: "custom"` tercih edilir: tercih sunucuda `ListFormCustomization` kaydı olarak
(`ListFormCustomizationTypeEnum.GridState = 2`) kullanıcı bazlı saklanır, bu yüzden başka (`ListFormCustomizationTypeEnum.GridState = 2`) kullanıcı bazlı saklanır, bu yüzden başka
tarayıcıdan girildiğinde de korunur. `localStorage`/`sessionStorage` yalnızca o tarayıcıdadır. tarayıcıdan girildiğinde de korunur. `localStorage`/`sessionStorage` yalnızca o tarayıcıdadır.
Aynı tablonun diğer türleri: `UserUiFilter = 1` (kaydedilmiş filtre, §2.6), `ServerJoin = 3` ve
`ServerWhere = 4` — `UserId`/`RoleId` boşsa herkese, doluysa o rol/kullanıcıya sunucu tarafında
eklenen join ve `WHERE` parçası (`SelectQueryManager`; `ServerWhere` token'ları `DefaultValueHelper`
ile çözülür). **Satır bazlı veri kısıtının** kod yazmadan kurulduğu yer burasıdır; ListForm
editörünün **Kişiselleştirme** sekmesinden yazılır.
### 2.6 Filtre, arama ve gruplama panelleri ### 2.6 Filtre, arama ve gruplama panelleri
@ -255,7 +266,7 @@ metnini biçimlendirmek için — sözlükte tipi yoktur, olduğu gibi bileşene
| `SendOnlyChangedFormValuesUpdate` | `false` | Update'te yalnızca değişen alanları gönder | | `SendOnlyChangedFormValuesUpdate` | `false` | Update'te yalnızca değişen alanları gönder |
| `AddPageUrl` | — | Yeni kayıt popup yerine bu adreste açılır (`window.open`; PWA'da aynı sekme) | | `AddPageUrl` | — | Yeni kayıt popup yerine bu adreste açılır (`window.open`; PWA'da aynı sekme) |
| `AddDialogName` | — | Yeni kayıt kayıtlı bir diyalogda açılır (`CommandColumnDto.DialogName` ile aynı liste). `AddPageUrl` ile birlikte verilirse **diyalog önceliklidir**; diyalog kapanınca liste yenilenir | | `AddDialogName` | — | Yeni kayıt kayıtlı bir diyalogda açılır (`CommandColumnDto.DialogName` ile aynı liste). `AddPageUrl` ile birlikte verilirse **diyalog önceliklidir**; diyalog kapanınca liste yenilenir |
| `AddDialogParameters` | — | `AddDialogName` diyaloguna geçilen sabit parametreler (JSON nesnesi). Toolbar'da satır bağlamı olmadığı için `@Kolon` token'i kullanılmaz | | `AddDialogParameters` | — | `AddDialogName` diyaloguna geçilen sabit parametreler. Tipi **string**'dir: nesne değil, JSON metni yazılır (`"{\"id\":\"\"}"`); istemci `safeJsonParse` ile açar, bozuksa `{}` geçer. Toolbar'da satır bağlamı olmadığı için `@Kolon` token'i kullanılmaz |
| `Popup` | — | Aşağıdaki alt nesne | | `Popup` | — | Aşağıdaki alt nesne |
`Popup` (`GridEditingPopupDto`): `Title`, `ShowTitle` (`true`), `Width` (`700`), `Height` (`500`), `Popup` (`GridEditingPopupDto`): `Title`, `ShowTitle` (`true`), `Width` (`700`), `Height` (`500`),
@ -384,7 +395,7 @@ Ekranın üstündeki KPI şeridi. **Sözleşmesi sezgisel değildir, dikkatle ok
| `Title` · `SubTitle` · `Value` · `Color` · `Icon` · `OnClick` | **Sorgu sonucundaki kolon adları** — sabit metin değil. Sunucu her satırda bu adlı kolonu okur; kolon yoksa boş string döner. `Title`/`SubTitle` kolonunun **değeri** ekranda dil anahtarı olarak çözülür (`WidgetGroup`, `::` öneki eklenerek); karşılığı olmayan metin aynen basılır, bu yüzden sorguya dil anahtarı yazılır | | `Title` · `SubTitle` · `Value` · `Color` · `Icon` · `OnClick` | **Sorgu sonucundaki kolon adları** — sabit metin değil. Sunucu her satırda bu adlı kolonu okur; kolon yoksa boş string döner. `Title`/`SubTitle` kolonunun **değeri** ekranda dil anahtarı olarak çözülür (`WidgetGroup`, `::` öneki eklenerek); karşılığı olmayan metin aynen basılır, bu yüzden sorguya dil anahtarı yazılır |
| `ColSpan` · `ColGap` · `ClassName` | Şeritteki yerleşim (widget başına, karta değil) | | `ColSpan` · `ColGap` · `ClassName` | Şeritteki yerleşim (widget başına, karta değil) |
| `ValueClassName` | Değerin CSS sınıfı, varsayılan `text-3xl` | | `ValueClassName` | Değerin CSS sınıfı, varsayılan `text-3xl` |
| `IsActive` | `false` ise sorgu hiç çalıştırılmaz | | `IsActive` | **Varsayılanı `false`'tur** — yazılmazsa sorgu hiç çalışmaz ve şerit boş kalır; her widget'a `true` yaz |
**Bir widget, sorgunun döndürdüğü her satır için bir kart çizer.** Yani tek bir widget kaydıyla **Bir widget, sorgunun döndürdüğü her satır için bir kart çizer.** Yani tek bir widget kaydıyla
"Bekleyen / Onaylı / Reddedilen" üçlüsü tek sorgudan üretilebilir: "Bekleyen / Onaylı / Reddedilen" üçlüsü tek sorgudan üretilebilir:
@ -400,26 +411,31 @@ SELECT 'Onaylı', COUNT(*), 'green', 'FaCheck' FROM Mrp_T_Order WHERE Status = 2
{ "Title": "Baslik", "Value": "Deger", "Color": "Renk", "Icon": "Ikon", "ColSpan": 4, "IsActive": true } { "Title": "Baslik", "Value": "Deger", "Color": "Renk", "Icon": "Ikon", "ColSpan": 4, "IsActive": true }
``` ```
Sorgu ekranın `DataSourceCode` bağlantısında, **olduğu gibi** çalıştırılır: Sorgu ekranın bağlantısında (`IsTenant` + `DataSourceCode` ile çözülen, `lowcode` §9.3.3),
**olduğu gibi** çalıştırılır:
- Ekranın otomatik tenant/şube/OU filtresi **uygulanmaz**. - Ekranın otomatik tenant/şube/OU filtresi **uygulanmaz**.
- `@USERID` / `@TENANTID` gibi token'lar **çözülmez** — bunlar `*FieldsDefaultValueJson` ve - `@USERID` / `@TENANTID` gibi token'lar **çözülmez** — bunlar `*FieldsDefaultValueJson` ve
`DefaultFilter` yolunun sözleşmesidir. Widget sorgusuna yazılırsa bağlanmamış parametre `DefaultFilter` yolunun sözleşmesidir. Widget sorgusuna yazılırsa bağlanmamış parametre
hatası verir. Kiracı kırılımı gerekiyorsa ya kiracıya özel bir `DataSource` kullan, ya da hatası verir. Kiracı kırılımı gerekiyorsa ya kiracıya özel bir `DataSource` kullan, ya da
kırılımı sorgunun okuduğu view'ın içine göm. kırılımı sorgunun okuduğu view'ın içine göm.
- Soft delete'li tabloda `"IsDeleted" = 'false'` koşulunu sorguya kendin yaz.
### 5.4 `LayoutJson` (`LayoutDto`) ### 5.4 `LayoutJson` (`LayoutDto`)
| Anahtar | Varsayılan | | Anahtar | Varsayılan |
| --- | --- | | --- | --- |
| `Grid` · `Card` · `Pivot` · `Chart` · `Tree` · `Gantt` · `Scheduler` | `true` | | `Grid` · `Card` · `Pivot` · `Chart` | `true` |
| `Todo` | `false` | | `Tree` · `Gantt` · `Scheduler` · `Todo` | `false` |
| `DefaultLayout` | `"grid"` | | `DefaultLayout` | `"grid"` |
Wizard'daki görünüm bayraklarının karşılığıdır. **DTO varsayılanları yanıltıcıdır:** blok Wizard'daki görünüm bayraklarının karşılığıdır. Varsayılan **dörtlüdür**: `Grid`, `Card`, `Pivot`,
yazılmazsa yedi görünüm birden açık gelir; ekranın üstünde çalışmayan görünüm düğmeleri `Chart` her liste ekranında açık gelir; üretilen ekranda bunlardan biri yalnızca istek onu açıkça
çıkmasın diye wizard bu bloğu her zaman açıkça yazar. `DefaultLayout`, `true` olan bir görünümü dışarıda bıraktığında kapatılır (`lowcode` §9.8). Aynı varsayılan üç yerde tutulur ve birlikte
göstermelidir (§7'deki zorunlu `*Expr` alanları boşsa o görünümün JSON'u hiç yazılmaz). değişir: UI wizard başlangıç değerleri (`Wizard.tsx`), `ListFormWizardDto` ve `LayoutDto`
(+ `WizardConsts.DefaultLayoutJson`). Tree/Gantt/Scheduler/Todo zorunlu `*Expr` alanı ister
(§7); bayrak açık olsa bile alanlar boşsa istemci görünümü göstermez (`List.tsx` `isLayoutValid`)
ve seeder o görünümün JSON'unu yazmaz. `DefaultLayout`, `true` olan bir görünümü göstermelidir.
### 5.5 `CustomJsSourcesJson` / `CustomStyleSourcesJson` ### 5.5 `CustomJsSourcesJson` / `CustomStyleSourcesJson`
@ -491,16 +507,19 @@ Pivot ekranı ayrı bir sorgu istemez; ızgarayla aynı `SelectCommand` üzerind
### 7.1 `TreeOptionJson` (`TreeOptionDto`) ### 7.1 `TreeOptionJson` (`TreeOptionDto`)
`KeyExpr`*, `ParentIdExpr`*, `HasItemsExpr`, `RootValue` (varsayılan `null`), `KeyExpr`*, `ParentIdExpr`*, `HasItemsExpr`, `RootValue` (varsayılan `null`; `""` de `null`
`ExpandedRowKeys[]`, `AutoExpandAll` (`false`), `RecursiveSelection` (`false`), sayılır), `ExpandedRowKeys[]`, `AutoExpandAll` (`false`; seeder yardımcısı
`TitleExpr`, `StartExpr`, `EndExpr`, `ProgressExpr`. `DefaultTreeOptionJson` `true` yazar), `RecursiveSelection` (`false`).
DTO'daki `TitleExpr`/`StartExpr`/`EndExpr`/`ProgressExpr` ağaçta okunmaz — Gantt alanlarıdır.
### 7.2 `GanttOptionJson` (`GanttOptionDto`) ### 7.2 `GanttOptionJson` (`GanttOptionDto`)
Ağaç alanlarının tamamı + `TitleExpr`*, `StartExpr`*, `EndExpr`*, `ProgressExpr`, Ağaç alanlarının tamamı + `TitleExpr`*, `StartExpr`*, `EndExpr`*, `ProgressExpr`*
`ScaleType` (varsayılan `weeks`; tam küme `GanttScaleTypeEnum`: `auto` \| `minutes` \| `hours` \| (istemci dördü olmadan görünümü açmaz — `List.tsx` `isLayoutValid`), `ScaleType` (varsayılan
`sixHours` \| `days` \| `weeks` \| `months` \| `quarters` \| `years`) ve izin bayrakları: `weeks`; DevExtreme `GanttScaleType`: `auto` \| `minutes` \| `hours` \| `sixHours` \| `days` \|
`AllowEditing`, `AllowTaskAdding`, `AllowTaskUpdating`, `AllowTaskResourceUpdating`, `weeks` \| `months` \| `quarters` \| `years`; kullanıcının seçtiği ölçek grid durumuyla saklanır)
ve düzenleme bayrakları: **`EditingEnabled`** (ana anahtar — `AllowEditing` diye bir alan yoktur,
yazılırsa düşer), `AllowTaskAdding`, `AllowTaskUpdating`, `AllowTaskResourceUpdating`,
`AllowTaskDeleting`, `AllowDependencyAdding`, `AllowDependencyDeleting`, `AllowResourceAdding`, `AllowTaskDeleting`, `AllowDependencyAdding`, `AllowDependencyDeleting`, `AllowResourceAdding`,
`AllowResourceUpdating`, `AllowResourceDeleting` (hepsi `false`). `AllowResourceUpdating`, `AllowResourceDeleting` (hepsi `false`).
@ -509,7 +528,7 @@ Ağaç alanlarının tamamı + `TitleExpr`*, `StartExpr`*, `EndExpr`*, `Progress
| Anahtar | Varsayılan | Anlam | | Anahtar | Varsayılan | Anlam |
| --- | --- | --- | | --- | --- | --- |
| `TextExpr`* · `StartDateExpr`* · `EndDateExpr`* | — | Başlık ve zaman kolonları | | `TextExpr`* · `StartDateExpr`* · `EndDateExpr`* | — | Başlık ve zaman kolonları |
| `UserNameExpr` · `DescriptionExpr` | — | Kaynak/kişi ve açıklama | | `UserNameExpr` · `DescriptionExpr` | — | Randevu sahibinin kullanıcı adı (kartta avatarı çizilir) ve açıklama |
| `AllDayExpr` | — | Tüm gün bayrağı kolonu | | `AllDayExpr` | — | Tüm gün bayrağı kolonu |
| `RecurrenceRuleExpr` · `RecurrenceExceptionExpr` | — | Tekrar kuralı kolonları | | `RecurrenceRuleExpr` · `RecurrenceExceptionExpr` | — | Tekrar kuralı kolonları |
| `StartDayHour` / `EndDayHour` | `8` / `20` | Görünen saat aralığı | | `StartDayHour` / `EndDayHour` | `8` / `20` | Görünen saat aralığı |
@ -519,11 +538,12 @@ Ağaç alanlarının tamamı + `TitleExpr`*, `StartExpr`*, `EndExpr`*, `Progress
| `FirstDayOfWeek` | `1` | 0 = Pazar | | `FirstDayOfWeek` | `1` | 0 = Pazar |
| `CrossScrollingEnabled` | `false` | Kaynak (resource) görünümünde yatay+dikey kaydırma | | `CrossScrollingEnabled` | `false` | Kaynak (resource) görünümünde yatay+dikey kaydırma |
| `AllowAdding` / `AllowEditing` / `AllowDeleting` / `AllowDragging` / `AllowResizing` | `false` | | | `AllowAdding` / `AllowEditing` / `AllowDeleting` / `AllowDragging` / `AllowResizing` | `false` | |
| `Resources[]` | — | Randevuları renklendiren kaynak eşlemesi (`FieldExpr`, `DataSource[]`, `Label`, `UseColorAsDefault`) |
`Resources` C# `SchedulerOptionDto`'da **tanımlı değildir**; yalnızca UI modelinde (`proxy/form/ > **`Resources[]` bugün çalışmaz.** UI modeli (`proxy/form/models.ts`) ve `SchedulerView`
models.ts`) vardır. Yani seed'den yazılabilir (bilinmeyen anahtar korunur ve bileşene geçer) ama > randevuları renklendiren kaynak eşlemesini (`FieldExpr`, `DataSource[]`, `Label`,
ListForm editöründeki tipli formdan düzenlenemez; kalıcı kullanılacaksa C# DTO'suna eklenmelidir. > `UseColorAsDefault`) okur, ama C# `SchedulerOptionDto`'da alan yoktur — girişteki kural gereği
> sunucu anahtarı düşürür, seed'e yazılan değer istemciye hiç ulaşmaz. Gerekirse önce DTO'ya
> geriye dönük uyumlu alan eklenir.
### 7.4 `TodoOptionJson` (`TodoOptionDto`) — Kanban ### 7.4 `TodoOptionJson` (`TodoOptionDto`) — Kanban
@ -540,9 +560,10 @@ bırakıldığında pano sayfanın kalan yüksekliğini kaplar ve her kolon kend
## 8. Chart (grafik) sözleşmesi ## 8. Chart (grafik) sözleşmesi
Grafik, ListForm üzerindeki **22 ayrı JSON kolonuyla** yapılandırılır. Hepsi DevExtreme Grafik, ListForm üzerindeki **21 JSON kolonuyla** yapılandırılır. Hepsi DevExtreme
`dxChart` yapılandırmasının karşılık gelen bölümüne geçer — ama tipli DTO'dan süzülerek `dxChart` yapılandırmasının karşılık gelen bölümüne geçer — ama tipli DTO'dan süzülerek
(girişteki "bilinmeyen anahtar düşer" kuralı grafik kolonları için de geçerlidir). (girişteki "bilinmeyen anahtar düşer" kuralı grafik kolonları için de geçerlidir). Entity'deki
22. kolon `DataSourceJson` hiçbir yerde okunmaz (§8.2).
Grafik iki yoldan açılır: ekranın `LayoutJson.Chart` bayrağıyla bir görünüm olarak, ya da Grafik iki yoldan açılır: ekranın `LayoutJson.Chart` bayrağıyla bir görünüm olarak, ya da
`ListFormType = "Chart"` ile yalnız grafikten oluşan bir ekran (`/admin/chart/{kod}`) olarak. `ListFormType = "Chart"` ile yalnız grafikten oluşan bir ekran (`/admin/chart/{kod}`) olarak.
@ -550,10 +571,9 @@ Grafik iki yoldan açılır: ekranın `LayoutJson.Chart` bayrağıyla bir görü
| Kolon | Karşılığı | | Kolon | Karşılığı |
| --- | --- | | --- | --- |
| `SeriesJson` | `series[]` — **zorunlu**, §8.1 | | `SeriesJson` | `series[]` — **zorunlu**, §8.1 |
| `DataSourceJson` | Grafiğin kendi sorgusu, §8.2 | | `CommonJson` | Grafik geneli (palet, zemin), §8.3 |
| `CommonJson` | Grafik geneli (palet, tema), §8.3 | | `CommonSeriesSettingsJson` | Tüm serilere ortak ayarlar — `ChartSeriesDto`'nun `Name`/`SummaryType`/`UserId` dışındaki alanları |
| `CommonSeriesSettingsJson` | Tüm serilere ortak ayarlar | | `ArgumentAxisJson` · `ValueAxisJson` (**dizi**) · `CommonAxisSettingsJson` | Eksenler, §8.5 |
| `ArgumentAxisJson` · `ValueAxisJson` · `CommonAxisSettingsJson` | Eksenler, §8.5 |
| `LegendJson` | Açıklama kutusu, §8.6 | | `LegendJson` | Açıklama kutusu, §8.6 |
| `TooltipJson` | İpucu balonu, §8.7 | | `TooltipJson` | İpucu balonu, §8.7 |
| `PanesJson` · `CommonPaneSettingsJson` | Bölmeler (çok panelli grafik) | | `PanesJson` · `CommonPaneSettingsJson` | Bölmeler (çok panelli grafik) |
@ -566,18 +586,18 @@ Grafik iki yoldan açılır: ekranın `LayoutJson.Chart` bayrağıyla bir görü
| `AnimationJson` | Animasyon | | `AnimationJson` | Animasyon |
| `ExportJson` | Dışa aktarma/yazdırma | | `ExportJson` | Dışa aktarma/yazdırma |
Ayrıca grafiğe **kullanıcı/rol kısıtı**: ListForm kaydındaki `UserId` / `RoleId` alanları boşsa Kullanıcı/rol bazlı farklı grafik, ekranın `UserId`/`RoleId` varyantıyla kurulur (§5.7); boşsa
grafik herkese açıktır. grafik herkese aynıdır.
### 8.1 `SeriesJson` (`ChartSeriesDto[]`) ### 8.1 `SeriesJson` (`ChartSeriesDto[]`)
| Anahtar | Varsayılan | Anlam | | Anahtar | Varsayılan | Anlam |
| --- | --- | --- | | --- | --- | --- |
| `Name` | — | Açıklamada görünen seri adı | | `Name` | — | Açıklamada görünen seri adı |
| `Type` | `line` | `line` \| `bar` \| `spline` \| `area` \| `scatter` \| `bubble` \| `stackedbar` \| `fullstackedbar` \| `stackedline` \| `stackedarea` \| `steparea` \| `stepline` \| `rangebar` \| `rangearea` \| `candlestick` \| `stock` ve stacked/fullstacked varyantları | | `Type` | — (DevExtreme: `line`) | `line` \| `stepline` \| `spline` \| `bar` \| `area` \| `splinearea` \| `steparea` \| `scatter` \| `bubble` \| `rangebar` \| `rangearea` \| `candlestick` \| `stock` \| `stackedbar` \| `stackedarea` \| `stackedline` \| `stackedspline` \| `stackedsplinearea` \| `fullstackedbar` \| `fullstackedarea` \| `fullstackedline` \| `fullstackedspline` \| `fullstackedsplinearea` (ListForm editörünün listesi: `chartSeriesTypeOptions`) |
| `ArgumentField` | `"arg"` | X ekseni kolonu | | `ArgumentField` | `"arg"` | X ekseni kolonu — ekranın sorgusundaki bir **alan adı** |
| `ValueField` | — | Y ekseni kolonu | | `ValueField` | — | Y ekseni kolonu |
| `SummaryType` | `"sum"` | `sum` \| `avg` \| `count` \| `min` \| `max` \| `custom` | | `SummaryType` | `"sum"` | `sum` \| `avg` \| `count` \| `min` \| `max` — sunucuda `ArgumentField` kırılımıyla toplanır (§8.2) |
| `Color` | — | Seri rengi | | `Color` | — | Seri rengi |
| `Axis` · `Pane` | — | Hangi eksen/bölme | | `Axis` · `Pane` | — | Hangi eksen/bölme |
| `Visible` | `true` | | | `Visible` | `true` | |
@ -589,17 +609,19 @@ grafik herkese açıktır.
| `SelectionMode` | `"none"` | `onlyPoint` \| `allSeriesPoints` \| `allArgumentPoints` \| `includePoints` \| `excludePoints` \| `none` | | `SelectionMode` | `"none"` | `onlyPoint` \| `allSeriesPoints` \| `allArgumentPoints` \| `includePoints` \| `excludePoints` \| `none` |
| `RangeValue1Field` / `RangeValue2Field` | `val1` / `val2` | Aralık serileri | | `RangeValue1Field` / `RangeValue2Field` | `val1` / `val2` | Aralık serileri |
| `Label` | — | `ChartLabelDto`: `Visible`, `Format`, `Font`, `BackgroundColor`, `CustomizeText` | | `Label` | — | `ChartLabelDto`: `Visible`, `Format`, `Font`, `BackgroundColor`, `CustomizeText` |
| `UserId` | — | Seriyi yalnızca bu kullanıcıya göster | | `UserId` | — | Kullanıcı adı (`UserName`, kimlik değil). O kullanıcının kendi serisi varsa **yalnızca** onun serileri çizilir, yoksa `UserId`'si ne olursa olsun bütün seriler. Kullanıcı grafik çekmecesinden kendi serisini kaydettiğinde bu alan dolar |
### 8.2 `DataSourceJson` (`ChartDataSourceDto`) ### 8.2 Veri — grafik ekranın kendi sorgusundan beslenir
```json Grafik ayrı bir sorgu çalıştırmaz: ekranın `SelectCommand`'ı (ve `DefaultFilter`, kırılım
{ "Query": "SELECT Status AS arg, SUM(Amount) AS val FROM Mrp_T_Order GROUP BY Status" } filtreleri, kullanıcının o anki filtresi) üzerinde, serilerin `ArgumentField` değerleriyle
``` **gruplanmış** ve her serinin `ValueField` + `SummaryType` çiftiyle **özetlenmiş** bir istek atılır
(`useListFormCustomDataSource`, `layoutTypes.chart`). Yani `SELECT … GROUP BY` yazmaya gerek yoktur;
özetlenecek ham satırları döndüren sorgu yeter. Farklı kırılımda ikinci bir grafik gerekiyorsa
ikinci bir ListForm (ya da view) açılır.
Grafik, ızgaranın `SelectCommand`'ından **ayrı** bir sorgu kullanabilir. Sorgu kolonları `DataSourceJson` kolonu ve `ChartDataSourceDto { Query }` / `ChartDataRequestDto` tipleri kodda
`ArgumentField` / `ValueField` adlarıyla eşleşmelidir. Ekranın filtresi grafik isteğine durur ama **okunmaz** — oraya sorgu yazmak grafiği değiştirmez.
`Filter` parametresi olarak taşınır.
### 8.3 `CommonJson` (`ChartCommonDto`) ### 8.3 `CommonJson` (`ChartCommonDto`)
@ -607,7 +629,7 @@ Grafik, ızgaranın `SelectCommand`'ından **ayrı** bir sorgu kullanabilir. Sor
| --- | --- | --- | | --- | --- | --- |
| `Palette` | `"Material"` | `Bright` \| `Harmony Light` \| `Ocean` \| `Pastel` \| `Soft` \| `Soft Pastel` \| `Vintage` \| `Violet` \| `Carmine` \| `Dark Moon` \| `Dark Violet` \| `Green Mist` \| `Soft Blue` \| `Material` \| `Office` | | `Palette` | `"Material"` | `Bright` \| `Harmony Light` \| `Ocean` \| `Pastel` \| `Soft` \| `Soft Pastel` \| `Vintage` \| `Violet` \| `Carmine` \| `Dark Moon` \| `Dark Violet` \| `Green Mist` \| `Soft Blue` \| `Material` \| `Office` |
| `PaletteExtensionMode` | `"blend"` | `alternate` \| `blend` \| `extrapolate` | | `PaletteExtensionMode` | `"blend"` | `alternate` \| `blend` \| `extrapolate` |
| `Theme` | `"generic.light"` | `generic.*` ve `material.*.light` varyantları | | `Theme` | `"generic.light"` | DTO'da durur ama `Chart.tsx` grafiğe geçirmez — tema uygulamanın temasından gelir |
| `ContainerBackgroundColor` | `"#FFFFFF"` | | | `ContainerBackgroundColor` | `"#FFFFFF"` | |
| `AdjustOnZoom` | `true` | | | `AdjustOnZoom` | `true` | |
| `DefaultPane` | — | | | `DefaultPane` | — | |
@ -616,7 +638,7 @@ Grafik, ızgaranın `SelectCommand`'ından **ayrı** bir sorgu kullanabilir. Sor
### 8.4 Boyut ve yerleşim ### 8.4 Boyut ve yerleşim
- `SizeJson` (`ChartSizeDto`): `UseSize` (`false`), `Width` (`400`), `Height` (`200`). - `SizeJson` (`ChartSizeDto`): `UseSize` (`false`), `Width` (`400`), `Height` (`200`).
`UseSize: false` iken grafik kapsayıcıya yayılır. `UseSize: false` iken grafik pencereye yayılır (`Width`/`Height` yok sayılır).
- `MarginJson` (`ChartMarginDto`): `Top`, `Bottom`, `Left`, `Right`. - `MarginJson` (`ChartMarginDto`): `Top`, `Bottom`, `Left`, `Right`.
- `AdaptiveLayoutJson` (`ChartAdaptivelayoutDto`): `Width`/`Height` eşiği (`80`/`80`), - `AdaptiveLayoutJson` (`ChartAdaptivelayoutDto`): `Width`/`Height` eşiği (`80`/`80`),
`KeepLabels` (`true`). `KeepLabels` (`true`).
@ -629,18 +651,23 @@ Grafik, ızgaranın `SelectCommand`'ından **ayrı** bir sorgu kullanabilir. Sor
### 8.5 Eksenler ### 8.5 Eksenler
`ArgumentAxisJson` (`ChartArgumentAxisDto`): `ArgumentType` (`datetime` \| `numeric` \| `string`), `ArgumentAxisJson` (`ChartArgumentAxisDto`): `Title`, `Visible` (`true`), `Width` (`1`),
`AggregationInterval` (`day` \| `hour` \| `minute` \| `month` \| `quarter` \| `second` \| `week` \| `year`), `ArgumentType` (— \| `datetime` \| `numeric` \| `string`),
`Position` (`bottom` \| `left` \| `right` \| `top`), `HoverMode` (`none` \| `allArgumentPoints`), `AggregationInterval` (`millisecond` \| `second` \| `minute` \| `hour` \| `day` \| `week` \| `month` \| `quarter` \| `year`),
`Grid`, `Label` → `DisplayMode` (`standard` \| `rotate` \| `stagger`), `RotationAngle` (`90`), `WorkdaysOnly` (`false`), `Position` (`bottom` \| `left` \| `right` \| `top`),
`OverlappingBehavior` (`hide` \| `rotate` \| `stagger` \| `none`). `HoverMode` (`none` \| `allArgumentPoints`), `Grid` (`ChartAxisGridDto`: `Visible`, `Color`
`#d3d3d3`, `Width` `1`), `Label` → `DisplayMode` (`standard` \| `rotate` \| `stagger`),
`RotationAngle` (`90`), `OverlappingBehavior` (`hide` \| `stagger` \| `none`). Argüman alanında
lookup varsa etiket metni lookup'ın görünen değerine otomatik çevrilir.
`ValueAxisJson` (`ChartValueAxisDto`): `Name`, `Title`, `ValueType` (`numeric`), `ValueAxisJson` bir **dizidir** (`ChartValueAxisDto[]`; çok eksenli grafik — seri `Axis` alanıyla
`Position` (`left`), `Type` (`continuous` \| `discrete` \| `logarithmic`), `Visible` (`true`), `Name`'e bağlanır): `Name`, `Title`, `ValueType` (`numeric`), `Position` (`left`),
`Width` (`1`), `Grid`, `Breaks[]`, `BreakStyle`, `AutoBreaksEnabled` (`true`), `Type` (`continuous` \| `discrete` \| `logarithmic`), `Visible` (`true`), `Width` (`1`), `Grid`,
`MaxAutoBreakCount` (`2`). `Breaks[]` (`StartValue`/`EndValue`), `BreakStyle` (`Color` `#ababab`, `Line` `waved`, `Width` `5`),
`AutoBreaksEnabled` (`true`), `MaxAutoBreakCount` (`2`). Tek nesne yazmak `JsonException` verir.
`CommonAxisSettingsJson` iki eksene birden uygulanır; **eksene özel ayar varsa yok sayılır.** `CommonAxisSettingsJson` (`ChartCommonAxisDto`: `Title`, `Visible`, `Width`, `Grid`) iki eksene
birden uygulanır; **eksene özel ayar varsa yok sayılır.**
### 8.6 `LegendJson` (`ChartLegendDto`) ### 8.6 `LegendJson` (`ChartLegendDto`)
@ -664,8 +691,14 @@ Grafik, ızgaranın `SelectCommand`'ından **ayrı** bir sorgu kullanabilir. Sor
- `ZoomAndPanJson` (`ChartZoomAndPanDto`): `ArgumentAxis` / `ValueAxis` - `ZoomAndPanJson` (`ChartZoomAndPanDto`): `ArgumentAxis` / `ValueAxis`
(`none` \| `pan` \| `zoom` \| `both`), `AllowMouseWheel` (`true`), `AllowTouchGestures` (`true`), (`none` \| `pan` \| `zoom` \| `both`), `AllowMouseWheel` (`true`), `AllowTouchGestures` (`true`),
`DragToZoom` (`false`), `PanKey` (`shift`), `DragBoxStyle`. `DragToZoom` (`false`), `PanKey` (`shift`), `DragBoxStyle`.
- `AnnotationsJson` (`ChartAnnotationDto[]`): `Name`, `Text`, `Image`, `Series`, `Argument`, - `AnnotationsJson` (`ChartAnnotationDto[]`): `Name`, `Type` (`text` \| `image`), `Text`, `Image`,
`OffsetX`/`OffsetY`, `Color`, `Font`, `Border`, `TooltipEnabled`, `Description`. konum için `Series` + `Argument`/`Value` ya da piksel `X`/`Y`, `OffsetX`/`OffsetY` (`-1`),
`Width`/`Height`, `PaddingLeftRight`/`PaddingTopBottom` (`10`), `WordWrap` (`normal`),
`Color` (`#ffffff`), `Font`, `Border`, `TooltipEnabled` (`true`), `Description`.
`CommonAnnotationsSettingsJson` (`ChartCommonAnnotationDto`) aynı alanları `Name` olmadan taşır.
- `CommonPaneSettingsJson` (`ChartCommonPaneDto`): yalnızca `BackgroundColor`.
- Ortak alt nesneler: `Font` (`Color` `#FFFFFF`, `Family`, `Size` `12`, `Weight` `400`),
`Border` (`Visible`, `Color` `#d3d3d3`, `Width` `1`, `CornerRadius` `0`, `DashStyle` `solid`).
--- ---
@ -685,14 +718,18 @@ dışında kalanlar:
### 9.2 `ColumnHeaderJson` (`ColumnHeaderDto`) ### 9.2 `ColumnHeaderJson` (`ColumnHeaderDto`)
`AllowHeaderFiltering` (`true`), `AllowSearch` (`false`) ve **özel başlık filtresi listesi**: `AllowHeaderFiltering` (`true`), `AllowSearch` (`false`) ve **özel başlık filtresi listesi**
(`ColumnsHeaderDataSourceDto`: `Text` + `Value` — DevExtreme filtre ifadesi dizisi):
```json ```json
{ "AllowHeaderFiltering": true, { "AllowHeaderFiltering": true,
"DataSource": [ { "text": "3000 altı", "value": ["Amount", "<", 3000] }, "DataSource": [ { "Text": "3000 altı", "Value": ["Amount", "<", 3000] },
{ "text": "3000 üstü", "value": ["Amount", ">=", 3000] } ] } { "Text": "3000 üstü", "Value": ["Amount", ">=", 3000] } ] }
``` ```
Anahtarlar PascalCase yazılır; `text`/`value` küçük harfle yazılırsa liste boş gelir (giriş, ortak
kurallar). Ekranın `HeaderFilterJson.Visible` bayrağı kapalıysa bu liste de görünmez.
### 9.3 `GroupingJson` (`ColumnGroupingDto`) ### 9.3 `GroupingJson` (`ColumnGroupingDto`)
`AllowGrouping` (`true`), `GroupIndex` (kaçıncı seviyeden gruplanacağı), `AutoExpandGroup` (`false`). `AllowGrouping` (`true`), `GroupIndex` (kaçıncı seviyeden gruplanacağı), `AutoExpandGroup` (`false`).
@ -707,7 +744,7 @@ Sol/sağa sabitlenmiş kolon yatay kaydırmada sabit kalır.
| Anahtar | Anlam | | Anahtar | Anlam |
| --- | --- | | --- | --- |
| `SummaryType` | `sum` \| `avg` \| `count` \| `min` \| `max` \| `custom` | | `SummaryType` | `sum` \| `avg` \| `count` \| `min` \| `max` (`SummaryTypeEnum`; `custom` hesaplayıcısı bağlanmadığı için kullanılmaz) |
| `ValueFormat` | DevExtreme format adı (`fixedPoint`, `currency`, `percent`, `shortDate`…) | | `ValueFormat` | DevExtreme format adı (`fixedPoint`, `currency`, `percent`, `shortDate`…) |
| `DisplayFormat` | Metin şablonu: `{0}` biçimlenmiş değer, `{1}` `ShowInColumn`'daki sütunun başlığı | | `DisplayFormat` | Metin şablonu: `{0}` biçimlenmiş değer, `{1}` `ShowInColumn`'daki sütunun başlığı |
| `ShowInColumn` | Özetin hangi sütunun altında görüneceği (kolon adı). `DisplayFormat`'taki `{1}` bunun başlığıdır | | `ShowInColumn` | Özetin hangi sütunun altında görüneceği (kolon adı). `DisplayFormat`'taki `{1}` bunun başlığıdır |
@ -731,7 +768,7 @@ Bir kolonu **başka bir tablodan** çekmek için; view yazmadan tek alanlık joi
| `JoinFieldName` | Join kurulan tablonun ilişkili alanı | | `JoinFieldName` | Join kurulan tablonun ilişkili alanı |
| `SelectFieldName` | Ekranda gösterilecek alan | | `SelectFieldName` | Ekranda gösterilecek alan |
| `FieldNameAlias` | Alanın takma adı | | `FieldNameAlias` | Alanın takma adı |
| `JoinCondition2` | İkinci koşulun bağlacı (`AND` \| `OR`) | | `JoinCondition2` | İkinci koşulun bağlacı (`AND` varsayılan \| `OR`) |
| `JoinFieldName2` | İkinci koşulun alanı — **tablo adıyla birlikte** (`Def_T_City.CultureName`) | | `JoinFieldName2` | İkinci koşulun alanı — **tablo adıyla birlikte** (`Def_T_City.CultureName`) |
| `BaseTableJoinFieldName2_OrValue` | İkinci koşulun karşı tarafı: tablo adlı bir alan ya da `'en'` gibi sabit | | `BaseTableJoinFieldName2_OrValue` | İkinci koşulun karşı tarafı: tablo adlı bir alan ya da `'en'` gibi sabit |
@ -759,7 +796,8 @@ Bir kolonu **başka bir tablodan** çekmek için; view yazmadan tek alanlık joi
| `PermissionJson` | — | Alan yetkileri (§5.1) | | `PermissionJson` | — | Alan yetkileri (§5.1) |
| `CultureName` · `UserId` · `RoleId` | — | Alan varyantı (§5.7) | | `CultureName` · `UserId` · `RoleId` | — | Alan varyantı (§5.7) |
> **`DefaultValue` / `DefaultValueType` / `ReadOnly` diye bir alan kolonu yoktur.** > **`DefaultValue` / `DefaultValueType` / `ReadOnly` diye bir alan kolonu yoktur.** İstemciye
> giden `ColumnFormatDto`'da bu adlar görünür ama çıktı alanlarıdır; seed'e yazılan değer düşer.
> Varsayılan değerler ekran seviyesindeki `Insert/Update/Delete/Form/SelectFieldsDefaultValueJson` > Varsayılan değerler ekran seviyesindeki `Insert/Update/Delete/Form/SelectFieldsDefaultValueJson`
> bloklarında, alan adıyla eşleşen `FieldsDefaultValueDto` satırları olarak durur > bloklarında, alan adıyla eşleşen `FieldsDefaultValueDto` satırları olarak durur
> (`lowcode` §4.3.5); salt okunurluk ise `EditorOptions.readOnly` ya da `EditorScript`'in > (`lowcode` §4.3.5); salt okunurluk ise `EditorOptions.readOnly` ya da `EditorScript`'in
@ -768,7 +806,8 @@ Bir kolonu **başka bir tablodan** çekmek için; view yazmadan tek alanlık joi
### 9.8 Tipli editör seçenekleri ### 9.8 Tipli editör seçenekleri
`EditorOptions` JSON'unun bazı anahtarları backend'de **tipli DTO'ya** çözülür; yanlış tip `EditorOptions` JSON'unun bazı anahtarları backend'de **tipli DTO'ya** çözülür; yanlış tip
sessizce yok sayılır: sessizce yok sayılır. Bu çözme, ekran kolonlarının aksine **büyük/küçük harfe duyarsızdır**
(`columns` ile `Columns` aynıdır):
| DTO | Hangi `EditorType2` | Anahtarlar (varsayılan) | | DTO | Hangi `EditorType2` | Anahtarlar (varsayılan) |
| --- | --- | --- | | --- | --- | --- |
@ -782,6 +821,16 @@ metni istemciye **her hâlükârda** gider; tipli DTO'lar onun yanında ek bir k
`JsonException` durumunda sessizce `null` döner — yani bozuk JSON burada ekranı düşürmez, ama `JsonException` durumunda sessizce `null` döner — yani bozuk JSON burada ekranı düşürmez, ama
tipli okumaya bağlı davranış (GridBox kolonları, TagBox etiket sayısı) çalışmaz. tipli okumaya bağlı davranış (GridBox kolonları, TagBox etiket sayısı) çalışmaz.
**Cihaz yetenekleri yeni editör tipi istemez** (üçü de HTTPS ister):
| İhtiyaç | Nerede |
| --- | --- |
| Fotoğraf çekme | `dxImageUpload` · `Capture` (yukarıda) |
| Alana barkod/QR okutma | `dxTextBox` `EditorOptions.buttons[]` içinde `onClick: "@SCAN_BARCODE"` (`lowcode` §6.4) |
| Sürekli okutup her kodu yeni satır yapma | Toolbar butonu `DialogName: "BarcodeScanDialog"` + `DialogParameters` `{"field": "…", …sabit alanlar}` — ekranın insert ucundan geçer (`lowcode` §4.9) |
| Cihaz konumu | `EditorScript` `location` tarifi → `geoTo('Enlem', 'Boylam')` (`lowcode` §5.3) |
| Tasarımcıda okutma / kod basma | `BarcodeScanField` · `BarcodeViewer` (§10.9) |
--- ---
## 10. Visual Designer envanteri ## 10. Visual Designer envanteri
@ -798,9 +847,9 @@ otomatik çıkarılan metadata (`generated/componentProps.json`).
| --- | --- | | --- | --- |
| `layout` | `PageContainer` (maxWidth, padding, gap, className), `FlexRow` (columns, firstColumnWidth, gap, wrap, align, className), `Table` | | `layout` | `PageContainer` (maxWidth, padding, gap, className), `FlexRow` (columns, firstColumnWidth, gap, wrap, align, className), `Table` |
| `data` | `Form` (§10.2) ve veri bağlanabilen UI bileşenleri: `Select`, `AutoComplete`, `Dropdown`, `Menu`, `Pagination`, `Radio.Group`, `Tabs`, `Grid` | | `data` | `Form` (§10.2) ve veri bağlanabilen UI bileşenleri: `Select`, `AutoComplete`, `Dropdown`, `Menu`, `Pagination`, `Radio.Group`, `Tabs`, `Grid` |
| `platform` | `ListView`, `DataGridView`, `TreeView`, `GanttView`, `TodoBoard`, `CardView`, `SchedulerView`, `PivotView`, `ChartView` — hepsi aynı üç prop'u alır: `listFormCode` (**zorunlu**), `height` (varsayılan `520px`, `ChartView`'da `420px`), `className` | | `platform` | Gömülü ListForm görünümleri: `ListView`, `DataGridView`, `TreeView`, `GanttView`, `TodoBoard`, `CardView`, `SchedulerView`, `PivotView`, `ChartView` (§10.7). Public site düğümleri: `PublicHeaderBar`, `PublicNav`, `PublicMobileMenu`, `PublicLogo`, `PublicThemeToggle`, `PublicLanguageSelector`, `PublicDemoButton` (`PUBLIC_SITE_COMPONENTS`, §10.7) |
| `html` | `div`, `p`, `span`, `h1`, `h2`, `h3`, `h4`, `h5`, `img` — **yalnız bu dokuz etiket** | | `html` | `a`, `div`, `p`, `span`, `h1`, `h2`, `h3`, `h4`, `h5`, `img` — **yalnız bu on etiket** |
| `ui` | `Avatar`, `Badge`, `Button`, `Calendar`, `Card`, `Checkbox`, `Chips`, `ColorPicker`, `DatePicker`, `ImageViewer`, `Input`, `Knob`, `Marquee`, `Notification`, `Progress`, `Radio`, `RangeCalendar`, `Rate`, `ScrollBar`, `Skeleton`, `Slider`, `Spacer`, `Spinner`, `Switcher`, `Tag`, `TimeInput`, `Tooltip`, `Upload` | | `ui` | `Avatar`, `Badge`, `BarcodeScanField`, `BarcodeViewer`, `Button`, `Calendar`, `Card`, `Checkbox`, `Chips`, `ColorPicker`, `DatePicker`, `ImageViewer`, `Input`, `Knob`, `Marquee`, `Notification`, `PlatformIcon`, `Progress`, `Radio`, `RangeCalendar`, `Rate`, `ScrollBar`, `Skeleton`, `Slider`, `Spacer`, `Spinner`, `Switcher`, `Tag`, `TimeInput`, `Tooltip`, `Upload` |
| `custom` | Kayıtlı diğer custom component'ler (`Dependencies`'e eklenir) | | `custom` | Kayıtlı diğer custom component'ler (`Dependencies`'e eklenir) |
**`input`, `button`, `textarea`, `select`, `checkbox` HTML etiketleri kutuda yoktur** **`input`, `button`, `textarea`, `select`, `checkbox` HTML etiketleri kutuda yoktur**
@ -812,8 +861,8 @@ Kutu dışında tutulanlar (`EXCLUDED_COMPONENTS`): `Alert`, `Breadcrumb`, `Dial
duyan bir yerleşim, tasarımcı yerine **Code modunda** yazılır (`lowcode` §7.1.1) — orada duyan bir yerleşim, tasarımcı yerine **Code modunda** yazılır (`lowcode` §7.1.1) — orada
`components/ui`'nin tamamı kapsamdadır. `components/ui`'nin tamamı kapsamdadır.
Çocuk düğüm kabul edenler: `PageContainer`, `FlexRow`, `Form`, `div`, `Card`, `Table`, `Tabs` Çocuk düğüm kabul edenler: `PageContainer`, `FlexRow`, `Form`, `div`, `a`, `Card`, `Table`, `Tabs`,
ve **her custom component**. Diğer düğümlerin içine bırakma; kanvas kabul etse de üretilen kod `PublicHeaderBar`, `PublicMobileMenu` ve **her custom component**. Diğer düğümlerin içine bırakma; kanvas kabul etse de üretilen kod
çocukları çizmez. çocukları çizmez.
Düğüm başına iki ortak prop, hangi ailede olursa olsun geçerlidir: Düğüm başına iki ortak prop, hangi ailede olursa olsun geçerlidir:
@ -954,7 +1003,7 @@ istiyorsan `Grid` (data) ya da `DataGridView` (platform) kullan.
### 10.7 `platform` bileşenleri — prop sözleşmesi ### 10.7 `platform` bileşenleri — prop sözleşmesi
Dokuzu da aynı üç prop'u alır; başka prop'ları **yoktur** (görünümün tüm davranışı gömülen Dokuz görünüm düğümü de aynı üç prop'u alır; başka prop'ları **yoktur** (görünümün tüm davranışı gömülen
ListForm ekranının kendi tanımından gelir): ListForm ekranının kendi tanımından gelir):
| Prop | Varsayılan | Anlam | | Prop | Varsayılan | Anlam |
@ -968,14 +1017,30 @@ ListForm ekranının kendi tanımından gelir):
ekranın kendi yetki hatasını gösterir; ayrıca gizlemek istiyorsan `designerPermission` yaz. ekranın kendi yetki hatasını gösterir; ayrıca gizlemek istiyorsan `designerPermission` yaz.
Gömülen görünüm, hedef ekranın `LayoutJson`'ında açık olmalıdır. Gömülen görünüm, hedef ekranın `LayoutJson`'ında açık olmalıdır.
**Public site düğümleri** yalnızca public bileşenlerde (`PublicHeader`, `PublicFooter`, public
sayfalar) anlamlıdır; veriyi uygulama konfigürasyonundan (`publicMenus`, tema, dil) okur:
| Düğüm | Prop'lar (varsayılan) |
| --- | --- |
| `PublicHeaderBar` (çocuk kabul eder) | `scrolledClassName`, `scrollThreshold` (`10`) — sayfa kaydırılınca ek sınıf |
| `PublicNav` | `source` (`navigation` gezinme bağlantıları \| `actions` vurgulu/CTA kayıtlar \| `all`; kaynak `Pub` menüsündeki `App.Public.Header` düğümleri), `variant` (`horizontal` \| `vertical`), `showIcons` (`true`), `iconSize`, `itemClassName`, `activeItemClassName` |
| `PublicMobileMenu` (çocuk kabul eder) | `buttonClassName`, `panelClassName` |
| `PublicLogo` · `PublicThemeToggle` · `PublicLanguageSelector` · `PublicDemoButton` | Yalnız sınıf prop'ları (`imgClassName`, `buttonClassName`, `activeClassName`, `iconSize` `15`) |
Runtime kapsamında `react-icons`/`react-router` yoktur: ikon `PlatformIcon` (`name` `FaUser`,
`size` `24`), gezinme `a` düğümüdür. Kanvasın doğrudan çizdiği düğümler
`componentEditor/runtimeNodes.ts` sözlüğündedir; yeni düğüm = bileşen + bu sözlük + `catalog.ts` +
dil anahtarı.
### 10.8 `html` elemanları — prop sözleşmesi ### 10.8 `html` elemanları — prop sözleşmesi
| Eleman | Prop'lar | Olaylar | | Eleman | Prop'lar | Olaylar |
| --- | --- | --- | | --- | --- | --- |
| `a` (çocuk kabul eder) | `children`, `href`, `target`, `aria-label`, `className`, `style` — public sayfalarda gezinmenin tek yolu | `onClick` |
| `div` (çocuk kabul eder) | `children`, `className`, `style` | `onClick`, `onMouseEnter`, `onMouseLeave` | | `div` (çocuk kabul eder) | `children`, `className`, `style` | `onClick`, `onMouseEnter`, `onMouseLeave` |
| `p` · `span` | `children`, `className` | `onClick` | | `p` · `span` | `children`, `className` | `onClick` |
| `h1`–`h5` | `children`, `className` — başlıklar hazır Tailwind sınıfıyla düşer (`h1`: `text-4xl font-bold` … `h5`: `text-lg font-semibold`); Tailwind reset'i yüzünden sınıfı silersen başlık paragraf boyutuna iner | `onClick` | | `h1`–`h5` | `children`, `className` — başlıklar hazır Tailwind sınıfıyla düşer (`h1`: `text-4xl font-bold` … `h5`: `text-lg font-semibold`); Tailwind reset'i yüzünden sınıfı silersen başlık paragraf boyutuna iner | `onClick` |
| `img` | `src` (yeni düşen eleman gömülü SVG yer tutucusuyla gelir; herhangi bir URL/data-URI yazılabilir), `alt`, `width`, `height`, `className` (`max-w-full rounded-md`) | `onClick`, `onLoad` | | `img` | `src` (yeni düşen eleman gömülü SVG yer tutucusuyla gelir; herhangi bir URL/data-URI yazılabilir), `alt`, `width`, `height`, `loading`, `decoding`, `className` (`max-w-full rounded-md`) | `onClick`, `onLoad` |
`input`/`button`/`textarea`/`select`/`checkbox` etiketleri kutuda yoktur — `ui` karşılıklarını `input`/`button`/`textarea`/`select`/`checkbox` etiketleri kutuda yoktur — `ui` karşılıklarını
kullan (§10.1). kullan (§10.1).
@ -1056,8 +1121,9 @@ Script kapsamındaki her şey (`refs`, `api`, `notify`, `translate`, `checkPermi
| `Pagination` | `onChange` | Seçilen sayfa numarası | | `Pagination` | `onChange` | Seçilen sayfa numarası |
| `Radio.Group` | `onChange` | Seçilen öğenin `value` değeri | | `Radio.Group` | `onChange` | Seçilen öğenin `value` değeri |
| `Tabs` | `onChange` | Aktif sekmenin `value` değeri | | `Tabs` | `onChange` | Aktif sekmenin `value` değeri |
| `BarcodeScanField` | `onScan` | Okunan kodun metni |
Bu on bileşen `DESIGNER_PRIMARY_EVENTS` kaydıdır — panel yalnızca bu olayları gösterir. Bu on bir bileşen `DESIGNER_PRIMARY_EVENTS` kaydıdır — panel yalnızca bu olayları gösterir.
Kayıtta olmayan bileşenlerde bütün `function` prop'ları listelenir; işe yarayanlar: Kayıtta olmayan bileşenlerde bütün `function` prop'ları listelenir; işe yarayanlar:
| Bileşen | Olaylar | | Bileşen | Olaylar |
@ -1067,6 +1133,7 @@ Kayıtta olmayan bileşenlerde bütün `function` prop'ları listelenir; işe ya
| `Upload` | `beforeUpload` (false → dosya reddedilir), `onChange` (dosya listesi), `onFileRemove` | | `Upload` | `beforeUpload` (false → dosya reddedilir), `onChange` (dosya listesi), `onFileRemove` |
| `Card` · `Avatar` · `p` · `span` · `h1`–`h5` | `onClick` | | `Card` · `Avatar` · `p` · `span` · `h1`–`h5` | `onClick` |
| `div` | `onClick`, `onMouseEnter`, `onMouseLeave` | | `div` | `onClick`, `onMouseEnter`, `onMouseLeave` |
| `a` | `onClick` |
| `img` | `onClick`, `onLoad` | | `img` | `onClick`, `onLoad` |
| `Notification` · `ImageViewer` | `onClose` (`ImageViewer` ayrıca `onIndexChange`) | | `Notification` · `ImageViewer` | `onClose` (`ImageViewer` ayrıca `onIndexChange`) |
| `Marquee` | `onFinish`, `onCycleComplete` | | `Marquee` | `onFinish`, `onCycleComplete` |
@ -1081,8 +1148,12 @@ bir kez çalışır; açılış verisi çekme ve `refs` üzerinden ilk durumu ku
## 11. Zamanlanmış e-posta (MailQueue modülü) ## 11. Zamanlanmış e-posta (MailQueue modülü)
`BackgroundWorker` kaydı `WorkerType: 1` (MailQueueWorker) ise gövde bu modüldür `BackgroundWorker` kaydı (`Sas_H_BackgroundWorker`, ekran Saas › Background Workers ›
(`api/modules/Sozsoft.MailQueue`). Recurring Jobs) `WorkerType: 1` (MailQueueWorker) ise gövde bu modüldür
(`api/modules/Sozsoft.MailQueue`). Diğer tipler: `2` SqlWorker (`BeforeSp`/`AfterSp`) · `3`
NotificationWorker · `4` SessionCleanupWorker · `5` BackupWorker. `Scope`: `1` Host · `2` Tenant ·
`3` All (host + her kiracı) — kiracı tablosuna dokunan iş `Host` olamaz (`README.md` §14). Hazır
işler `data/App.BackgroundWorkers.RecurringJobs.json` ile gelir.
### 11.1 Worker `Options` (`MailQueueWorkerOptions`) ### 11.1 Worker `Options` (`MailQueueWorkerOptions`)
@ -1105,15 +1176,16 @@ birden fazlası `};{` ile birleştirilir:
- `TabloAdi` bir **tablo/view adıdır**; `SELECT * FROM {TabloAdi} WHERE ...` olarak parametreli - `TabloAdi` bir **tablo/view adıdır**; `SELECT * FROM {TabloAdi} WHERE ...` olarak parametreli
çalıştırılır (parametreler kuyruk satırındaki `TableParameter` alanından gelir). çalıştırılır (parametreler kuyruk satırındaki `TableParameter` alanından gelir).
- `DosyaTipi` = `IN` ise tablo mail gövdesine gömülür; `PDF` / `XLS` / `TXT` ise ek dosya olur. - `DosyaTipi` = `IN` ise tablo mail gövdesine gömülür; `PDF` / `XLS` / `TXT` ise ek dosya olur.
- Sütun başlıkları, sırası, CSS'i ve alt toplamları `BackgroundWorker_MailQueueTableFormat` - Sütun başlıkları, sırası, CSS'i ve alt toplamları `Sas_H_BackgroundWorker_MailQueueTableFormat`
kayıtlarından okunur: `TableName`, `Order`, `ColumnName`, `Caption`, `HeaderCss`, `Css`, kayıtlarından okunur: `TableName`, `Order`, `ColumnName`, `Caption`, `HeaderCss`, `Css`,
`FooterCss`, `DataType`, `DataFormat`, `IsHidden`, `IsProtected`, `SubTotal`, `Width`. `FooterCss`, `DataType`, `DataFormat`, `IsHidden`, `IsProtected`, `SubTotal`, `Width`.
### 11.3 Kuyruk satırı (`BackgroundWorker_MailQueue`) ### 11.3 Kuyruk satırı (`Sas_H_BackgroundWorker_MailQueue`)
`TemplateId` (worker), `From`, `To`, `MailParameter`, `TableName`, `TableParameter`, `TemplateId` (worker), `From`, `To`, `MailParameter`, `TableName`, `TableParameter`,
`Attachment`, `AttachmentParameter`, `RelatedRecordId`, `SendStatus`, `SendTime`, `AwsMessageId`. `Attachment`, `AttachmentParameter`, `RelatedRecordId`, `SendStatus`, `SendTime`, `AwsMessageId`.
Gönderim sonuçları `BackgroundWorker_MailQueueEvents` tablosunda izlenir. Gönderim sonuçları `Sas_H_BackgroundWorker_MailQueueEvents` tablosunda izlenir. Tabloların
ekranı yoktur; satırı kanca/prosedür yazar.
Kuyruğa satır yazma işi genellikle worker'ın `BeforeSp` prosedüründe ya da ekranın Kuyruğa satır yazma işi genellikle worker'ın `BeforeSp` prosedüründe ya da ekranın
`InsertAfterCommand` kancasında yapılır — yani "kayıt onaylanınca mail çıksın" isteği kod `InsertAfterCommand` kancasında yapılır — yani "kayıt onaylanınca mail çıksın" isteği kod
@ -1143,12 +1215,14 @@ Platform tablolarının adı `TableNameResolver` tarafından üretilir:
| Parça | Değerler | | Parça | Değerler |
| --- | --- | | --- | --- |
| Modül ön eki (`MenuPrefix`) | `Sas` Saas · `Adm` Administration · `Crm` · `Crd` Coordinator · `Scp` SupplyChain · `Mnt` Maintenance · `Str` Store · `Prj` Project · `Hr` · `Mrp` · `Acc` Accounting | | Modül ön eki (`MenuPrefix`) | Yalnızca `Sas` (Saas) · `Adm` (Administration). Modüller (`api/modules/*`) kendi `*DbProperties.MenuPrefix` değerini taşır (MailQueue/Settings/Languages `Sas`, Notifications `Adm`) |
| Kapsam | `H` host (tüm tenant'lar için ortak) · `T` tenant · `B` şube | | Kapsam | `H` host (tüm tenant'lar için ortak) · `T` tenant · `B` şube (`TablePrefix.BranchByName`; şu an eşlemesi olan tablo yok) |
| Ad | `TableNameEnum` üyesi | | Ad | `TableNameEnum` üyesi |
Örnek: `Sas_H_Currency` (host — tüm kiracılar aynı para birimlerini görür), `Adm_T_Department` Örnek: `Sas_H_Currency` (host — tüm kiracılar aynı para birimlerini görür), `Adm_T_Department`
(kiracı başına), `V_Sas_H_Order` (view). Özel view'ler (kiracı başına), `V_Sas_H_Order` (view). Menü ile tablo öneki her zaman örtüşmez:
`Sas_T_GlobalSearch`, `Sas_T_Branch`, `Sas_T_Forum*`, `Sas_T_IntranetWidget` kiracı tablosudur;
`Adm_T_Sequence` Saas menüsündedir. Özel view'ler
`TableNameResolver.GetFullSpecialViewName` ile `V_{Önek}_{Prefix}_{Ad}` biçiminde üretilir. `TableNameResolver.GetFullSpecialViewName` ile `V_{Önek}_{Prefix}_{Ad}` biçiminde üretilir.
> Yeni bir platform tablosu eklenecekse `TableNameEnum` + `TableNameResolver._map` birlikte > Yeni bir platform tablosu eklenecekse `TableNameEnum` + `TableNameResolver._map` birlikte
@ -1163,84 +1237,87 @@ soneklerini alır.
| Ekran | Kod / route | Tablo | Kapsam | Komponent üretirken ne işe yarar | | Ekran | Kod / route | Tablo | Kapsam | Komponent üretirken ne işe yarar |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| **Tenants** | `AbpTenantManagement.Tenants` | `AbpTenants` | host | Kiracı kaydı, bağlantı dizesi diyaloğu (`TenantsConnectionString`), alt form olarak şubeler. Ekranların `IsTenant` davranışının kaynağı. |
| **Branches** | `App.Branches` | `Sas_T_Branch` | tenant | Şube listesi. Ekranı `IsBranch = true` yaparsan filtre bu tablodan gelir; `BranchSeed` diyaloğu şube verisini kurar. |
| **Definitions › AiBot** | `App.Definitions.AiBot` | `Sas_H_AiBot` | host | Yapay zekâ asistanı tanımı (`Name`, `ApiUrl`, `Tenants`); `/admin/ai` bu kayıtları kullanır. | | **Definitions › AiBot** | `App.Definitions.AiBot` | `Sas_H_AiBot` | host | Yapay zekâ asistanı tanımı (`Name`, `ApiUrl`, `Tenants`); `/admin/ai` bu kayıtları kullanır. |
| **Definitions › Global Search** | `App.Definitions.GlobalSearch` | `Sas_T_GlobalSearch` | tenant | Üretilen ekranın üst aramada çıkması için kayıt: `System`, `Group`, `Term`, `Weight`, `Url`. | | **Definitions › Global Search** | `App.Definitions.GlobalSearch` | `Sas_T_GlobalSearch` | tenant | Üretilen ekranın üst aramada çıkması için kayıt: `System`, `Group`, `Term`, `Weight`, `Url`. |
| **Definitions › Contact Title** | `App.Definitions.ContactTitle` | `Sas_H_ContactTitle` | host | Ünvan lookup'ı (`Title`, `Abbreviation`). | | **Definitions › Contact Title** | `App.Definitions.ContactTitle` | `Sas_H_ContactTitle` | host | Ünvan/hitap lookup'ı (`Title`, `Abbreviation`). |
| **Definitions › Currency** | `App.Definitions.Currency` | `Sas_H_Currency` | host | Para birimi + `Rate`. Tutar alanı olan ekranın kur lookup'ı ve `DbQuery` varsayılanı buradan beslenir. | | **Definitions › Currency** | `App.Definitions.Currency` | `Sas_H_Currency` | host | Para birimi + `Rate`. Tutar alanı olan ekranın kur lookup'ı ve `DbQuery` varsayılanı buradan beslenir. |
| **Definitions › Country Group / Country / City / District** | `App.Definitions.CountryGroup` · `.Country` · `.City` · `.District` | `Sas_H_CountryGroup` · `Sas_H_Country` · `Sas_H_City` · `Sas_H_District` | host | Adres alanlarının hazır cascade zinciri. `Country` ayrıca `PhoneCode`, `PhoneNumberFormat`, `ZipRequired`, `StateRequired`, `TaxLabel` taşır — adres doğrulaması için kullan. | | **Definitions › Country Group / Country / City / District** | `App.Definitions.CountryGroup` · `.Country` · `.City` · `.District` | `Sas_H_CountryGroup` · `Sas_H_Country` · `Sas_H_City` · `Sas_H_District` | host | Adres alanlarının hazır cascade zinciri (dört ayrı menü ve seed dosyası; `Order` sırası grup → ülke → il → ilçe). `Country` ayrıca `PhoneCode`, `PhoneNumberFormat`, `ZipRequired`, `StateRequired`, `TaxLabel` taşır — adres doğrulaması için kullan. |
| **Definitions › Skill Type / Skill / Skill Level** | `App.Definitions.SkillType` (+ alt kayıtlar) | `Sas_H_SkillType` · `Sas_H_Skill` · `Sas_H_SkillLevel` | host | Yetkinlik ağacı; `SkillType` kendi kendine ebeveyn olan alt form örneğidir. | | **Definitions › Skill Type** | `App.Definitions.SkillType` (alt formlar `.Skill`, `.SkillLevel`) | `Sas_H_SkillType` · `Sas_H_Skill` · `Sas_H_SkillLevel` | host | Yetkinlik tanımı; bir ana ekrandan iki alt forma açılan **çoklu alt form** örneği. |
| **Definitions › UoM Category / UoM** | `App.Definitions.UomCategory` | `Sas_H_UomCategory` · `Sas_H_Uom` | host | Ölçü birimi, `Ratio`/`Rounding` — miktar alanı olan ekranlarda birim lookup'ı ve çevrim. | | **Definitions › UoM Category** | `App.Definitions.UomCategory` (alt form `.Uom`) | `Sas_H_UomCategory` · `Sas_H_Uom` | host | Ölçü birimi, `Ratio`/`Rounding` — miktar alanı olan ekranlarda birim lookup'ı ve çevrim. |
| **Definitions › Sequence** | `App.Definitions.Sequence` | `Adm_T_Sequence` | tenant | Belge numarası üretimi (`lowcode.instructions.md` §9.9); alan varsayılanında `CustomValueType: 5` ile bağlanır. | | **Definitions › Sequence** | `App.Definitions.Sequence` | `Adm_T_Sequence` | tenant | Belge numarası üretimi (`lowcode` §9.9); alan varsayılanında `CustomValueType: 5` ile bağlanır. |
| **Public › Home / About / Services / Contact** | `App.DeveloperKit.CustomComponents` — DeveloperKit > Custom Components (Visual Designer) | `data/App.DeveloperKit.CustomComponents/{Id}.json` (her bileşen kendi satır dosyasında) | host | Genel siteye açık sayfalar Custom Component'tir; `RoutePath` `/admin/` ile başlamıyorsa otomatik public route olur. Public sayfa isteği kod değil bu tasarımcıdır (README.md §10.4). | | **Public › Products / Payment Methods / Installment Options** | `App.Orders.Products` · `.PaymentMethods` · `.InstallmentOptions` | `Sas_H_Product` · `Sas_H_PaymentMethod` · `Sas_H_InstallmentOption` | host | Ürün, ödeme yöntemi (`Commission`), taksit — satış/abonelik ekranlarının ve public `/products` sayfasının kaynağı. |
| **Public › Products / Payment Methods / Installment Options** | `App.Orders.Products` · `.PaymentMethods` · `.InstallmentOptions` | `Sas_H_Product` · `Sas_H_PaymentMethod` · `Sas_H_InstallmentOption` | host | Ürün, ödeme yöntemi (`Commission`), taksit — satış/abonelik ekranlarının lookup kaynağı. | | **Public › Sales Orders** | `App.Orders.SalesOrders` (alt form Sales Order Item) | `Sas_H_Order` + `Sas_H_OrderItem` | host | **Onay akışı + alt kalem + toplam + diyalog** birlikte kullanılan tam örnek (§12.6). |
| **Public › Sales Orders** | `App.Orders.SalesOrders` | `Sas_H_Order` + `Sas_H_OrderItem` | host | **Onay akışı + alt kalem + toplam + diyalog** birlikte kullanılan tam örnek (§12.6). | | **Public › Blog Category / Posts** | `App.BlogManagement.Category` · `.Posts` | `Sas_H_BlogCategory` · `Sas_H_BlogPost` | host | Çok dilli içerik (`ContentTr`/`ContentEn`), slug, yayın durumu, sayaç alanları; public `/blog` bu tablolardan okur, yayınlanmış yazılar sitemap'e girer. |
| **Public › Blog Category / Posts** | `App.BlogManagement.Category` · `.Posts` | `Sas_H_BlogCategory` · `Sas_H_BlogPost` | host | Çok dilli içerik (`ContentTr`/`ContentEn`), slug, yayın durumu, sayaç alanları. Veri `configs/seeds/host/data/App.BlogManagement.Category.json` ve `App.BlogManagement.Posts.json` dosyalarından seed edilir. | | **Public › Demos** | `App.Demos` | `Sas_H_Demo` | host | Public `/demo` formundan gelen talepler — public form → tablo akışının örneği. |
| **Public › Demos** | `App.Demos` | `Sas_H_Demo` | host | Siteden gelen demo talepleri — public form → tablo akışının örneği. | | **Dev Requests** | `App.DevRequests` | `Sas_H_DevRequest` | host | **Kanban/Todo düzeninin** referansı (`DefaultLayout: todo`): `Status`, `Priority`, `SortOrder`, `Tags`, `Assignees`, `SubTasks`, `Timesheets`. |
| **Dev Requests** | `App.DevRequests` | `Sas_H_DevRequest` | host | **Kanban/Todo düzeninin** referansı: `Status`, `Priority`, `SortOrder`, `Tags`, `Assignees`, `SubTasks`, `Timesheets`. | | **Tenants** | `AbpTenantManagement.Tenants` | `AbpTenants` | host | Kiracı kaydı, bağlantı dizesi diyaloğu (`TenantsConnectionString`), alt form olarak şubeler; yazma `list-form-dynamic-api/tenant-*`. Ekranların `IsTenant` davranışının kaynağı. |
| **Setting Definitions** | `App.SettingDefinitions` | `Sas_H_SettingDefinition` | host | Yeni uygulama ayarı: `Code`, `MainGroupKey`/`SubGroupKey`, `DataType`, `SelectOptions`, `DefaultValue`, `Providers`, `RequiredPermissionName`, `IsEncrypted`, `IsVisibleToClients`. Ayarlanabilir olması gereken değeri koda gömme. | | **Branches** | `App.Branches` | `Sas_T_Branch` | tenant | Şube listesi. Ekranı `IsBranch = true` yaparsan filtre bu tablodan gelir; `BranchSeed` diyaloğu şube verisini kurar. |
| **Setting Definitions** | `App.SettingDefinitions` | `Sas_H_SettingDefinition` | host | Yeni uygulama ayarı: `Code`, `MainGroupKey`/`SubGroupKey`, `DataType`, `SelectOptions`, `DefaultValue`, `Providers`, `RequiredPermissionName`, `IsEncrypted`, `IsVisibleToClients`. Hazır tanımlar `data/App.SettingDefinitions.json`'dan gelir. Ayarlanabilir olması gereken değeri koda gömme. |
| **Languages › Language / Language Text** | `App.Languages.Language` · `.LanguageText` | `Sas_H_Language` · `Sas_H_LanguageKey` · `Sas_H_LanguageText` | host | Dil anahtarları. Üretilen her ekranın EN+TR metinleri buraya (ve `LanguagesData.json`'a) yazılır. | | **Languages › Language / Language Text** | `App.Languages.Language` · `.LanguageText` | `Sas_H_Language` · `Sas_H_LanguageKey` · `Sas_H_LanguageText` | host | Dil anahtarları. Üretilen her ekranın EN+TR metinleri buraya (ve `LanguagesData.json`'a) yazılır. |
| **Data Source** | `App.DataSource` | `Sas_H_DataSource` | host | `Code`, `DataSourceType`, `ConnectionString`. **İki tür kayıt bir arada:** elle tanımlanan host/harici bağlantılar ve `Code = tenant adı` olan otomatik tenant bağlantıları (Tenants ekranındaki bağlantı diyaloğu yönetir, elle dokunma). `IsTenant` ekran önce tenant kaydını, yoksa `DataSourceCode`'u kullanır — çözüm kuralı `lowcode` §9.3.3. Bağlantı dizesi koda/JSON'a yazılmaz. | | **Data Source** | `App.DataSource` | `Sas_H_DataSource` | host | `Code`, `DataSourceType`, `ConnectionString`. **İki tür kayıt bir arada:** elle tanımlanan host/harici bağlantılar ve `Code = tenant adı` olan otomatik tenant bağlantıları (Tenants ekranındaki bağlantı diyaloğu yönetir, elle dokunma). Varsayılan kaydı `HostDataSeeder` appsettings'teki bağlantı cümlesinden kurar. Çözüm kuralı `lowcode` §9.3.3. Bağlantı dizesi koda/JSON'a yazılmaz. |
| **Background Workers › Recurring Jobs / Jobs** | `App.BackgroundWorkers.RecurringJobs` · `.Jobs` | `Sas_H_BackgroundWorker` · `Sas_H_BackgroundWorker_JobFlow` | host | Cron'lu işler ve çalıştırma geçmişi (`Tenant`, `ExecutionDate`, `Duration`, `Status`, `FailureReason`, `ExceptionDetails`). `Scope` alanı işin gövdesinin hangi bağlamda çalışacağını belirler: `Host` / `Tenant` / `Host ve Kiracılar`; her kapsam ayrı bir iş kaydıdır, `Tenant` kolonu hangi kiracıda çalıştığını gösterir. Ayrıntı: §9.10, `README.md` §14 ve bu dosyanın §11'i. | | **Background Workers › Recurring Jobs / Jobs** | `App.BackgroundWorkers.RecurringJobs` · `.Jobs` | `Sas_H_BackgroundWorker` · `Sas_H_BackgroundWorker_JobFlow` | host | Cron'lu işler ve çalıştırma geçmişi (`Tenant`, `ExecutionDate`, `Duration`, `Status`, `FailureReason`, `ExceptionDetails`). `WorkerType`/`Scope` değerleri §11'de; her kapsam ayrı bir Hangfire işidir, `Tenant` kolonu hangi kiracıda çalıştığını gösterir. Hazır işler (oturum temizliği, bildirim, yedek, şema sözlüğü) `data/App.BackgroundWorkers.RecurringJobs.json`'dan gelir. Ayrıntı: `lowcode` §9.10, `README.md` §14. |
| **Menus › Routes / Module / Menu / Manager** | `App.Menus.Routes` · `.Module` · `.Menu` · `.Manager` (`/admin/menuManager`) | `Sas_H_Route` · `Sas_H_Module` · `Sas_H_Menu` | host | Menü ve route veritabanından gelir; üretilen ekranın menü kaydı buradan açılır. `Menu` ekranı ağaç düzeninin referansıdır, `Routes` yalnızca özel React sayfası eklenirken kullanılır. | | **Menus › Module / Routes / Menu / Manager** | `App.Menus.Module` · `.Routes` · `.Menu` · `.Manager` (`/admin/menuManager`) | `Sas_H_Module` · `Sas_H_Route` · `Sas_H_Menu` | host | Menü ve route veritabanından gelir; üretilen ekranın menü kaydı buradan açılır. `Menu` ekranı ağaç düzeninin referansıdır. Seed: `data/App.Menus.{Routes,Module,Menu}.json` — `Routes` dosyasına yalnızca var olan satırın `Seo*` alanları için dokunulur. |
| **Developer Kit › SQL Query Manager** | `App.SqlQueryManager` · `/admin/sqlQueryManager` | — | — | View/procedure/function yazma ve çalıştırma; karar sırasının 2. adımı buradan başlar. | | **Developer Kit › SQL Query Manager** | `App.SqlQueryManager` · `/admin/sqlQueryManager` | `Sas_H_CrudEndpoint` (üretilen CRUD uçları) | — | View/procedure/function/tablo tasarımı ve çalıştırma, tablodan CRUD endpoint üretimi (`.CrudEndpoints` yetkisi); karar sırasının 2. adımı buradan başlar. |
| **Developer Kit › Custom Endpoints** | `App.DeveloperKit.CustomEndpoints` | `Sas_H_CustomEndpoint` | tenant | `Name`, `Url`, `Method`, `DataSourceCode`, `Sql`, `ParametersJson`, `PermissionsJson` — parametreli SQL'i yetkili bir HTTP ucuna çevirir. | | **Developer Kit › Files** | `App.Files` · `/admin/files` | Blob depolama | tenant | Dosya yöneticisi. Ekranın dosya alanı için ayrı depolama kurma; dosya/görsel editörleri ve Intranet Documents bu altyapıyı kullanır. |
| **Developer Kit › Dynamic Services** | `App.DeveloperKit.DynamicServices` · `/admin/list/App.DeveloperKit.DynamicServices` | `Sas_H_DynamicService` | host | Liste ListForm ekranıdır; kod, listenin toolbar/satır butonlarından açılan `DynamicServiceEditor` diyalogunda (Monaco) yazılıp derlenir ve yayınlanır. SQL'in yetmediği iş kuralı için 3. adım. | | **Developer Kit › Custom Endpoints** | `App.DeveloperKit.CustomEndpoints` | `Sas_H_CustomEndpoint` | host | `Name`, `Url`, `Method`, `DataSourceCode`, `Sql`, `ParametersJson` (`Static`/`Query`/`Path`/`Body`), `PermissionsJson` (`Global`/`Role`/`User`) — parametreli SQL'i yetkili bir HTTP ucuna çevirir. |
| **Developer Kit › Components** | `App.DeveloperKit.CustomComponents` · `/admin/list/App.DeveloperKit.CustomComponents` | `Sas_H_CustomComponent` | host | Custom component listesi (ListForm) ve satırdaki **Design** butonuyla **Visual Designer** girişi (§10). Kayıtlar `data/App.DeveloperKit.CustomComponents/{Id}.json` klasörüne senkronlanır. | | **Developer Kit › Dynamic Services** | `App.DeveloperKit.DynamicServices` | `Sas_H_DynamicService` | host | Liste ListForm ekranıdır; kod, toolbar/satır butonlarından açılan `DynamicServiceEditor` diyalogunda (Monaco) yazılıp derlenir ve yayınlanır (`.TestCompile`, `.Publish`, `.ViewCode`). SQL'in yetmediği iş kuralı için 3. adım. |
| **Developer Kit › Components** | `App.DeveloperKit.CustomComponents` | `Sas_H_CustomComponent` | host | Custom component listesi ve satırdaki **Design** butonuyla **Visual Designer** girişi (§10; `/admin/developerkit/components/design/:id`). Kayıtlar `data/App.DeveloperKit.CustomComponents/{Id}.json` klasörüne satır başına senkronlanır; public sayfalar ile üst/alt bilgi de buradadır. |
| **Developer Kit › ListForm** | `App.Listforms.Listform` | `Sas_H_ListForm` · `Sas_H_ListFormField` · `Sas_H_ListFormWorkflow` · `Sas_H_ListFormCustomization` · `Sas_H_ListFormImport` | host | Ekran tanımlarının kendisi. Bu dosyada anlatılan bütün JSON kolonlarının canlı hâli; düzenleyicisi `/admin/listform/edit/{kod}`. | | **Developer Kit › ListForm** | `App.Listforms.Listform` | `Sas_H_ListForm` · `Sas_H_ListFormField` · `Sas_H_ListFormWorkflow` · `Sas_H_ListFormCustomization` · `Sas_H_ListFormImport` | host | Ekran tanımlarının kendisi. Bu dosyada anlatılan bütün JSON kolonlarının canlı hâli; düzenleyicisi `/admin/listform/edit/{kod}`. |
| **Developer Kit › Wizard Manager** | menü kodu `App.Listforms.WizardManager` · yetki `App.Listforms.Wizard` · `/admin/listform/wizardManager` | — | host | Wizard seed dosyalarının listesi, düzenlemesi, silinmesi, export/import'u. Sihirbazın kendisi ayrı bir rotadadır: `/admin/listform/wizard`. | | **Developer Kit › Intranet Widgets** | `App.DeveloperKit.IntranetWidgets` | `Sas_T_IntranetWidget` | tenant | Intranet panosunda hangi widget'ın hangi kolonda (`Column`), hangi sırada (`Order`) ve hangi yetkiyle (`PermissionName`) çizileceği; `SourceType` `Builtin` (koddaki `Code`) ya da `Custom` (`ComponentName` ile bir custom component). Seed: `data/App.DeveloperKit.IntranetWidgets.json`. |
| **Developer Kit › MCP Servers** | `App.DeveloperKit.McpServers` · `/admin/list/App.DeveloperKit.McpServers` | `Sas_H_McpServer` | host | `/mcp` ucunun kiracı bazlı sözleşmesi: `Name`, `Url`, `Tenants`, `AllowedTools` (boşsa tüm araçlar, doluysa yalnızca seçilenler açık), `MaxRows`. Araç listesi bu kayda göre süzülür, çağrı anında aynı kural yeniden uygulanır. Yetkiler: ekran için `App.DeveloperKit.McpServers`, araç çağırma için `.Invoke`, veri yazma için `.Write`, prompt ile tablo/ekran/bileşen geliştirme (`create_table`, wizard deploy, custom component kaydı) için `.Develop` (host; Wizard ve Custom Components yetkilerini ayrıca ister). Kiracı kullanıcısı yetkisi ne olursa olsun yalnızca okur (`McpToolNames.TenantTools`: şema araçları, `query_list`, `run_select`); yazma, `create_table`, wizard, component ve `run_query` kiracıya kapalıdır. Host için tek sunucu anahtarı `AllowedTools`. MCP yetki vermez: kullanıcı yalnızca uygulamada okuyabildiği listeleri görür ve sorgular; ham SQL `App.SqlQueryManager` ister. Kayıtlar `data/App.DeveloperKit.McpServers.json` dosyasına senkronlanır. Araçlar ve şema keşfinin kaynağı: `README.md` §13.9. | | **Developer Kit › MCP Servers** | `App.DeveloperKit.McpServers` | `Sas_H_McpServer` | host | `/mcp` ucunun kiracı bazlı sözleşmesi: `Name`, `Url`, `Tenants`, `AllowedTools` (boşsa tüm araçlar, doluysa yalnızca seçilenler), `MaxRows`. Yetkiler: ekran `App.DeveloperKit.McpServers`, araç çağırma `.Invoke`, veri yazma `.Write`, tablo/ekran/bileşen geliştirme (`McpToolNames.DevelopTools`) `.Develop` — arkasındaki Wizard/Custom Components yetkileri ayrıca istenir. Kiracı kullanıcısı yalnızca okur (`TenantTools`: şema araçları, `query_list`, `run_select`); ham SQL `App.SqlQueryManager` ister; MCP yetki vermez. Kayıtlar `data/App.DeveloperKit.McpServers.json`'a senkronlanır. Ayrıntı: `README.md` §13.9. |
| **Forum Management** | `App.ForumManagement` (grup menüsü) | `Sas_T_ForumCategory` · `Sas_T_ForumTopic` · `Sas_T_ForumPost` | tenant | Altında Categories / Topics / Posts ListForm ekranları; yayın tarafı Administration'daki `/admin/forum`. | | **Developer Kit › Wizard Manager** | menü kodu `App.Listforms.WizardManager` · yetki `App.Listforms.Wizard` · `/admin/listform/wizardManager` | `configs/seeds/{kapsam}/wizard/*.json` | host | Wizard seed dosyalarının kart/liste görünümü: menü üst düğümü ve URL, **bağımlılıklar**, düzenleme, export (bağımlılık kapanışı) / import ve **silme** (`WizardRecordCleaner`: ekran ve izlenen kayıtları kaldırılır, başka ekran kullanıyorsa engellenir, sonuç raporlanır — `lowcode` §4.5). Sihirbazın kendisi `/admin/listform/wizard`. |
| **Forum Categories** | `App.ForumManagement.Categories` · `/admin/list/App.ForumManagement.Categories` | `Sas_T_ForumCategory` | tenant | Forum kategorilerinin ListForm ekranı; veri `configs/seeds/host/data/App.ForumManagement.Categories.json` dosyasından seed edilir. | | **Forum Management › Categories / Topics / Posts** | `App.ForumManagement.Categories` · `.Topics` · `.Posts` | `Sas_T_ForumCategory` · `Sas_T_ForumTopic` · `Sas_T_ForumPost` | tenant | Forumun yönetim tarafı: kategori (seed `data/App.ForumManagement.Categories.json`), konu (kategori lookup'ı, sayaçlar, sabitle/kilitle/çözüldü bayrakları), gönderi (konu lookup'ı, kabul edilen yanıt). Kullanıcı tarafı Administration'daki `/admin/forum`. |
| **Forum Topics** | `App.ForumManagement.Topics` · `/admin/list/App.ForumManagement.Topics` | `Sas_T_ForumTopic` | tenant | Forum konuları; kategori lookup'ı, sayaçlar ve sabitle/kilitle/çözüldü bayrakları. |
| **Forum Posts** | `App.ForumManagement.Posts` · `/admin/list/App.ForumManagement.Posts` | `Sas_T_ForumPost` | tenant | Forum gönderileri; konu lookup'ı, kabul edilen yanıt bayrağı. |
> Menü kodu ile yetki adı **her zaman aynı değildir**: Wizard Manager'da kod > Menü kodu ile yetki adı **her zaman aynı değildir**: Wizard Manager'da kod
> `App.Listforms.WizardManager`, yetki `App.Listforms.Wizard`'dır; Administration'daki Forum > `App.Listforms.WizardManager`, yetki `App.Listforms.Wizard`'dır; Administration'daki Forum
> ekranında kod `App.Forum`, yetki `App.ForumManagement.Publish`'tir. Yeni ürettiğin ekranlarda > ekranında kod `App.Forum`, yetki `App.ForumManagement.Publish`'tir; Org Chart menüsü
> `App.Definitions.OrgChart` ister ama `/admin/organization` rotası `App.Definitions.Department`
> ister (menüyü gören ama sayfayı açamayan kullanıcı olabilir). Yeni ürettiğin ekranlarda
> ikisini ayırma — wizard zaten aynı kökü kullanır (`lowcode` §2). > ikisini ayırma — wizard zaten aynı kökü kullanır (`lowcode` §2).
### 12.3 Administration menüsü ### 12.3 Administration menüsü
Kök menü `App.Administration`. Bu menünün tabloları `Adm_T_*` — yani **kiracı başına** ayrışır. Kök menü `App.Administration`. Tabloların çoğu `Adm_T_*` — yani **kiracı başına** ayrışır; Identity
ekranları ABP tablolarıdır, Licence/Dev Request host tablolarını okur.
| Ekran | Kod / route | Tablo | Komponent üretirken ne işe yarar | | Ekran | Kod / route | Tablo | Komponent üretirken ne işe yarar |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| **Definitions › Sector** | `App.Definitions.Sector` | `Adm_T_Sector` | Sektör lookup’ı. Veri `configs/seeds/host/data/App.Definitions.Sector.json` dosyasından seed edilir. | | **Definitions › Sector** | `App.Definitions.Sector` | `Adm_T_Sector` | Sektör lookup’ı. Veri `data/App.Definitions.Sector.json`'dan seed edilir. |
| **Definitions › Department** | `App.Definitions.Department` | `Adm_T_Department` | `ParentId` ile **ağaç (TreeList) düzeninin** referansı; personel/onay ekranlarının departman lookup'ı. | | **Definitions › Department** | `App.Definitions.Department` | `Adm_T_Department` | `ParentId` ile **ağaç (TreeList) düzeninin** referansı; personel/onay ekranlarının departman lookup'ı. |
| **Definitions › Job Position** | `App.Definitions.JobPosition` | `Adm_T_JobPosition` | Ünvan ağacı (`ParentId` + `DepartmentId`) — departmana bağlı cascade örneği. | | **Definitions › Job Position** | `App.Definitions.JobPosition` | `Adm_T_JobPosition` | Ünvan ağacı (`ParentId` + `DepartmentId`) — departmana bağlı cascade örneği. |
| **Definitions › Org Chart** | `App.Definitions.OrgChart` · `/admin/organization` | `Adm_T_Department` | Departman/ünvan verisinin organizasyon şeması görünümü. | | **Definitions › Org Chart** | menü yetkisi `App.Definitions.OrgChart` · `/admin/organization` | `Adm_T_Department` · `Adm_T_JobPosition` | Departman/ünvan verisinin organizasyon şeması görünümü (özel React sayfası). |
| **Licence** | `App.Licence` · `/admin/form/App.Licence` | `AbpTenants` + `V_Sas_H_OrderItem_ByTenantId` | **`ListFormType = Form`** (listesiz, tek kayıtlık ekran) + alt kalem listesi. "Tek kayıtlık kart ekran" isteğinin karşılığı budur. | | **Licence** | `App.Licence` · `/admin/form/App.Licence` | `AbpTenants` + `V_Sas_H_OrderItem_ByTenantId` | **`ListFormType = Form`** (listesiz, tek kayıtlık ekran) + alt kalem listesi. "Tek kayıtlık kart ekran" isteğinin karşılığı budur. |
| **Dev Request** | `App.DevRequest` | `Sas_H_DevRequest` | Kiracı tarafındaki talep ekranı (Saas'taki listenin kullanıcı yüzü). | | **Dev Request** | `App.DevRequest` | `Sas_H_DevRequest` | Kiracı tarafındaki talep ekranı (Saas'taki listenin kullanıcı yüzü; `UserName` varsayılanı `@USERNAME`). |
| **Agenda** | `App.Agenda` | `Adm_T_Agenda` | **Takvim (Scheduler) düzeninin** referansı: `StartDate`, `EndDate`, `AllDay`, `RecurrenceRule`, `RecurrenceException`. Tekrarlayan randevu isteği kod gerektirmez. | | **Bildirimler › Bildirim Şablonları** | `App.Notifications.NotificationTemplates` | `Adm_T_NotificationTemplate` | Elle gönderimde seçilen mesaj metinleri: `Code`, `Name`, `Channel` (boş = tüm kanallar), `Subject`, `Body` (`{AdSoyad}`, `{KullaniciAdi}`, `{Eposta}`, `{Tarih}`, `{Saat}`, `{Kiraci}` yer tutucuları), `IsActive`. Boş bırakılan konu/gövde şablondan tamamlanır. Seed: `data/App.Notifications.NotificationTemplates.json`. |
| **Bildirimler › Bildirim Türleri / Kuralları** | `App.Notifications.NotificationTypes` · `.NotificationRules` | `Adm_T_NotificationType` · `Adm_T_NotificationRule` | Olay bazlı bildirim (7 kanal); tür ve kural kiracıya aittir, yeni kiraciya varsayılan küme kopyalanır. Ayrıntı: §9.11, `README.md` §13.5.1. | | **Bildirimler › Bildirim Türleri / Kuralları** | `App.Notifications.NotificationTypes` · `.NotificationRules` | `Adm_T_NotificationType` · `Adm_T_NotificationRule` | Olay bazlı bildirim: tür + kanal + alıcı (`All`/`User`/`Role`/`OrganizationUnit`/`Custom`), `IsFixed` zorunlu kural. 8 kanal (`Sms`, `Mail`, `Rocket`, `Desktop`, `UiActivity`, `UiToast`, `WhatsApp`, `Telegram`); etiketleri `App.NotificationChannel.{Kanal}` dil anahtarlarıdır. Tür ve kural kiracıya aittir, yeni kiracıya varsayılan küme kopyalanır (`NotificationTenantDefaultsSeedContributor`). Kurallar ekranında `CreateNotification` diyaloğu da vardır. Ayrıntı: `lowcode` §9.11, `README.md` §13. |
| **Bildirimler › Bildirimler** | `App.Notifications.Notification` | `Adm_T_Notification` | Hem kuyruk günlüğü hem elle gönderim ekranı: liste kural motorunun ürettiklerini de gösterir, ekleme formu alıcı × kanal açılımını kuyruğa yazar (`list-form-dynamic-api/notification-insert`). Ayrı bir manuel gönderim tablosu yoktur. Ayrıntı: `README.md` §13.5.1. | | **Bildirimler › Bildirimler** | `App.Notifications.Notification` | `Adm_T_Notification` | Hem kuyruk günlüğü hem elle gönderim ekranı: liste kural motorunun ürettiklerini de gösterir, ekleme formu alıcı × kanal açılımını kuyruğa yazar (`InsertServiceAddress = list-form-dynamic-api/notification-insert`; `dxTagBox` çoklu alıcı/kanal). Tip her zaman `Manuel`, güncelleme kapalı. Ayrı bir manuel gönderim tablosu yoktur. Ayrıntı: `README.md` §13.5.1. |
| **Bildirimler › Bildirim Şablonları** | `App.Notifications.NotificationTemplates` | `Adm_T_NotificationTemplate` | Elle gönderimde seçilen mesaj şablonları (kanal, konu, gövde, yer tutucular); şablon seçilince konu ve gövde forma kopyalanır. Örnek satırlar seed ile gelir. | | **Agenda** | `App.Agenda` | `Adm_T_Agenda` | **Takvim (Scheduler) düzeninin** referansı (`DefaultLayout: scheduler`): `StartDate`, `EndDate`, `AllDay`, `RecurrenceRule`, `RecurrenceException`. Tekrarlayan randevu isteği kod gerektirmez. |
| **Settings** | `App.Setting` · `/admin/settings` | — | `SettingDefinition` kayıtlarından üretilen ayar ekranı; değerler burada girilir. | | **Settings** | `App.Setting` · `/admin/settings` | — | `SettingDefinition` kayıtlarından üretilen ayar ekranı; değerler burada girilir. |
| **Intranet › Announcement (+Like/Comment)** | `App.Intranet.Announcement` | `Adm_T_Announcement` · `Adm_T_AnnouncementLike` · `Adm_T_AnnouncementComment` | Duyuru + beğeni + yorum: **ana kayıt / alt etkileşim** kalıbının hazır örneği. | | **Intranet › Announcement** | `App.Intranet.Announcement` (alt formlar Like/Comment) | `Adm_T_Announcement` · `Adm_T_AnnouncementLike` · `Adm_T_AnnouncementComment` | Duyuru + beğeni + yorum: **ana kayıt / alt etkileşim** kalıbının hazır örneği. |
| **Intranet › Survey (+Question/Option/Response/Answer)** | `App.Intranet.Survey` | `Adm_T_Survey` · `Adm_T_SurveyQuestion` · `Adm_T_SurveyQuestionOption` · `Adm_T_SurveyResponse` · `Adm_T_SurveyAnswer` | Anket motoru; soru–seçenek–yanıt zinciri **iki seviyeli alt form** ihtiyacının referansıdır. | | **Intranet › Survey** | `App.Intranet.Survey` (alt form Question → Option; Response → Answer) | `Adm_T_Survey` · `Adm_T_SurveyQuestion` · `Adm_T_SurveyQuestionOption` · `Adm_T_SurveyResponse` · `Adm_T_SurveyAnswer` | Anket motoru; soru–seçenek–yanıt zinciri **iki seviyeli alt form** ihtiyacının referansıdır. |
| **Intranet › Social Post (+Comment/Like)** | `App.Intranet.SocialPost` | `Adm_T_SocialPost` · `Adm_T_SocialComment` · `Adm_T_SocialLike` (+ `SocialPollOption`, `SocialMedia`, `SocialLocation`) | Kurum içi akış; `IsLiked`, `IsOwnPost` gibi hesaplanmış kolonların view içinde üretilmesine örnek. Alt formlar: `App.Intranet.SocialMedia`, `SocialComment`, `SocialLike` (`Id` → `SocialPostId`); anket seçenekleri (`App.Intranet.SocialPollOption`) medyaya bağlı olduğu için `SocialMedia` ekranının alt formudur (`Id` → `SocialMediaId`). | | **Intranet › Social Post** | `App.Intranet.SocialPost` | `Adm_T_SocialPost` · `Adm_T_SocialComment` · `Adm_T_SocialLike` (+ `SocialPollOption`, `SocialMedia`, `SocialLocation`) | Kurum içi akış; `IsLiked`, `IsOwnPost` gibi hesaplanmış kolonların view içinde üretilmesine örnek. Alt formlar: `App.Intranet.SocialMedia`, `SocialComment`, `SocialLike` (`Id` → `SocialPostId`); anket seçenekleri (`App.Intranet.SocialPollOption`) medyaya bağlı olduğu için `SocialMedia` ekranının alt formudur (`Id` → `SocialMediaId`). |
| **Intranet › Event Type / Category / Event (+Like/Comment)** | `App.Intranet.Events.*` | `Adm_T_EventType` · `Adm_T_EventCategory` · `Adm_T_Event` · `Adm_T_EventPhoto` · `Adm_T_EventLike` · `Adm_T_EventComment` | Etkinlik yönetimi; foto ve katılımcı sayacı olan kayıt kalıbı. `EventComment` menüde Intranet altında (Documents'ın üstünde), `EventPhoto` menüde yer almaz; ikisinin yetkisi de `App.Intranet.Events.Event` altındadır. `Adm_T_EventPhoto` tablosu `configs/seeds/host/sql/object/Adm_T_EventPhoto.sql` ile oluşturulur. | | **Intranet › Event Type / Category / Event** | `App.Intranet.Events.EventType` · `.EventCategory` · `.Event` | `Adm_T_EventType` · `Adm_T_EventCategory` · `Adm_T_Event` · `Adm_T_EventPhoto` · `Adm_T_EventLike` · `Adm_T_EventComment` | Etkinlik yönetimi; foto ve katılımcı sayacı olan kayıt kalıbı. `EventLike`/`EventComment` alt formdur, `EventPhoto` menüde yer almaz; yetkileri `App.Intranet.Events.Event` altındadır. `Adm_T_EventPhoto` tablosu `sql/object/Adm_T_EventPhoto.sql` ile oluşturulur. |
| **Intranet › Documents** | `App.Intranet.Document` · `/admin/intranet-documents` | Dosya yöneticisi (`intranet` / `intranet\|_passive` klasörleri) | Kurum içi doküman paylaşımı — aktif/pasif klasör, yükleme, taşıma, toplu silme. Doküman listesi isteği yeni tablo gerektirmez. |
| **Restrictions › Work Hour** | `App.Restrictions.WorkHour` | `Adm_T_WorkHour` | Gün bazlı çalışma saati (`Monday`…`Sunday`, `StartTime`, `EndTime`); kullanıcıya `AbpUsers.WorkHour` ile bağlanır. "Sadece mesai saatinde girilebilsin" burada çözülür. | | **Restrictions › Work Hour** | `App.Restrictions.WorkHour` | `Adm_T_WorkHour` | Gün bazlı çalışma saati (`Monday`…`Sunday`, `StartTime`, `EndTime`); kullanıcıya `AbpUsers.WorkHour` ile bağlanır. "Sadece mesai saatinde girilebilsin" burada çözülür. |
| **Restrictions › IP Restrictions** | `App.Restrictions.IpRestrictions` | `Adm_T_IpRestriction` | `ResourceType` + `ResourceId` + `IP` — kullanıcı/rol bazlı IP kısıtı. | | **Restrictions › IP Restrictions** | `App.Restrictions.IpRestrictions` | `Adm_T_IpRestriction` | `ResourceType` + `ResourceId` + `IP` — kullanıcı/rol bazlı IP kısıtı. |
| **Identity › Permission Groups / Permissions** | `Abp.Identity.PermissionGroups` · `Abp.Identity.Permissions` | `AbpPermissionGroups` · `AbpPermissions` | Yetki ağacı (tree düzeni). Yeni ekranın yetkileri burada görünür; `Modules` kolonu yetkiyi modüllere bağlar (pipe ile çoklu). | | **Identity › Permission Groups / Permissions** | `Abp.Identity.PermissionGroups` · `Abp.Identity.Permissions` | `AbpPermissionGroups` · `AbpPermissions` | Yetki ağacı (tree düzeni). Yeni ekranın yetkileri burada görünür; `Modules` kolonu yetkiyi modüllere bağlar (pipe ile çoklu), `Order` kardeşler arası sıradır. Seed: `data/Abp.Identity.Permission{Groups,s}.json`. |
| **Identity › Claim Type** | `App.IdentityManagement.ClaimType` | `AbpClaimTypes` | Kullanıcıya ek alan (claim) tanımı: `ValueType`, `Regex`, `Required`, `IsStatic`. | | **Identity › Claim Type** | `App.IdentityManagement.ClaimType` | `AbpClaimTypes` | Kullanıcıya ek alan (claim) tanımı: `ValueType`, `Regex`, `Required`, `IsStatic`. |
| **Identity › Roles** | `AbpIdentity.Roles` | `AbpRoles` | Rol yönetimi + `RolesPermission` diyaloğu; yeni ekranın yetkisi role buradan verilir. | | **Identity › Roles** | `AbpIdentity.Roles` | `AbpRoles` | Rol yönetimi + `RolesPermission` diyaloğu; yeni ekranın yetkisi role buradan verilir. Yazma `list-form-dynamic-api/role-*`. |
| **Identity › Users** | `AbpIdentity.Users` | `AbpUsers` | Kullanıcı yönetimi + `UsersPermission` diyaloğu, **KPI widget'ları** ve `list-form-dynamic-api/user-*` ile devredilen yazma. Kullanıcı `WorkHour`, `DepartmentId`, `JobPositionId` alanlarını taşır. | | **Identity › Users** | `AbpIdentity.Users` · detay `/admin/users/detail/:userId` | `AbpUsers` | Kullanıcı yönetimi + `UsersPermission` diyaloğu, **KPI widget'ları** ve `list-form-dynamic-api/user-*` ile devredilen yazma. Kullanıcı `WorkHour`, `DepartmentId`, `JobPositionId` alanlarını taşır. |
| **Identity › Organization Units** | `Abp.Identity.OrganizationUnits` · `/admin/ous` | ABP OU tabloları | Birim ağacı. Ekranı `IsOrganizationUnit = true` yaparsan veri bu ağaca göre süzülür; bildirim alıcısı da OU olabilir. | | **Identity › Organization Units** | `Abp.Identity.OrganizationUnits` · `/admin/ous` | ABP OU tabloları | Birim ağacı. Ekranı `IsOrganizationUnit = true` yaparsan veri bu ağaca göre süzülür; bildirim alıcısı da OU olabilir. |
| **Identity › Audit Logs** | `App.IdentityManagement.AuditLogs` | `AbpAuditLogs` | İstek denetim kaydı + `AuditLogDetail` diyaloğu. "Kim ne zaman ne yaptı" isteği yeni tablo gerektirmez. | | **Identity › Audit Logs** | `App.IdentityManagement.AuditLogs` | `AbpAuditLogs` | İstek denetim kaydı + `AuditLogDetail` diyaloğu. "Kim ne zaman ne yaptı" isteği yeni tablo gerektirmez. |
| **Identity › Sessions** | `App.IdentityManagement.Sessions` | `AbpSessions` | Açık oturumlar; `UiEvalService.ApiKickUser` ile oturum düşürme (§9.13). | | **Identity › Sessions** | `App.IdentityManagement.Sessions` | `AbpSessions` | Açık oturumlar; `UiEvalService.ApiKickUser` ile oturum düşürme (`lowcode` §9.13). |
| **Reports › Categories / Templates** | `App.Reports.Categories` · `App.Reports.ReportTemplates` | `Adm_T_ReportCategory` · `Adm_T_ReportTemplate` | Kendi düzeni olan çıktılar (fatura, teklif); ekrana `CommandColumnJson` butonuyla bağlanır (§9.12). | | **Reports › Categories / Templates** | `App.Reports.Categories` · `App.Reports.ReportTemplates` | `Adm_T_ReportCategory` · `Adm_T_ReportTemplate` | Kendi düzeni olan çıktılar (fatura, teklif); ekrana `CommandColumnJson` butonuyla bağlanır (`lowcode` §9.12). |
| **Videoroom** | `App.Videoroom` · `/admin/videoroom/dashboard` | `Adm_T_Videoroom` · `Adm_T_VideoroomParticipant` · `Adm_T_VideoroomAttandance` · `Adm_T_VideoroomChat` | Görüntülü oda, katılım ve sohbet kaydı. | | **Videoroom** | `App.Videoroom` · `/admin/videoroom/dashboard` | `Adm_T_Videoroom` · `Adm_T_VideoroomParticipant` · `Adm_T_VideoroomAttandance` · `Adm_T_VideoroomChat` | Görüntülü oda, katılım ve sohbet kaydı. |
| **Files** | `App.Files` · `/admin/files` | — | Dosya yöneticisi. Ekranın dosya alanı için ayrı depolama kurma; dosya/görsel editörleri bu altyapıyı kullanır. |
| **Forum** | menü kodu `App.Forum` · yetki `App.ForumManagement.Publish` · `/admin/forum` | `Sas_T_Forum*` | Forumun kullanıcı tarafı. | | **Forum** | menü kodu `App.Forum` · yetki `App.ForumManagement.Publish` · `/admin/forum` | `Sas_T_Forum*` | Forumun kullanıcı tarafı. |
Menüde görünmeyen ama route'u olan ekranlar: `/admin/dashboard`, `/admin/ai`, Menüde görünmeyen ama route'u olan ekranlar: `/admin/dashboard`, `/admin/ai`,
`/admin/activityLog`, `/admin/changeLog`, `/admin/profile/{general,password,notification-settings}`, `/admin/activityLog`, `/admin/changeLog`, `/admin/profile/{general,password,notification-settings}`,
`/admin/users/detail/:userId` (yetki `AbpIdentity.Users.Update`), `/admin/videoroom/list` ve `/admin/users/detail/:userId` (yetki `AbpIdentity.Users.Update`), `/admin/videoroom/list` ve
`/admin/videoroom/room/:id`, `/admin/reports/*`, `/admin/listform/{wizard,wizardManager}`, `/admin/videoroom/room/:id`, `/admin/reports/*`, `/admin/listform/{wizard,wizardManager}`,
`/admin/listform/edit/:listFormCode` ve dinamik ekran rotaları. `/admin/listform/edit/:listFormCode`, `/admin/developerkit/components/design/:id` ve dinamik ekran
rotaları. Custom component'lerin kendi `RoutePath`'leri (`/admin/roles`, `/admin/roles-list` gibi)
route tablosunda değil bileşen kaydındadır.
**Dinamik ekran rotaları** — üretilen her ListForm ekranı bunları kullanır, ayrıca route kaydı **Dinamik ekran rotaları** — üretilen her ListForm ekranı bunları kullanır, ayrıca route kaydı
açılmaz: açılmaz:
@ -1258,10 +1335,15 @@ açılmaz:
### 12.4 ListForm olmayan (özel React) ekranlar ### 12.4 ListForm olmayan (özel React) ekranlar
Bu ekranlar `Sas_H_Route` kayıtlarıyla yönetilir (seed: Bu ekranlar `Sas_H_Route` kayıtlarıyla yönetilir (seed:
`configs/seeds/host/data/App.Menus.Routes.json`). Yenisini eklemek **kod yazmak demektir** — karar sırasının son adımıdır. `configs/seeds/host/data/App.Menus.Routes.json`). Yenisini eklemek **kod yazmak demektir** — karar
sırasının son adımıdır ve çerçeve dışıdır (onay ister, `lowcode` §0.8). Rotalı bir sayfa ihtiyacının
çerçeve içi karşılığı `RoutePath` taşıyan bir custom component'tir.
Bir route kaydının alanları: `Id`, `Key`, `Path`, `ComponentType`, `ComponentPath` (`@/views/...`), Bir route kaydının alanları: `Id`, `Key`, `Path`, `ComponentType`, `ComponentPath` (`@/views/...`),
`RouteType`, `Authority` (virgülle ayrılmış yetki listesi). `RouteType`, `Authority` (virgülle ayrılmış yetki listesi) ve SEO alanları `SeoTitle`,
`SeoDescription`, `SeoKeywords`, `SeoOgImage`, `SeoCanonicalUrl`, `SeoNoIndex`,
`SeoIncludeInSitemap`, `SeoChangeFrequency`, `SeoPriority`, `SeoStructuredData` (Custom Component
kaydı aynı `Seo*` kümesini taşır).
| `routeType` | Anlam | | `routeType` | Anlam |
| --- | --- | | --- | --- |
@ -1284,29 +1366,35 @@ görünürlük `checkPermission` ile bileşen içinde kurulur (`lowcode` §7.5).
| `/admin/reports/:report/{view,design}/:id?/:listFormCode?` | `DevexpressReportViewer` · `DevexpressReportDesigner` | — | | `/admin/reports/:report/{view,design}/:id?/:listFormCode?` | `DevexpressReportViewer` · `DevexpressReportDesigner` | — |
| `/admin/settings` | `settings/Settings` | `App.Setting` | | `/admin/settings` | `settings/Settings` | `App.Setting` |
| `/admin/files` | `admin/files/FileManager` | `App.Files` | | `/admin/files` | `admin/files/FileManager` | `App.Files` |
| `/admin/ous` · `/admin/organization` | `organization-unit/OrganizationUnits` · `hr/OrgChart` | `Abp.Identity.OrganizationUnits` · `App.Definitions.Department` | | `/admin/intranet-documents` | `intranet/documents/IntranetDocuments` | `App.Intranet.Document` |
| `/admin/ous` · `/admin/organization` | `organization-unit/OrganizationUnits` · `hr/OrgChart` | `Abp.Identity.OrganizationUnits` · `App.Definitions.Department` (menü `App.Definitions.OrgChart` ister — §12.2 notu) |
| `/admin/forum` | `forum/Forum` | `App.ForumManagement.Publish` | | `/admin/forum` | `forum/Forum` | `App.ForumManagement.Publish` |
| `/admin/videoroom/{dashboard,list,room/:id}` | `admin/videoroom/{Dashboard,RoomList,RoomDetail}` | `App.Videoroom{,.List,.Detail}` | | `/admin/videoroom/{dashboard,list,room/:id}` | `admin/videoroom/{Dashboard,RoomList,RoomDetail}` | `App.Videoroom{,.List,.Detail}` |
| `/admin/ai` | `ai/Assistant` | `App.Definitions.AiBot.Asistant` | | `/admin/ai` | `ai/Assistant` | `App.Definitions.AiBot.Asistant` |
| `/admin/dashboard` · `/admin/activityLog` · `/admin/changeLog` · `/admin/profile/*` | `Dashboard` · `admin/activityLog/ActivityLog` · `version/ChangeLog` · `admin/profile/Profile` | `[]` | | `/admin/dashboard` · `/admin/activityLog` · `/admin/changeLog` · `/admin/profile/*` | `Dashboard` · `admin/activityLog/ActivityLog` · `version/ChangeLog` · `admin/profile/Profile` | `[]` |
| `/admin/users/detail/:userId` | `admin/user-management/Details` | `AbpIdentity.Users.Update` | | `/admin/users/detail/:userId` | `admin/user-management/Details` | `AbpIdentity.Users.Update` |
**Oturum gerektirmeyen sayfalar** (`routeType: public`) — genel site. `/home` · `/about` · **Oturum gerektirmeyen sayfalar** — genel site. `/home` · `/about` · `/contact` route tablosunda
`/contact` içerikleri kod değil, DeveloperKit > Custom Components (Visual Designer) altındaki **yoktur**: `/admin/` ile başlamayan `RoutePath`'li Custom Component otomatik public rota olur
tasarım belgesinden gelir (README.md §10.4); bir "tanıtım sayfası" isteğinde yeni React sayfası (aynı yolu paylaşan fiziksel rotayı gölgeler). Bir "tanıtım sayfası" isteğinde yeni React sayfası
yazma, oradan yeni bir Custom Component üret. `Services` sayfası yoktur. yazma; tasarımcıda yeni bir Custom Component + `Pub` menü kaydı (`App.Public.Header` altı) üret
(`README.md` §10.4). Üst ve alt bilgi rotasız bileşenlerdir (`PublicHeader`, `PublicFooter`,
`RoutePath = NULL`); public bileşenlerin hepsi tasarımcı belgesidir (`sourceMode: visual`).
| Route | Bileşen | Veri | | Route | Bileşen | Veri |
| --- | --- | --- | | --- | --- | --- |
| `/home` · `/about` · `/contact` | Custom Component (`PublicHomePage` · `PublicAboutPage` · `PublicContactPage`) | `data/App.DeveloperKit.CustomComponents/{Id}.json` · tasarımcı: DeveloperKit > Custom Components | | `/home` · `/about` · `/contact` | Custom Component (`PublicHomePage` · `PublicAboutPage` · `PublicContactPage`) | `data/App.DeveloperKit.CustomComponents/{Id}.json` · SEO bileşen kaydında |
| (rotasız) | Custom Component (`PublicHeader` · `PublicFooter`) | Üst menü + alt bilgi hızlı bağlantıları: `Pub` menüsü `App.Public.Header` (uygulama konfigürasyonunun `publicMenus` alanı) |
| `/products` · `/checkout` · `/payment` · `/success` | `views/public/{Products,Checkout,Payment,Success}` | `Sas_H_Product` · `Sas_H_PaymentMethod` · `Sas_H_InstallmentOption` · `Sas_H_Order` | | `/products` · `/checkout` · `/payment` · `/success` | `views/public/{Products,Checkout,Payment,Success}` | `Sas_H_Product` · `Sas_H_PaymentMethod` · `Sas_H_InstallmentOption` · `Sas_H_Order` |
| `/blog` · `/blog/:id` | `views/public/{Blog,BlogDetail}` | `Sas_H_BlogPost` · `Sas_H_BlogCategory` | | `/blog` · `/blog/:id` | `views/public/{Blog,BlogDetail}` | `Sas_H_BlogPost` · `Sas_H_BlogCategory` |
| `/demo` | `views/public/Demo` | `Sas_H_Demo` | | `/demo` | `views/public/Demo` | `Sas_H_Demo` |
| `/access-denied` | `views/AccessDenied` | — | | `/access-denied` | `views/AccessDenied` | — |
Ziyaretçiye açık her yolun SEO alanları ayrı bir tabloda değil, yolu tanımlayan kaydın Ziyaretçiye açık her yolun SEO alanları ayrı bir tabloda değil, yolu tanımlayan kaydın
üzerindedir: `Route` satırının ya da Custom Component'in `Seo*` kolonları. Listeye yeni bir public üzerindedir: `Route` satırının ya da Custom Component'in `Seo*` kolonları; genel varsayılanlar
yol eklediğinde bu alanları da doldur (lowcode §0.9). `App.SiteManagement.Seo.*` ayarlarındadır. `sitemap.xml` `Pub` menülerini, aktif custom component
rotalarını ve yayınlanmış blog yazılarını toplar (`SeoAppService`). Yeni bir public yol üreten iş bu
alanları da doldurur (`lowcode` §0.9).
**Kimlik akışı** (`routeType: authenticated`): `/login`, `/register`, `/forgot-password`, **Kimlik akışı** (`routeType: authenticated`): `/login`, `/register`, `/forgot-password`,
`/reset-password`, `/confirm`, `/confirm/:userId/:token`, `/extend-login` → `/reset-password`, `/confirm`, `/confirm/:userId/:token`, `/extend-login` →
@ -1320,15 +1408,20 @@ yol eklediğinde bu alanları da doldur (lowcode §0.9).
| --- | --- | --- | | --- | --- | --- |
| "numara otomatik gelsin" | Saas › Definitions › Sequence | Kayıt aç, alan varsayılanına `CustomValueType: 5` | | "numara otomatik gelsin" | Saas › Definitions › Sequence | Kayıt aç, alan varsayılanına `CustomValueType: 5` |
| "her gece / saat başı çalışsın" | Saas › Background Workers | `WorkerType: 2` + `BeforeSp`; prosedür `sql/object/` altına | | "her gece / saat başı çalışsın" | Saas › Background Workers | `WorkerType: 2` + `BeforeSp`; prosedür `sql/object/` altına |
| "bilgilendirme gitsin" | Saas › Notifications (+ MailQueue §11) | Tür + kural; e-posta ise MailQueue | | "bilgilendirme gitsin" | Administration › Bildirimler (+ MailQueue §11) | Tür + kural (8 kanal); tablolu/ekli e-posta ise MailQueue |
| "elden bildirim/duyuru gönderelim" | Administration › Bildirimler › Bildirimler (+ Şablonlar) | Ekleme formu = elle gönderim; hazır metin için şablon kaydı |
| "onaya düşsün" | `WorkflowJson` + `ListFormWorkflow` (örnek: Sales Orders) | Onay düğümleri; `Inform` düğümü e-posta gönderir | | "onaya düşsün" | `WorkflowJson` + `ListFormWorkflow` (örnek: Sales Orders) | Onay düğümleri; `Inform` düğümü e-posta gönderir |
| "çıktısı alınsın / fatura basılsın" | Administration › Reports | Hazır `DynamicGrid` ya da `ReportTemplate` | | "çıktısı alınsın / fatura basılsın" | Administration › Reports | Hazır `DynamicGrid` ya da `ReportTemplate` |
| "dosya eklensin" | Administration › Files | Dosya/görsel editörü; ayrı depolama kurma | | "dosya eklensin" | Saas › Developer Kit › Files | Dosya/görsel editörü; ayrı depolama kurma |
| "fotoğraf çekilsin / barkod okutulsun / konum alınsın" | Alan editörü (§9.8 tablosu) · tasarımcıda `BarcodeScanField` | `Capture`, `@SCAN_BARCODE`, `BarcodeScanDialog`, `geoTo`; yeni editör yazma |
| "barkod/QR basılsın" | Visual Designer › `BarcodeViewer` | `value`'yu `Form` kolonuna bağla |
| "başka veritabanından gelsin" | Saas › Data Source | Yeni DataSource + ekranın `DataSourceCode` alanı | | "başka veritabanından gelsin" | Saas › Data Source | Yeni DataSource + ekranın `DataSourceCode` alanı |
| "ayarlanabilir olsun" | Saas › Setting Definitions | Tanım aç, değeri `/admin/settings`'ten yönet | | "ayarlanabilir olsun" | Saas › Setting Definitions | Tanım aç, değeri `/admin/settings`'ten yönet |
| "İngilizcesi de olsun" | Saas › Languages | Dil anahtarı + `LanguagesData.json` | | "İngilizcesi de olsun" | Saas › Languages | Dil anahtarı + `LanguagesData.json` |
| "aramada çıksın" | Saas › Definitions › Global Search | `System`/`Group`/`Term`/`Weight`/`Url` kaydı | | "aramada çıksın" | Saas › Definitions › Global Search | `System`/`Group`/`Term`/`Weight`/`Url` kaydı |
| "sadece şu rol görsün" | Administration › Identity › Roles / Permissions | Yetki kodu + ekranın `PermissionJson`'ı | | "sadece şu rol görsün" | Administration › Identity › Roles / Permissions | Yetki kodu + ekranın `PermissionJson`'ı |
| "herkes yalnızca kendi kayıtlarını görsün" / "şu rol şu bölgeyi görsün" | ListForm editörü › Kişiselleştirme | `ServerWhere` kaydı (herkes/rol/kullanıcı; §2.5) ya da `DefaultFilter` |
| "intranet ana sayfasına kutu eklensin" | Saas › Developer Kit › Intranet Widgets | `Custom` kaynaklı widget + custom component |
| "şube bazlı olsun" | Saas › Branches | `IsBranch = true` | | "şube bazlı olsun" | Saas › Branches | `IsBranch = true` |
| "birim ağacına göre süzülsün" | Administration › Identity › Organization Units | `IsOrganizationUnit = true` | | "birim ağacına göre süzülsün" | Administration › Identity › Organization Units | `IsOrganizationUnit = true` |
| "mesai dışında girilemesin" / "sadece ofis IP'si" | Administration › Restrictions | Work Hour · IP Restriction kaydı | | "mesai dışında girilemesin" / "sadece ofis IP'si" | Administration › Restrictions | Work Hour · IP Restriction kaydı |
@ -1353,9 +1446,11 @@ içinde ilgili `#region` altındadır.
| Tek kayıtlık form ekranı | `Licence` (`ListFormType = Form` + alt kalem listesi) | | Tek kayıtlık form ekranı | `Licence` (`ListFormType = Form` + alt kalem listesi) |
| Onay akışı | `Sales Orders` — `WorkflowJson` (`ApprovalUserFieldName`, `ApprovalStatusFieldName`, `ApprovalDateFieldName`, `ApprovalDescriptionFieldName`) + `ListFormWorkflow` düğümleri (Start → Approval → End/End) | | Onay akışı | `Sales Orders` — `WorkflowJson` (`ApprovalUserFieldName`, `ApprovalStatusFieldName`, `ApprovalDateFieldName`, `ApprovalDescriptionFieldName`) + `ListFormWorkflow` düğümleri (Start → Approval → End/End) |
| Alt form (master-detail) | `Tenant → Branches`, `Sales Orders → Sales Order Item`, `Survey → Question → Option` | | Alt form (master-detail) | `Tenant → Branches`, `Sales Orders → Sales Order Item`, `Survey → Question → Option` |
| KPI widget | `User` — `WidgetsJson`; sorgu `Title`, `Value`, `Color`, `SubTitle`, `Icon` kolonlarını döndürür | | KPI widget | `User`, `Dynamic Services`, `Custom Components` — `WidgetsJson`; tek sorgu `UNION ALL` ile birden çok kart döndürür (`Title`, `Value`, `Color`, `SubTitle`, `Icon`) |
| Toolbar'dan diyalog açma | `Tenant` (`TenantsConnectionString`), `Role` (`RolesPermission`), `User` (`UsersPermission`), `Audit Logs` (`AuditLogDetail`), `Notification Rule` (`CreateNotification`), `Branches` (`BranchSeed`), `Sales Orders` (`CreateTenantFromOrderDialog`), `Dynamic Services` (`DynamicServiceEditor` — hem toolbar hem satır) | | Toolbar'dan diyalog açma | `Tenant` (`TenantsConnectionString`), `Role` (`RolesPermission`), `User` (`UsersPermission`), `Audit Logs` (`AuditLogDetail`), `Notification Rule` (`CreateNotification`), `Branches` (`BranchSeed`), `Sales Orders` (`CreateTenantFromOrderDialog`), `Dynamic Services` (`DynamicServiceEditor` — hem toolbar hem satır) |
| Yazmayı servise devretme | `Tenant`, `Role`, `User` — `*ServiceAddress = "list-form-dynamic-api/{tenant\|role\|user}-{insert\|update}"` | | Yazmayı servise devretme | `Tenant`, `Role`, `User` — `*ServiceAddress = "list-form-dynamic-api/{tenant\|role\|user}-{insert\|update}"`; `Notification` — `notification-insert` (çoklu değer `MultiValueStringJsonConverter`) |
| Ekle düğmesini diyaloğa bağlama | `Dynamic Services` — `EditingOptionJson.AddDialogName = "DynamicServiceEditor"` |
| Satır butonundan servis silme | `Dynamic Services` — `UiEvalService.ApiDeleteDynamicService` |
| Toplam satırı | `Sales Order Item`, `Licence Item` (`TotalSummaryJson`) | | Toplam satırı | `Sales Order Item`, `Licence Item` (`TotalSummaryJson`) |
| View üzerinden okuma | `Background Worker Jobs`, `Licence Item` (`SelectCommandType = View`) | | View üzerinden okuma | `Background Worker Jobs`, `Licence Item` (`SelectCommandType = View`) |
| Cascade lookup | `City` → `District` (ülke/il/ilçe zinciri) | | Cascade lookup | `City` → `District` (ülke/il/ilçe zinciri) |

File diff suppressed because it is too large Load diff

View file

@ -54,7 +54,7 @@ React/C# kodu yazmadan, yalnızca konfigürasyon ile mümkündür.
| **Custom Component** | Babel ile tarayıcıda derlenen, veritabanında saklanan React bileşenleri ve bunların route'ları. | | **Custom Component** | Babel ile tarayıcıda derlenen, veritabanında saklanan React bileşenleri ve bunların route'ları. |
| **İş akışı / onay** | ListForm üzerinde görsel workflow tasarımcısı, koşullu dallanma ve çok kişili onay adımları. | | **İş akışı / onay** | ListForm üzerinde görsel workflow tasarımcısı, koşullu dallanma ve çok kişili onay adımları. |
| **Çok kiracılılık** | Tenant başına ayrı bağlantı dizesi (ayrı veritabanı) desteği, şube (branch) ve organizasyon birimi kırılımı. | | **Çok kiracılılık** | Tenant başına ayrı bağlantı dizesi (ayrı veritabanı) desteği, şube (branch) ve organizasyon birimi kırılımı. |
| **Bildirim ve entegrasyon** | SMS, e-posta, WhatsApp, Rocket.Chat, masaüstü ve UI kanallarına kural tabanlı bildirim. | | **Bildirim ve entegrasyon** | SMS, e-posta, WhatsApp, Telegram, Rocket.Chat, masaüstü ve UI kanallarına kural tabanlı bildirim. |
| **Raporlama** | DevExpress Report Designer/Viewer + ListForm'dan otomatik üretilen dinamik raporlar. | | **Raporlama** | DevExpress Report Designer/Viewer + ListForm'dan otomatik üretilen dinamik raporlar. |
| **Arka plan işleri** | Hangfire + ABP Background Worker; zamanlanmış SQL, mail kuyruğu, yedekleme, oturum temizliği. | | **Arka plan işleri** | Hangfire + ABP Background Worker; zamanlanmış SQL, mail kuyruğu, yedekleme, oturum temizliği. |
| **Gerçek zamanlı** | SignalR tabanlı messenger ve video oda (WebRTC/TURN) altyapısı. | | **Gerçek zamanlı** | SignalR tabanlı messenger ve video oda (WebRTC/TURN) altyapısı. |
@ -963,7 +963,7 @@ içindedir; oradaki kontroller yalnızca butonları gizler, asıl kontrol AppSer
| Aktivite ve denetim kaydı | `/admin/activityLog`, `/admin/changeLog` | Kullanıcı hareketleri ve ABP audit log detayı. | | Aktivite ve denetim kaydı | `/admin/activityLog`, `/admin/changeLog` | Kullanıcı hareketleri ve ABP audit log detayı. |
| Bildirimler | `/admin/profile/notification-settings`, bildirim ekranları | Kanal tercihleri ve bildirim oluşturma. | | Bildirimler | `/admin/profile/notification-settings`, bildirim ekranları | Kanal tercihleri ve bildirim oluşturma. |
| Forum | `/admin/forum` | Forum kullanımı; yönetim `App.ForumManagement` altındaki ListForm ekranlarıyla yapılır. | | Forum | `/admin/forum` | Forum kullanımı; yönetim `App.ForumManagement` altındaki ListForm ekranlarıyla yapılır. |
| Intranet | Intranet dashboard ve widget'ları | Duyuru, anket, sosyal duvar, etkinlik. Hangi widget'ın hangi kolonda, hangi sırada ve hangi yetkiyle yayınlandığı `Adm_T_IntranetWidget` kaydından gelir; kayıtlar `configs/seeds/{kapsam}/data/App.DeveloperKit.IntranetWidgets.json` ile senkron tutulur. | | Intranet | Intranet dashboard ve widget'ları | Duyuru, anket, sosyal duvar, etkinlik. Hangi widget'ın hangi kolonda, hangi sırada ve hangi yetkiyle yayınlandığı `Sas_T_IntranetWidget` kaydından gelir; kayıtlar `configs/seeds/{kapsam}/data/App.DeveloperKit.IntranetWidgets.json` ile senkron tutulur. |
| Video oda | `/admin/videoroom/*` | Oda listesi, detay, planlama, katılımcı ve ekran paylaşımı. | | Video oda | `/admin/videoroom/*` | Oda listesi, detay, planlama, katılımcı ve ekran paylaşımı. |
| Raporlar | `/admin/reports/:report/view|design/...` | DevExpress rapor görüntüleyici ve tasarımcı. | | Raporlar | `/admin/reports/:report/view|design/...` | DevExpress rapor görüntüleyici ve tasarımcı. |
| AI asistanı | `/admin/ai` | n8n webhook üzerinden sohbet arayüzü. | | AI asistanı | `/admin/ai` | n8n webhook üzerinden sohbet arayüzü. |
@ -1184,7 +1184,14 @@ rota ve menüleri.
### 13.1. Kanallar ### 13.1. Kanallar
`Sms` · `Mail` · `Rocket` · `Desktop` · `UiActivity` · `UiToast` · `WhatsApp` (`Telegram` altyapıda tanımlı, UI'da kapalı) `Sms` · `Mail` · `Rocket` · `Desktop` · `UiActivity` · `UiToast` · `WhatsApp` · `Telegram`
Kanal kayıt defteri iki yerdedir: backend `NotificationChannels` (Domain.Shared), UI
`constants/notification-channel.enum.ts` (kanal değeri + `NotificationChannelColors` +
`NotificationChannelIcons`). Kanal listesi gösteren ekranlar (tercih matrisi, Activity Log filtresi)
listeyi bu kayıt defterinden üretir; etiket her yerde `App.NotificationChannel.{Kanal}` dil
anahtarından okunur, kanal lookup'ı (`ListFormSeeder_DefaultJsons`) da aynı anahtarları kullanır.
Yeni kanal = iki kayıt defteri + renk + ikon + dil anahtarı + `NotificationWorker` gönderimi.
### 13.2. Yönlendirme modeli ### 13.2. Yönlendirme modeli
@ -1248,7 +1255,12 @@ kayıt üretilir.
Tercih ekranı (`/admin/profile/notification-settings`) satırlarını bildirim **tipinin id'si** Tercih ekranı (`/admin/profile/notification-settings`) satırlarını bildirim **tipinin id'si**
üzerinden eşler; tip adı yalnızca gösterimdir. `NotificationType.Description` alanı aynı ekranda üzerinden eşler; tip adı yalnızca gösterimdir. `NotificationType.Description` alanı aynı ekranda
ipucu olarak görünür ve Bildirim Türleri ekranından yazılır. ipucu olarak görünür ve Bildirim Türleri ekranından yazılır. Ekran geniş ekranda tür × kanal
matrisi, dar ekranda kart listesidir; hücre `Switcher`'dır, `IsFixed` kural kilit ikonuyla
gösterilir ve değiştirilemez, kullanıcının değiştirdiği tür işaretlenir. Kayıt sırasında yalnızca
ilgili hücre/satır kilitlenir. Satırı varsayılana döndürmek
`DELETE /api/app/notification-rule/my-notification-rules/{notificationTypeId}` ile kullanıcının o
türdeki tercihlerini siler.
### 13.5.1. Bildirim ekranı ve elle gönderim (Administration › Bildirimler) ### 13.5.1. Bildirim ekranı ve elle gönderim (Administration › Bildirimler)
@ -1311,6 +1323,7 @@ gönderimde ekrandan ya da şablondan gelir — yani konu artık gövdeye gömü
| SMS | Posta Güvercini HTTP API | | SMS | Posta Güvercini HTTP API |
| WhatsApp | WhatsApp Cloud API (şablon tabanlı) | | WhatsApp | WhatsApp Cloud API (şablon tabanlı) |
| Rocket.Chat | Rocket.Chat HTTP API | | Rocket.Chat | Rocket.Chat HTTP API |
| Telegram | Telegram Bot API (`SozsoftTelegramSender`; alıcı kullanıcının `TelegramChatId` özelliği) |
Tüm sağlayıcı kimlik bilgileri ayar ekranından yönetilir (`App.Settings.*` anahtarları); Tüm sağlayıcı kimlik bilgileri ayar ekranından yönetilir (`App.Settings.*` anahtarları);
koda gömülmez. koda gömülmez.
@ -1871,7 +1884,6 @@ configs/seeds/
`mrp`, `accounting` ve `hr` yol sabitleri **yol sözleşmesidir**; bu alanların ekranları fiziksel `mrp`, `accounting` ve `hr` yol sabitleri **yol sözleşmesidir**; bu alanların ekranları fiziksel
React sayfaları olarak değil, ListForm konfigürasyonu ile üretilir. `hr` altında yalnızca React sayfaları olarak değil, ListForm konfigürasyonu ile üretilir. `hr` altında yalnızca
organizasyon şeması (`OrgChart.tsx`) fiziksel bir view'dır. organizasyon şeması (`OrgChart.tsx`) fiziksel bir view'dır.
- `Telegram` bildirim kanalı altyapıda tanımlıdır ancak UI'da kapalıdır.
- Depodaki `appsettings*.json` ve deployment dokümanları geliştirme değerleri/örnek kimlik - Depodaki `appsettings*.json` ve deployment dokümanları geliştirme değerleri/örnek kimlik
bilgileri içerir; üretim öncesi tümü değiştirilmelidir. bilgileri içerir; üretim öncesi tümü değiştirilmelidir.
- SQL View Designer tek yönlüdür (model → T-SQL). Elle yazılmış ya da tasarımcının kanonik - SQL View Designer tek yönlüdür (model → T-SQL). Elle yazılmış ya da tasarımcının kanonik

View file

@ -59,7 +59,7 @@ public sealed class McpDevelopTools(IMcpDevelopAppService developAppService)
=> await developAppService.GetWizardAsync(fileName); => await developAppService.GetWizardAsync(fileName);
[McpServerTool(Name = McpToolNames.DeployWizard, Destructive = true, Idempotent = false)] [McpServerTool(Name = McpToolNames.DeployWizard, Destructive = true, Idempotent = false)]
[Description("Wizard'i deploy eder: ListForm ekrani (ComponentKind 0) ya da bir custom component'i menuye baglayan kayit (ComponentKind 1), yetkileri, dil anahtarlari, menusu ve seed dosyasi birlikte uretilir. Hedef tablo onceden var olmalidir; yoksa once create_table ile olustur. replaceFileName verilirse o wizard ve urettigi kayitlar silinip yeniden uretilir; ekran wizard cevaplarindan yeniden turetildigi icin tasarimcida yapilmis ve wizard'da karsiligi olmayan ayarlar kaybolur. Ne yazacagini get_dev_guide 4. bolumunden ogren.")] [Description("Wizard'i deploy eder: ListForm ekrani (ComponentKind 0) ya da bir custom component'i menuye baglayan kayit (ComponentKind 1), yetkileri, dil anahtarlari, menusu ve seed dosyasi birlikte uretilir. Liste ekraninda Grid, Card, Pivot ve Chart gorunumleri varsayilan aciktir (DefaultLayout grid); kullanici bir gorunumu istemedigini soylemedikce bu bayraklari false yazma. Hedef tablo onceden var olmalidir; yoksa once create_table ile olustur. replaceFileName verilirse o wizard ve urettigi kayitlar silinip yeniden uretilir; ekran wizard cevaplarindan yeniden turetildigi icin tasarimcida yapilmis ve wizard'da karsiligi olmayan ayarlar kaybolur. Ne yazacagini get_dev_guide 4. bolumunden ogren.")]
public async Task<WizardFileInfoDto?> DeployWizardAsync( public async Task<WizardFileInfoDto?> DeployWizardAsync(
[Description("Wizard JSON'u: seed dosyasi bicimi ({\"Wizard\": {...}}, get_wizard cikisi gibi) ya da duz wizard cevaplari. Enum alanlari sayi olarak yazilir.")] [Description("Wizard JSON'u: seed dosyasi bicimi ({\"Wizard\": {...}}, get_wizard cikisi gibi) ya da duz wizard cevaplari. Enum alanlari sayi olarak yazilir.")]
string wizard, string wizard,

View file

@ -6,10 +6,10 @@ public class LayoutDto
public bool Card { get; set; } = true; public bool Card { get; set; } = true;
public bool Pivot { get; set; } = true; public bool Pivot { get; set; } = true;
public bool Chart { get; set; } = true; public bool Chart { get; set; } = true;
public bool Tree { get; set; } = true; public bool Tree { get; set; }
public bool Gantt { get; set; } = true; public bool Gantt { get; set; }
public bool Scheduler { get; set; } = true; public bool Scheduler { get; set; }
public bool Todo { get; set; } = false; public bool Todo { get; set; }
public string DefaultLayout { get; set; } = "grid"; public string DefaultLayout { get; set; } = "grid";
} }

View file

@ -77,12 +77,14 @@ public class ListFormWizardDto
public bool AllowDetail { get; set; } public bool AllowDetail { get; set; }
public bool ConfirmDelete { get; set; } public bool ConfirmDelete { get; set; }
public string DefaultLayout { get; set; } // Liste ekranı varsayılan olarak dört analiz görünümüyle gelir (UI wizard ve LayoutDto ile aynı);
public bool Grid { get; set; } // MCP/prompt ile gelen cevapta bayrak yazılmazsa görünüm sessizce kapanmasın diye.
public bool Card { get; set; } public string DefaultLayout { get; set; } = "grid";
public bool Pivot { get; set; } public bool Grid { get; set; } = true;
public bool Card { get; set; } = true;
public bool Pivot { get; set; } = true;
public bool Chart { get; set; } = true;
public bool Tree { get; set; } public bool Tree { get; set; }
public bool Chart { get; set; }
public bool Gantt { get; set; } public bool Gantt { get; set; }
public bool Scheduler { get; set; } public bool Scheduler { get; set; }
public bool Todo { get; set; } public bool Todo { get; set; }

View file

@ -41,7 +41,7 @@ public static class WizardConsts
Margin = 10 Margin = 10
}); });
public static string DefaultLayoutJson(string DefaultLayout = "grid", bool Grid = true, bool Card = true, bool Pivot = true, bool Chart = true, bool Tree = true, bool Gantt = true, bool Scheduler = true, bool Todo = true) => JsonSerializer.Serialize(new public static string DefaultLayoutJson(string DefaultLayout = "grid", bool Grid = true, bool Card = true, bool Pivot = true, bool Chart = true, bool Tree = false, bool Gantt = false, bool Scheduler = false, bool Todo = false) => JsonSerializer.Serialize(new
{ {
Grid = Grid, Grid = Grid,
Card = Card, Card = Card,

View file

@ -156,6 +156,10 @@ Bir çelişki varsa sıra: `ai.instructions.md` → `dotnet.instructions.md` →
migration, platform tablosu şeması, yeni paket, `Routes`, dış entegrasyon — **önce sorulur, migration, platform tablosu şeması, yeni paket, `Routes`, dış entegrasyon — **önce sorulur,
yalnızca onayla yapılır**; onay talebe özeldir. Çerçeve içinde yapılabilen kısım sorudan önce yalnızca onayla yapılır**; onay talebe özeldir. Çerçeve içinde yapılabilen kısım sorudan önce
bitirilir. "Yapılamaz" cevabı yoktur. Listeler: `lowcode.instructions.md` §0.8. bitirilir. "Yapılamaz" cevabı yoktur. Listeler: `lowcode.instructions.md` §0.8.
12. **Liste ekranı görünümleri** → prompt/görsel/tarifle üretilen her liste ekranı `Grid` + `Card` +
`Pivot` + `Chart` açık, `DefaultLayout: "grid"` ile gelir; "liste/grid" demek diğerlerini
kapatmak değildir. Bir görünüm yalnızca istek onu açıkça dışarıda bıraktığında `false` yazılır.
Tree/Gantt/Scheduler/Todo yalnızca istenince açılır. Ayrıntı: `lowcode.instructions.md` §9.8.
### Cross-cutting: touching one thing means touching these too ### Cross-cutting: touching one thing means touching these too