2026-08-10 09:08:08 +00:00
# Sozsoft Platform
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
**Çalı şma zamanı nda yapı landı rı labilen, çok kiracı lı (multi-tenant) low-code uygulama motoru.**
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Sozsoft Platform, klasik bir "kod yaz– derle– yayı nla" uygulaması değildir. Ekranlar, menüler,
route'lar, yetkiler, veri kaynakları , iş akı şları ve hatta API endpoint'leri **veritabanı ndaki
konfigürasyon kayı tları ndan** üretilir. Yeni bir modül veya ekran eklemek çoğu durumda tek satı r
React/C# kodu yazmadan, yalnı zca konfigürasyon ile mümkündür.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
> **Temel ilke:** Configuration first, code last.
> Bu ilkenin operasyonel karşı lı ğı ve yapay zeka ajanları için bağlayı cı kurallar
> [`.github/instructions/ai.instructions.md`](.github/instructions/ai.instructions.md) dosyası ndadı r.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
## İçindekiler
2026-08-10 09:08:08 +00:00
1. [Platform Ne Yapar? ](#1-platform-ne-yapar )
2. [Mimari Genel Bakı ş ](#2-mimari-genel-bakı ş )
3. [Teknoloji Yı ğı nı ](#3-teknoloji-yı ğı nı )
4. [Depo Yapı sı ](#4-depo-yapı sı )
5. [Hı zlı Başlangı ç ](#5-hı zlı -başlangı ç )
6. [Yapı landı rma (Configuration) ](#6-yapı landı rma-configuration )
7. [Low-Code Motoru: ListForm Ekosistemi ](#7-low-code-motoru-listform-ekosistemi )
8. [Developer Kit ](#8-developer-kit )
9. [Dinamik Menü, Route ve Yetki Modeli ](#9-dinamik-menü-route-ve-yetki-modeli )
10. [Modül Kataloğu ](#10-modül-kataloğu )
11. [Kimlik, Oturum ve Güvenlik ](#11-kimlik-oturum-ve-güvenlik )
12. [Çok Kiracı lı lı k (Multi-Tenancy) ](#12-çok-kiracı lı lı k-multi-tenancy )
13. [Bildirim ve Entegrasyonlar ](#13-bildirim-ve-entegrasyonlar )
14. [Arka Plan İşleri ](#14-arka-plan-işleri )
15. [Raporlama ](#15-raporlama )
16. [Dosya Yönetimi ve CDN ](#16-dosya-yönetimi-ve-cdn )
17. [Gerçek Zamanlı Özellikler ](#17-gerçek-zamanlı -özellikler )
18. [Frontend Mimarisi ](#18-frontend-mimarisi )
19. [API ve Swagger ](#19-api-ve-swagger )
20. [Dağı tı m (Deployment) ](#20-dağı tı m-deployment )
21. [Geliştirme Standartları ve Sı k Kullanı lan Komutlar ](#21-geliştirme-standartları -ve-sı k-kullanı lan-komutlar )
22. [Sorun Giderme ](#22-sorun-giderme )
23. [Bilinen Sı nı rlar ve Notlar ](#23-bilinen-sı nı rlar-ve-notlar )
---
## 1. Platform Ne Yapar?
| Yetenek | Açı klama |
| --- | --- |
| **Dinamik liste/form ekranları ** | `ListForm` + `ListFormField` kayı tları yla tanı mlanan; grid, pivot, ağaç, grafik, gantt, scheduler, kart ve todo görünümlerini destekleyen ekranlar. |
| **Dinamik menü ve route** | Menüler ve route'lar veritabanı ndan okunur; frontend bunları çalı şma zamanı nda React Router'a bağlar. |
| **Yetki tabanlı görünürlük** | Menü, ekran, sütun ve buton seviyesinde ABP permission kontrolü. |
| **SQL Query Manager** | Tarayı cı içinden SQL nesne gezgini, sorgu editörü, sonuç grid'i ve tablo tasarı mcı sı . |
| **Custom / CRUD Endpoint** | Kod yazmadan, SQL veya tablo tanı mı ndan REST endpoint üretimi. |
| **Dynamic Service** | Roslyn ile çalı şma zamanı nda derlenen ve controller olarak kaydedilen C# ApplicationService'ler. |
| **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ı . |
| **Ç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ı . |
2026-09-24 07:24:48 +00:00
| **Bildirim ve entegrasyon** | SMS, e-posta, WhatsApp, Telegram, Rocket.Chat, masaüstü ve UI kanalları na kural tabanlı bildirim. |
2026-08-10 09:08:08 +00:00
| **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. |
| **Gerçek zamanlı ** | SignalR tabanlı messenger ve video oda (WebRTC/TURN) altyapı sı . |
| **Intranet & Forum** | Duyuru, anket, sosyal duvar, etkinlik; kategori/konu/gönderi tabanlı forum. |
2026-09-09 06:06:25 +00:00
| **Public web sitesi** | Menüsü ve sayfaları veritabanı ndan yönetilen ziyaretçi sitesi: sayfalar Custom Component, menü `Pub` modülü (bkz. §10.4). Ürün/ödeme ve demo akı şları fiziksel sayfalardı r. |
2026-08-10 09:08:08 +00:00
| **PWA** | Service worker ile offline kabuk, kontrollü sürüm güncellemesi ve changelog bildirimi. |
---
## 2. Mimari Genel Bakı ş
```
┌──────────────────────────────────────────────────────────────────────┐
2026-08-26 18:44:53 +00:00
│ UI — React 19 + Vite + TypeScript + DevExtreme + Tailwind (PWA) │
2026-08-10 09:08:08 +00:00
│ ├─ DynamicRouter (route kayı tları ndan React Router üretimi) │
│ ├─ ListForm runtime (Grid / Pivot / Tree / Chart / Gantt / ...) │
│ ├─ Form runtime (DevExtreme Form, metadata ile alan üretimi)│
│ ├─ Developer Kit UI (SQL, endpoint, component, dynamic service) │
│ └─ easy-peasy store + React Query + SignalR │
└───────────────┬──────────────────────────────────────────────────────┘
│ HTTPS / OAuth2 (OpenIddict) / SignalR
┌───────────────▼──────────────────────────────────────────────────────┐
│ API — ASP.NET Core (.NET 10) + ABP Framework 10 │
│ ├─ HttpApi.Host : Swagger, OpenIddict, Hangfire, SignalR Hub, │
│ │ DevExpress Reporting, Setup/Migration akı şı │
│ ├─ Application : ListForms, DeveloperKit, Identity, Tenants, │
│ │ Menu, Routes, DataSource, FileManagement, ... │
│ ├─ Domain : Entity'ler, dinamik veri erişimi, seed'ler │
│ └─ EF Core : Migration'lar, dinamik DbContext, tenant DB │
│ │
│ Modüller: Languages · Settings · Notifications · MailQueue · │
│ Sender · SqlQueryManager │
└───────────────┬──────────────────────────────────────────────────────┘
│
┌───────────────▼──────────────────────────────────────────────────────┐
│ Veri ve Altyapı │
│ SQL Server / PostgreSQL · Redis (cache + SignalR backplane) · │
│ Hangfire (job storage) · Dosya sistemi tabanlı BLOB/CDN · │
│ coturn (TURN) · nginx · Elasticsearch (opsiyonel) │
└──────────────────────────────────────────────────────────────────────┘
```
**Akı şı n özeti:** Kullanı cı giriş yapar → ABP `application-configuration` yanı tı na
`PlatformApplicationConfigurationContributor` menü, route ve yetkileri ekler → `DynamicRouter`
route kayı tları nı React bileşenlerine bağlar → `/admin/list/{ListFormCode}` gibi bir ekran
açı ldı ğı nda `ListFormsAppService` metadata'yı , `ListFormDataAppService` ise veriyi döner →
DevExtreme bileşenleri bu metadata'ya göre kendini kurar.
---
## 3. Teknoloji Yı ğı nı
### Backend
| Bileşen | Sürüm / Notlar |
| --- | --- |
| .NET | `net10.0` (SDK 10.0.300, `global.json` ile sabit) |
| ABP Framework | 10.0.0 (Identity, TenantManagement, PermissionManagement, AuditLogging, OpenIddict, BlobStoring, BackgroundWorkers) |
| Veritabanı | SQL Server 2022 veya PostgreSQL 17 (`PlatformConsts.DefaultDatabaseProvider`) |
| ORM | Entity Framework Core |
| Kimlik | OpenIddict (password + refresh token, `/connect/token` ) |
| Cache | Redis (opsiyonel; `Redis:IsEnabled` ) |
| Job | Hangfire (`default`, `platform` kuyrukları ) + ABP Background Workers |
| Raporlama | DevExpress Reporting (Web Document Viewer + Report Designer) |
| Log | Serilog |
| Dinamik derleme | Roslyn (`DynamicServiceCompiler`) |
| Şablon | Scriban (mail şablonları ), MailKit/MimeKit |
| Gerçek zamanlı | SignalR (Redis backplane destekli) |
### Frontend
| Bileşen | Sürüm / Notlar |
| --- | --- |
2026-08-26 18:44:53 +00:00
| React | 19.2 |
2026-08-10 09:08:08 +00:00
| Build | Vite 8 + TypeScript 5.9 |
2026-08-26 18:44:53 +00:00
| UI kütüphaneleri | DevExtreme 26.1 (React), Tailwind CSS 3.4, kendi `components/ui` tasarı m sistemi |
| Routing | react-router-dom 7 (dinamik route üretimi) |
2026-08-10 09:08:08 +00:00
| State | easy-peasy (global store) + @tanstack/react -query |
| Form | Formik + Yup, DevExtreme Form |
| Kod editörü | Monaco Editor |
| Runtime derleme | @babel/standalone (Custom Component) |
2026-09-09 09:01:01 +00:00
| Takvim/Gantt | DevExtreme Scheduler/Gantt |
2026-08-10 09:08:08 +00:00
| Gerçek zamanlı | @microsoft/signalr |
| PWA | vite-plugin-pwa (Workbox) |
| Node | 24.13 / npm 11 (`volta` ile sabitlenmiş) |
---
## 4. Depo Yapı sı
```
sozsoft-platform/
├── api/ # .NET çözümü (Sozsoft.Platform.sln)
│ ├── src/
│ │ ├── Sozsoft.Platform.Domain.Shared/ # Sabitler, enum'lar, permission kodları (AppCodes)
│ │ ├── Sozsoft.Platform.Domain/ # Entity'ler, dinamik veri erişimi, repository'ler
│ │ ├── Sozsoft.Platform.Application.Contracts/ # DTO'lar, servis arayüzleri, permission tanı mları
│ │ ├── Sozsoft.Platform.Application/ # Uygulama servisleri (iş mantı ğı )
│ │ ├── Sozsoft.Platform.EntityFrameworkCore/ # DbContext, migration'lar, dinamik veri katmanı
│ │ ├── Sozsoft.Platform.HttpApi/ # Controller'lar (conventional)
│ │ ├── Sozsoft.Platform.HttpApi.Client/ # HTTP istemci proxy'leri
│ │ ├── Sozsoft.Platform.HttpApi.Host/ # Host: Swagger, auth, Hangfire, SignalR, raporlama
│ │ └── Sozsoft.Platform.DbMigrator/ # Migration + seed uygulaması
│ ├── modules/ # Bağı msı z ABP modülleri
│ │ ├── Sozsoft.Languages/ # Dil, dil anahtarı , çeviri metinleri
│ │ ├── Sozsoft.Settings/ # Ayar tanı mları ve ayar UI'ı
│ │ ├── Sozsoft.Notifications/ # Bildirim tipleri, kuralları , kullanı cı bildirimleri
│ │ ├── Sozsoft.MailQueue/ # Şablonlu mail kuyruğu ve ekleri
│ │ ├── Sozsoft.Sender/ # Mail (SES), SMS, WhatsApp, Rocket.Chat göndericileri
2026-09-17 09:01:14 +00:00
│ │ ├── Sozsoft.SqlQueryManager/ # SQL nesne yönetimi ve sorgu çalı ştı rma
2026-09-18 13:47:23 +00:00
│ │ └── Sozsoft.Mcp/ # MCP sunucusu: /mcp ucu, şema keşfi, sorgu ve geliştirme araçları
2026-08-10 09:08:08 +00:00
│ └── test/ # Test projeleri
├── ui/ # React uygulaması
│ └── src/
│ ├── routes/ # dynamicRouter, dynamicRouteLoader, route.constant
│ ├── views/ # list, form, admin, developerKit, public, intranet, forum, report, auth, setup
│ ├── components/ # ui (tasarı m sistemi), template (layout), importManager, visualDesigner, componentEditor
│ ├── services/ # API istemcileri (her modül için ayrı servis dosyası )
│ ├── store/ # easy-peasy modelleri (auth, theme, locale, abpConfig, admin)
│ ├── contexts/ # ComponentContext (runtime bileşenler), Dialog, Scroll
│ └── utils/ # editorScriptRuntime, workflow, hooks, hoc, biçimlendirme yardı mcı ları
├── configs/
│ ├── docker/ # Yerel geliştirme için veri katmanı compose dosyaları ve scriptler
│ ├── deployment/ # Dev/Prod compose dosyaları , nginx/redis/turn konfigürasyonu, deploy scriptleri
2026-08-17 09:23:47 +00:00
│ ├── seeds/ # Runtime'da düzenlenebilen seed'ler; CDN ile aynı kapsam düzeni
│ │ # host/{crud,custom,wizard,sql,postgres}
│ │ # tenants/{tenantId}/{crud,custom,wizard,sql,postgres}
│ │ # {sql|postgres}/{object,execute}
2026-09-17 12:24:51 +00:00
│ └── ai/ # AI entegrasyonu (n8n akı ş tanı mları , Ollama model kurulum notları )
2026-08-26 18:44:53 +00:00
├── .github/instructions/ # ai.instructions.md (bağlayı cı platform kuralları )
│ # lowcode.instructions.md (artefakt üretim referansı : şemalar, örnekler)
│ # dotnet.instructions.md (api/ için bağlayı cı .NET/ABP kod standardı )
│ # list.instructions.md (modül/liste ekleme prosedürü)
2026-08-10 09:08:08 +00:00
├── CLAUDE.md # Claude Code için operasyon kuralları
└── README.md
```
---
## 5. Hı zlı Başlangı ç
### 5.1. Önkoşullar
- .NET SDK **10.0.300+**
- Node.js **24.x** ve npm **11.x** (Volta önerilir)
- Docker Desktop (veritabanı ve Redis için)
- DevExpress lisansı (`api/DevExpress_License.txt`) ve DevExtreme npm erişimi
### 5.2. Veri katmanı nı ayağa kaldı rma
```powershell
# SQL Server + Redis
.\configs\docker\start_sql.bat
# veya PostgreSQL + Redis
.\configs\docker\start_postgres.bat
```
Compose dosyaları `configs/docker/docker-compose-data.yml` içindedir; `sql` ve `postgres`
profilleri ile hangi veritabanı nı n kalkacağı seçilir. Redis her iki profilde de çalı şı r.
### 5.3. Backend
```powershell
cd api
dotnet restore
dotnet run --project src/Sozsoft.Platform.HttpApi.Host
```
Uygulama `https://localhost:44344` adresinde açı lı r. Swagger UI kök adreste yayı nlanı r.
**Veritabanı ilk kurulum:** Veritabanı yoksa host, tam ABP yı ğı nı yerine minimal bir
"setup" uygulaması ile açı lı r (`DbStartup/SetupAppRunner`). Bu durumda:
- `GET /api/setup/application-status` — veritabanı nı n hazı r olup olmadı ğı nı döner (anonim).
- UI tarafı nda `/setup` route'u (`views/setup/DatabaseSetup.tsx`) migration'ı tetikleyen ekranı gösterir.
- Migration için `Setup:MigrationPassword` yapı landı rması veya `App.Setup.Migrate` yetkisi gerekir.
Alternatif olarak migration + seed'i doğrudan çalı ştı rabilirsiniz:
```powershell
dotnet run --project api/src/Sozsoft.Platform.DbMigrator
```
DbMigrator; şema migration'ları nı uygular ve ardı ndan menü, route, permission, dil,
host ayarları , ülke/şehir/ilçe verileri ile seed edilmiş ListForm ekranları nı yükler
2026-08-17 05:56:52 +00:00
(kodla versiyonlanan sabit seed'ler `api/src/Sozsoft.Platform.DbMigrator/Migrations/` ,
runtime'da düzenlenebilen seed'ler `configs/seeds/` altı ndadı r — bkz. `App:SeedsPath` ).
2026-08-17 09:23:47 +00:00
`configs/seeds` altı nda en üst seviye kapsamdı r (CDN klasörleriyle aynı mantı k): host
veritabanı için `host/` , her tenant için `tenants/{tenantId}/` . Kapsamı n altı nda içerik
2026-09-05 18:20:18 +00:00
türüne göre `crud/` , `wizard/` , `data/` , `sql/` , `postgres/` klasörleri bulunur:
2026-08-17 09:23:47 +00:00
```
configs/seeds/
host/
2026-09-05 18:20:18 +00:00
crud/ wizard/ data/
2026-08-17 09:23:47 +00:00
sql/ { object/ execute/ }
postgres/ { object/ execute/ }
tenants/
{tenantId}/
2026-09-05 18:20:18 +00:00
crud/ wizard/ data/
2026-08-17 09:23:47 +00:00
sql/ { object/ execute/ }
postgres/ { object/ execute/ }
```
Aktif veritabanı sağlayı cı sı na göre `sql/` (SQL Server) ya da `postgres/` okunur. Her
`.sql` dosyası amacı nı belirten bir klasörün altı ndadı r; klasör köklerinde dosya bulunmaz:
2026-08-17 05:56:52 +00:00
| Klasör | Ne zaman çalı şı r |
| --- | --- |
2026-08-17 09:23:47 +00:00
| `{sql\|postgres}/object` | Seed sı rası nda nesneyi oluşturur/günceller. SqlTableDesigner ve SqlQueryManager, deploy ettiği script'i çalı ştı ğı kapsamı n bu klasörüne yazar (host bağlamı → `host/` , tenant seçiliyken → `tenants/{tenantId}/` ). |
2026-09-18 06:03:19 +00:00
| `{sql\|postgres}/execute` | Nesneyi oluşturur; ayrı ca tüm migration ve seed'ler bittikten sonra `FinalSeeder` dosya adı ndan türettiği procedure'ü çalı ştı rı r (dosya adı = procedure adı , `schema.Procedure.sql` de olur). |
2026-08-17 09:23:47 +00:00
| `wizard` | ListForm Wizard'ı n ürettiği `.json` konfigürasyonları ; `WizardDataSeeder` kendi kapsamı ndaki dosyaları okur. |
2026-09-07 14:43:46 +00:00
| `crud` | CrudEndpoint konfigürasyonları ; `CrudDataSeeder` kendi kapsamı ndaki dosyaları `ICrudEndpointSeedApplier` üzerinden uygular. Politika **damga karşı laştı rmalı dı r** : eksik endpoint her zaman eklenir, mevcut bir kayı t yalnı zca dosyanı n `GeneratedAt` damgası kaydı n `LastModificationTime` /`CreationTime` değerinden **yeniyse** güncellenir ya da silinir; aksi halde kayı t korunur ve log'a drift uyarı sı düşer. Böylece CRUD Endpoint Manager'dan yapı lan bir revizyon depodan gelen eski bir dosya yüzünden migrate sı rası nda geri alı nmaz. Damgası olmayan (eski biçimde yazı lmı ş) dosya hiçbir zaman yeni sayı lmaz. |
2026-09-21 19:40:13 +00:00
| `data` | Ekranlardan girilen listelerin veri aynası : tek dosya (`{ListFormCode}.json`) ya da satı r başı na dosya tutan klasör (`{ListFormCode}/{anahtar}.json`; klasör özyinelemeli taranı r ve tamamı tek unit of work'te uygulanı r). `ListForm.SeedFilePath` dolu olan ekranda `SeedSyncInsert/Update/Delete` bayrakları ndan işaretli olan işlemler dosyaya yansı r (`ListFormSeedDataSynchronizer`); migrate/seed sı rası nda bütün contributor'lar bittikten sonra `ListFormSeedDataApplier` dosyayı geri uygular: anahtarı veritabanı nda **olmayan** satı rları ekler, var olanlara dokunmaz. Aynı uygulayı cı wizard import'unun kapanı şı nda da (`CompleteImport`) yalnı zca o import'ta yazı lan dosyalar için, `overwriteExisting` açı k olarak çalı şı r — orada var olan satı r dosyadaki değerlerle güncellenir. |
2026-08-17 05:56:52 +00:00
Klasör kökünde kalmı ş eski `.sql` dosyaları geriye dönük uyumluluk için hâlâ işlenir,
fakat `SqlDataSeeder` bunları uyarı ile loglar — ilgili klasöre taşı nmaları beklenir.
2026-08-10 09:08:08 +00:00
### 5.4. Frontend
```powershell
cd ui
npm install
2026-08-12 12:20:00 +00:00
npm start # vite dev server (http://localhost:3000)
2026-08-10 09:08:08 +00:00
```
2026-08-12 12:20:00 +00:00
Visual Designer ve Custom Component altyapı sı nı n kullandı ğı bileşen kataloğu
`src/components/visualDesigner/generated/componentProps.json` dosyası nda tutulur ve repoya
dahildir. `src/components/ui` altı ndaki bileşen prop'ları değiştiğinde bu dosya elle
güncellenmelidir.
2026-08-10 09:08:08 +00:00
### 5.5. İlk giriş
Seed edilen host yöneticisi ile `/login` üzerinden giriş yapı lı r (kullanı cı bilgileri
2026-09-18 06:28:25 +00:00
`PlatformIdentityDataSeeder` ile belirlenir). Giriş sonrası
2026-08-10 09:08:08 +00:00
`/admin/dashboard` açı lı r.
---
## 6. Yapı landı rma (Configuration)
### 6.1. Backend (`appsettings.json`)
| Anahtar | Açı klama |
| --- | --- |
| `App:SelfUrl` | API'nin kendi adresi (OpenIddict authority ile uyumlu olmalı ). |
| `App:ClientUrl` | React uygulaması nı n kök adresi (mail linkleri bu adresi kullanı r). |
| `App:CorsOrigins` | Virgülle ayrı lmı ş izinli origin listesi; wildcard subdomain destekli. |
| `App:RedirectAllowedUrls` | OAuth yönlendirme için izinli adresler. |
| `App:CdnUrl` / `App:CdnPath` | Dosya servisinin adresi ve BLOB kök dizini. |
| `App:AttachmentsPath` | Mail kuyruğu eklerinin yazı ldı ğı dizin. |
| `App:BackupPath` | Veritabanı yedek dizini (BackupWorker kullanı r). |
| `App:Version` | Uygulama sürümü (UI sürüm kontrolü ile eşleşir). |
| `ConnectionStrings:SqlServer` / `PostgreSql` | Host veritabanı bağlantı ları . |
| `Redis:IsEnabled` / `Redis:Configuration` | Dağı tı k cache ve SignalR backplane. |
| `AuthServer:Authority` / `SwaggerClientId` | OpenIddict authority ve Swagger istemcisi. |
| `OpenIddict:TokenLifetimes:*` | Access/refresh token ömrü (dakika). |
| `Setup:MigrationPassword` | Setup ekranı ndan migration tetiklemek için parola. |
| `StringEncryption:DefaultPassPhrase` | ABP string şifreleme anahtarı . |
| `Serilog:MinimumLevel` | Log seviyeleri. |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
> **Güvenlik:** Depodaki `appsettings.json` dosyaları geliştirme değerleri içerir.
> Üretimde bağlantı dizeleri, `MigrationPassword`, `DefaultPassPhrase` ve entegrasyon
> anahtarları **ortam değişkeni veya secret yöneticisi** ile verilmelidir; repoya yazı lmamalı dı r.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 6.2. Frontend (`ui/.env`, `.env.dev`, `.env.production`)
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Değişken | Açı klama |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| `VITE_API_URL` | API kök adresi. |
| `VITE_CDN_URL` | Dosya/CDN kök adresi. |
| `VITE_REACT_APP_VERSION` | `package.json` sürümünden beslenir. |
| `VITE_AI_URL` | AI asistanı nı n n8n webhook kökü. |
| `VITE_USE_POLLING` | Dosya izlemede polling (WSL/Docker senaryoları ). |
| `VITE_PWA_DEV` | Geliştirmede service worker'ı açar (varsayı lan kapalı ). |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 6.3. Uygulama içi ayarlar
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Çalı şma zamanı ayarları veritabanı nda tutulur ve **Ayarlar** ekranı ndan (`/admin/settings`)
yönetilir. `Sozsoft.Settings` modülü ayar tanı mları nı , `SettingUiAppService` ise bu tanı mları n
UI gösterimini yönetir. Şifre politikası , oturum kuralları , gönderici kimlik bilgileri (SMS,
mail, WhatsApp, Rocket) ve AI bot yapı landı rması bu yolla değiştirilir — kod dağı tı mı gerekmez.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 7. Low-Code Motoru: ListForm Ekosistemi
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Platformun kalbi budur. Bir iş ekranı ; bir `ListForm` kaydı , ona bağlı `ListFormField`
kayı tları ve bir menü/route/permission üçlüsünden oluşur.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 7.1. Kavramlar
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Varlı k | Rolü |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| `DataSource` | Hedef veritabanı bağlantı sı (MSSQL / PostgreSQL). Ekranlar `DataSourceCode` ile bağlanı r. |
| `ListForm` | Ekranı n tüm davranı şı : veri kaynağı , sütun/filtre/sayfalama/düzenleme ayarları , yetkiler, alt formlar, iş akı şı , grafik ayarları . |
| `ListFormField` | Tek bir sütun/alanı n davranı şı : başlı k, tip, genişlik, editör, lookup, doğrulama, biçim, yetki. |
| `ListFormCustomization` | Kullanı cı bazlı kişiselleştirme: kayı tlı filtre, grid state, sunucu tarafı join/where. |
| `ListFormWorkflow` | Onay ve koşul düğümlerinden oluşan iş akı şı grafiği. |
| `ListFormImport` / `ImportLog` | Excel/CSV içe aktarma tanı mı ve satı r bazlı sonuç günlüğü. |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 7.2. `ListForm` anatomisi
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Ekran davranı şı büyük ölçüde JSON kolonları nda saklanı r. Öne çı kanlar:
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Alan | İşlevi |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| `SelectCommandType` + `SelectCommand` | Veri kaynağı türü: `Table` , `View` , `TableValuedFunction` , `Query` , `StoredProcedure` . |
| `KeyFieldName` / `KeyFieldDbSourceType` | Birincil anahtar alanı ve tipi. |
| `PermissionJson` | Ekranı n create/read/update/delete/export/import/note yetki eşlemesi. |
| `EditingOptionJson` / `EditingFormJson` | Düzenleme modu (row/cell/batch/form/popup) ve düzenleme formu düzeni. |
| `FilterRowJson` , `HeaderFilterJson` , `FilterPanelJson` , `SearchPanelJson` , `GroupPanelJson` | Filtreleme, arama ve gruplama davranı şı . |
| `ColumnOptionJson` , `PagerOptionJson` , `SelectionJson` , `StateStoringJson` | Sütun, sayfalama, seçim ve durum saklama ayarları . |
| `Insert/Update/DeleteCommand` (+ `Before` / `After` ) | CRUD komutları ve öncesi/sonrası çalı şacak SQL kancaları . |
| `Insert/Update/DeleteServiceAddress` | Varsayı lan olarak `list-form-data/*` ; özel endpoint'e yönlendirilebilir. |
2026-09-21 19:40:13 +00:00
| `SeedFilePath` | Doluysa seed sı rası nda listenin verisi kapsam klasöründeki bu hedeften geri yüklenir: `.json` ile biten değer tek dosya (`data/{ListFormCode}.json`), uzantı sı z değer satı r başı na dosya tutan klasördür (`data/{ListFormCode}/{anahtar}.json`). |
2026-09-04 09:05:26 +00:00
| `SeedSyncInsert` / `SeedSyncUpdate` / `SeedSyncDelete` | Ekranda yapı lan hangi işlemin seed dosyası na yansı yacağı ; kapalı ysa o işlem dosyaya dokunmaz. |
2026-08-10 09:08:08 +00:00
| `SubFormsJson` | Ana-detay ilişkisi (ParentFieldName → ChildFieldName eşlemesi). |
2026-09-30 20:52:33 +00:00
| `WidgetsJson` | Ekranı n üstünde gösterilecek KPI kartları . Alt form olarak üretilen ekrana (menüsüz ya da menülü) yazı lmaz; menüsüz wizard'da deploy boşaltı r, alt form sekmesinde çizilmez. |
2026-08-10 09:08:08 +00:00
| `WorkflowJson` | İş akı şı bağlaması . |
| `ExtraFilterJson` | Ekrana özel ek filtre araç çubuğu. |
| `PivotOptionJson` , `TreeOptionJson` , `GanttOptionJson` , `SchedulerOptionJson` , `TodoOptionJson` | Alternatif görünümlerin ayarları . |
| Grafik alanları (`SeriesJson`, `LegendJson` , `ArgumentAxisJson` , `ValueAxisJson` , `TooltipJson` , `ZoomAndPanJson` , …) | DevExtreme Chart yapı landı rması . |
| `CustomJsSourcesJson` / `CustomStyleSourcesJson` | Ekran yüklendiğinde çalı şacak JS/CSS. |
| `IsTenant` , `IsBranch` , `IsOrganizationUnit` | Otomatik tenant/şube/organizasyon birimi filtrelemesi. |
| `UserId` , `RoleId` , `CultureName` | Aynı ekranı n kullanı cı , rol veya dil bazlı varyantları . |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 7.3. Görünüm tipleri
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Aynı `ListForm` tanı mı , aynı veri hattı üzerinden birden fazla görünümle sunulabilir:
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
`Grid` · `Pivot` · `Tree` · `Chart` · `Gantt` · `Scheduler` · `CardView` · `TodoBoard (Kanban)` ·
`Widget Group`
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Kullanı cı görünümler arası nda geçiş yapabilir; grid durumu (sütun sı rası , genişlik, filtre,
gruplama) kullanı cı bazlı saklanı r ve sı fı rlanabilir.
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
**TodoBoard artı k bir Kanban panosudur:** kolonlar `TodoOptionJson` içindeki `statusExpr`
değerlerinden üretilir, kartlar kolonlar arası nda sürüklenerek durum değiştirir ve panodan yeni
kolon (durum) eklenebilir. Kart içeriği `titleExpr` , `descriptionExpr` , `dueDateExpr` , `tagExpr`
ve atanan kullanı cı alanları ndan kurulur.
2026-08-10 09:08:08 +00:00
### 7.4. Alan (field) davranı şı
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- **Editör tipleri:** `dxTextBox` , `dxTextArea` , `dxNumberBox` , `dxDateBox` , `dxDateRangeBox` ,
`dxCalendar` , `dxCheckBox` , `dxSwitch` , `dxRadioGroup` , `dxSelectBox` , `dxTagBox` , `dxLookup` ,
`dxDropDownBox` , `dxGridBox` , `dxAutocomplete` , `dxColorBox` , `dxHtmlEditor` , `dxSlider` ,
`dxRangeSlider` — ayrı ca görsel yükleme/görüntüleme editörleri.
- **Lookup kaynakları :** `StaticData` , `Query` , `WebService` ; ebeveyn– çocuk (cascade) desteklidir.
- **Doğrulama:** `ValidationRuleJson` ile required/range/pattern/custom kuralları .
- **Editör script:** `EditorScript` alanı ile alan değişiminde çalı şan JS (örn. tarih farkı ndan
gün hesaplama, miktar × birim fiyat toplamı ). Çalı ştı rma `utils/editorScriptRuntime.ts` üzerinden yapı lı r.
2026-08-26 18:44:53 +00:00
- **Editör seçenekleri:** `EditorOptions` alanı DevExtreme editörüne geçirilen JSON'dur
(format, maske, placeholder, yükseklik, buton görünürlüğü, platform editörlerinin tipli
ayarları ). Elle JSON yazmak zorunlu değildir; bkz. 7.4.1.
2026-08-10 09:08:08 +00:00
- **Koşullu biçimlendirme:** `ColumnStylingJson` , `ColumnCssClass` /`ColumnCssValue`.
- **Alan bazlı yetki:** `PermissionJson` ile sütun düzeyinde okuma/yazma/dı şa aktarma kontrolü.
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
#### 7.4.1. Script Builder ve Editor Options Builder
`EditorScript` ve `EditorOptions` alanları hem görsel olarak hem de seeder kodundan üretilir;
**iki tarafı n çı ktı sı birebir aynı olmak zorundadı r.**
**Editor Script Builder** (`json-row-operations/editor-script/`)
- Kural sözlüğü `scriptRecipes.ts` içindedir; her tarif (recipe) tek satı rlı k runtime çağrı sı üretir.
Gruplar: hesap (`calc`), veri (`data`), görünüm (`view`), bildirim, API.
- Üretilen script'in ilk satı rı ndaki `// @builder {...}` başlı ğı kuralları saklar. Dialog script'i
regex ile çözmeye çalı şmaz, bu başlı ktan geri okur; başlı k bozulursa/elle düzenlenirse script
"manuel" sayı lı r ve kural editörü kapanı r.
- Kural tetikleyicileri: `change` (varsayı lan), `open` (form açı lı şı nda — varsayı lan değer üretmek
için, script başı na `// @runOnOpen` direktifi eklenir), `both` .
- Koşullar `and` /`or` ile birleşir: `equals` , `notEquals` , `contains` , `empty` , `notEmpty` ,
`greaterThan` , `lessThan` , `isTrue` , `isFalse` , `always` .
- Dialog'un kendisi ortaktı r (`components/scriptBuilder/ScriptBuilderDialog.tsx` + IntelliSense);
ListForm lehçesi `formScriptDialect.ts` , Visual Designer lehçesi `designerScriptDialect.ts`
ile aynı sözleşmeye bağlanı r.
**Seeder tarafı (C#)** — `Sozsoft.Platform.Domain.Shared/Editors/`
`scriptRecipes.ts` ve editorOptions sözlüğünün C# portudur. Seeder ile bası lan script/JSON,
dialogda açı lı p görsel olarak düzenlenebilir kalı r. Bir tarif TypeScript tarafı nda değişirse
buradaki karşı lı ğı da güncellenmelidir.
| Tip | Kullanı m |
| --- | --- |
2026-09-21 15:01:40 +00:00
| `EditorScript` | `Multiply` , `Subtract` , `Percent` , `Sum` , `Formula` , `Today` , `Days` , `Hours` , `Copy` , `SetValue` , `Clear` , `ReadOnly` , `Notify` , `Ask` , `OpenUrl` , `ApiToField` , `Location` , `Custom` → `EditorScript.Build(rules)` |
2026-08-26 18:44:53 +00:00
| `EditorScriptRule` | `.When(...)` / `.WhenAny(...)` koşulları , `.OnChange()` / `.OnOpen()` / `.OnOpenAndChange()` tetikleyicisi; `string` 'e örtük dönüşür |
| `EditorScriptCondition` | `Is` , `IsNot` , `Contains` , `IsEmpty` , `IsNotEmpty` , `GreaterThan` , `LessThan` , `IsTrue` , `IsFalse` , `Always` |
| `EditorOptions` | Hazı r başlangı çlar: `Disabled()` , `ReadOnly()` , `ShowClearButton()` , `Multiline(h)` , `Number(precision)` , `Percent()` , `Date()` , `DateTime()` , `Time(interval)` , `Phone()` , `Slider()` , `ImageUpload()` , `Html(h)` |
| `EditorOptionsBuilder` | Akı cı ekleme: `.Placeholder()` , `.MaxLength()` , `.Height()` , `.Width()` , `.Format()` , `.Mask()` , `.Flag()` , `.Text()` , `.Number()` , `.Json()` ; `string` 'e örtük dönüşür |
```csharp
EditorOptions = EditorOptions.Number(4).ShowClearButton(),
EditorOptions = EditorOptions.Multiline(60).Placeholder("Açı klama"),
EditorScript = EditorScript.Build(
EditorScript.Multiply("Quantity", "UnitPrice", "Total"),
EditorScript.Percent("Total", "VatRate", "VatAmount", mode: EditorScriptPercentMode.Add)
.When(EditorScriptCondition.IsNotEmpty("VatRate"))),
```
**Editor Options Builder** (`json-row-operations/editor-options/`)
- UI tamamen `optionSpecs.ts` veri sözlüğünden üretilir; yeni bir ayar eklemek için oraya tek
satı r yazmak yeterlidir. Her ayar `path` (örn. `format.precision` ), tip (`boolean` üç durumlu /
`number` / `text` / `select` / `size` / `stringList` / `json` ), grup ve hangi editörlerde
anlamlı olduğu bilgisini taşı r.
- `platform: true` işaretli ayarlar backend'in tipli DTO'ya (`GridBoxOptionsDto`,
`TagBoxOptionsDto` , `ImageUploadOptionsDto` ) deserialize ettiği alanlardı r; yanlı ş tipte
yazı lı rsa sessizce yok sayı lı r.
- `presets.ts` hazı r kalı plar sunar (HTML editör tam araç çubuğu, telefon maskesi, tarih/saat…);
kalı p mevcut JSON ile **birleştirilir** , diğer ayarları silmez.
2026-08-10 09:08:08 +00:00
### 7.5. İş akı şı ve onay
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
`FormTabWorkflow` ve `views/admin/listForm/workflow/WorkflowDesigner.tsx` üzerinden görsel
tasarlanı r. Düğüm türleri koşul karşı laştı rması (`CompareColumn`/`CompareOperator`/`CompareValue`)
ve onay adı mları dı r; her adı m için `NextOnTrue` , `NextOnFalse` , `NextOnApprove` , `NextOnReject`
geçişleri tanı mlanı r. Onaycı birden fazla kişi olabilir. Formlar içinde iş akı şı na bağlı özel
butonlar gösterilebilir.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 7.6. Yeni ekran ekleme akı şı (Wizard)
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
`/admin/listform/wizard` altı ndaki sihirbaz, aşağı daki artefaktları tek akı şta üretir:
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
1. **ListForm** kaydı (kod, ad, başlı k, veri kaynağı , select komutu, anahtar alan)
2. **ListFormField** kümesi (sütunlar, editörler, lookup'lar, doğrulamalar)
3. **Route** kaydı (`key`, `path` , `componentPath` , `routeType` , `authority` )
4. **Menu** kaydı (`ParentCode`, `Code` , `DisplayName` , `Url` , `Icon` , `RequiredPermissionName` , `Order` )
5. **Permission** kayı tları (`.Default`, `.Create` , `.Update` , `.Delete` , `.Export` , `.Import` , `.Note` )
2026-08-26 18:44:53 +00:00
6. **Dil anahtarları ** (menü, başlı k, açı klama; EN + TR)
7. Gerekiyorsa **ayar/entegrasyon** bağı mlı lı kları
2026-09-02 08:32:53 +00:00
8. **Seed dosyası ** — `configs/seeds/{host|tenants/{tenantId}}/wizard/{Ad}.json` (wizard cevapları + üretilen `ListForm` /`Fields` sözleşmesi)
2026-08-26 18:44:53 +00:00
9. **Doğrulama ve geri alma** notları
**Adı m bileşenleri.** Adı mlar numaralı dosya adları yerine işlevleriyle adlandı rı lı r ve
`React.lazy` ile yüklenir; aynı anda yalnı zca görünen adı m indirilir, sihirbazı n açı lı ş maliyeti
adı m sayı sı ndan bağı msı zdı r.
| Adı m | Dosya | İçerik |
| --- | --- | --- |
| Menü ve kimlik | `WizardStepMenu.tsx` | Wizard adı , ListForm kodu, menü ağacı /üst menü, ikon, sı ra, izin grubu, dil metinleri |
| Veri ayarları | `WizardStepDataSettings.tsx` | Veri kaynağı , select komutu tipi, anahtar alan, CRUD endpoint diyaloğu |
| Alanlar | `WizardStepFields.tsx` | Sütun grupları , editör tipleri, lookup, doğrulama |
| Alt formlar | `WizardStepSubForms.tsx` | Ana– detay ilişki eşlemesi |
| Widget'lar | `WizardStepWidgets.tsx` | KPI kartları |
| İş akı şı | `WizardStepWorkflow.tsx` | Onay/koşul grafiği |
| Düzen adı mları | `WizardStepTodoLayout` · `WizardStepTreeLayout` · `WizardStepGanttLayout` · `WizardStepSchedulerLayout` | Yalnı zca ilgili görünüm açı ksa görünür |
| Bileşen | `WizardStepComponent.tsx` · `WizardStepCustomComponent.tsx` | Custom yolunda bağlanacak bileşen |
2026-09-25 06:39:34 +00:00
| Yayı nlama | `WizardStepDeploy.tsx` | Özet, doğrulama ve seed dosyaları nı n üretimi; ardı ndan Wizard Manager'a dönülür |
2026-08-26 18:44:53 +00:00
Menü ağacı yardı mcı ları (`menuTree.ts`) adı m bileşenlerinden ayrı bir modüldedir; böylece Wizard
ve `SqlTableDesignerDialog` bu fonksiyonları kullanı rken adı m bileşenlerini pakete çekmez.
2026-09-02 08:32:53 +00:00
**Seed dosyası ekranı n kendisini taşı r.** Dosya `Wizard` bölümünün yanı nda ekranı n
`GridOptionsEditDto` sözleşmesini (`ListForm`) ve alanları n `ColumnFormatEditDto` sözleşmesini
2026-09-25 06:39:34 +00:00
(`Fields`) tutar; `WizardDataSeeder` ekranı bu iki bölümden kurar. **Deploy veritabanı na yazmaz:**
wizard dosyası nı n yanı nda menü, modül, izin grubu, yetki ve dil metinleri platform seed
dosyaları na (`data/App.Menus.{Menu,Module}.json`, `data/Abp.Identity.Permission{Groups,s}.json` ,
`data/App.Languages.LanguageText.json` ) satı r olarak yazı lı r (`WizardSeedRowStore`) ve hepsi DB
Migrate ile kurulur. Deploy/import dosyaya `Pending` yazar; Wizard Manager dosyayı "Migrate
bekliyor" rozetiyle gösterir, migrate bitince liste ve menü yenilenir. Yetkiler hiçbir role
otomatik atanmaz. Böylece Wizard ile ListForm
2026-09-02 08:32:53 +00:00
detayı aynı veri yapı sı nı konuşur ve tasarı mcı daki değişiklikler wizard'a geri yazı labilir.
`Wizard` bölümü yalnı zca ekrandan üretilemeyen bilgileri (menü, yetki, dil metinleri, bileşen
yolu, alan başlı kları nı n dil karşı lı kları ) taşı r; `ListForm` /`Fields` içinde karşı lı ğı olan alanlar
dosyaya yazı lmaz, okuma sı rası nda geri doldurulur. Kalanlar dosyada `Menu` , `Language` ve `Groups`
başlı kları altı nda toplanı r (`WizardSeedFileDto.ToSeedJson` / `FromSeedJson` ). Dosya adı `{Ad}.json` 'dı r (zaman damgası yok);
2026-09-30 07:28:12 +00:00
uygulama sı rası `Wizard.SeededAt` damgası ndan gelir. MCP `deploy_wizard` dosyaya etkin talebi
`DevRequest` (`Id`, `Title` ) olarak yazar; elle yapı lan kayı t bu bağı korur, talepsiz wizard'da bölüm yoktur.
2026-09-02 08:32:53 +00:00
2026-08-26 18:44:53 +00:00
**İki yol: `ComponentKind` .** `ListFormWizardDto.ComponentKind` sihirbazı n yol ayrı mı dı r ve seed
dosyası nda ilk alandı r. Varsayı lan `List` olduğu için bu alanı taşı mayan eski seed dosyaları
eskisi gibi çalı şı r.
| `ComponentKind` | Üretilen | Menü URL'i | Yetkiler |
| --- | --- | --- | --- |
2026-09-29 06:14:07 +00:00
| `List` | ListForm + ListFormField (+ iş akı şı ) + Menu + Permission + dil anahtarları (rota üretilmez; genel `/admin/list/{ListFormCode}` rotası kullanı lı r) | `/admin/list/{ListFormCode}` | `.Create` , `.Update` , `.Delete` , `.Export` , `.Import` , `.Note` |
2026-08-26 18:44:53 +00:00
| `Custom` | Menü + Permission + dil anahtarları ; ekran seçilen Custom Component'tir | Component'in `RoutePath` değeri | Yalnı zca `.Create` , `.Update` , `.Delete` (Export/Import/Note ListForm'a özgüdür) |
**Menüsüz wizard (`CreateMenu = false`).** Menü (ve gerekiyorsa üst menü) kaydı hiç üretilmez;
ListForm, permission ve dil anahtarları her iki durumda da üretilir. Menüsüz wizard'lar başka bir
ekranda SubGrid/parça olarak kullanı lmak üzere tanı mlanı r. Alan varsayı lanı `true` olduğundan bu
alanı taşı mayan eski seed dosyaları etkilenmez.
**İzin grubu seçimi.** Menü adı mı nda izin grubu bir seçim listesinden gelir
2026-09-29 06:14:07 +00:00
(`ListFormWizardAppService.GetPermissionGroups`, `/api/app/list-form-wizard/permission-groups` ). Görünen adlar, grup adı yla aynı olan dil anahtarı nı n metinlerinden
2026-09-02 14:31:39 +00:00
okunur; seçim yapı ldı ğı nda `PermissionGroupEn/Tr` forma doldurulur. Yeni bir grup
2026-08-26 18:44:53 +00:00
tanı mlanı rsa grup adı yla aynı dil anahtarı na bu metinler yazı lı r; mevcut grup seçilip alanlar boş
bı rakı lı rsa sunucu veritabanı ndaki değeri geri yazar. Böylece seed dosyası her durumda iki dilli
görünen adı taşı r.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Dinamik liste ekranları nı n route deseni `/admin/list/{ListFormCode}` biçimindedir; form
görünümleri `/admin/form/{listFormCode}/:id` , grafik `/admin/chart/{listFormCode}` , pivot
`/admin/pivot/{listFormCode}` yolları nı kullanı r.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Var olan bir ekranı düzenlemek için `/admin/listform/edit/{listFormCode}` — tüm JSON
yapı landı rması sekmeli bir editörde yönetilir (Veritabanı , Sütunlar, Filtreler, Düzenleme,
Yetkiler, Alt Form, Pivot, Tree, Gantt, Scheduler, Todo, Widget, Workflow, Durum, Grafik sekmeleri).
2026-06-09 12:54:05 +00:00
2026-09-29 06:14:07 +00:00
**Wizard File Manager** (`/admin/listform/wizardManager`; sihirbazı n kendisi `/admin/listform/wizard` ) üretilmiş seed dosyaları nı yönetir:
2026-08-26 18:44:53 +00:00
liste/kart görünümü arası nda geçiş (tercih diğer listelerle aynı yerde, `admin.lists.states`
altı nda saklanı r), arama, düzenleme (dosyanı n yerine geçen yeni bir çalı ştı rma), silme, veritabanı
2026-09-05 18:20:18 +00:00
migrate tetikleme, dı şa aktarma ve içe aktarma. Liste, wizard'ı n ilk deploy damgası na
(`Wizard.SeededAt`) göre **tersine** sı ralı dı r — en son üretilen ekran en üstte durur; damgası
2026-09-29 06:14:07 +00:00
okunamayan dosyalar sona düşer. Silme, bağlı wizard'ı olan dosyada reddedilir; onay diyaloğu önce
`DeleteAnalysis` ile düşürülebilecek tabloyu sorar, sonuç her kaydı n akı betiyle (`Deleted` / `Kept` +
kullananlar / `NotFound` ) rapor olarak gösterilir (`WizardRecordCleaner`, `WizardTableCleaner` ;
`lowcode.instructions.md` §4.5). Butonlar `App.Listforms.Wizard.*` yetkileriyle gizlenir; ası l
2026-09-05 18:20:18 +00:00
kontrol `ListFormWizardAppService` üzerindedir.
2026-08-26 18:44:53 +00:00
2026-08-10 09:08:08 +00:00
### 7.7. İçe/dı şa aktarma
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
**Veri (ekran içi)**
2026-08-10 09:08:08 +00:00
- **Dı şa aktarma:** xlsx, csv, pdf (grid durumuna ve görünür sütunlara saygı duyar).
- **İçe aktarma:** `components/importManager` altı ndaki dosya yükleme → önizleme → ilerleme →
sonuç akı şı ; sonuçlar `ListFormImportLog` üzerinde satı r bazı nda raporlanı r. Şablon dosyası
ekran tanı mı ndan üretilir.
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
**Ekran tanı mı (wizard seed paketi)**
Bir ekranı n tanı mı , bağı mlı lı kları yla birlikte tek bir zip olarak taşı nı r. Zip içindeki yollar seed
kapsam klasörü (`host` / `tenants/{tenantId}` ) kökü baz alı narak yazı lı r; arşiv başka bir ortamda
aynı klasör düzenine doğrudan açı labilir.
2026-09-07 14:43:46 +00:00
Toplama **özyinelemelidir** (`WizardExportCollector`): alt formları n wizard dosyaları kuyruğa
eklenir ve onları n bağı mlı lı kları da aynı kurallarla toplanı r. Böylece zip tek başı na çalı şı r.
2026-09-30 07:28:12 +00:00
**Talep export'u** (`api/app/list-form-wizard/export-dev-request{,-analysis}`) bir geliştirme
talebinin `DevRequest` bağı taşı yan bütün wizard'ları nı aynı toplayı cı da tek kapanı şa koyar;
paylaşı lan dosyalar arşive bir kez, birleşik satı rlarla girer ve import arşivi tek oturumda uygular.
2026-09-07 14:43:46 +00:00
2026-08-26 18:44:53 +00:00
| Yol | İçerik |
| --- | --- |
2026-09-07 14:43:46 +00:00
| `wizard/{dosya}.json` | Wizard tanı mı nı n kendisi **ve** `SubFormsDto[].Code` ile bağlı alt form ekranları nı n wizard dosyaları (özyinelemeli) |
2026-09-21 19:40:13 +00:00
| `data/App.DeveloperKit.CustomComponents/{Id}.json` | Custom yolunda bağlı component ve bağı mlı lı kları — yalnı zca bu bileşenlerin satı r dosyaları |
| `data/{ListFormCode}.json` ya da `data/{ListFormCode}/{anahtar}.json` | Ekranı n `SeedFilePath` değeri doluysa kendi veri aynası (dosya ya da klasör) |
2026-08-26 18:44:53 +00:00
| `crud/{entity}.json` | Component'lerin/nesnenin kullandı ğı CRUD endpoint tanı mları |
2026-09-07 14:43:46 +00:00
| `{sql\|postgres}/{object\|execute}/{nesne}.sql` | `SelectCommand` 'a karşı lı k gelen SQL nesnesi, lookup sorguları nı n (`LookupDto.LookupQuery`) `FROM` /`JOIN` ile işaret ettiği nesneler ve Custom yolunda CRUD endpoint'lerinin dayandı ğı tablolar |
Script dosyaları sabit bir sağlayı cı /klasör kombinasyonundan **tahmin edilmez** : kapsam kökündeki
script klasörleri (`sql/object`, `postgres/execute` …) diskten taranı r ve nesne adı yla eşleşen her
dosya arşive girer. Yeni bir sağlayı cı ya da script klasörü eklendiğinde toplayı cı değişmez.
Script bulunamaması **uyarı üretmez** : her tablo seed ile yönetilmez — ABP'nin kendi tabloları
(`AbpUsers`, `AbpRoles` …) EF migration'ları yla kurulur ve seed script'leri yoktur. "Bu tablo
hedefte var mı " sorusunun tek doğru cevabı hedef veritabanı ndadı r; kararı import analizi verir,
export varsayı mda bulunmaz.
Çözülemeyen bir **kayı tlı referans** (seed dosyası nda adı geçen ama karşı lı ğı bulunmayan alt form,
`SeedFilePath` veri aynası , `DataSources[].SeedFile` CRUD dosyası , custom component satı rı )
indirmeyi engellemez ama sessiz de kalmaz: `ExportAnalysis` ucu indirmeden önce arşivin tam
içeriğini ve eksikleri döndürür, Wizard File Manager eksik varsa önce bu listeyi gösterir.
**İçe aktarma dört adı mlı bir sihirbazdı r** (`WizardImportDialog`, `Steps` bileşeni):
2026-08-26 18:44:53 +00:00
2026-09-07 14:43:46 +00:00
| Adı m | İçerik | Geçiş koşulu |
| --- | --- | --- |
| **Dosyalar** | Zip girdileri ve durumları ; çakı şanlar Monaco `DiffEditor` ile çözülür | Çözülmemiş çakı şma kalmamalı |
| **Kontroller** | Analiz bulguları ve zip'te atlanan girdiler. Engelleyiciler iki başlı kta ayrı lı r — **arşiv eksik ya da bozuk** (burada giderilemez, kaynak ortamda export tekrarlanmalı ; düzeltme düğmesi yoktur) ve **ortamda giderilebilir** . Tabloya dokunan bulgularda mevcut `SqlTableDesignerDialog` açı lı r — şema farkı nda **Tabloyu düzenle** (düzenleme modu), eksik tabloda **Tabloyu oluştur** (oluşturma modu, ad ön dolu); deploy sonrası analiz kendiliğinden yenilenir (önceki oturum bı rakı lı r) | Engelleyici (`Error`) bulgu kalmamalı |
| **Yapı lacaklar** | Onaylandı ğı nda ne olacağı nı n tam listesi: yazı lacak dosyalar, çalı şacak SQL script'leri, eklenecek kolonlar (cümleleriyle), uygulanacak CRUD ve veri dosyaları , kurulacak ekranlar. Sı ra sunucudaki kapanı ş sı rası yla aynı dı r | Onay |
| **Uygulama** | Dosya dosya yazı m, kapanı ş adı mları nı n sonucu | — |
Geriye dönüş her zaman serbesttir; ileri atlama bağı mlı lı k koşulları na bağlı dı r. Adı m başlı kları na
tı klanarak da gezinilebilir.
İçe aktarma **toplu (batch) bir işlemdir** : engelleme oturum genelindedir, dosya bazlı değildir.
Bir tek engelleyici bulgu tüm zip'i durdurur ve o dosyanı n işaretini kaldı rarak aşı lamaz — yarı m
kurulum üretmemenin tek güvenli yolu budur. Karşı lı ğı nda, tabloya dair her engel diyalogdan
çı kmadan giderilebilir (tablo tasarı mcı sı → deploy → analiz yenilenir). Tabloyla ilgisi olmayan
engeller (eksik alt form, eksik custom component bağı mlı lı ğı , bozuk JSON) zip'in kendisinin eksik
olduğunu gösterir; bunlar kaynakta düzeltilip yeniden export edilmelidir.
Adı mları n altı nda yatan üç sunucu işlemi şunlardı r:
2026-08-26 18:44:53 +00:00
1. **Analiz** (`AnalyzeImport`) — zip, seed kökü altı ndaki `.imports/{importId}/staged` klasörüne
açı lı r (nokta ile başladı ğı için seeder taramaları na girmez) ve her dosya hedefteki karşı lı ğı yla
karşı laştı rı lı r: `New` (hedefte yok), `Identical` (aynı , sorulmaz), `Conflict` (farklı ).
Çakı şan dosyalar Monaco `DiffEditor` ile karşı laştı rı lı p birleştirilir.
2026-09-05 18:20:18 +00:00
`data/*.json` girdilerinde karşı laştı rma **satı r bazlı dı r** : hedef dosyadan yalnı zca gelen
satı rları n anahtarları süzülür, dosya düzeyindeki `GeneratedAt` /`Order` karşı laştı rmaya girmez.
Böylece aktarı lan kaydı n dı şı ndaki satı rlar fark olarak görünmez; gelen satı rları n hiçbiri
hedefte yoksa dosya var olsa bile durum `New` (ekleme), varsa ve içerik aynı ysa `Identical`
(hiç aktarı lmaz), farklı ysa `Conflict` (güncelleme) olur.
2026-08-26 18:44:53 +00:00
2. **Uygulama** (`ApplyImport`) — dosyalar tek tek yazı lı r, ilerleme satı r satı r gösterilir. Yazı lan
her dosyanı n önceki hâli `.imports/{importId}/backup` altı na alı ndı ğı için hata durumunda
2026-09-05 18:20:18 +00:00
`RollbackImport` ile toplu işlem geri alı nabilir.
2026-09-07 14:43:46 +00:00
3. **Kapanı ş** (`CompleteImport`) — oturum kapatı lmadan önce zip'in getirdiği dosyalar
**bağı mlı lı k sı rası yla** veritabanı na uygulanı r. Sı ra bilinçli ve sabittir:
** (a)** `{sql|postgres}/{object,execute}/*.sql` scriptleri çalı ştı rı lı r (`object` önce) — tablo
yoksa burada oluşur, aksi halde sonraki iki adı m eksik tablo yüzünden baştan düşerdi;
** (b)** hedefte eksik olan kolonlar eklenir (aşağı ya bakı n);
** (c)** `crud/*.json` dosyaları `ICrudEndpointSeedApplier` ile uygulanı r;
** (d)** `data/*.json` dosyaları
2026-09-05 18:20:18 +00:00
`IListFormSeedDataApplier.ApplyFilesAsync(..., overwriteExisting: true)` ile veritabanı na
uygulanı r: tabloda olmayan satı r eklenir, var olan satı r dosyadaki değerlerle **güncellenir**
(migrate/seed akı şı ndan farkı budur — orada dosya bayat olabileceği için canlı kayda
dokunulmaz). Kayı t daha önce **soft delete** edilmişse silinme izleri de temizlenir
(`IsDeleted`, `DeletionTime` , `DeleterId` ); aksi halde satı r tabloda durur ama ekranı n
varsayı lan süzgeci (`"IsDeleted" = 'false'`) onu gizlemeye devam ederdi. Hangi kolonları n
sı fı rlanacağı ekranı n `DeleteCommand` 'ı ndan okunur, hard delete yapan ekranda hiçbir şey
eklenmez. Hedefle **zaten aynı ** olan (`Identical`) veri dosyaları da uygulanı r: yazacak bir şey
yoktur ama satı rlar veritabanı nda eksik ya da silinmiş olabilir. Kullanı cı nı n "mevcudu koru"
dediği (farklı olup yazı lmayan) dosyaya dokunulmaz. Anahtarı olmayan satı r güncellenemez,
atlanı r; eklenen/güncellenen/atlanan satı r
sayı sı dialogda raporlanı r. Bu adı m `RollbackImport`
2026-09-07 14:43:46 +00:00
kapsamı nda **değildir** — geri alma bu adı mdan önce yapı lı r.
2026-09-25 06:39:34 +00:00
5. **Ekran tanı mları ** (`wizard/*.json`) — ekran import'ta **kurulmaz** : dosyaya `Pending` yazı lı r,
Wizard Manager onu "Migrate bekliyor" gösterir ve ekran, deploy'daki gibi, DB Migrate'te
`WizardDataSeeder` tarafı ndan kurulur (hedefte kurulu olsa da dosyadaki hâliyle). Dosya ekranı n
üretilmiş `ListForm` /`Fields` sözleşmesini taşı dı ğı için bunlar wizard cevapları ndan **yeniden
türetilmez**. Wizard'ı n menü/yetki/dil satı rları nı taşı yan platform dosyaları 4. adı mda
uygulanmaz; onları da migrate ekler.
2026-09-07 14:43:46 +00:00
**Analiz doğrulama da yapar** (`WizardImportValidator`). Zip'in hedef ortamda yarı m bir kurulum
bı rakı p bı rakmayacağı dosyalar yazı lmadan **önce** denetlenir; bulgular `Error` /`Warning` olarak
raporlanı r ve en az bir `Error` varken import başlatı lamaz — sunucu oturuma `blocked` işaret
dosyası bı rakı r, dolayı sı yla `ApplyImport` ucu doğrudan çağrı lsa bile reddeder.
| Kural | Ağı rlı k |
| --- | --- |
| Bozuk JSON (`wizard`, `crud` , `data` ) | Error |
| Wizard bölümü ya da adı olmayan wizard dosyası ; `ListForm` bölümü eksik List wizard'ı | Error |
| Ekranı n tablosu (`SelectCommand`, `Table` /`View`) hedefte **yok** ve zip onu oluşturan `.sql` dosyası nı **taşı mı yor** | Error |
| `crud/{Entity}.json` 'un tablosu hedefte yok ve zip'te oluşturan script yok | Error |
| `data/{code}.json` 'un ekranı ne zip'te ne hedefte var | Error |
| Custom component'in `Dependencies` ya da `DataSources[].SeedFile` bağı mlı lı ğı ne zip'te ne hedefte var | Error |
| Custom wizard'da bileşen adı / rota yolu boş | Error |
| Alt form (`SubFormsDto[].Code`) ne zip'te ne hedefte var | Error |
| Nesne varlı ğı sorgulanamadı (bağlantı /izin) ve script de yok | Warning |
| Zip yalnı zca karşı sağlayı cı nı n (`sql` ↔ `postgres` ) scriptlerini taşı yor | Warning |
| Ekranı n `SeedFilePath` veri dosyası ne zip'te ne hedefte var; boş CRUD/veri dosyası | Warning |
| Script'in kurduğu tablo hedefte **var** ama bir kolonu eksik | Warning — kapanı şta eklenir |
| Eksik kolon `NOT NULL` , varsayı lanı yok ve tabloda kayı t var | Error (otomatik eklenemez) |
| Var olan kolonun uzunluk / kesinlik / ondalı k / nullability değeri script'ten farklı | Error |
| Hedefte script'te olmayan fazladan kolon var | Warning (dokunulmaz) |
Eksik tablo ölçütü "veritabanı nda var" değil, "veritabanı nda var **ya da** zip onu oluşturan
scripti taşı yor"dur — kapanı ş scriptleri veri satı rları ndan önce çalı ştı rdı ğı için zip'te scripti
olan tablo eksik sayı lmaz.
#### Şema karşı laştı rması — tablo var ama yapı sı farklı ysa
Üretilen tablo script'leri `IF OBJECT_ID(...) IS NULL BEGIN CREATE TABLE ... END` kalı bı yla sarı lı dı r:
hedefte tablo varsa `CREATE` bloğu **tamamen atlanı r** . Dolayı sı yla eski şemalı bir tabloya yeni bir
kolon kendiliğinden gelmez; ekran o kolonu bir alan olarak tanı mladı ğı için açı lı şta "geçersiz kolon"
hatası verir. Bu sessiz uyuşmazlı ğı analiz adı mı yakalar (`SqlCreateTableParser` +
`WizardImportValidator` ): zip'in getirdiği `CREATE TABLE` bildirimi, hedef tablonun
`INFORMATION_SCHEMA.COLUMNS` üzerinden okunan canlı şeması yla karşı laştı rı lı r.
Ayrı m **kayı p riskine** göre yapı lı r:
- **Eksik kolon eklenir.** Kolon eklemek kayı psı z bir işlemdir; analiz "şu kolon eklenecek" diye
uyarı r, çalı ştı rı lacak cümleyi gösterir ve kapanı şta (SQL script'lerinden sonra, CRUD ve veriden
önce) uygular. Tek istisna: `NOT NULL` olup varsayı lan değeri olmayan bir kolon dolu bir tabloya
eklenemez — kolona hangi değerin yazı lacağı bir iş kararı dı r, bu durumda import durdurulur ve
cümle kullanı cı ya bı rakı lı r. Tablonun boş olup olmadı ğı çalı şma anı nda sorgulanı r; boş tabloya
böyle bir kolon güvenle eklenir.
- **Var olan kolon değiştirilmez.** Uzunluk/kesinlik/ondalı k/nullability farkı nda import durur.
Daraltma veri keser, tip dönüşümü başarı sı z olabilir; doğru işlem veriye bakmayı gerektirir.
Fark somut olarak bildirilir ("uzunluk hedefte 200, script'te 300"), düzeltmeyi kullanı cı yapar.
- **Hiçbir kolon düşürülmez, hiçbir tablo `DROP` edilmez.** Hedefteki fazla kolon yalnı zca
bilgilendirme olarak listelenir.
Karşı laştı rma **tip adı na bakmaz** . Sağlayı cı kataloğu kendi kanonik adı nı raporlar (PostgreSQL'de
`VARCHAR` → `character varying` , `TIMESTAMP` → `timestamp without time zone` ); script'teki yazı lı şla
metin olarak karşı laştı rmak her `VARCHAR` kolonunda sahte fark üretirdi. Yalnı zca her iki
sağlayı cı da da aynı anlamı taşı yan ölçüler karşı laştı rı lı r: uzunluk, kesinlik/ondalı k, nullability.
Script bir tablo kurmuyorsa (procedure, view) ya da `CREATE TABLE` çözülemiyorsa karşı laştı rma
sessizce atlanı r — tahmin yürütülmez.
2026-09-05 18:20:18 +00:00
`data/*.json` dosyaları kapsamdaki bütün satı rları taşı dı ğı için üzerine yazı lmaz: satı rlar anahtar
alan üzerinden birleştirilir (gelen satı r varsa günceller, yoksa eklenir, hedefteki diğer satı rlar
korunur). Diff ekranı nda düzenlenen içerik de aynı sözleşmeyi taşı dı ğı için elle birleştirme bu
davranı şı bozmaz.
Güvenlik sı nı rları : yalnı zca `wizard` , `crud` , `data` , `sql` , `postgres` kök klasörleri
2026-08-26 18:44:53 +00:00
(SQL sağlayı cı klasörlerinin altı nda yalnı zca `object` ve `execute` ) kabul edilir; dosya başı na
5 MB, arşiv başı na 50 MB, en çok 500 girdi. Kabul edilmeyen girdiler analiz sonucunda uyarı
olarak listelenir. Yetkiler: `App.Listforms.Wizard.Export` / `App.Listforms.Wizard.Import` .
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 8. Developer Kit
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Teknik kullanı cı lar için `/admin/developerkit` altı nda toplanan araçlar:
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Araç | Route | Ne işe yarar |
2026-06-09 12:54:05 +00:00
| --- | --- | --- |
2026-08-26 18:44:53 +00:00
| **SQL Query Manager** | `/admin/sqlQueryManager` | Nesne gezgini, Monaco tabanlı SQL editörü, sonuç grid'i, **tablo tasarı mcı sı ** , **view tasarı mcı sı ** ve **CRUD endpoint yönetimi** . |
2026-08-17 14:26:51 +00:00
| **Custom Endpoint** | `/admin/list/App.DeveloperKit.CustomEndpoints` | SQL veya servis tanı mı ndan REST endpoint üretimi; GET/POST/PUT/DELETE için ayrı yetki kapı ları (`App.DeveloperKit.CustomEndpoints.*`) ve kullanı cı /rol/global erişim kuralları . |
| **CRUD Endpoint** | SQL Query Manager içinde | Tablo tanı mı ndan tam CRUD endpoint kümesi üretimi. Ayrı ekranı yoktur; bkz. aşağı daki not. |
2026-09-05 09:06:14 +00:00
| **Dynamic Service** | `/admin/list/App.DeveloperKit.DynamicServices` | Liste bir ListForm ekranı dı r (KPI şeridi, Swagger butonu, kart/ı zgara görünümü); kod yazma listeden açı lan `DynamicServiceEditor` diyalogundadı r: Monaco editörü, Roslyn ile derleme (`TestCompile`), yayı nlama (`Publish`) ve çalı şan uygulamaya controller olarak kaydetme. Yetkiler: Create/Edit/Delete/Manage/TestCompile/Publish/ViewCode. |
2026-09-21 19:40:13 +00:00
| **Custom Component** | `/admin/list/App.DeveloperKit.CustomComponents` | React bileşenini veritabanı nda saklama; `@babel/standalone` ile tarayı cı da derleyip route'a bağlama. Liste bir ListForm ekranı dı r (KPI şeridi, ı zgara/kart görünümü, grid'in kendi ekleme/düzenleme formu); satı rdaki **Design** butonu `/admin/developerkit/components/design/{id}` tasarı mcı sı nı , **Open URL** butonu bileşenin `RoutePath` 'ini açar. Kayı tlar `configs/seeds/host/data/App.DeveloperKit.CustomComponents/{Id}.json` klasörüne senkronlanı r. Yetkiler `App.DeveloperKit.CustomComponents{,.Create,.Update,.Delete,.Export,.Import}` . |
2026-09-07 06:14:00 +00:00
| **Visual Designer** | `/admin/developerkit/components/design/:id` | Custom Component listesindeki **Design** butonundan açı lı r; sürükle-bı rak kanvas ile bileşen üretimi ve kod üretimi (`visualDesigner/codeGenerator.ts`). |
2026-08-26 18:44:53 +00:00
| **ListForm** | `/admin/list/App.Listforms.Listform` | Var olan ekranları n ham tanı m listesi; buradan `/admin/listform/edit/{kod}` sekmeli editörüne geçilir. |
2026-09-30 20:52:33 +00:00
| **Wizard Manager** | `/admin/listform/wizardManager` | Üretilmiş wizard seed dosyaları nı n listesi/kartı , düzenleme, silme, DB migrate, export/import. Menüsüz alt formlar onları sekme olarak açan ekranı n altı nda iç içe görünür; kendi menüsü olan ekran başka bir ekranı n sekmesi olsa da kökte kalı r (export kapanı şı onu yine taşı r). Wizard'ı üreten talep listede görünür ve kaydı na bağlanı r; talebin bütün wizard'ları tek arşivde export edilir (`export-dev-request`) ya da bağı mlı lı k sı rası yla tek işlemde silinir (`delete-dev-request`; alt formlar önce, talebin ekranları birbirini kullanı m saymaz, tablolar en sonda — `lowcode.instructions.md` §4.5). Yetki `App.Listforms.Wizard{,.Create,.Update,.Delete,.Export,.Import}` . |
2026-08-26 18:44:53 +00:00
> Bu ekranları n artefakt şemaları , enum değerleri ve çalı şan örnekleri
> [`.github/instructions/lowcode.instructions.md`](.github/instructions/lowcode.instructions.md)
> dosyası ndadı r.
### 8.1. SQL View Designer
`SqlViewDesignerDialog` (+ `sqlViewDesigner/` ), SSMS Query Designer düzeninde görsel view
oluşturma aracı dı r. Üç panel:
- **Diagram** (`DiagramPane.tsx`) — `ViewSource` kutuları (x/y konumlu, daraltı labilir, yalnı zca
seçili kolonları gösterebilir) ve araları ndaki JOIN okları . Kaynak bir tablo/view olabileceği
gibi `CROSS/OUTER APPLY` ya da türetilmiş bir alt sorgu da olabilir; alt sorgunun gövdesi
olduğu gibi saklanı r. JOIN türleri: `INNER` , `LEFT` , `RIGHT` , `FULL` , `CROSS` ; koşul
operatörleri `=` , `<>` , `>` , `>=` , `<` , `<=` .
- **Criteria grid** (`CriteriaGrid.tsx`) — Column / Alias / Output / Group By / Sort / Filter /
Or… satı rları . Bir satı r ya `sourceId + columnName` referansı dı r ya da serbest bir SQL
ifadesidir. Group By sütunu `GroupBy` , `Where` (satı r çı ktı ya girmez, yalnı zca filtre taşı r) ve
`SUM` /`COUNT`/`COUNT_DISTINCT`/`AVG`/`MIN`/`MAX` değerlerini alı r. Filtre hücreleri SSMS'teki
gibi serbest yüklemdir (`> 100`, `LIKE '%abc%'` , `IS NULL` ).
- **T-SQL önizleme** — model → SQL üretimi (`generateViewSql`).
Tasarı mcı tek yönlü çalı şı r: **model → T-SQL** . Mevcut bir view açı lı rken `parseViewSql` ile geri
okunmaya çalı şı lı r; üretilen kanonik şekle uymayan bir tanı m gelirse dialog **ham SQL moduna**
düşer ve kullanı cı Query Editor'dan devam eder (`onOpenInEditor`). PostgreSQL bağlantı ları nda
`isPostgreSql` bayrağı ile söz dizimi buna göre üretilir.
2026-06-09 12:54:05 +00:00
2026-08-17 14:26:51 +00:00
> **CRUD Endpoint, SQL Query Manager ile birleştirildi.** Ayrı `/admin/developerkit/endpoints`
> ekranı ve menüsü kaldı rı ldı . Endpoint üretme, aktif/pasif etme, test etme ve silme işlemleri
> artı k iki yerden yapı lı r: SQL Query Manager nesne gezgininde tablo satı rı nı n **CRUD Endpoints**
> aksiyonu (ve seçili tablolar için toolbar'daki toplu üretim butonu), ayrı ca ListForm
> sihirbazı nı n **Adı m 2 – Veri Kaynağı ** ekranı ndaki aynı diyalog. Ayrı ca **tablo
> tasarı mcı sı nda deploy öncesi bir adı m** vardı r: endpoint üretilip üretilmeyeceği ve
> hangi operasyonları n (GetList/GetById/Create/Update/Delete) aktif başlayacağı seçilir
> ("tümünü seç" destekli); seçilmeyenler pasif olarak kaydedilir, sonradan diyalogdan
> açı labilir. Hepsi `CrudEndpointDialog` bileşenini kullanı r. Yetki `App.SqlQueryManager` altı ndaki
> `App.SqlQueryManager.CrudEndpoints`'tir; izin verilmemişse butonlar görünmez ve
> `crud-endpoint-generate` uçları nı n tamamı (base CRUD metotları dahil) reddedilir.
> Üretilen endpoint'ler `configs/seeds/{host|tenants/{tenantId}}/crud/{EntityName}.json` olarak
> seed dosyası na yazı lı r; `CrudDataSeeder` aynı dosyaları okuyup endpoint'leri geri yükler.
2026-08-10 09:08:08 +00:00
> **Tablo tasarı mı varsayı lanı :** Yeni tablo oluştururken tenant ve tam denetim (audit) kolonları
> varsayı lan olarak eklenir: `Id`, `TenantId`, `CreationTime`, `CreatorId`, `LastModificationTime`,
> `LastModifierId`, `IsDeleted`, `DeletionTime`, `DeleterId`. Kullanı cı açı kça istemedikçe bu
> kolonlar çı karı lmaz.
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
### 8.2. Custom Component ve Visual Designer
**Saklanan tanı m.** Bir custom component `Name` , `RoutePath` , `Code` (JSX), `Props` ,
`Dependencies` ve `DataSources` alanları ndan oluşur. Görsel tasarı mcı dokümanı iki yerde tutulur:
`Props.visualDesigner` içinde (nodes, canvas, lifecycle, dataSources) ve üretilen kodun ilk
satı rı ndaki `/*__SOZSOFT_VISUAL_DESIGNER__…__*/` yorumunda. Böylece yalnı zca kod elinizdeyse bile
tasarı mcı dokümanı geri okunabilir. `sourceMode` alanı `visual` ya da `code` olur; kod moduna
geçilen bir bileşen kanvasa geri dönmez.
2026-09-21 19:40:13 +00:00
**Seed senkronizasyonu.** Bileşenlerin seed kaynağı Custom Components ekranı nı n veri klasörüdür:
`configs/seeds/{host|tenants/{tenantId}}/data/App.DeveloperKit.CustomComponents/{Id}.json` — her
bileşen kendi dosyası ndadı r; bileşen kodu satı rı n içinde durduğu için tek dosya hı zla büyürdü.
Bileşene yazan **iki yol** da bu klasöre işlenir (`ListFormSeedDataSynchronizer`): listeden yapı lan
2026-09-05 18:20:18 +00:00
ekleme/güncelleme/silme ve Visual Designer'ı n kaydı (`CustomComponentAppService`). Veritabanı
sı fı rlandı ğı nda `ListFormSeedDataApplier` satı rları geri yazar; `Code` , `Props` ve `DataSources`
kolonları bu yüzden ekranda gizli alan olarak tanı mlı dı r. `DataSources` sütunu tasarı mcı
dokümanı ndan türetilir (`CustomComponentDataSourceResolver`): Data sekmesindeki her endpoint
`method + path` ile CRUD endpoint kataloğunda aranı r, eşleşenler `EntityName` +
`crud/{EntityName}.json` referansı nı taşı r, elle yazı lmı ş olanlar listede kalı r ama bu alanları
boş gelir. Wizard export'u bu referansları izleyerek bağlı `crud/*.json` dosyaları nı zip'e ekler.
2026-08-26 18:44:53 +00:00
**Toolbox.** Kanvasa bı rakı labilecekler beş aileye ayrı lı r:
| Aile | İçerik |
| --- | --- |
| `layout` | `PageContainer` , `FlexRow` (kolon sayı sı , ilk kolon genişliği, hizalama, gap, wrap), `Spacer` |
| `data` | `Form` — ASP.NET'in Form + FormView karşı lı ğı ; dört CRUD endpoint'ini sahiplenen kapsayı cı |
| `platform` | `ListView` , `DataGridView` , `TreeView` , `GanttView` , `TodoBoard` , `CardView` , `SchedulerView` , `PivotView` , `ChartView` — hepsi `listFormCode` ile bir ListForm ekranı nı gömer |
| `html` / `ui` | Ham HTML etiketleri ve `components/ui` tasarı m sistemi bileşenleri (sözleşmeleri metadata'dan okunur) |
| `custom` | Başka custom component'ler (bağı mlı lı k olarak kaydedilir) |
**Form bileşeni.** `selectEndpoint` / `insertEndpoint` / `updateEndpoint` / `deleteEndpoint` ,
`keyFieldName` , `collectionPath` , `keySource` + `keyParamName` , `previewKeyValue` , `autoLoad` ,
`showToolbar` , `columnCount` , `gap` özellikleriyle yapı landı rı lı r. İçine bı rakı lan her bileşen
Select sonucunun bir kolonuna bağlanı r ve Save/Delete üzerinden geri yazar.
**Veri bağlama.** `DesignerBinding` bir kaynağa (`sourceId`) ve yola (`path`) bağlanı r; `labelPath`
/ `valuePath` seçim bileşenleri içindir. `columns` ile ekranda görünmeyen ek sütunlar da taşı nı r
ve script'ten `refs.<ad>.getColumn('sutun')` ile okunup başka bir bileşenin değerine ya da Form
kaydı na yazı lı r. Filtreler CrudEndpoint `GetList` sözleşmesine göre üretilir: `eq` çı plak query
parametresi (`?RoleId=…`), diğerleri son ek taşı r (`?Name.contains=…`). Operatörler: `eq` , `ne` ,
`contains` , `startswith` , `endswith` , `gt` , `gte` , `lt` , `lte` , `in` , `isnull` , `notnull` .
**Yetki modeli.** İki katmanlı dı r:
- **Node görünürlüğü** — `designerPermission` prop'u dolu olan bir düğüm, yetki verilmemişse
render edilmez.
- **Form komutları ** — her komut (`selectPermission`, `insertPermission` , `updatePermission` ,
`deletePermission` ) ya serbesttir (boş) ya da bir yetkiye bağlı dı r. `Otomatik` modda temel,
Wizard'ı n bu bileşen için ürettiği okuma yetkisidir (menü kaydı nı n korunduğu yetkinin aynı sı ) ve
komutlara `''` / `.Create` / `.Update` / `.Delete` son ekleri eklenir. `Özel` modda yetki adı
elle yazı lı r.
**Script.** Tasarı mcı , ListForm Editor Script ile aynı ortak dialog'u kullanı r
(`designerScriptDialect.ts` + `designerScriptRecipes.ts` ); tarif grupları bileşen erişimi, API
çağrı ları , form ve olay/sayfa başlı kları altı nda toplanı r.
2026-09-09 06:06:25 +00:00
**Kanvas doğruluğu.** Tasarı m zamanı nda görülen, canlı da görülendir; bunu iki mekanizma sağlar.
(1) *Yerleşim sı nı fları nı n taşı nması * : kanvas her düğümü seçim/sürükleme için bir sarmalayı cı ya
alı r ve üst öğe grid/flex olduğunda ası l öğe o sarmalayı cı olur. `splitLayoutClasses` düğümün
yerleşim sı nı fları nı sarmalayı cı ya geçirir — `col-span` /`row-span`/`order`/`self`/`flex-1`/`basis`,
sabit ve kesirli `w-*` , kenar boşlukları taşı nı r; konum sı nı fları (`absolute`, `inset-*` , `z-*` ,
`w-full` ) her ikisinde de kalı r. Görünürlük sı nı fları da sarmalayı cı ya kopyalanı r (`hidden lg:flex`
→ sarmalayı cı da `hidden lg:block` ): aksi hâlde mobilde gizlenmesi gereken masaüstü şeridi yine bir
grid hücresi işgal eder ve komşuları nı yanlı ş hücreye iter. `fixed` kanvasta akı şa çevrilir, yoksa
düğüm tasarı m yüzeyinden taşardı . (2) *Cihaz çerçevesi* : araç çubuğundan masaüstü/tablet/mobil seçildiğinde kanvas kendi
belgesinde çizilir (`CanvasFrame`), böylece `md:` /`lg:` kuralları tarayı cı penceresine değil seçilen
genişliğe göre çözülür. Cihaz modunda tasarı m yüzeyi kenar boşluğunu bı rakı r: kanvas o cihazı n ekranı dı r. `Responsive`
seçimi aynı sayfada, çerçevesiz ve boşluklu çizer. (3) *Gezinme kapalı dı r* : kanvastaki bir bağlantı ya
tı klamak seçim yapar, sayfayı değiştirmez — tı klama yakalama evresinde durdurulur, `react-router` 'ı n
`Link` 'i de `defaultPrevented` görünce gezinmez.
2026-08-26 18:44:53 +00:00
**Diğer notlar.** `PlatformIcon` tasarı mcı dokümanı ndaki ikon adı nı çözer; `selectComponents.ts`
`Select.componentAs` için saklanan adı (`ReactSelect`, `CreatableSelect` , `AsyncSelect` ) gerçek
bileşene çevirir — kanvas ve üretilen bileşenin aynı adı aynı şekilde yorumlaması nı sağlayan tek
2026-09-29 06:14:07 +00:00
nokta budur. Yeni bileşen `configs/seeds/host/data/App.DeveloperKit.CustomComponents/` klasöründe
kendi `{Id}.json` satı r dosyası olarak başlar.
2026-08-26 18:44:53 +00:00
2026-08-10 09:08:08 +00:00
**Dinamik servis yaşam döngüsü:** `DynamicServiceCompiler` kodu derler →
`DynamicAssemblyRegistrationService` assembly'yi tenant bağlamı yla kaydeder →
`ActionDescriptorChangeProvider` MVC'ye route tablosunun değiştiğini bildirir →
`DynamicControllerActivator` bağı mlı lı kları enjekte eder. Uygulama yeniden başlatı lmaz.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 9. Dinamik Menü, Route ve Yetki Modeli
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
```
Permission (ABP) ──┐
├──► Menu.RequiredPermissionName ──► menüde görünürlük
Route.Authority ──┘ └► PermissionGuard ile erişim
```
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- **Route** (`Entities/Tenant/Administration/Route.cs`): `Key` , `Path` , `ComponentType` ,
`ComponentPath` , `RouteType` (`public` / `protected` ), `Authority[]` .
- **Menu** (`Menu.cs`): `Code` , `ParentCode` , `DisplayName` , `Url` , `Icon` , `Order` ,
`RequiredPermissionName` , `Target` , `IsDisabled` , ayrı ca `UserId` / `RoleId` / `CultureName`
ile kullanı cı , rol ve dil bazlı menü varyantları .
2026-10-01 09:37:30 +00:00
- **Menü yöneticisi** (`/admin/menuManager`): sürükle-bı rak ağaç ile menü düzenleme. Kayı tlar `App.Menus.Menu` ekranı yla aynı seed dosyası na (`data/App.Menus.Menu.json`, `SeedSync*` bayrakları na bağlı ) yazı lı r; menü adları `App.Languages.LanguageText.json` 'a.
2026-08-10 09:08:08 +00:00
- Frontend'de `dynamicRoutesContext` route'ları çeker, `dynamicRouteLoader` bunları fiziksel
view'lara veya runtime derlenmiş Custom Component'lere eşler, `DynamicRouter` React Router
ağacı nı kurar; her korumalı route `ProtectedRoute` + `PermissionGuard` ile sarı lı r.
2026-09-09 06:06:25 +00:00
- Aynı yolu bir fiziksel route ile bir Custom Component paylaşı yorsa **Custom Component kazanı r** ;
karşı lı ğı olan dosyası bulunmayan rota kaydı hiç yüklenmez. Public site menüsü bu modelin
dı şı ndadı r: `Pub` modülü altı nda tutulur ve uygulama konfigürasyonuyla taşı nı r (bkz. §10.4).
2026-06-09 12:54:05 +00:00
2026-09-29 11:46:39 +00:00
**Modüller ve kök menüler.** Kök menüler bir modüle bağlı dı r (`Menu.ModuleId` →
`data/App.Menus.Module.json` ): `Sas` → `App.Saas` (Saas), `Adm` → `App.Administration` ,
`Hr` → `App.Hr` (İK), `Pub` → `App.Public.Header` (public site). Tablo ön eki aynı modülden gelir
(`MenuPrefix`: `Sas_` , `Adm_` , `Hr_` ; `TableNameResolver` ). Her yetki satı rı `Modules`
(pipe ile ayrı lmı ş) değeri taşı r; kiracı nı n modül listesi doluysa menü (`MenuAppService`) ve rol
yetki ekranı (`RolesPermission.tsx`) yalnı zca kesişen modüllerin yetkilerini gösterir. Sözleşme:
`Sas` host'ta görünürlüğü, `Adm` ve `Hr` kiracı daki görünürlüğü belirler — Saas/Administration
yetkileri `Sas|Adm` , İK yetkileri `Sas|Hr` taşı r.
**İK (Hr) modülü.** Menü `App.Hr` → `App.Hr.Definitions` (Yetenek Tipleri `App.Hr.SkillType` ,
Departmanlar `App.Hr.Department` , Pozisyonlar `App.Hr.JobPosition` ) ve doğrudan
Organizasyon Şeması `App.Hr.OrgChart` (`/admin/organization`; menü ve route aynı yetkiyi ister).
Yetki grubu `App.Hr` ; ListForm kodu = menü kodu = yetki adı = dil anahtarı . Tablolar
2026-09-29 14:18:47 +00:00
`Hr_T_SkillType` / `Hr_T_SkillLevel` / `Hr_T_Skill` / `Hr_T_Department` / `Hr_T_JobPosition`
(hepsi kiracı , `IMultiTenant` , `Guid` anahtar); ekranlar `ListFormSeeder_Hr.cs` 'tedir, entity'ler
`Entities/Tenant/Hr/Definitions` . Departman ve pozisyon **şube bazlı dı r** : `BranchId` zorunlu kolondur
2026-09-29 11:46:39 +00:00
(`Guid`, `NOT NULL` ), listenin ilk sütunu Şube Adı 'dı r (`LookupQueryValues.TenantBranchValues`);
departman lookup'ı şubeye göre süzülür (`BranchDepartmentValues`). Host varsayı lan şubesi sabit
kimlikle kurulur (`PlatformConsts.Branches.BranchIdDefaultValue`) ve
`data/App.Hr.{Department,JobPosition}.json` satı rları bu kimliğe bağlı dı r. Numaratör
(`App.Definitions.Sequence`) Administration › Definitions altı ndadı r. Ayrı ntı :
`lowcode-reference.instructions.md` §12.4.
2026-08-10 09:08:08 +00:00
**Yetki kodları ** `PlatformConsts.AppCodes` içinde merkezî olarak tanı mlı dı r ve
2026-09-17 17:54:23 +00:00
`configs/seeds/host/data/Abp.Identity.Permissions.json` ile seed edilir (gruplar:
2026-09-29 11:46:39 +00:00
`Abp.Identity.PermissionGroups.json` — `App.Saas` (1), `App.Administration` (2), `App.Hr` (3)).
2026-10-02 23:11:39 +00:00
Ana yetki kökleri: `App.Saas` , `App.Branches` ,
`App.Definitions.*` , `App.Hr.*` (Intranet dahil, `App.Hr.Intranet.*` ), `App.Restrictions.*` , `App.Languages.*` , `App.Listforms.*` ,
2026-08-10 09:08:08 +00:00
`App.Notifications.*` , `App.BackgroundWorkers.*` , `App.Menus.*` , `App.DeveloperKit.*` ,
2026-08-17 14:26:51 +00:00
`App.SqlQueryManager.*` ,
2026-08-10 09:08:08 +00:00
`App.Orders.*` , `App.BlogManagement.*` , `App.IdentityManagement.*` , `App.Reports.*` ,
`App.Administration` , `App.Setting` , `App.Setup.Migrate` .
2026-06-09 12:54:05 +00:00
2026-09-20 20:23:39 +00:00
Yetki ekranı ndaki **sı ralama** `AbpPermissions.Order` ve `AbpPermissionGroups.Order`
sütunları ndan gelir (`Modules` gibi genişletme alanları , `PlatformEfCoreEntityExtensionMappings` );
ABP kayı tları sı rası z okuduğu için sı ra taşı nmazsa ekran her açı lı şta başka bir dizilim gösterirdi.
Sı ra **kardeşler arası ndadı r** : her üst yetkinin altı nda 1'den başlar, grubun kök yetkileri de
kendi araları nda 1'den. `PlatformPermissionAppService` sı ralama anahtarı nı kökten yaprağa üst yetki
zincirinden kurar, böylece çocuk her zaman ebeveyninin altı nda kalı r. Değerler seed dosyaları ndaki
`Order` alanı nda tutulur ve Permissions / Permission Groups ekranları ndan düzenlenebilir.
2026-09-29 14:55:13 +00:00
**Yetki ağacı menü ağacı nı izler.** Wizard ekranı n okuma yetkisini menüde durduğu dalı n altı na
yazar: üst menü zincirindeki (`MenuParentPath` + `MenuParentCode` ) her seviye, izin grubunun
kendisi hariç, aynı kodlu bir ara yetkidir (`İnsan Kaynakları › Tanı mlamalar › Ekran` →
`App.Hr.Definitions › App.Hr.Doctor` ). Var olan ara yetki kullanı lı r, eksik olan menü seviyesinin
2026-10-02 12:46:52 +00:00
görünen adı yla wizard'a ait üretilir; başka bir gruptaki aynı adlı yetki atlanı r. Kodu bulunamayan
bir seviye önce aynı üstün altı ndaki dallarla adı yla eşleştirilir (dalı n `DisplayName` anahtarı =
verilen kod ya da EN/TR adı aynı ) ve eşleşen dalı n koduna bağlanı r; böylece MCP'nin yalnı zca yol
verdiği deploy'da ikinci bir "Tanı mlamalar" menüsü ve ara yetkisi oluşmaz
(`ListFormWizardAppService.BindExistingMenuParentsAsync`). Menüsüz wizard'ı n
2026-09-30 14:57:25 +00:00
(`CreateMenu: false`, alt form) okuma yetkisi onu `SubForms` içinde taşı yan listenin yetkisine
bağlanı r: `ParentName` = listenin yetki kodu (`App.Hr.HealthCard › App.Hr.HealthCardFile`), sı rası
listenin alt yetkilerinin (Create/Update/…) ardı ndandı r. Alt form listeden önce deploy edildiği için
yetkisi önce grubun köküne yazı lı r; liste deploy edildiğinde alt formun satı rı listenin altı na
taşı nı r (satı r alt formun wizard'ı na ait kalı r, başka bir listeye bağlanmı ş alt form taşı nmaz).
Hiçbir listenin alt formu olmayan menüsüz wizard'ı n yetkisi grubun kökünde kalı r.
2026-09-29 14:55:13 +00:00
Wizard deploy'u yeni grubu ve yeni yetkileri (seed satı rı olarak) veritabanı ile seed
2026-09-29 06:14:07 +00:00
dosyası ndaki kardeşlerin en büyük sı rası nı n bir fazlası yla, alt yetkileri `WizardSeedRowKeys.ChildPermissions` dizilimiyle
(List: Create/Update/Delete/Export/Import/Note, Custom: Create/Update/Delete) 1'den yazar
(`ListFormWizardAppService.WritePermissionGroupAsync` / `WritePermissionRowsAsync` ).
2026-09-20 20:23:39 +00:00
2026-08-26 18:44:53 +00:00
Aksiyon yetkisi olan alt gruplar (UI tarafı ndaki karşı lı kları `constants/permission.constant.ts`
içindedir; oradaki kontroller yalnı zca butonları gizler, ası l kontrol AppService'lerdedir):
| Grup | Alt yetkiler |
| --- | --- |
| `App.Listforms.Wizard` | `.Create` , `.Update` , `.Delete` , `.Export` , `.Import` |
2026-09-07 06:14:00 +00:00
| `App.DeveloperKit.CustomComponents` | `.Create` , `.Update` , `.Delete` , `.Export` , `.Import` |
2026-08-26 18:44:53 +00:00
| `App.DeveloperKit.CustomEndpoints` | `.Get` , `.Post` , `.Put` , `.Remove` (dispatcher üzerinden çağrı kapı sı ; endpoint bazlı User/Role/Global kuralları bunun üstünde denetlenir) |
| `App.DeveloperKit.DynamicServices` | `.Create` , `.Edit` , `.Delete` , `.Manage` , `.TestCompile` , `.Publish` , `.ViewCode` |
| `App.SqlQueryManager` | `.CrudEndpoints` |
| `App.Setup.Migrate` | Migration + seed tetikleme (host tarafı ) |
2026-08-10 09:08:08 +00:00
> **Kural:** Yetki sözleşmesi olmayan menü/route önerilmez ve eklenmez.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 10. Modül Kataloğu
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 10.1. Backend modülleri (`api/modules`)
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Modül | Kapsam |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| **Sozsoft.Languages** | Dil tanı mları , dil anahtarları , çeviri metinleri; tenant bazlı lokalizasyon (`TenantLocalizationMiddleware`). |
| **Sozsoft.Settings** | Ayar tanı mları , sağlayı cı lar, şifreleme bayrakları ve ayar ekranı metadata'sı . |
| **Sozsoft.Notifications** | Bildirim tipleri, kuralları ve kullanı cı bildirimleri; kanal bazlı yönlendirme. |
| **Sozsoft.MailQueue** | Şablon (Scriban) tabanlı gövde üretimi, ek dosya yaşam döngüsü, kuyruk çalı ştı rma ve günlükleme. |
| **Sozsoft.Sender** | Amazon SES (mail), Posta Güvercini (SMS), WhatsApp Cloud API, Rocket.Chat göndericileri. |
| **Sozsoft.SqlQueryManager** | SQL nesne yönetimi, sorgu çalı ştı rma, tablo/kolon metadata'sı . |
2026-09-29 06:14:07 +00:00
| **Sozsoft.Mcp** | MCP (Model Context Protocol) sunucusu: `/mcp` Streamable HTTP ucu, kiracı bazlı araç seti, şema keşfi, sorgu, veri yazma ve (host) tablo/ekran/bileşen geliştirme. Kiracı kullanı cı sı veri okur ve ekranı n C/U/D sözleşmesinden geçerek satı r yazar; geliştirme araçları yalnı zca host'tadı r. Bkz. §13.9. |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 10.2. Uygulama servisleri (`api/src/Sozsoft.Platform.Application`)
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
`AiBots` · `AuditLogs` · `BackgroundWorker` · `Blog` · `Branch` · `Dashboard` · `DataSource` ·
`DeveloperKit` · `FileManagement` · `Forum` · `GlobalSearch` · `Hr` · `Identity` · `Intranet` ·
`ListForms` (+ `Administration` ) · `Menu` · `Messenger` · `Note` · `OrgChart` ·
`OrganizationUnits` · `Public` · `Routes` · `Tenants` · `Videoroom`
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 10.3. Yönetim ekranları (UI)
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Alan | Route | Açı klama |
2026-06-09 12:54:05 +00:00
| --- | --- | --- |
2026-08-10 09:08:08 +00:00
| Dashboard | `/admin/dashboard` | Widget tabanlı özet ekran. |
| Kullanı cı / Rol | `/admin/list/...` , `/admin/users/detail/:userId` | Kullanı cı , rol ve permission atamaları . |
| Organizasyon birimleri | `/admin/ous` | OU ağacı ve üyelik yönetimi. |
| Tenant yönetimi | ListForm ekranları | Tenant kayı tları , bağlantı dizeleri, siparişten otomatik tenant açma. |
| Ayarlar | `/admin/settings` | Sistem ve entegrasyon ayarları . |
| Menü yöneticisi | `/admin/menuManager` | Menü ağacı düzenleme. |
| Dosya yöneticisi | `/admin/files` | Klasör/dosya işlemleri. |
| 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. |
2026-09-04 12:51:58 +00:00
| Forum | `/admin/forum` | Forum kullanı mı ; yönetim `App.ForumManagement` altı ndaki ListForm ekranları yla yapı lı r. |
2026-09-24 07:24:48 +00:00
| 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. |
2026-08-10 09:08:08 +00:00
| Video oda | `/admin/videoroom/*` | Oda listesi, detay, planlama, katı lı mcı ve ekran paylaşı mı . |
2026-10-01 12:01:57 +00:00
| Raporlar | `/admin/reports/:report/view|design/...` | DevExpress rapor görüntüleyici ve tasarı mcı . `Raporlar` kategorisindeki şablon: `/admin/reports/DynamicReport/view/{ŞablonId}[/{ListFormCode}?recordId=...]` (§15). |
2026-08-10 09:08:08 +00:00
| AI asistanı | `/admin/ai` | n8n webhook üzerinden sohbet arayüzü. |
| Profil | `/admin/profile/*` | Genel bilgiler, şifre, bildirim ayarları . |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 10.4. Public site
2026-06-09 12:54:05 +00:00
2026-09-09 06:06:25 +00:00
`/home` · `/about` · `/contact` (Custom Component) · `/products` · `/checkout` · `/payment` ·
`/success` · `/blog` · `/blog/:id` · `/demo` (fiziksel sayfalar).
Ziyaretçiye açı k kı sı m iki parçadan oluşur ve ikisi de veritabanı nda yaşar:
**Menü.** Public menüler `Menu` tablosunda `ModuleId = "Pub"` modülü altı nda tutulur ve Menü
Yönetimi ekranı ndan girilir (sözleşme: `PlatformConsts.PublicSite` ). `App.Public.Header` kökü hem
üst navigasyonu hem de alt bilgideki hı zlı bağlantı ları besler — ikisi de `PublicNav` düğümüdür,
menü bir kez eklenir iki yerde birden görünür; alt kaydı olan bir menü üstte açı lı r liste olur.
Alt bilgide `cta` kayı tları (Giriş) yer almaz: oradaki düğüm `source="navigation"` ile çizilir. `Url` sayfa yolu, `Icon`
react-icons adı , `Order` sı ra, `IsDisabled` yayı n anahtarı , `DisplayName` dil anahtarı dı r;
`CssClass` içinde `cta` geçen kayı t düz bağlantı yerine vurgulu buton olarak çizilir. Menü ucu
`[Authorize]` olduğu için menüler uygulama konfigürasyonunun `publicMenus` alanı yla taşı nı r
(`PlatformApplicationConfigurationContributor`), istemcide `usePublicMenu` okur. `Pub` modülü
yönetim navigasyonuna girmez (`abpConfig.model.ts` menüyü kurarken bu modülü eler; Menü Yönetimi
2026-09-17 17:54:23 +00:00
ekranı elemez, menüler oradan düzenlenir). Seed: `configs/seeds/host/data/App.Menus.Module.json` ve
`App.Menus.Menu.json` .
2026-09-09 06:06:25 +00:00
**Sayfa.** Her public sayfa bir Custom Component'tir: `RoutePath` `/admin/` ile başlamadı ğı sürece
bileşen otomatik olarak public route olur ve `PublicLayout` altı nda yayı nlanı r. Tasarı m yalnı zca
DeveloperKit > Custom Components (Visual Designer) üzerinden değişir. Aynı yolu bir fiziksel route
ile paylaşan custom component kazanı r; karşı lı ğı olan dosyası bulunmayan rota kaydı ise hiç
yüklenmez (`hasPhysicalComponent`) — seeder yalnı zca eklediği için eski kayı tlar veritabanı nda
2026-09-21 19:40:13 +00:00
kalsa bile ekran patlamaz. Seed: `configs/seeds/host/data/App.DeveloperKit.CustomComponents/{Id}.json` ;
2026-09-29 06:14:07 +00:00
ekran klasör modundadı r, her bileşen kendi satı r dosyası ndadı r (dosya adı satı rı n `Id` 'si).
2026-09-09 06:06:25 +00:00
Runtime kapsamı sı nı rlı dı r: bileşen kodundaki `import` satı rları derlemede temizlenir,
kullanı labilenler `React` , `ui` kit, `PlatformViewHost` , `apiService` , `axios` , `DOMPurify` ,
`translate` , `checkPermission` , `getCulture` ve **katalog düğümleri**
(`components/componentEditor/runtimeNodes.ts`). ** `react-icons` ve `react-router` yoktur** — ikon
`<PlatformIcon name="FaUsers" size={40} className="..." />` ile ada göre çizilir (menü ikonları yla
aynı sözlük), gezinme `<a href>` ile yazı lı r. Kullanı cı ya görünen metinler dil anahtarı üzerinden
gelir.
**Tailwind sı nı f yüzeyi.** Bileşenin kodu veritabanı nda yaşar; derleme sı rası nda taranan tek
2026-09-21 19:40:13 +00:00
kaynak seed dosyaları dı r (`configs/seeds/*/data/App.DeveloperKit.CustomComponents/{Id}.json`). Bu klasör
2026-09-09 06:06:25 +00:00
depo kökünde, `ui/` dı şı ndadı r — derleme bağlamı yalnı zca `ui/` klasörü olduğunda (docker, ayrı
checkout) glob boş döner ve seed'e özgü sı nı flar (`md:col-span-4`, `bg-gray-950/80` , `opacity-20` )
CSS'e hiç girmez: uygulama yerelde doğru, sunucuda stilsiz görünür. Bu yüzden aynı sı nı flar var
olan `ui/safelist.txt` dosyası na da yazı lı r. Dosyayı zaten `twSafelistGenerator` eklentisi üretiyor
(renk/ölçü listesi); eklenti artı k seed dosyaları ndaki `className` değerlerini de toplayı p
`# --- custom component classes ---` işaretinin altı na ekliyor. `safelist.txt` `ui/` içinde ve
depoda olduğu için her ortamda taranı r. Seed kökü görünmüyorsa işaretin altı ndaki liste olduğu gibi
korunur — eksik bir bağlam listeyi silip sorunu büyütmez. Ayrı bir betik ya da ikinci bir safelist
dosyası yoktur; liste her `npm run build` / `npm start` ile tazelenir.
**Katalog düğümleri.** Kanvası n doğrudan çizdiği, derlenen bileşen listesinde yer almayan
bileşenler tek bir sözlükte durur (`RUNTIME_NODE_COMPONENTS`): kanvas onu `VisualCanvas` içinde,
üretilen kod ise runtime kapsamı üzerinden kullanı r — iki taraf aynı kaynaktan beslendiği için
2026-09-21 15:01:40 +00:00
tasarı m ve çalı şma zamanı ayrı şamaz. Sözlükte `PlatformIcon` , `BarcodeScanField`
2026-09-21 19:53:48 +00:00
(`components/shared/BarcodeScanner`), `BarcodeViewer` (`components/shared/BarcodeViewer.tsx`) ve
public site parçaları (`components/publicSite`) bulunur. Yeni bir düğüm eklerken: bileşen `components/publicSite` (ya da
2026-09-24 19:39:00 +00:00
uygun klasör) → `runtimeNodes.ts` sözlüğü → `catalog.ts` tanı mı (`kind: 'custom'`) → `data/App.Languages.LanguageText.json`
2026-09-09 06:06:25 +00:00
açı klama anahtarı .
2026-09-21 19:53:48 +00:00
**Barkod.** Okuma ve çizme ayrı yollardı r, ikisi de `utils/barcode.ts` içindedir ve `zxing-wasm`
yalnı zca gerektiğinde lazy iner. Okuma: Chromium'da yerleşik `BarcodeDetector` , olmayan tarayı cı da
`zxing-wasm/reader` (`BarcodeScanField`, `BarcodeScannerDialog` ). Çizme: `zxing-wasm/writer`
(`writeBarcodeSvg` → `BarcodeViewer` ); SVG üretilir, böylece büyütmede ve baskı da kı rı lmaz.
Desteklenen çizim formatları `BARCODE_WRITE_FORMATS` listesindedir (QRCode, Code39, Code93,
Code128, EAN13/8, UPCA/E, ITF, Codabar, DataMatrix, PDF417, Aztec) ve katalogdaki `format`
seçenekleri de bu listeden üretilir — liste tek yerde değişir. `BarcodeViewer` bir `value` propu
taşı dı ğı için tasarı mcı daki `Form` düğümünün içinde tı pkı bir `Input` gibi bir kolona bağlanabilir;
kayı t değiştikçe kod yeniden çizilir.
2026-09-09 06:06:25 +00:00
Elle yazı lmı ş bir bileşen Visual Designer'da **kod modunda** açı lı r: tasarı mcı yalnı zca kendi
ürettiği kodu düğüm ağacı na çevirir (`isDesignerGeneratedCode`), aksi hâlde tanı madı ğı JSX'i
düşürüp kaydederken kodu yok ederdi.
Public bileşenlerin tamamı — `/home` , `/about` , `/contact` sayfaları ile üst ve alt bilgi
(`PublicHeader`, `PublicFooter` ; rotaları yok) — **tasarı mcı belgesi** olarak tutulur: `Props` alanı ndaki
`visualDesigner` düğüm ağacı kaynaktı r (`sourceMode: "visual"`), `Code` ondan üretilir
(`generateDesignerCode`) ve runtime da bileşeni bu belgeden derler. Yani hepsi kanvasta görünür,
sürükle-bı rak ve özellik paneliyle düzenlenir. Belgeler `div` /`h1`-`h5`/`p`/`span`/`img`/`a`
HTML düğümleri ve `PlatformIcon` ikon düğümüyle kurulmuştur; `::` ile başlayan metinler üretilen
kodda `translate()` çağrı sı na döner. `RoutePath` boş bı rakı labilir; rotası olmayan bir bileşen
yalnı zca başka bir ekranı n içinde çizilir (alt bilgi gibi).
Üst ve alt bilgi de birer Custom Component'tir (`PublicHeader`, `PublicFooter` ; rota yok):
`PublicLayout` ikisini de `renderComponent` ile çizer ve geriye yalnı zca rota değişiminde başa
sarma ile demo penceresi kalı r. Bileşen kayı tlı değilse o parça çizilmez.
Üst bilginin davranı şı (menü listesi, aktif bağlantı , kaydı rmada değişen görünüm, mobil panel,
tema/dil/demo kontrolleri) `components/publicSite` altı ndaki katalog düğümlerinde yaşar; yerleşim
ve sı nı flar tasarı mcı dadı r: `PublicHeaderBar` (kaydı rı ldı ğı nda `scrolledClassName` 'e geçen kabuk),
`PublicNav` (`source`: `navigation` /`actions`/`all`, `variant` : `horizontal` /`vertical`),
`PublicMobileMenu` (hamburger + içeriği tasarlanan panel), `PublicLogo` , `PublicThemeToggle` ,
`PublicLanguageSelector` , `PublicDemoButton` .
Rotası olmayan bileşende `RoutePath` **NULL** yazı lı r; `Sas_H_CustomComponent` 'in `RoutePath`
tekil indeksi yalnı zca dolu değerleri kapsar (`[IsDeleted] = 0 AND [RoutePath] IS NOT NULL`), aksi
hâlde ikinci rotası z bileşen birincisiyle çakı şı rdı .
`/home` , `/about` , `/contact` bu yolla çalı şı r (`PublicHomePage`, `PublicAboutPage` ,
`PublicContactPage` ); üst ve alt bilgi rotası zdı r (`PublicHeader`, `PublicFooter` ).
2026-09-22 20:59:36 +00:00
Yalnı zca ikon taşı yan bir bağlantı ya da düğmenin ekran okuyucuda adı olmaz; `a` ve `button`
düğümleri bunun için `aria-label` özelliği taşı r (`componentDefinitions.ts`). Görsel düğümüne
`width` /`height` yazmak da tarayı cı nı n yeri önceden ayı rması nı sağlar ve yerleşim kayması nı
(CLS) önler — gösterim ölçüsü `className` 'den gelmeye devam eder.
2026-09-09 06:06:25 +00:00
Veriden beslenen public sayfalar (`/products`, `/checkout` , `/payment` , `/success` , `/blog` ,
`/blog/:id` , `/demo` ) fiziksel kalı r; içerik sayfaları Custom Component'tir. Blog listesi ve detayı
`PublicAppService` 'in `post-list` / `post-by-slug` uçları ndan beslenir, yönetimi
`App.BlogManagement.*` ekranları ndadı r.
2026-09-22 20:59:36 +00:00
**SEO.** Ziyaretçiye açı k yüzeyin arama motoru sözleşmesi üç parçadı r:
| Parça | Nerede | Ne taşı r |
| --- | --- | --- |
2026-09-29 06:14:07 +00:00
| Genel varsayı lanlar | `App.SiteManagement.Seo.*` ayarları (Ayarlar ekranı , yetki `App.SiteManagement.Seo` ) | Site adresi, site adı , varsayı lan başlı k/açı klama/paylaşı m görseli, Twitter hesabı , diller, robots yönergesi, Google doğrulaması , sosyal hesaplar, varsayı lan anahtar kelimeler (`DefaultKeywords`), sitemap anahtarı (`SitemapEnabled`), sitemap dı şı yollar (`SitemapExcludePaths`) |
2026-09-22 20:59:36 +00:00
| Yol bazlı alanlar | Yolu tanı mlayan kaydı n `Seo*` kolonları : `Route` (`Sas_H_Route`, ekran **Menü Yönetimi › Route** ) ve `CustomComponent` (`Sas_H_CustomComponent`, ekran **DeveloperKit › Custom Components** ) | Yolun başlı ğı , açı klaması , anahtar kelimeleri, paylaşı m görseli, kanonik adresi, `SeoNoIndex` , sitemap davranı şı ve ek JSON-LD |
| İstemci | `components/shared/SeoHead.tsx` | `title` , `description` , `robots` , `canonical` , `og:` /`twitter:` kartı , `og:locale:alternate` ve JSON-LD |
Ayrı bir SEO tablosu yoktur: meta, yolu tanı mlayan kaydı n üzerinde yaşar. `SeoAppService`
iki kaynağı tek sözleşmede birleştirir — `RouteType = public` olan `Route` satı rları ve rota
taşı yan aktif Custom Component'ler. Aynı yolu ikisi de tanı mlı yorsa bileşen kazanı r; çalı şma
zamanı nda da bileşen fiziksel rotayı gölgeler.
Alanlar ve ayarlar uygulama konfigürasyonunun `seo` alanı yla ziyaretçiye taşı nı r
(`PlatformApplicationConfigurationContributor` → `SeoAppService.GetConfigAsync` ); sayfa ayrı bir
istek atmaz, meta ilk boyamada hazı rdı r. Yol çözümü daraldı kça öncelik kazanı r: birebir yol, sonra
en uzun joker (`/blog/*`). Metin alanları kültür başı na çoğalmaz: `::Anahtar` biçimindeki değer
istemcide çevrilir (`resolveSeoText`), düz metin olduğu gibi kullanı lı r.
Sayfanı n kendi `SeoHead` 'i, kabuğun (`PublicLayout`) `fallback` kaydı nı her zaman yener —
`PageTitle` ile aynı çözümleme.
`sitemap.xml` ve `robots.txt` aynı servisten üretilir (`SeoController`, anonim). Sitemap'in
kaynakları : `Pub` menüleri, aktif custom component rotaları , yayı nlanmı ş blog yazı ları ve
yolu tanı mlayan kayı tları n `Seo*` alanları ; `/admin` yolları , parametreli rotalar (`/blog/:id`) ve
2026-09-29 06:14:07 +00:00
`SeoNoIndex` işaretli ya da `SeoIncludeInSitemap = false` olan yollar elenir.
`App.SiteManagement.Seo.SitemapExcludePaths` (satı r başı na bir yol, sonu `*` ise önek) hem sitemap'ten
düşer hem `robots.txt` 'e `Disallow` olarak yazı lı r; `robots.txt` ayrı ca `/admin/` , `/auth/` ,
`/checkout` , `/payment` , `/success` yolları nı her zaman kapatı r. `SitemapEnabled` kapalı yken
`sitemap.xml` 404 döner ve robots'a `Sitemap:` satı rı yazı lmaz. Arama motorları bu iki dosyayı **sitenin** kök dizininde aradı ğı için UI sunucusu her iki
2026-09-22 20:59:36 +00:00
yolu da API'ye geçirir (`vite.config.ts` > `seoProxy` , hem `server` hem `preview` ); ayrı bir ters
vekil kuralı gerekmez. `VITE_API_URL` tanı mlı değilse proxy kurulmaz ve `ui/public/robots.txt`
içindeki statik varsayı lan geçerli kalı r.
Yönetim ve oturum yüzeyi `noindex` gelir (`Layouts.tsx`), satı n alma akı şı (`/checkout`,
`/payment` , `/success` ) kendi sayfası nda `noIndex` bildirir.
**Ziyaretçiye açı k yeni bir yol üreten her iş SEO alanları nı da doldurur**; iki ekranı n da
`SeedSync*` bayrakları açı k olduğu için ekrandan girilen değer `data/App.Menus.Routes.json` ya da
`data/App.DeveloperKit.CustomComponents/{Id}.json` dosyası na düşer.
Ayrı ntı : `.github/instructions/lowcode.instructions.md` §0.9.
2026-09-09 06:06:25 +00:00
Eski statik içerik sayfaları ve sayfa içi tasarı m modu (`?design=1`) kaldı rı lmı ştı r:
`views/public/Home|About|Contact|Services` , `views/public/designer/` , bunlara özel istemci
servisleri; sunucuda `Home` /`About`/`Contact`/`Service` entity'leri, `PublicAppService` sayfa
Get/Save uçları ve DTO'ları , `TenantData.json` + `TenantDataSeeder` ,
`App.{Home,About,Services,Contact}` yetkileri ve `.Design` alt yetkileri, `/admin/public/*/designer`
rota ve menüleri.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 11. Kimlik, Oturum ve Güvenlik
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 11.1. Kimlik doğrulama
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- **OpenIddict** password + refresh token akı şı . Token uç noktası : `POST /connect/token`
(`grant_type=password`, `client_id=Platform_PublicApi` , `scope=offline_access Platform` ).
- Token ömürleri `OpenIddict:TokenLifetimes` ile yapı landı rı lı r (varsayı lan 60 dk access, 90 dk refresh).
- Swagger için ayrı istemci: `AuthServer:SwaggerClientId` .
- İki aşamalı doğrulama (2FA) ve hesap doğrulama (e-posta/telefon) desteklenir.
- Kayı t ve iletişim formları nda Cloudflare Turnstile tabanlı captcha (`CaptchaMiddleware`).
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 11.2. Oturum yönetimi
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- `PlatformSessionValidationMiddleware` her istekte oturumun hâlâ geçerli olduğunu doğrular.
- `PlatformSessionRevocationHandler` token iptalinde oturumu sonlandı rı r.
- `PlatformSessionCleanupWorker` süresi dolmuş oturumları temizler.
- Eş zamanlı kullanı cı limiti aşı ldı ğı nda giriş reddedilir.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 11.3. Giriş engelleri
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
`UserCannotSignInErrors` altı nda tanı mlı , kullanı cı ya lokalize mesajla dönen durumlar:
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Kod | Anlamı |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| `LoginNotAllowed_NotVerified` | Hesap doğrulanmamı ş. |
| `LoginNotAllowed_NotAllowedIp` | IP kı sı tlaması (`IpRestriction`). |
| `LoginNotAllowed_WorkHour` | Çalı şma saati kı sı tlaması (`WorkHour`). |
| `LoginNotAllowed_LoginEndDateDue` | Kullanı cı nı n giriş yetki süresi dolmuş. |
| `ShouldChangePasswordOnNextLogin` / `ShouldChangePasswordPeriodic` | Zorunlu şifre değişimi. |
| `LoginNotAllowed_TenantIsPassive` / `TenantNotFound` | Tenant pasif veya bulunamadı . |
| `LoginNotAllowed_BranchLimit` | Şube lisans limiti aşı ldı . |
| `LoginNotAllowed_ConcurrentUserLimit` | Eş zamanlı kullanı cı limiti aşı ldı . |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 11.4. Güvenlik kuralları
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- Tüm katmanlarda RBAC ve yetki tabanlı görünürlük zorunludur.
- Dinamik SQL'de **yalnı zca parametreli** desenler kullanı lı r; kullanı cı girdisi string birleştirme ile sorguya eklenmez.
- Her sorgu ve eylemde tenant izolasyonu korunur (`IsTenant`, `IsBranch` , `IsOrganizationUnit` bayrakları ve ABP tenant filtreleri).
- Gerçek kimlik bilgileri, token ve anahtarlar örneklerde/dokümanda yer almaz; yer tutucu kullanı lı r.
- Denetim: kritik işlemler ABP Audit Log'a yazı lı r; yüksek frekanslı `list-form-customization` çağrı ları denetim dı şı bı rakı lmı ştı r.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 12. Çok Kiracı lı lı k (Multi-Tenancy)
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- `PlatformConsts.IsMultiTenant = true` .
- Tenant çözümleme host adı (subdomain) ve ABP tenant resolver'ları ile yapı lı r (`utils/subdomain.ts`).
- **Tenant başı na ayrı veritabanı :** `TenantConnectionString` kayı tları ile her tenant kendi
veritabanı na yönlendirilebilir; migration'lar `DatabaseMigrationEventHandlerBase` üzerinden
tenant oluşturulduğunda otomatik uygulanı r.
- **Şube (Branch):** Tenant altı ndaki fiziksel/örgütsel kı rı lı m; kullanı cı – şube eşlemesi
`BranchUsers` ile tutulur, lisans limiti girişte kontrol edilir.
- **Organizasyon birimi:** ABP `OrganizationUnit` ağacı ; ListForm'lar OU bazlı filtrelenebilir.
- Tenant bazlı lokalizasyon: `TenantLocalizationInitializer` + `TenantLocalizationMiddleware` .
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 13. Bildirim ve Entegrasyonlar
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 13.1. Kanallar
2026-06-09 12:54:05 +00:00
2026-09-24 07:24:48 +00:00
`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.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 13.2. Yönlendirme modeli
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Bildirim **tip + kanal** eşleşmesiyle yönlendirilir. Alı cı hedefleme seçenekleri:
`All` , `User` , `Role` , `OrganizationUnit` , `Custom` . Kullanı cı lar kendi bildirim tercihlerini
`/admin/profile/notification-settings` üzerinden kanal bazı nda yönetir.
2026-06-09 12:54:05 +00:00
2026-09-20 20:23:39 +00:00
### 13.3. Kayı t durumu: gönderildi → okundu
Bir bildirim kaydı iki bayrak taşı r ve sı ra değişmez: **önce `IsSent`, sonra `IsRead`** .
Gönderilmemiş bir kayı t okunmuş olamaz.
| Kanal | `IsSent` ne zaman |
| --- | --- |
| `UiActivity` | Kayı t oluşurken (`NotificationManager`); ayrı bir gönderim adı mı yoktur, kayı t doğrudan kullanı cı nı n akı şı na yazı lı r |
| `UiToast` · `Desktop` | Tarayı cı da gösterildiğinde, UI `updateSentMany` ile işaretler |
| `Mail` · `Sms` · `Rocket` · `WhatsApp` · `Telegram` | `NotificationWorker` sağlayı cı ya teslim ettiğinde |
`IsRead` ve `ReadTime` birlikte yazı lı r (`NotificationAppService.UpdateRead*`): okundu işaretinde
`ReadTime = Clock.Now` , okunmadı ya çevirmede `null` . `IsSent = false` olan kayı t okundu
işaretlenmez — tekil ve toplu okuma yolları bu kaydı sessizce atlar, gönderim gerçekleştiğinde
okunabilir olur. Bu yüzden UI işaretlemeden sonra listeyi sunucudan tazeler; iyimser güncelleme
rozette yanlı ş sayı bı rakı rdı .
Tarayı cı kanalları tek kümededir (`NotificationChannels.BrowserChannels`); `sent-many` ucu
yalnı zca bu kanalları işaretler, böylece istemci Mail/Sms gibi bir kanalı "gönderildi" yapamaz.
Masaüstü bildirimi izin verilmemişse hiç işaretlenmez — işaretlenseydi izin sonradan verildiğinde
de gösterilmezdi.
### 13.4. Gerçek zamanlı iletim
Bildirim üretildiği anda açı k istemcilere **SignalR** ile duyurulur: hub `/notificationhub` ,
bağlantı kullanı cı başı na gruplanı r (`NotificationHub.UserGroupName`, kiracı + kullanı cı ).
`NotificationManager` kayı tları yazdı ktan **sonra** duyurur (`INotificationRealtimeNotifier`);
duyuru yükü yalnı zca hangi kanallarda kayı t oluştuğunu söyler, istemci listesini yine sunucudan
okur — okundu/gönderildi bayrakları tek kaynaktan gelir.
Katman sı nı rı : sözleşme bildirim modülünün Domain katmanı ndadı r (`INotificationRealtimeNotifier`),
SignalR gerçeklemesi ise barı ndı ran uygulamadadı r (`Sozsoft.Platform.Application/Notifications/`,
`MessengerHub` ile aynı yer) — modül katmanları ASP.NET Core'a bağlanmaz. Gerçekleme
`[Dependency(ReplaceServices = true)]` ile devreye girer; SignalR olmayan barı ndı rmalarda
(DbMigrator, testler) `NullNotificationRealtimeNotifier` kalı r.
Duyuru **en iyi çaba**dı r: bağlantı yoksa ya da mesaj kaybolursa bildirim kaybolmaz —
istemcideki yedek yoklama (5 dakika, sekme öne geldiğinde ayrı ca) aynı kaydı getirir. Ters
vekilde `/notificationhub` kendi bloğunda WebSocket yükseltmesiyle karşı lanı r
(`configs/deployment/configs/nginx.conf`); token sorgu dizesinden geldiği için host bu yolu da
`Authorization` başlı ğı na çevirir.
Masaüstü bildirimine tı klamak uygulamaya döner: service worker açı k sekmeyi öne alı p bildirimin
`data.url` adresine götürür, sekme yoksa yenisini açar (varsayı lan hedef Activity Log).
### 13.5. Kullanı cı tercihleri
Kurallar alı cı kümesini belirler; kullanı cı nı n profilinden yazdı ğı tercih (`IsCustomized`,
`RecipientType = User` ) **kural değildir** , yalnı zca sahibinin o tür/kanal aboneliğini kapatı r
(`NotificationManager`). Tercihi kural gibi işletmek, bir kullanı cı nı n kendi tercihini yazması yla
aynı tür ve kanaldaki herkesin bildirimini kesmesi anlamı na gelirdi. `IsFixed` kural zorunludur,
tercih dikkate alı nmaz. Aynı kullanı cı yı birden çok kural hedeflerse (All + Role) kanal başı na tek
kayı t üretilir.
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
2026-09-24 07:24:48 +00:00
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.
2026-09-20 20:23:39 +00:00
2026-09-22 09:48:14 +00:00
### 13.5.1. Bildirim ekranı ve elle gönderim (Administration › Bildirimler)
Bildirimin tamamı Administration menüsünde `App.Administration.Notifications` grubundadı r:
**Bildirim Türleri**, **Bildirim Kuralları ** , **Bildirimler** , **Bildirim Şablonları ** . Grup
Agenda'nı n üstündedir; Saas altı nda bildirim ekranı **yoktur** .
2026-09-29 06:14:07 +00:00
Tablolar kiracı kapsamı ndadı r (`Adm_T_NotificationTemplate`, `Adm_T_NotificationType` ,
`Adm_T_NotificationRule` , `Adm_T_Notification` ; dördü de `IMultiTenant` ). Her kiracı kendi türünü, kuralı nı ve kuyruğunu
2026-09-22 09:48:14 +00:00
görür; host kaydı (`TenantId = null`) yalnı zca host oturumunda görünür. Yeni bir kiracı
oluşturulduğunda varsayı lan tür ve kural kümesi o kiracı ya kopyalanı r
(`NotificationTenantDefaultsSeedContributor`): kaynak host kapsamı ndaki
`data/App.Notifications.Notification{Types,Rules}.json` dosyaları dı r, satı rlar **yeni
2026-09-29 06:14:07 +00:00
kimliklerle** yazı lı r ve eşleşme ad üzerinden yapı ldı ğı için ikinci çalı ştı rma bir şey eklemez;
şablonlar kopyalanmaz.
2026-09-22 09:48:14 +00:00
**Bildirimler** ekranı (`App.Notifications.Notification`) hem kuyruk günlüğü hem gönderim
ekranı dı r: liste kural motorunun ürettiklerini de gösterir, ekleme formu ise elle gönderimdir.
Ayrı bir manuel gönderim kaydı yoktur — gönderimin kaydı bildirimin kendisidir. Ekleme anı nda
yazma işi `list-form-dynamic-api/notification-insert` ucuna gider (`InsertServiceAddress`); uç
seçilen alı cı × kanal açı lı mı nı `INotificationManager.SendManualNotificationAsync` ile kuyruğa
2026-09-29 06:14:07 +00:00
yazar. Bildirim Kuralları ekranı ndaki `CreateNotification` diyaloğu ise aynı yöneticinin
`SendNotificationAsync` yolunu kullanı r: türün kuralları nı işletir ve kullanı cı tercihini dikkate
alı r; bu uç alı cı yı ekrandan alı r ve tercihi okumaz. Güncelleme kapalı dı r, silme kaydı kaldı rı r.
2026-09-22 09:48:14 +00:00
Formdaki `NotificationChannel` ve `UserId` alanları listede tek değerlidir (her satı r bir
alı cı × kanal), formda `dxTagBox` ile çoklu seçilir; tipli DTO yolunda çoklu değeri
`MultiValueStringJsonConverter` taşı r (`CreateNotificationInput`).
2026-09-21 06:57:02 +00:00
| Kural | Nerede |
| --- | --- |
| Bildirim tipi her zaman `Manuel` | `NotificationConsts.ManualTypeName` ; tip kaydı `App.Notifications.NotificationTypes.json` |
| `Notification.NotificationRuleId` NOT NULL olduğu için tipin **çapa kuralı na** bağlanı r (`RecipientType = Custom`, `IsActive = false` ) | `App.Notifications.NotificationRules.json` ; kural pasif olduğu için kural motoru ve profil tercih ekranı nda görünmez |
| Kullanı cı tercihi okunmaz (zorunlu bildirim gibi davranı r) | `NotificationManager.SendManualNotificationAsync` |
| Alı cı listesi kiracı filtresinden geçer | Kullanı cı sorgusu ABP kiracı filtresiyle çalı şı r; istekteki kimlikler değiştirilse bile başka kiracı ya gönderilemez |
2026-09-22 09:48:14 +00:00
| İlgili kanalda adresi olmayan alı cı atlanı r | Hiç satı r üretilemezse uç `App.Notifications.SkippedChannel` gerekçesiyle hata döndürür; kı smi atlamada gönderim sürer |
| Metnin geldiği şablon kayda yazı lı r | `Notification.NotificationTemplateId` (provenans; tür değil, metin kaynağı ) |
2026-09-21 06:57:02 +00:00
| Kanaldan çı kı ş yine `NotificationWorker` | `UiActivity` oluşurken iletilmiş sayı lı r, tarayı cı kanalları nı istemci işaretler (§13.3) |
**Şablonlar** (`Administration › Bildirimler › Bildirim Şablonları `,
`App.Notifications.NotificationTemplates` ,
`Adm_T_NotificationTemplate` ) mesaj metnini taşı r: `Code` , `Name` , `Channel` (boş = tüm kanallar),
`Subject` , `Body` , `IsActive` . Örnek şablonlar seed ile gelir
(`data/App.Notifications.NotificationTemplates.json`; ekran `SeedFilePath` ile bu dosyaya
aynalanı r). Gönderimde şablon seçilirse ekranda **boş bı rakı lan** konu ve gövde şablondan
tamamlanı r; ekranda yazı lan metin şablonu ezer.
Gövdedeki yer tutucular alı cı bazı nda çözülür (`NotificationMessageTokens`): `{AdSoyad}` ,
`{KullaniciAdi}` , `{Eposta}` , `{Tarih}` , `{Saat}` , `{Kiraci}` . Bildirim kaydı nı n `Message` kolonu
2048 karakterdir; yer tutucular çözülünce metin bu sı nı rda kı rpı lı r.
2026-09-22 09:48:14 +00:00
**Mail konu satı rı :** bildirim kaydı `Subject` kolonu taşı r (`Adm_T_Notification`, 256).
2026-09-21 06:57:02 +00:00
`NotificationWorker` konuyu bu kolondan alı r; kolon boşsa bildirim tipinin adı na düşer
2026-09-22 09:48:14 +00:00
(`Platform Bildirim: {tip}`). Kural motorundan gelen bildirimlerde kolon boş kalı r, elle
2026-09-21 06:57:02 +00:00
gönderimde ekrandan ya da şablondan gelir — yani konu artı k gövdeye gömülmez.
2026-09-20 20:23:39 +00:00
### 13.6. Göndericiler (`Sozsoft.Sender`)
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Kanal | Sağlayı cı |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| E-posta | ABP Emailing + Amazon SES (`AmazonSesEmailSender`), arka plan iş kuyruğu ile |
| SMS | Posta Güvercini HTTP API |
| WhatsApp | WhatsApp Cloud API (şablon tabanlı ) |
| Rocket.Chat | Rocket.Chat HTTP API |
2026-09-24 07:24:48 +00:00
| Telegram | Telegram Bot API (`SozsoftTelegramSender`; alı cı kullanı cı nı n `TelegramChatId` özelliği) |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Tüm sağlayı cı kimlik bilgileri ayar ekranı ndan yönetilir (`App.Settings.*` anahtarları );
koda gömülmez.
2026-06-09 12:54:05 +00:00
2026-09-20 20:23:39 +00:00
### 13.7. Mail kuyruğu
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
`Sozsoft.MailQueue` ; şablondan gövde üretir, PDF/XLS/TXT çı ktı ları ve ek dosyaları yönetir,
kuyruğu arka plan işçisiyle çalı ştı rı r ve sonuçları günlükler.
2026-06-09 12:54:05 +00:00
2026-09-20 20:23:39 +00:00
### 13.8. AI entegrasyonu
2026-06-09 12:54:05 +00:00
2026-09-17 12:24:51 +00:00
`AiBot` kayı tları tenant bazlı dı r; n8n webhook üzerinden bir niyet sı nı flandı rma adı mı ve
ardı ndan sohbet ya da SQL dalı çalı şı r (`configs/ai/Chat.json`). Model, DevOps makinesindeki
Ollama'da yerel olarak koşar (`http://ollama:11434/api/chat`, varsayı lan `qwen2.5:3b` ) — dı şarı ya
model çağrı sı yapı lmaz. UI tarafı nda `/admin/ai` ve header'daki asistan bileşeni bu uç noktayı
kullanı r.
Ollama'ya yüklü modelleri yönetmek için `configs/ai/Kurulum.txt` , sohbet arayüzü (Open WebUI) ve
alan adı yönlendirmesi için §20 kullanı lı r. Akı ştaki model adı değiştirilirse `configs/ai/Chat.json`
içindeki üç varsayı lanı n (`intentModel`, `chatModel` , `sqlModel` ) birlikte güncellenmesi gerekir;
biri kalı rsa o dal "model not found" ile düşer.
2026-06-09 12:54:05 +00:00
2026-09-20 20:23:39 +00:00
### 13.9. MCP sunucusu
2026-09-17 09:01:14 +00:00
Yapay zekâ istemcileri (Claude Code, Claude Desktop, ChatGPT) platforma ** `/mcp` ** ucundan
bağlanı r. Uç, API imajı nı n içinde aynı portta (`8080`) yayı nlanı r; ayrı bir container yoktur.
Modül `api/modules/Sozsoft.Mcp` altı nda standart ABP katmanları yla durur.
**Kimlik ve kiracı .** Kimlik doğrulama mevcut OpenIddict bearer token'ı dı r. Uç,
`UseAuthentication` → `UseAbpOpenIddictValidation` → `UseMultiTenancy` → `UseUnitOfWork`
ardı şı k düzeninden sonra bağlanı r ve açı kça bearer şeması na bağlı dı r (token'sı z istek giriş
sayfası na 302 ile değil, 401 ile döner); kiracı token talebinden ya da `__tenant` başlı ğı ndan
çözülür. Taşı yı cı **durumsuz** kiptedir
(`HttpServerSessionMode.Stateless`): her istek kendi ABP kapsamı nda koşar, ters vekil
2026-09-24 13:29:53 +00:00
arkası nda oturum yapı şkanlı ğı gerekmez. `/mcp` istek düzeyindeki unit of work'ün **dı şı ndadı r**
(`AbpAspNetCoreUnitOfWorkOptions.IgnoredUrls`): cevap SSE ile aktı ğı için istek UoW'si sonuç
istemciye gittikten sonra commit edilir ve bağlantı kapanı nca geri alı nı rdı — araç başarı lı
görünür, EF kayı tları (ListForm, menü, yetki) kaybolur, DDL ve seed dosyası kalı rdı . Her MCP
servis çağrı sı kendi UoW'sini sonuç dönmeden tamamlar.
2026-09-17 09:01:14 +00:00
**Kiracı bazlı sözleşme.** `Sas_H_McpServer` tablosundaki kayı t (ekran:
2026-09-18 13:47:23 +00:00
`App.DeveloperKit.McpServers` ) hangi araçları n yayı nlandı ğı nı ve sorguları n hangi satı r tavanı yla koşacağı nı
belirler; sorgular her zaman isteğin kiracı sı nı n veritabanı nda koşar. `Tenants` boşsa kayı t tüm
2026-09-17 09:01:14 +00:00
kiracı lara açı ktı r (AiBot ile aynı sözleşme). Araç listesi bu kayda göre süzülür
(`AddListToolsFilter`) **ve** çağrı anı nda aynı kural yeniden uygulanı r — süzme tek başı na
bir yetki sı nı rı değildir.
2026-09-24 11:58:23 +00:00
**Kiracı veri okur ve yazar, geliştirme yapamaz.** Kiracı bağlamı ndaki istekte açı k araçlar
2026-09-18 13:47:23 +00:00
`McpToolNames.TenantTools` kümesiyle sı nı rlı dı r: `server_info` , `list_lists` , `describe_list` ,
2026-09-24 11:58:23 +00:00
`search_schema` , `query_list` , `run_select` , `insert_row` , `update_row` , `delete_row` .
`AllowedTools` bu kümeyi yalnı zca daraltabilir. Satı r araçları ekranı n C/U/D sözleşmesinden ve
kiracı nı n kendi veritabanı ndan geçer. `create_table` , wizard, component ve geliştirme talebi
araçları kiracı nı n yetkisi ne olursa olsun listelenmez, çağrı lı rsa `App.Mcp.Error.TenantToolDisabled`
ile reddedilir. `list_queries` /`run_query` da dı şarı dadı r: procedure ve Custom Endpoint çağrı sı
ekran yetkisinden geçmeden veri yazabilir. Host kullanı cı sı için tek sunucu anahtarı
2026-09-18 13:47:23 +00:00
`AllowedTools` 'tur (boşsa tümü); sı nı rı yetkiler çizer. Karar `McpToolPolicy.IsAllowed` 'dadı r,
liste süzgeci ve çağrı kapı sı aynı kuralı kullanı r.
2026-09-17 09:01:14 +00:00
**Araçlar.**
| Araç | İş |
| --- | --- |
2026-09-24 13:29:53 +00:00
| `server_info` | Bağlantı nı n bağlamı (`scope`: `host` / `tenant` ; kiracı adı `server.tenantName` ), açı k araçlar, veri sözlüğünün tazelik bilgisi. Sözlüğün `dictionaryKey` alanı (host'ta `Sozsoft` ) sözlüğün yazı ldı ğı anahtardı r, kiracı bağlamı nı göstermez. Her zaman açı ktı r. |
2026-09-17 09:01:14 +00:00
| `list_lists` | Listeler: kod, başlı k, açı klama, arkası ndaki tablo. |
| `describe_list` | Bir listenin sütunları : alan adı , görünen başlı k, SQL tipi, lookup ilişkisi, `isSensitive` . |
| `search_schema` | Liste ve sütun adları /başlı kları üzerinde aksan ve büyük/küçük harf duyarsı z arama. |
2026-09-24 11:58:23 +00:00
| `query_list` | Listenin verisini ekranı n kendi sorgusuyla (`GetSelectAsync`) okur: filtre, sı ralama, gruplama, özet (DevExtreme biçimi). Sı ralama/gruplama/özet JSON'u, arayüzün `Utils.ts` 'te yaptı ğı gibi select ucunun metin biçimine (`Alan desc|Alan2 asc`) `McpLoadOptions` ile çevrilir; select ucu JSON'u tanı maz. Normal kullanı cı nı n veri okuma yolu. |
2026-09-17 09:01:14 +00:00
| `run_select` | Parametreli tek SELECT; çoklu ifade, DDL ve DML reddedilir, satı r tavanı sorguya yazı lı r. Yalnı zca SQL Query Manager yetkisiyle. |
| `list_queries` | View/procedure/function nesneleri (SQL Query Manager yetkisiyle) + çağrı labilir Custom Endpoint'ler (`App.DeveloperKit.CustomEndpoints.Get` ile). |
| `run_query` | Kayı tlı bir nesneyi ya da Custom Endpoint'i parametreleriyle çağı rı r; yetkiler `list_queries` ile aynı . |
2026-09-18 13:47:23 +00:00
| `insert_row` / `update_row` / `delete_row` | ListForm ekranı nı n insert/update/delete sözleşmesinden geçer. |
| `get_dev_guide` | Üretim sözleşmesi: `lowcode` / `reference` belgelerinin başlı k listesi ya da istenen bölümü (numarayla, örn. `4.2` ). Çok büyük bir üst bölüm yalnı zca giriş metni + alt başlı kları yla döner. |
2026-09-24 11:58:23 +00:00
| `create_table` | Yeni tabloyu SQL Query Manager tablo tasarı mcı sı yla aynı script biçimiyle kurar (`McpTableCreator`): `Id` + `TenantId` + tam audit kolonları şablondan gelir, istemci yalnı zca iş kolonları nı verir; tip ve varsayı lan değer beyaz listeden geçer, istemci SQL yazamaz. Script `{kapsam}/sql/object/{Tablo}.sql` dosyası na yazı lı r. Yalnı zca oluşturur — tablo varsa reddeder; yalnı zca SQL Server. `.Write` + `App.SqlQueryManager` ister. |
2026-09-18 13:47:23 +00:00
| `list_wizards` / `get_wizard` | Wizard File Manager dosyaları ; `get_wizard` seed dosyası nı diskteki biçimiyle döndürür. |
2026-09-30 07:28:12 +00:00
| `deploy_wizard` | Wizard'ı Wizard ekranı yla aynı yoldan (`IListFormWizardAppService.Create`) deploy eder. Girdi seed dosyası biçimi (`{"Wizard": …}`) ya da düz cevaplardı r; ikisi de `WizardSeedFileDto.FromSeedJson` 'dan geçer. Dosyaya kullanı cı nı n etkin talebi `DevRequest` olarak yazı lı r (sunucu doldurur). Wizard ekranı gibi yalnı zca seed dosyaları nı yazar; ekran DB Migrate ile kurulur ve çı kı ştaki `isPending` o zamana kadar `true` kalı r (model migrate'i beklemez; `verify_wizard` bekleyen dosyada `install` kontrolünde durur). `replaceFileName` doluysa güncellemedir (dosyalar yeniden yazı lı r, önceki kayı tları migrate kaldı rı r). İstek demo veri taşı yorsa (prompt'taki satı rlar, ekran görüntüsü) wizard `SeedData: true` ile deploy edilir — ekranı n `SeedFilePath` 'i `data/{ListFormCode}.json` olur ve `SeedSync*` bayrakları açı lı r — satı rlar aynı çağrı da `seedRows` ile bu dosyaya yazı lı r (alan adları doğrulanı r, `Guid` anahtarı sunucu üretir); migrate ekranı kurduktan sonra satı rları ekler (`lowcode.instructions.md` §0.10.1). Widget sorguları ndaki her dil anahtarı tanı mlı olmalı ya da wizard'ı n `Language.Texts` alanı nda EN + TR verilmeli, yoksa deploy adları yla reddeder (`ValidateWidgetLanguageKeysAsync`). `uploadUrl` 'süz `dxImageUpload` alanı base64 sakladı ğı için kolonu sı nı rlı boyluysa (katalogdaki karakter sı nı rı ) deploy reddedilir; tablo kolonuna bağlı `dxImageViewer` alanı da reddedilir — görsel kolonunun editörü her zaman `dxImageUpload` 'dı r (`ValidateImageColumnLengths`). `MenuOrder` yok sayı lı r: yeni ekran kardeşlerinin sonuna, güncelleme mevcut yerine yazı lı r — lookup kaynağı ekran önce deploy edildiği için onu kullanan ekranı n üstünde kalı r. |
2026-09-24 13:29:53 +00:00
| `delete_wizard` | Wizard Manager'daki silmeyle aynı : `InsertedRecords` + ekranı n veri aynası , bağı mlı wizard varsa reddedilir. `dropTables: true` ekranı n tablosunu (yalnı zca tasarı mcı /`create_table` ile kurulmuş ve başka yerde kullanı lmayan) CRUD endpoint'leri, `sql/object` ve `crud` dosyaları yla düşürür; model bunu kullanı cı onayı olmadan göndermez (`WizardTableCleaner`, `lowcode.instructions.md` §4.5). |
2026-09-25 07:52:06 +00:00
| `verify_wizard` | Deploy edilmiş ekranı veri yazmadan doğrular: menü kaydı ve URL'si, menünün istediği yetki tanı mı (`AbpPermissions`), List yolunda ekran sorgusu (`GetSelectAsync`, tek satı r, çağı ranı n yetkisiyle), Custom yolunda bileşen (etkin, rota = menü URL'si) ve seed kapanı şı (`ExportAnalysis` uyarı ları ; engellemez). İsteğe bağlı dı r, migrate sonrası nda kullanı lı r; `App.DevRequests` döngüsünün adı mı değildir — döngü `Testing` 'de biter, kullanı cı elle test edip `Staging` 'e alı r (`lowcode.instructions.md` §0.11). |
2026-09-24 11:58:23 +00:00
| `start_dev_request` | Geliştirme talebini Id ya da tam başlı kla üstlenir: yalnı zca `Ready to Start` durumundakini `In Progress` durumuna alı r, diğerlerini reddeder; talebin metnini döndürür. Açı klamaya yapı ştı rı lmı ş base64 görseller (`data:image/png|jpeg|gif|webp`) metinden ayı klanı r (`McpDevRequestImages`), yerlerinde `[image-N]` kalı r ve her biri ayrı MCP resim içeriği (`ImageContentBlock`) olarak döner — model görseli resim olarak görür, görsel hiçbir yere yüklenmez. `.Write` + `App.DevRequests.Update` ister. |
2026-09-28 09:28:56 +00:00
| `get_dev_request` | Talebi durumuna dokunmadan, `start_dev_request` ile aynı biçimde (metin + analiz + resim içerikleri) okur; analizden önce ya da yarı m kalan talebe dönmek için. `App.DevRequests` ister. |
| `save_dev_request_analysis` | `Backlog` ya da `Analysis` durumundaki talebin analizini (HTML) `Analysis` kolonuna yazar — var olanı değiştirir — ve talebi `Analysis` durumuna alı r; diğer durumları reddeder. `Description` 'a dokunmaz. Analizin standardı `lowcode.instructions.md` §0.12. `.Write` + `App.DevRequests.Update` ister. |
2026-09-24 13:29:53 +00:00
| `add_dev_request_subtasks` | Talebin `SubTasks` listesine tamamlanmı ş satı rlar ekler: model yalnı zca başlı ğı verir, atanan kişi bağlanan kullanı cı nı n adı (`userName`), bitiş tarihi bugün (`yyyy-MM-dd`) olarak sunucuda yazı lı r; var olan satı rlar korunur. `.Write` + `App.DevRequests.Update` ister. |
2026-09-28 09:28:56 +00:00
| `append_dev_request_note` | Talebin `Analysis` kolonunun sonuna HTML ekler (üretim sonuç notu); `Description` talebin yazı ldı ğı hâliyle kalı r. İkisi de `update_row` ile yazı lmaz — açı klama base64 görsel taşı r. `.Write` + `App.DevRequests.Update` ister. |
2026-09-29 06:14:07 +00:00
| `list_components` / `get_component` / `save_component` / `delete_component` | Custom component'ler `ICustomComponentAppService` üzerinden; seed senkronu ve `DataSources` çözümü aynen çalı şı r. `save_component` ada göre ekler/günceller, tasarı mcı belgesi (`Props.visualDesigner`, `sourceMode ≠ code` ) taşı yan bileşene kod yazmayı reddeder — kod belgeden üretildiği için tasarı mcı daki ilk kayı tta ezilirdi. |
2026-10-01 12:01:57 +00:00
| `list_report_templates` / `get_report_template` / `save_report_category` / `save_report_template` / `delete_report_template` | Rapor kategorileri ve `DynamicReport` şablonları (`McpReportAppService`). Okuma depodan, ekranı n okuma yetkisiyle yapı lı r. Yazma `App.Reports.Categories` / `App.Reports.ReportTemplates` ekranları nı n C/U/D sözleşmesinden (`IListFormDataAppService`) geçer; seed senkronu aynen çalı şı r. Kayı t ada göre ekler/günceller. `listFormCode` verilirse HTML'deki `{{AlanAdi}}` yer tutucuları o ekranı n alanları na göre doğrulanı r ve cevapta satı r butonu (`rowButton`) döner (§15). |
2026-09-24 11:58:23 +00:00
2026-09-28 12:50:38 +00:00
**Timesheets.** Talebin `Timesheets` listesini sunucu doldurur (`IMcpDevRequestTimesheetRecorder`):
`get_dev_request` / `start_dev_request` talebi kullanı cı nı n etkin talebi yapar (dağı tı k önbellek,
`McpDevRequestActivityCacheItem` , 12 saat); sonraki her MCP yazma işlemi (`create_table`,
2026-10-01 12:01:57 +00:00
`deploy_wizard` , `delete_wizard` , `save_component` , `delete_component` , `save_report_category` ,
`save_report_template` , `delete_report_template` , satı r araçları ,
2026-09-29 06:14:07 +00:00
`save_dev_request_analysis` , `append_dev_request_note` , `add_dev_request_subtasks` ) o talebe bir satı r
ekler; talebi açan `start_dev_request` yazmaz. Açı klama `App.Mcp.Timesheet.*` anahtarı ndan
2026-09-28 12:50:38 +00:00
Türkçe üretilir, süre önceki satı rdan ya da talebin açı ldı ğı andan ölçülür (en az 1 dakika, saat
olarak), çalı şan bağlanan kullanı cı , tarih bugündür. Etkin talep yoksa satı r yazı lmaz; bozuk bir
2026-09-29 14:18:47 +00:00
`Timesheets` değeri işlemi geri almaz, yalnı zca satı r atlanı r ve log'a düşer. Satı r, aracı n unit of
work'ü commit edildikten sonra ayrı bir UoW'de yazı lı r (`OnCompleted`): satı r araçları talebi Dapper
bağlantı sı ndaki transaction ile günceller ve EF'in ayrı bağlantı dan aynı satı ra yazması o kilidi
bekleyip zaman aşı mı na düşerdi.
2026-09-28 12:50:38 +00:00
2026-09-24 11:58:23 +00:00
**Prompt'lar** (`McpPromptNames`, `McpDevelopPrompts` ). İstemcide komut olarak görünür; yalnı zca
2026-09-28 09:28:56 +00:00
metindir, yetki taşı maz. `analyze_dev_request` tek talebi, `analyze_backlog_requests` bütün
`Backlog` kuyruğunu analiz edip `Analysis` durumuna alı r (§0.12); `process_dev_request` tek talebi,
`process_ready_requests` bütün `Ready to Start` kuyruğunu işler (§0.11). Hiçbiri adı mları tekrar
etmez, `get_dev_guide` ile `lowcode.instructions.md` ilgili bölümüne yönlendirir.
2026-09-24 11:58:23 +00:00
**Geliştirme taleplerini çalı ştı rma.** Komutun adı istemcideki sunucu adı na göre değişir: aşağı daki
örnekler `claude mcp add sozsoft ...` ile eklenmiş sunucu içindir (`sozsoft-local` ile eklediysen
`mcp__sozsoft-local__...` yaz). Her durumda talep yalnı zca `Ready to Start` durumundaysa işlenir;
değilse sunucu reddeder ve hiçbir şey üretilmez.
| Ne istiyorsun | Claude Code | Claude.ai / Claude Desktop | Düz metin (her istemci) |
| --- | --- | --- | --- |
2026-09-28 09:28:56 +00:00
| Tek talebi analiz et | `/mcp__sozsoft__analyze_dev_request <Id>` | `+` menüsü → `sozsoft` → `analyze_dev_request` | `<Id ya da "başlı k"> talebini analiz et` |
| Backlog'u analiz et | `/mcp__sozsoft__analyze_backlog_requests` | `+` menüsü → `sozsoft` → `analyze_backlog_requests` | `Backlog'daki talepleri analiz et` |
2026-09-24 11:58:23 +00:00
| Tek talep | `/mcp__sozsoft__process_dev_request <Id>` | Mesaj kutusundaki `+` menüsü → `sozsoft` → `process_dev_request` , `request` alanı na Id ya da tam başlı k | `<Id ya da "başlı k"> talebini işle` |
| Bütün kuyruk | `/mcp__sozsoft__process_ready_requests` | `+` menüsü → `sozsoft` → `process_ready_requests` | `Ready to Start durumundaki talepleri sı rayla işle` |
| Önce kuyruğu görmek | — | — | `Ready to Start durumundaki talepleri Id'leriyle listele` |
```text
/mcp__sozsoft__process_dev_request 3f2a9c1e-5b7d-4e2a-9f10-6c8d2b4a1e77
/mcp__sozsoft__process_ready_requests
```
- **Id nereden gelir:** `App.DevRequests` ekranı nda `Id` kolonu gizlidir. Kolon seçiciden aç ya da
Claude'dan "Id'leriyle listele" ile iste.
- **Başlı kla çağı rmak:** Claude Code komut argümanları nı boşluktan böler, bu yüzden boşluklu
başlı kta komut yerine Id ya da düz metin kullan. Başlı k birden fazla talebe uyuyorsa sunucu Id ister.
- Düz metin de aynı yoldan geçer: sunucu talimatları modeli `start_dev_request` 'e yönlendirir,
durum şartı yine sunucuda uygulanı r.
2026-09-17 09:01:14 +00:00
2026-09-24 11:58:23 +00:00
**Yetki modeli: MCP yetki vermez.** Kullanı cı MCP'de uygulamadaki yetkisini taşı r; MCP'nin iki
yetkisi yalnı zca kapı dı r. Bir çağrı üç katmandan geçer ve her katman ayrı reddeder:
1. **Sunucu kaydı ** (`AllowedTools`, `Tenants` ) — o kiracı da hangi araçları n var olduğu. Kiracı daki
herkes için aynı dı r.
2. **MCP kapı sı ** (`.Invoke`, `.Write` ) — kullanı cı nı n MCP'yi okumak / değiştirmek için
kullanabilir olup olmadı ğı . Rol/kullanı cı bazı ndadı r.
3. **Uygulama yetkisi** — işlemin kendisi: ekranı n C/R/U/D yetkisi, Wizard, Custom Components,
SQL Query Manager. Kullanı cı uygulamada yapamadı ğı nı MCP'de de yapamaz.
**MCP yetkileri — ne açar, sı nı rı ne**
| Yetki | Kim alabilir | Ne açar | Açmadı ğı / sı nı rı |
| --- | --- | --- | --- |
| `App.DeveloperKit.McpServers` | Host, kiracı | MCP Servers ekranı nı görme (`.Create/.Update/.Delete/.Export/.Import` ekran işlemleri) | `/mcp` ucuna erişim vermez |
2026-09-29 06:14:07 +00:00
| `App.DeveloperKit.McpServers.Invoke` | Host, kiracı | `/mcp` bağlantı sı ve bütün okuma araçları : `server_info` , `list_lists` , `describe_list` , `search_schema` , `query_list` ; host'ta ayrı ca `get_dev_guide` , `list_wizards` , `get_wizard` , `verify_wizard` , `get_dev_request` , `list_components` , `get_component` | Hiçbir şey yazmaz. Okuma da ekran yetkisine bağlı dı r: `R` yetkisi olmayan liste görünmez, sorgulanamaz. Ham SQL (`run_select`, `list_queries` , `run_query` ) ayrı ca `App.SqlQueryManager` ister |
2026-10-01 12:01:57 +00:00
| `App.DeveloperKit.McpServers.Write` | Host, kiracı | MCP üzerinden her değişiklik. **Kiracı da:** `insert_row` , `update_row` , `delete_row` . **Host'ta:** bunlara ek olarak `create_table` , `deploy_wizard` , `delete_wizard` , `save_component` , `delete_component` , `save_report_category` , `save_report_template` , `delete_report_template` , `start_dev_request` , `save_dev_request_analysis` , `append_dev_request_note` , `add_dev_request_subtasks` | Kendi başı na bir şey yazdı rmaz: satı r araçları ekranı n `C` /`U`/`D` yetkisini, geliştirme araçları Wizard / Custom Components / SQL Query Manager / `App.DevRequests.Update` yetkisini ayrı ca ister. Kiracı da geliştirme araçları nı **açmaz** — kiracı bağlamı nda bu araçlar yetkiden bağı msı z kapalı dı r (`McpToolNames.TenantTools`). `Invoke` olmadan işe yaramaz |
2026-09-24 11:58:23 +00:00
**Araç → gereken yetkiler** (Invoke hepsinde aranı r, tabloda tekrar yazı lmadı )
| Araç | Kiracı | MCP kapı sı | Uygulama yetkisi |
| --- | --- | --- | --- |
| `server_info` , `list_lists` , `describe_list` , `search_schema` | ✓ | — | Listelenen her ekran için `PermissionJson.R` |
| `query_list` | ✓ | — | Ekranı n `R` yetkisi |
| `run_select` | ✓ | — | `App.SqlQueryManager` |
| `list_queries` , `run_query` | — | — | Nesne: `App.SqlQueryManager` ; Custom Endpoint: `App.DeveloperKit.CustomEndpoints.Get` + endpoint'in kullanı cı /rol listesi |
| `insert_row` / `update_row` / `delete_row` | ✓ | `.Write` | Ekranı n `C` / `U` / `D` yetkisi |
| `get_dev_guide` | — | — | — |
| `list_wizards` , `get_wizard` | — | — | `App.Listforms.Wizard` |
| `verify_wizard` | — | — | `App.Listforms.Wizard` ; seed kapanı şı için `.Export` (yoksa o kontrol atlanı r, doğrulama düşmez) |
| `deploy_wizard` | — | `.Write` | `App.Listforms.Wizard` + `.Create` (yeni) / `.Update` (`replaceFileName`) |
2026-09-24 13:29:53 +00:00
| `delete_wizard` | — | `.Write` | `App.Listforms.Wizard` + `.Delete` ; `dropTables` için ayrı ca `App.SqlQueryManager` |
2026-09-24 11:58:23 +00:00
| `create_table` | — | `.Write` | `App.SqlQueryManager` |
| `list_components` , `get_component` | — | — | `App.DeveloperKit.CustomComponents` |
| `save_component` | — | `.Write` | `App.DeveloperKit.CustomComponents.Create` (yeni) / `.Update` |
| `delete_component` | — | `.Write` | `App.DeveloperKit.CustomComponents.Delete` |
2026-10-01 12:01:57 +00:00
| `list_report_templates` , `get_report_template` | — | — | `App.Reports.ReportTemplates` |
| `save_report_category` | — | `.Write` | `App.Reports.Categories.Create` (yeni) / `.Update` |
| `save_report_template` | — | `.Write` | `App.Reports.ReportTemplates.Create` (yeni) / `.Update` |
| `delete_report_template` | — | `.Write` | `App.Reports.ReportTemplates.Delete` |
2026-09-24 11:58:23 +00:00
| `start_dev_request` | — | `.Write` | `App.DevRequests.Update` |
| `get_dev_request` | — | — | `App.DevRequests` |
2026-09-28 09:28:56 +00:00
| `save_dev_request_analysis` | — | `.Write` | `App.DevRequests.Update` |
2026-09-24 11:58:23 +00:00
| `append_dev_request_note` | — | `.Write` | `App.DevRequests.Update` |
2026-09-24 13:29:53 +00:00
| `add_dev_request_subtasks` | — | `.Write` | `App.DevRequests.Update` |
2026-09-24 11:58:23 +00:00
Kaynak: MCP kapı sı `McpToolNames.RequiredPermissions` , kiracı kümesi `McpToolNames.TenantTools` ,
arkadaki servisin attribute ile istediği yetkiler `McpToolNames.ServicePermissions` . `Invoke` her MCP
servisinin sı nı f düzeyindeki `[Authorize]` attribute'undadı r; `/mcp` ucu yalnı zca kimlik doğrulama
ister (ucun kendisinde aranı rsa kullanı cı nedeni yazmayan bir 403 alı r). Araç listesi aynı
kurallarla süzülür (`GetAvailableToolsAsync`), çağrı anı nda kontrol tekrarlanı r.
**Yetkisi olmayan çağrı ne görür.** SDK araç hatası nı n mesajı nı yalnı zca `McpException` ise
iletir; diğer her istisna "An error occurred invoking '…'" olarak gider. `McpToolErrorTranslator`
(çağrı ve araç listesi filtresi, `McpHttpApiModule` ) iki tür hatayı çevirir:
- **Yetki reddi** → `App.Mcp.Error.PermissionDenied` : "'deploy_wizard' için gereken yetkiniz yok:
Wizard (App.Listforms.Wizard). Yöneticinizden bu yetkiyi isteyin." Eksik yetkiler aracı n bilinen
yetkileri (`McpToolNames.KnownPermissionsOf`) ve reddin taşı dı ğı yetki adı kullanı cı nı n
yetkileriyle karşı laştı rı larak bulunur. Satı r ve `query_list` araçları ekranı n yetkisini adı yla
önceden ister (`IMcpListFormAccessFilter.GetPermissionNameAsync`), bu yüzden ekran yetkisi de
adı yla görünür. Eksik yetki belirlenemezse `PermissionDeniedUnspecified` döner.
- **İş kuralı hatası ** (`UserFriendlyException`: kiracı ya kapalı araç, `AllowedTools` dı şı araç,
`start_dev_request` durum reddi…) → yerelleştirilmiş mesajı olduğu gibi.
Başka istisnalar çevrilmez; SQL ve yı ğı n ayrı ntı sı istemciye sı zmaz.
2026-09-17 09:01:14 +00:00
2026-09-18 13:47:23 +00:00
**Geliştirme rehberi nereden okur.** `get_dev_guide` depodaki
`.github/instructions/lowcode*.instructions.md` dosyaları nı runtime'da okur; Claude Code ile MCP
istemcisi aynı sözleşmeyi görür. Klasör `App:DevGuidePath` ayarı ndan (konteynerde
`/etc/api/dev-guide` , compose'da `.github/instructions` salt okunur mount), boşsa çalı şma
dizininden yukarı `.github/instructions` aranarak bulunur. İmaja gömülmez: API build bağlamı
`api/` olduğu için `.github` imaja girmez, rehber değiştiğinde imaj derlenmez.
2026-09-17 09:01:14 +00:00
**Şema keşfi nereden okur.** Tablo ve sütun bilgisi canlı katalogdan değil,
`Sas_H_DbTableColumn` tablosundaki JSON veri sözlüğünden gelir — sözlük dil anahtarları ndan
çözülmüş başlı kları ve lookup ilişkilerini birlikte taşı dı ğı için modelin gördüğü adlar
kullanı cı nı n ekranda gördüğü adlarla aynı olur. Sözlük
`dbo.Sas_H_ListFormFieldsDictionaryJson_SaveDbTableColumns` prosedürüyle kiracı adı başı na
üretilir; sözlük yoksa araçlar tablo döndürmez ve `server_info` bunu bildirir.
**OAuth (Claude / ChatGPT connector'ları ).** Connector formuna yalnı zca ad ve URL girilir;
kimlik doğrulamayı istemci MCP OAuth akı şı yla kendisi yürütür:
1. `/mcp` token'sı z isteğe 401 + `WWW-Authenticate: Bearer resource_metadata="…"` döner
(`McpAuthenticationChallengeMiddleware`).
2. İstemci `/.well-known/oauth-protected-resource/mcp` (RFC 9728) belgesinden yetkilendirme
sunucusunu (`AuthServer:Authority`) öğrenir, `/.well-known/oauth-authorization-server`
(OpenIddict keşif belgesi, `registration_endpoint` eklenmiş) belgesini okur.
3. `/connect/register` (RFC 7591, `McpOAuthClientManager` ):
- İstenen geri dönüş adresleri **bilinen istemcide** (`Platform_Mcp`; Claude, ChatGPT —
`DbMigrator` ayarı `OpenIddict:Applications:Platform_Mcp:RedirectUris` ) kayı tlı ysa onun
kimliği döner; onay ekranı çı kmaz.
- Değilse (Cursor, VS Code, Claude Code, başka bir AI istemcisi) **dinamik istemci** üretilir:
`mcp_` önekli, PKCE zorunlu, **açı k onaylı ** OpenIddict uygulaması . Aynı adres kümesi aynı
uygulamaya bağlanı r; tavan `McpConsts.MaxDynamicClients` . Kabul edilen adresler: HTTPS,
localhost HTTP (RFC 8252), uygulama şemaları (`cursor://…`); `javascript:` vb. reddedilir.
Onay ekranı ndaki ad istemcinin beyanı + geri dönüş adresinin sahibidir (ad doğrulanamaz).
4. Kullanı cı platformun giriş ekranı na (`/Account/Login`, kiracı seçimi dahil) yönlenir;
authorization code + PKCE ile token alı nı r. Kiracı ve yetki giriş yapan kullanı cı dan gelir.
Üç ayrı ntı bilinçlidir:
- Yayı ncı (`issuer`) `AuthServer:Authority` 'den sabitlenir; ters vekil arkası nda istekten
2026-09-28 09:28:56 +00:00
türetilirse `http://` olur ve istemci keşif belgesini reddeder. Korumalı kaynak belgesindeki
`authorization_servers` değeri bu `issuer` ile birebir aynı dı r (sonda `/` dahil,
`McpOAuthOptions.AuthorizationServer` ); RFC 8414 §3.3'ü uygulayan istemci (`mcp-remote`)
farkta `IssuerMismatchError` ile durur.
2026-09-17 09:01:14 +00:00
- MCP istemcisinin gönderdiği RFC 8707 `resource` parametresi yok sayı lı r
(`McpOAuthServerConfiguration`): OpenIddict kayı tsı z kaynağı reddeder ya da token kitlesini
`/mcp` adresine daraltı r, API ise `Platform` kitlesini doğrular.
- MCP istemcilerinin (`McpConsts.IsMcpClient`) token'ları kullanı cı oturumuna bağlanmaz
(`PlatformTokenController`). Tek oturum kuralı her girişte diğer oturumları sildiği için,
bağlansaydı connector her token yenilemesinde kullanı cı nı n web oturumunu düşürürdü.
- MCP istemcilerinin yenileme token ömrü uygulama bazı nda 30 gündür
(`McpConsts.RefreshTokenLifetime`, OpenIddict uygulama ayarı ) ve her kullanı mda yenilenir;
web istemcisinin dakikalı k ömrü etkilenmez. Kullanı cı 30 gün hiç soru sormazsa bağlantı yı
yeniden kurar.
Bağlantı sunucu gerektirir: connector formu bağlantı yı istemci sağlayı cı nı n sunucuları ndan
kurar, `localhost` erişilemez. Forma `https://api.sozsoft.com/mcp` yazı lı r.
**Bağlanma (token ile, CLI).**
```bash
# sunucu
claude mcp add sozsoft --transport http https://api.sozsoft.com/mcp \n --header "Authorization: Bearer < access_token > "
# localhost (dotnet run / IIS Express)
claude mcp add sozsoft-local --transport http https://localhost:44344/mcp \n --header "Authorization: Bearer < access_token > "
```
Ters vekilde `/mcp` ayrı bir blokta karşı lanı r (`configs/deployment/configs/nginx.conf`):
Streamable HTTP yanı tları SSE akı şı dı r, `location /` altı ndaki tamponlama akı şı bekletir.
2026-09-17 12:24:51 +00:00
**Şema tuzağı .** İstek vekilden HTTP olarak gelir. `issuer` ve `registration_endpoint`
yapı landı rmadan sabitlenir (`AuthServer:Authority`), ama `authorization_endpoint` ve
`token_endpoint` adreslerini OpenIddict istekten türetir. Uygulama `X-Forwarded-Proto`
başlı ğı nı işlemezse bu iki adres keşif belgesine `http://` olarak yazı lı r ve **OAuth 2.1
istemcileri (MCP connector'ları ) TLS'siz uç kabul etmediği için bağlantı kurulamaz** —
istemci tarafı nda görülen hata genellikle "please register the OAuth client" olur.
Çözüm iki parçalı dı r ve ikisi birlikte olmak zorundadı r:
- API konteynerinde `ASPNETCORE_FORWARDEDHEADERS_ENABLED=true` (`docker-compose-app.yml`)
- nginx'te **her** `location` bloğunun `X-Forwarded-Proto $scheme` göndermesi. `location /`
2026-09-20 20:23:39 +00:00
bunu `proxy_params` üzerinden yapar; `/mcp` , `/videoroomhub` , `/messengerhub` ve
`/notificationhub` kendi
2026-09-17 12:24:51 +00:00
blokları olduğu için başlı ğı ayrı ca set eder. Bir blok atlanı rsa istemcinin gönderdiği
başlı k olduğu gibi geçer ve şema taklit edilebilir hale gelir.
Doğrulama:
```bash
curl -s https://api.sozsoft.com/.well-known/oauth-authorization-server \
| tr ',' '\n' | grep -E 'issuer|authorization_endpoint|token_endpoint|registration_endpoint'
```
Dördü de `https://` olmalı dı r.
2026-09-24 11:58:23 +00:00
**Yetkiler.** Ne açtı kları ve sı nı rları yukarı daki "Yetki modeli" tablosundadı r. İkisi de
`MultiTenancySide = Both` 'tur. Eskiden geliştirme için ayrı olan `.Develop` yetkisi `.Write` ile
birleştirildi; mevcut veritabanı nda atamalar migrate sı rası nda `.Write` 'a taşı nı r ve tanı m silinir
(`McpDevelopPermissionMergeDataSeedContributor`).
`AllowedTools` ile yetkiler farklı eksenlerdir: sunucu kaydı bir kiracı da **hangi araçları n var
olduğunu** belirler ve o kiracı nı n bütün kullanı cı ları için aynı dı r; yetkiler **kimin
kullanabileceğini** rol/kullanı cı bazı nda belirler. Örneğin `delete_row` açı k bir kayı tta yalnı zca
`.Write` verilmiş rol MCP ile silebilir, diğerleri aynı bağlantı yla yalnı zca okur.
2026-09-17 09:01:14 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 14. Arka Plan İşleri
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
İki motor birlikte kullanı lı r: **Hangfire** (kalı cı iş deposu, `default` ve `platform` kuyrukları )
ve **ABP Background Workers** (yinelenen işler). Yönetim `/admin` altı ndaki Background Worker
ekranları ndan yapı lı r; yetkiler `App.BackgroundWorkers.RecurringJobs` ve `.Jobs` .
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Worker tipi | İşlevi |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| `MailQueueWorker` | Mail kuyruğunu işler. |
| `SqlWorker` | Zamanlanmı ş SQL çalı ştı rı r. |
| `NotificationWorker` | Bildirim kuralları nı değerlendirir ve gönderir. |
| `SessionCleanupWorker` | Süresi dolmuş oturumları temizler. |
| `BackupWorker` | Veritabanı yedeği alı r ve eski yedekleri temizler. |
2026-10-02 23:11:39 +00:00
| `ProbationReminderWorker` | Deneme süresinin bitmesine 15 gün kalan çalı şanlar için `DenemeSuresiBitiyor` bildirim tipinin kuralları nı işletir (`Scope: All`, her gün 08:00). |
2026-06-09 12:54:05 +00:00
2026-09-22 09:48:14 +00:00
**Kapsam (`Scope`).** İş kaydı her zaman host tablosundadı r (`Sas_H_BackgroundWorker`); işin
**gövdesinin** hangi kiracı bağlamı nda kaç kez çalı şacağı nı `Scope` belirler
(`WorkerScopeEnum`): `Host` yalnı zca host bağlamı nda bir kez, `Tenant` her kiracı için bir kez,
`All` önce host sonra her kiracı için. **Her kapsam ayrı bir Hangfire işidir**
(`BackgroundWorkerInitializer`): host `{WorkerType}:{Name}` , kiracı `{WorkerType}:{Name}#{TenantId}` .
`PlatformBackgroundWorker.StartAsync` tek kapsam çalı ştı rı r, kilidi de kapsam başı na alı r — bir
kiracı nı n hatası ya da yavaşlı ğı diğerlerini durdurmaz ve Jobs ekranı kiracı başı na süre, durum ve
hata gösterir (`Tenant` kolonu; ad `Sas_H_BackgroundWorker_JobFlow` içinde iş adı nı n `#` ekinden
`AbpTenants` 'a çözülür). Kiracı adı sonradan değişebildiği için iş adı na kimlik yazı lı r.
Kiracı eklenip silindiğinde zamanlama yeniden üretilir (`BackgroundWorkerTenantHandler`).
`BeforeSp` /`AfterSp` de kapsam başı na çalı şı r, çünkü dokundukları veri kiracı ya aittir.
Bildirim kuyruğu kiracı tablosunda olduğu için `NotificationWorker` işi `All` kapsamı yla gelir
(`data/App.BackgroundWorkers.RecurringJobs.json`).
2026-08-10 09:08:08 +00:00
Hangfire panosu geliştirmede serbest, üretimde `AbpHangfireAuthorizationFilter` ile korumalı dı r
(`/hangfire`).
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 15. Raporlama
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- **DevExpress Reporting**: Web Document Viewer (`/admin/reports/:report/view/...`) ve
Report Designer (`/admin/reports/:report/design/...`).
2026-10-01 12:01:57 +00:00
- **Rapor deposu**: `ReportTemplate` ve `ReportCategory` varlı kları
(`data/App.Reports.{ReportTemplates,Categories}.json`, seed senkronu açı k). Tasarı mcı da
kaydedilen `.repx` düzenleri `CustomReportStorageWebExtension` ile sunucudaki
`PredefinedReports/Reports` klasörüne yazı lı r.
- **`DynamicReport` şablonları ** (`Raporlar` kategorisi): `HtmlContent` HTML'i A4'e bası lı r
(`/admin/reports/DynamicReport/view/{ŞablonId}`). Ekran satı rı ndan açı lı nca
(`.../view/{ŞablonId}/{ListFormCode}?recordId=@Id`) `{{AlanAdi}}` yer tutucuları kaydı n form
raporundaki metniyle doldurulur (`DynamicFormReport.GetRecordTextsAsync`; ekran okuma yetkisi +
kiracı filtresi, değerler HTML kodlanı r). Kiracı da bulunmayan şablon host'tan okunur. MCP
araçları §13.9.
2026-08-10 09:08:08 +00:00
- **Dinamik raporlar** (`HttpApi.Host/PredefinedReports`): ListForm tanı mı ndan otomatik üretilen
grid, form ve ağaç raporları — grid durumunu (sütun sı rası , gruplama, filtre) rapora yansı tı r.
- Linux konteynerlerde font sorunları nı önlemek için `DevExpressFontConfiguration` devrededir.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 16. Dosya Yönetimi ve CDN
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- ABP BlobStoring, dosya sistemi sağlayı cı sı yla `App:CdnPath` altı na yazar; dosyalar `App:CdnUrl`
üzerinden servis edilir.
- `FileManagementAppService` : listeleme, yükleme, indirme, kopyalama, taşı ma, yeniden adlandı rma, silme.
- UI: `/admin/files` (`views/admin/files/FileManager.tsx`) — breadcrumb, çoklu yükleme, önizleme.
- Avatar, aktivite görselleri, içe aktarma dosyaları ve veritabanı yedekleri ayrı konteynerlerde tutulur.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 17. Gerçek Zamanlı Özellikler
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- **Messenger**: SignalR hub'ı `/messengerhub` . Konuşma ve mesaj varlı kları veritabanı nda;
Redis etkinse backplane olarak kullanı lı r. Query string ile gelen `access_token` ,
hub bağlantı sı için `Authorization` başlı ğı na çevrilir.
- **Video oda**: Oda oluşturma/başlatma/bitirme, katı lı mcı yönetimi, sohbet, doküman ve ekran
paylaşı mı panelleri; TURN sunucusu `configs/deployment/configs/turnserver.conf` ile yapı landı rı lı r.
- **Global arama**: `GlobalSearchAppService` üzerinden çapraz modül arama.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 18. Frontend Mimarisi
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 18.1. Route ve bileşen çözümü
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
```
Route kayı tları (DB)
├─ componentPath ──► fiziksel view (React.lazy)
└─ CustomComponent ──► @babel/standalone ile runtime derleme ──► ComponentContext
│
DynamicRouter ──► ProtectedRoute ──► PermissionGuard ──► PageContainer
```
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
`ROUTES_ENUM` (`src/routes/route.constant.ts`) statik yol sözleşmelerini tutar; iş modülleri için
(`supplychain`, `maintenance` , `warehouse` , `projects` , `hr` , `crm` , `mrp` , `accounting` ) ayrı lmı ş
yol desenleri de buradadı r. Bu alanları n ekranları , fiziksel React sayfaları yerine ListForm
konfigürasyonu ile üretilir.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 18.2. Durum yönetimi
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- **easy-peasy** global store: `auth` , `theme` , `locale` , `abpConfig` , `admin` , `client` , `base` .
Oturum ve tercih verileri `localStorage` yerine store üzerinden yönetilir (`stateSync.ts`).
- **React Query**: sunucu verisi önbellekleme.
- **Context'ler**: `ComponentContext` (runtime bileşen kaydı ), `DialogContext` , `ScrollContext` .
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 18.3. Tema ve lokalizasyon
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- Tailwind tabanlı tasarı m sistemi (`components/ui`) + DevExtreme temaları ; açı k/koyu mod ve
tema yapı landı rı cı (`ThemeConfigurator`).
2026-08-26 18:44:53 +00:00
- **Varsayı lan mod koyudur.** `proxy/theme/theme.config.ts` : `mode` ve `navMode` `dark` , DevExtreme
stili `dx.material.blue.dark.compact` . Kullanı cı tercihi store üzerinden saklanı r; bu yalnı zca
ilk açı lı ş varsayı lanı dı r.
2026-08-10 09:08:08 +00:00
- Dil metinleri veritabanı ndan gelir (`Sozsoft.Languages`); dil seçici header'dadı r.
Tenant bazlı çeviri geçersiz kı lma desteklenir.
- Layout seçenekleri: dikey menü, yatay menü, yı ğı lmı ş yan menü, mobil navigasyon.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 18.4. PWA ve sürüm yönetimi
2026-06-09 12:54:05 +00:00
2026-08-12 19:08:14 +00:00
- Kurulum iki kademelidir: **kabuk** (index.html + entry JS/CSS + eager vendor chunk'ları )
workbox precache manifest'inden gelir ve zorunludur; **bileşenler** (tüm lazy chunk'lar,
build'de üretilen `dist/warmup.json` ) güncelleme penceresinde aynı ilerleme çubuğunda arka
planda indirilir. İkinci kademe best-effort'tur (inemeyen dosya kurulumu düşürmez, süre
bütçesi aşı lı rsa kalanlar runtime cache'e kalı r); böylece deploy sonrası ilk gezinmede chunk
beklenmez ama yavaş bağlantı da kurulum timeout'a düşmez. DevExtreme temaları (~33 MB), font
ve görseller runtime cache'tedir.
- `registerType: 'prompt'` — yeni sürüm indirilir, indirme bitince otomatik devreye alı nı r
(`views/version/swRegistration.ts`, `sw.ts` , `AppUpdateDialog.tsx` ).
2026-08-12 21:26:36 +00:00
- Isı tma yalnı zca kuruluma bağlı değildir: uygulama açı lı şta `ENSURE_WARMUP` mesajı yollar,
service worker eksik kalan bileşenleri kaldı ğı yerden tamamlar.
2026-08-17 08:51:46 +00:00
- **Sürüm bilgisi backend'dedir.** `Sas_H_ChangeLog` tablosu tek kaynaktı r; istemci sürüm
2026-08-12 21:26:36 +00:00
numarası nı ve son sürümün notları nı `application-configuration` yanı tı ndaki
`extraProperties.changeLogs` alanı ndan okur (`PlatformApplicationConfigurationContributor`),
2026-08-17 08:51:46 +00:00
tam listeyi ise `/api/app/change-log` endpoint'inden alı r. Ayrı bir `version.json` isteği
2026-08-12 21:26:36 +00:00
yoktur. Changelog `/admin/changeLog` ekranı nda gösterilir; sürüm numarası son görülenden
farklı ysa kullanı cı giriş sonrası oraya yönlendirilir (tetikleyici bundle değil, sürümdür —
yalnı zca yeni bir git tag'i eklenmiş olsa da çalı şı r).
2026-08-17 08:51:46 +00:00
- **Sürüm notu akı şı — DbMigrator gerektirmez:** `configs/change-logs/generate-change-logs.sh`
deploy sı rası nda (`deploy/app.sh`) git tag'lerinden `configs/change-logs/change-logs.json`
üretir, dosya API konteynerine `/etc/api/change-logs` altı na salt okunur mount edilir ve
`ChangeLogStartupService` uygulama açı lı şı nda tabloyu bu dosyayla eşitler. Dosya imaja
2026-08-15 06:30:36 +00:00
**gömülmez** : api build context'i içindeyken her yeni tag Dockerfile'daki `COPY . .`
katmanı nı geçersiz kı lı p imajı gereksiz yere yeniden derletiyordu; artı k kod değişmediyse
imaj cache'ten gelir. Yeni sürüm için tag atı p deploy etmek yeterlidir. Notlar
2026-08-12 21:26:36 +00:00
**annotated** tag mesajı ndan okunur (`git tag -a 1.2.0 -m "..."`), her satı r bir madde.
- **Tablo git tag listesinin aynası dı r:** yeni tag eklenir, mesajı düzeltilen tag güncellenir,
2026-08-17 08:51:46 +00:00
git'ten silinen tag tablodan da (hard delete ile) kaldı rı lı r. Bu yüzden `Sas_H_ChangeLog`
2026-08-12 21:26:36 +00:00
elle düzenlenmemelidir — ilk deploy'da geri alı nı r. Dosya okunamaz veya boşsa senkronizasyon
hiçbir şey yapmaz, tablo boşaltı lmaz.
- Deploy algı laması service worker'ı n kendi `registration.update()` kontrolüne dayanı r:
herhangi bir chunk değiştiğinde entry hash'i, dolayı sı yla index.html ve `sw.js` içindeki
precache manifest'i de değişir.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 19. API ve Swagger
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- Swagger UI, API kökünde yayı nlanı r; OAuth2 ile "Authorize" düğmesi üzerinden token alı nabilir.
- Endpoint'ler ABP **conventional controller** mekanizması yla uygulama servislerinden üretilir:
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Namespace | Kök yol |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| `Sozsoft.Platform.ListForms.Administration` | `/api/admin/...` |
| Diğer `Sozsoft.Platform.*` servisleri | `/api/app/...` |
| Modül servisleri (Languages, Settings, MailQueue, Notifications, SqlQueryManager) | Modül kendi kök yolunu kullanı r |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- DevExpress raporlama controller'ları (`CustomReportDesigner`, `CustomWebDocumentViewer` ,
`QueryBuilder` ) Swagger dokümanı ndan hariç tutulur.
- Yanı tlar Brotli/Gzip ile sı kı ştı rı lı r; `X-Correlation-Id` başlı ğı istemciye açı lı r.
- Hata kodları : `PlatformConsts.AppErrorCodes` (`Error:0001` yetkisiz, `App.NoResults` kayı t yok,
`Error:0003` parametre geçersiz, `Error:0005` iç hata).
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
**Token örneği** (yer tutucularla):
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
```http
POST /connect/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
grant_type=password
& username=< KULLANICI >
& password=< PAROLA >
& client_id=Platform_PublicApi
& scope=offline_access%20Platform
```
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 20. Dağı tı m (Deployment)
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
`configs/deployment` altı nda üç ortam için compose dosyaları ve numaralandı rı lmı ş scriptler bulunur.
2026-09-17 12:24:51 +00:00
Benzer adlı `configs/docker` ile karı ştı rı lmamalı : `docker/` yalnı zca **yerel geliştirmede** veri
katmanı nı (SQL/PostgreSQL/Redis) ayağa kaldı rı r, `deployment/` ise **sunucudaki** kurulumdur.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Dosya | Amaç |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| `docker-compose-data.yml` | Redis, SQL Server / PostgreSQL, yedek volume'ları |
| `docker-compose-app.yml` / `.dev.yml` / `.production.yml` | API, UI, migrator, nginx |
2026-09-17 12:24:51 +00:00
| `docker-compose-devops.yml` | Forgejo (CI/CD), Rocket.Chat, n8n, Ollama, Open WebUI, coturn |
2026-08-10 09:08:08 +00:00
| `Dockerfile` , `api/*.Dockerfile` , `ui/Sozsoft.Platform.Ui.Dockerfile` | İmaj tanı mları |
2026-09-17 12:24:51 +00:00
Servis yapı landı rma dosyaları tek klasörde, `configs/deployment/configs/` altı ndadı r — compose
dosyaları buradan mount eder, ikinci bir kopya tutulmaz:
| Dosya | Kullanan servis |
| --- | --- |
| `nginx.conf` | Ters vekil: tüm `*.sozsoft.com` vhost'ları , SSL sonlandı rma, `/mcp` bloğu |
| `redis.conf` / `redis.7.conf` | Redis (dağı tı k cache, sürüme göre) |
| `turnserver.conf` | coturn — WebRTC TURN/STUN (bkz. §Messenger) |
| `elasticsearch.yml` | Elasticsearch (opsiyonel log/arama katmanı ) |
### Alt alan adı → port eşlemesi
`nginx.conf` içindeki vhost'lar host üzerinde yayı nlanan portlara bakar; yeni bir servis
eklerken portun boş olduğu buradan doğrulanı r.
| Alan adı | Port | Servis |
| --- | --- | --- |
| `devops.sozsoft.com` | 3000 | Forgejo |
| `chat.sozsoft.com` | 3001 | Rocket.Chat |
| `sozsoft.com` + tenant alt alan adları | 3002 | UI (React) |
| `ollama.sozsoft.com` | 3003 | Open WebUI — sohbet arayüzü |
| `ollama.sozsoft.com/ollama-api/` | 11434 | Ollama ham API'si (basic auth) |
| `ai.sozsoft.com` | 5678 | n8n |
2026-09-20 20:23:39 +00:00
| `api.sozsoft.com` | 8080 | API (`/mcp`, `/videoroomhub` , `/messengerhub` , `/notificationhub` dahil) |
2026-09-17 12:24:51 +00:00
| `cdn.sozsoft.com` | 8081 | CDN |
Open WebUI kendi backend'ini `/api/...` altı nda sunduğu için Ollama'nı n ham API'si `/ollama-api/`
önekine alı nmı ştı r; iki uç aynı önekte yaşayamaz.
Basic auth yalnı zca `/ollama-api/` bloğundadı r — Ollama'nı n kendi kimlik doğrulaması yoktur.
Sohbet arayüzünün önüne **konmaz** : Open WebUI socket.io üzerinden WebSocket açar, tarayı cı WS
upgrade isteğine basic auth kimliğini eklemez ve bağlantı 401 döngüsüne girer. Arayüzün güvenlik
sı nı rı uygulamanı n kendi girişidir; bu yüzden kurulumdan hemen sonra **yeni kayı t alı mı nı n
kapatı lması bir tercih değil, kurulumun parçası dı r** (`Settings → Admin → General → Enable New
Sign Ups`). Daha sı kı bir sı nı r gerekiyorsa vhost'a `allow` /`deny` ile IP kı sı tı eklenir; basic
auth bu arayüz için bir seçenek değildir.
Compose tarafı nda `DEFAULT_USER_ROLE=pending` ikinci bir emniyet katmanı dı r: ilk kaydolan admin
olur, sonrakiler onay bekleyen role düşer. Bu değer ve `ENABLE_SIGNUP` Open WebUI'nin
*PersistentConfig* değişkenlerindendir — yalnı zca **ilk açı lı şta** env'den okunur, sonrası nda
veritabanı ndaki değer geçerlidir; yani env'i sonradan değiştirmek yerine arayüzdeki ayar kullanı lı r.
GPU olmayan 8 GB'lı k DevOps makinesinde Ollama `OLLAMA_MAX_LOADED_MODELS=1` ile sı nı rlı dı r ve
Open WebUI'nin gömme/erişim hattı kapalı dı r (`BYPASS_EMBEDDING_AND_RETRIEVAL`): varsayı lan RAG
hattı ayrı ca bir gömme modeli indirir, bu makinede bellek bütçesi yoktur. Yüklenen dosyanı n metni
doğrudan bağlama girer.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Script sı rası (`configs/deployment/scripts`):
```
2026-09-17 12:24:51 +00:00
1-devops.sh → DevOps makinesi (Forgejo, Rocket.Chat, n8n, Ollama, Open WebUI)
2026-08-10 09:08:08 +00:00
2-data-postgres.sh /
3-data-sql.sh → Veri katmanı
4-production-build.sh → İmaj build
5-production-deploy.sh → Yayı n
6-production-migrator-true.sh → Migration çalı ştı rma
7-setup_ssl.sh → Sertifika
8-dev-build.sh / 9-dev-deploy.sh / 10-dev-migrator-true.sh → Dev ortamı
```
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
Migrator servisi `SEED` ortam değişkeni ile çalı şı r ve compose dosyası nda `SEED=${SEED:-true}`
olarak tanı mlı dı r: değişken verilmezse seed **çalı şı r** . Seed dosyaları imaja gömülmez; depodaki
`configs/seeds` klasöründen mount edilir (`App:SeedsPath`), böylece bir seed değiştiğinde imaj
build etmek gerekmez.
2026-08-10 09:08:08 +00:00
Ayrı ntı lı kurulum notları : [`configs/deployment/README.md` ](configs/deployment/README.md ),
[`Readme_Production.md` ](configs/deployment/Readme_Production.md ),
[`Readme_Devops.md` ](configs/deployment/Readme_Devops.md ).
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
> Bu dokümanlarda geçmişte örnek amaçlı bı rakı lmı ş kimlik bilgileri bulunabilir; üretimde
> tümü döndürülmeli ve secret yöneticisine taşı nmalı dı r.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 21. Geliştirme Standartları ve Sı k Kullanı lan Komutlar
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 21.1. Çözüm kuralları
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
1. Her istek şu sı rayla değerlendirilir: ** (1)** ListForm konfigürasyonu → ** (2)** SQL Query
Manager + Custom Endpoint → ** (3)** Dynamic Service → ** (4)** kod değişikliği (son çare,
gerekçe zorunlu).
2. Standart iş ihtiyaçları için yeni özel React sayfası /bileşeni geliştirilmez.
3. Her öneri tenant ve yetki tasarı mı nı içerir.
4. Platform yetkilendirme desenleri atlanmaz.
5. Secret, tenant id veya bağlantı dizesi koda gömülmez.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 21.2. Frontend
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
```powershell
cd ui
npm start # geliştirme sunucusu
npm run build # üretim derlemesi (metadata + version + vite build)
npm run lint # ESLint
npm run format # prettier --write + eslint --fix
```
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 21.3. Backend
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
```powershell
cd api
dotnet build
dotnet run --project src/Sozsoft.Platform.HttpApi.Host
dotnet format --include .\modules\Sozsoft.Notifications\ --folder
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
# Kod standardı kapı sı (ölü kod / stil analizörleri)
dotnet build Sozsoft.Platform.sln --no-incremental `
-p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true
dotnet format Sozsoft.Platform.sln --diagnostics IDE0005,IDE0161 --severity warn
2026-08-10 09:08:08 +00:00
# Migration (EntityFrameworkCore projesi içinde)
dotnet ef migrations add < Ad >
dotnet ef database update
dotnet ef migrations remove
```
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
.NET/ABP kod standardı (hedef sürümler, nullable politikası , ölü kod kuralları , modern C#
kullanı mı , ABP katman sı nı rları ) bağlayı cı olarak
[`.github/instructions/dotnet.instructions.md` ](.github/instructions/dotnet.instructions.md )
dosyası ndadı r. Standart derlemede zorlanı r: `api/Directory.Build.props` analizörleri açar,
`api/.editorconfig` kural şiddetlerini tanı mlar; bu iki dosya standardı n tek kaynağı dı r.
2026-08-10 09:08:08 +00:00
Yeni ABP modülü eklemek için:
`abp new Sozsoft.<Modul> -t module --no-ui -m none --database-provider ef`
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
### 21.4. Seed dosyaları
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
İki ayrı seed yüzeyi vardı r ve karı ştı rı lmamalı dı r.
**1. Depo içi (kod ile taşı nan) seed'ler** — `api/src/Sozsoft.Platform.DbMigrator/Migrations/` .
2026-09-24 19:39:00 +00:00
Platformun kendi ekranları buradadı r (dil metinleri `configs/seeds/host/data/App.Languages.*.json` ); değişiklikleri
2026-08-26 18:44:53 +00:00
derlenip yayı nlanı r. Yeni bir modülün nası l kurulacağı nı öğrenmek için başvurulacak dosyalar:
2026-09-29 11:46:39 +00:00
- `ListFormSeeder_Saas.cs` , `ListFormSeeder_Administration.cs` , `ListFormSeeder_Hr.cs` — menü
modülüne göre ayrı lmı ş ListForm + alan tanı mları (İK ekranları `ListFormSeeder_Hr.cs` 'te)
2026-09-05 18:20:18 +00:00
- `WizardDataSeeder.cs` , `CrudDataSeeder.cs` — aşağı daki
2026-08-26 18:44:53 +00:00
runtime seed dosyaları nı okuyup uygulayan seeder'lar
2026-09-07 14:43:46 +00:00
- `ListFormSeedDataApplier` , `CrudEndpointSeedApplier` (`Domain/Data/`) — uygulama kuralı nı n tek
yeri; hem migrate/seed akı şı hem wizard import'unun kapanı şı aynı servisleri çağı rı r
2026-08-26 18:44:53 +00:00
2026-09-05 18:20:18 +00:00
**2. Runtime'da üretilen seed'ler** — `configs/seeds/` . Wizard, Custom Components ekranı /Visual
2026-09-07 06:14:00 +00:00
Designer, CRUD Endpoint Manager ve `SeedFilePath` tanı mlı ListForm ekranları çalı şma zamanı nda
burayı yazar; veritabanı silinip yeniden oluşturulduğunda aynı dosyalar
2026-08-26 18:44:53 +00:00
geri yüklenir. Kapsam klasörü CDN düzeniyle aynı dı r ve `SeedPathResolver` üzerinden çözülür:
```
configs/seeds/
├── host/ # host kapsamı
2026-09-02 08:32:53 +00:00
│ ├── wizard/ # {Ad}.json → WizardDataSeeder
2026-09-07 14:43:46 +00:00
│ ├── crud/ # {EntityName}.json → CrudEndpointSeedApplier
2026-09-21 19:40:13 +00:00
│ ├── data/ # {ListFormCode}.json ya da {ListFormCode}/{anahtar}.json → ListFormSeedDataApplier
2026-09-17 17:54:23 +00:00
│ │ # App.Menus.{Routes,Module,Menu}.json — route/modül/menü ağacı
│ │ # Abp.Identity.Permission{Groups,s}.json — yetki tanı mları
2026-09-18 06:03:19 +00:00
│ │ # App.Definitions.{CountryGroup,Country,City,District}.json — adres zinciri
2026-10-02 23:11:39 +00:00
│ │ # App.Definitions.{Currency,ContactTitle,AiBot,TerminationReason}.json — para birimi, hitap, AI bot, SGK çı kı ş kodu
2026-09-29 11:46:39 +00:00
│ │ # App.Hr.{SkillType,SkillLevel,Skill}.json — İK yetkinlik tanı mları
│ │ # App.Hr.{Department,JobPosition}.json — İK departman → pozisyon (BranchId ile şubeye bağlı )
2026-09-29 06:14:07 +00:00
│ │ # App.Notifications.Notification{Templates,Types,Rules}.json — bildirim şablonu, tipi → kuralı
2026-09-24 19:39:00 +00:00
│ │ # App.Languages.{Language,LanguageText}.json — dil → metin (eksik LanguageKey metinle üretilir)
2026-09-18 06:28:25 +00:00
│ │ # App.SettingDefinitions.json, App.BackgroundWorkers.RecurringJobs.json — ayar tanı mları , zamanlanmı ş işler
2026-08-26 18:44:53 +00:00
│ ├── sql/{object,execute}/ # .sql (SQL Server)
│ └── postgres/{object,execute}/
├── tenants/{tenantId}/… # aynı düzen, tenant kapsamı
└── .imports/{importId}/ # wizard import staging + backup (seeder taramaları na girmez)
```
2026-06-09 12:54:05 +00:00
2026-08-26 18:44:53 +00:00
> Bu dosyalar elle de düzenlenebilir; ilgili ekrandan tekrar kaydedildiğinde yeniden üretilirler.
2026-09-29 06:14:07 +00:00
> Wizard dosyası `EditFileName` ile güncellenirse deploy veritabanı na dokunmaz: dosyalar cevaptan
> yeniden yazı lı r (ad değiştiyse eski dosya silinir), önceki sürümün kayı tları `Pending.Replaced`'a
> alı nı r ve DB Migrate onları kaldı rı p ekranı yeniden kurar (`lowcode.instructions.md` §4.0). Wizard'ı n ürettiği ekran **ListForm detayı ndan** düzenlendiğinde
2026-09-02 08:32:53 +00:00
> de aynı dosya güncellenir (`WizardSeedSynchronizer`): `ListForm`/`Fields` bölümleri ve
> `Wizard` bölümündeki karşı lı kları veritabanı ndaki güncel haliyle değiştirilir.
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 22. Sorun Giderme
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
| Belirti | Olası neden ve çözüm |
2026-06-09 12:54:05 +00:00
| --- | --- |
2026-08-10 09:08:08 +00:00
| `/api/abp/application-configuration` 503 dönüyor | Veritabanı na erişilemiyor. Bağlantı dizesini ve veri konteynerini kontrol edin; `/api/setup/application-status` ile durumu görün. |
| UI `/setup` ekranı na düşüyor | Şema oluşmamı ş veya bekleyen migration var. Setup ekranı ndan migration'ı tetikleyin ya da DbMigrator'ı çalı ştı rı n. |
| Giriş "UserCannotSignIn..." hatası veriyor | [11.3 ](#113-giriş-engelleri ) tablosuna bakı n: IP, çalı şma saati, doğrulama, şube/eş zamanlı kullanı cı limiti. |
| Yeni sürüm tarayı cı da görünmüyor | Service worker `prompt` modundadı r; güncelleme bildirimini onaylayı n veya sekmeyi tamamen kapatı p açı n. |
| DevExtreme teması yüklenmiyor | `public/css` altı ndaki tema dosyaları runtime cache'tedir (StaleWhileRevalidate); hard refresh yeterlidir. |
| Hangfire başlangı çta hata veriyor | Bağlantı dizesi boşsa Hangfire kaydı atlanı r ama ABP modülleri yüklenir. Bağlantı dizesini doğrulayı n. |
| Dinamik servis yayı nlanmı yor | Önce `TestCompile` çalı ştı rı n; derleme hatası mesajı UI'da döner. `Publish` için ilgili yetki gerekir. |
| Raporlarda font/karakter bozukluğu (Linux) | `DevExpressFontConfiguration.InstallLinuxFonts` logları nı kontrol edin; konteynerde font paketi eksik olabilir. |
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
---
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
## 23. Bilinen Sı nı rlar ve Notlar
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
- `route.constant.ts` içindeki `supplychain` , `maintenance` , `warehouse` , `projects` , `crm` ,
`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
2026-09-29 11:46:39 +00:00
organizasyon şeması (`OrgChart.tsx`, İK menüsü `App.Hr.OrgChart` ) fiziksel bir view'dı r.
2026-08-10 09:08:08 +00:00
- Depodaki `appsettings*.json` ve deployment dokümanları geliştirme değerleri/örnek kimlik
bilgileri içerir; üretim öncesi tümü değiştirilmelidir.
2026-08-26 18:44:53 +00:00
- SQL View Designer tek yönlüdür (model → T-SQL). Elle yazı lmı ş ya da tasarı mcı nı n kanonik
şekline uymayan bir view tanı mı geri okunamaz; dialog ham SQL moduna düşer.
- `api/test/Sozsoft.Platform.EntityFrameworkCore.Tests` şu an SQLite şema oluşturmada
(`nvarchar(max)` → `SQLite Error 1` ) kı rı ktı r; bu kı rı klı k kod standardı ndan önce de vardı ve
ayrı bir iş olarak ele alı nmalı dı r.
2026-08-10 09:08:08 +00:00
- Rol– yetki eşleşmeleri veritabanı nda müşteri ortamı na göre değişir; buradaki yetki kodları
tanı mı n kendisidir, atama değil.
---
## Lisans ve Sahiplik
2026-06-09 12:54:05 +00:00
2026-08-10 09:08:08 +00:00
Bu depo Sozsoft'a aittir. DevExpress/DevExtreme bileşenleri ticari lisans gerektirir
(`api/DevExpress_License.txt`).