BackgroundWorkers Settings

This commit is contained in:
Sedat ÖZTÜRK 2026-09-18 09:28:25 +03:00
parent ca80c9d2f5
commit b5f411e684
15 changed files with 1095 additions and 1308 deletions

View file

@ -660,7 +660,6 @@ Platform-owned screens, menus, permissions and language texts. Changing them req
a deploy. AI must learn and teach implementation flow primarily from these assets: a deploy. AI must learn and teach implementation flow primarily from these assets:
- ListFormSeeder_Saas.cs / ListFormSeeder_Administration.cs / ListFormSeeder_{Modul}.cs - ListFormSeeder_Saas.cs / ListFormSeeder_Administration.cs / ListFormSeeder_{Modul}.cs
- HostData.json
- LanguagesData.json - LanguagesData.json
- WizardDataSeeder.cs / CrudDataSeeder.cs — the seeders that read - WizardDataSeeder.cs / CrudDataSeeder.cs — the seeders that read
surface B below surface B below
@ -753,7 +752,7 @@ AI must never propose menu/route without permission contract.
### 31.5 Step 5 - Add settings/integration dependencies ### 31.5 Step 5 - Add settings/integration dependencies
From `HostData.json` patterns, AI must define required settings when feature depends on external services: From the `configs/seeds/host/data/App.SettingDefinitions.json` / `App.Definitions.AiBot.json` patterns, AI must define required settings when feature depends on external services:
- Sender credentials and endpoints (sms/mail/whatsapp/rocket) - Sender credentials and endpoints (sms/mail/whatsapp/rocket)
- AiBot integration endpoint and activation state - AiBot integration endpoint and activation state

View file

@ -3525,9 +3525,10 @@ kullanılacağı** `lowcode-reference.instructions.md` §12'dedir.
> >
> 1. `sql/execute/{Ad}.sql` altında, kaydı **varsa güncelleyen/yoksa ekleyen** bir prosedür yaz > 1. `sql/execute/{Ad}.sql` altında, kaydı **varsa güncelleyen/yoksa ekleyen** bir prosedür yaz
> (§8.4 sözleşmesi) — proje kapsamındaki doğru yol budur. > (§8.4 sözleşmesi) — proje kapsamındaki doğru yol budur.
> 2. Platformun kendi varsayılanıysa `api/src/Sozsoft.Platform.DbMigrator/Migrations/HostData.json` > 2. Platformun kendi varsayılanıysa ilgili ekranın `configs/seeds/host/data/{ListFormCode}.json`
> (`AiBots`, `Settings`, `NotificationTypes`, `NotificationRules`, `BackgroundWorkers`, > dosyası (`App.Definitions.AiBot`, `App.SettingDefinitions`, `App.Notifications.NotificationTypes`,
> `Currencies`, `ContactTitles`) — bu dosya çekirdek koda aittir, proje talebi için tercih edilmez. > `App.Notifications.NotificationRules`, `App.BackgroundWorkers.RecurringJobs`, `App.Definitions.Currency`,
> `App.Definitions.ContactTitle`) — bunlar platformun kendi verisidir, proje talebi için tercih edilmez.
> >
> "Ekranı ürettim ama numaratörü/zamanlanmış işi de kurdum" diyorsan, o kayıtların seed karşılığını > "Ekranı ürettim ama numaratörü/zamanlanmış işi de kurdum" diyorsan, o kayıtların seed karşılığını
> da yazmadıysan teslim eksiktir. > da yazmadıysan teslim eksiktir.

View file

@ -291,8 +291,7 @@ güncellenmelidir.
### 5.5. İlk giriş ### 5.5. İlk giriş
Seed edilen host yöneticisi ile `/login` üzerinden giriş yapılır (kullanıcı bilgileri Seed edilen host yöneticisi ile `/login` üzerinden giriş yapılır (kullanıcı bilgileri
`PlatformIdentityDataSeeder` ve `HostData.json` ile belirlenir; ortam bazlı değerler `PlatformIdentityDataSeeder` ile belirlenir). Giriş sonrası
`HostData.Dev.json` / `HostData.Production.json` dosyalarındadır). Giriş sonrası
`/admin/dashboard` açılır. `/admin/dashboard` açılır.
--- ---
@ -1595,7 +1594,6 @@ Platformun kendi ekranları, menüleri, yetkileri ve dil metinleri buradadır; d
derlenip yayınlanır. Yeni bir modülün nasıl kurulacağını öğrenmek için başvurulacak dosyalar: derlenip yayınlanır. Yeni bir modülün nasıl kurulacağını öğrenmek için başvurulacak dosyalar:
- `ListFormSeeder_Saas.cs`, `ListFormSeeder_Administration.cs` — ListForm + alan tanımları - `ListFormSeeder_Saas.cs`, `ListFormSeeder_Administration.cs` — ListForm + alan tanımları
- `HostData.json` — ayar/entegrasyon değerleri
- `LanguagesData.json` — dil anahtarları (EN/TR) - `LanguagesData.json` — dil anahtarları (EN/TR)
- `WizardDataSeeder.cs`, `CrudDataSeeder.cs` — aşağıdaki - `WizardDataSeeder.cs`, `CrudDataSeeder.cs` — aşağıdaki
runtime seed dosyalarını okuyup uygulayan seeder'lar runtime seed dosyalarını okuyup uygulayan seeder'lar
@ -1618,6 +1616,7 @@ configs/seeds/
│ │ # App.Definitions.{CountryGroup,Country,City,District}.json — adres zinciri │ │ # App.Definitions.{CountryGroup,Country,City,District}.json — adres zinciri
│ │ # App.Definitions.{Currency,ContactTitle,AiBot}.json — para birimi, hitap, AI bot │ │ # App.Definitions.{Currency,ContactTitle,AiBot}.json — para birimi, hitap, AI bot
│ │ # App.Notifications.Notification{Types,Rules}.json — bildirim tipi → kuralı │ │ # App.Notifications.Notification{Types,Rules}.json — bildirim tipi → kuralı
│ │ # App.SettingDefinitions.json, App.BackgroundWorkers.RecurringJobs.json — ayar tanımları, zamanlanmış işler
│ ├── sql/{object,execute}/ # .sql (SQL Server) │ ├── sql/{object,execute}/ # .sql (SQL Server)
│ └── postgres/{object,execute}/ │ └── postgres/{object,execute}/
├── tenants/{tenantId}/… # aynı düzen, tenant kapsamı ├── tenants/{tenantId}/… # aynı düzen, tenant kapsamı

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,10 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Sozsoft.Platform.Entities; using Sozsoft.Platform.Entities;
using Sozsoft.Platform.Enums; using Sozsoft.Platform.Enums;
using Sozsoft.Settings.Entities;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
@ -14,50 +12,17 @@ using static Sozsoft.Settings.SettingsConsts;
namespace Sozsoft.Platform.Data.Seeds; namespace Sozsoft.Platform.Data.Seeds;
#region SeedDtos /// <summary>
public class LanguageTextsSeedDto /// Varsayilan veri kaynagini olusturur. Baglanti cumlesi ortamin appsettings dosyasindan gelir;
{ /// bu yuzden diger host verisi gibi <c>configs/seeds/host/data</c> altina yazilamaz.
public string ResourceName { get; set; } /// </summary>
public string Key { get; set; }
public string En { get; set; }
public string Tr { get; set; }
}
public class BackgroundWorkerSeedDto
{
public string Name { get; set; }
public string Cron { get; set; }
public string WorkerType { get; set; }
public bool IsActive { get; set; }
public string DataSourceCode { get; set; }
public string BeforeSp { get; set; }
public string AfterSp { get; set; }
}
public class HostSeederDto
{
public List<DataSource> DataSources { get; set; }
public List<SettingDefinition> Settings { get; set; }
public List<BackgroundWorkerSeedDto> BackgroundWorkers { get; set; }
}
#endregion
public class HostDataSeeder : IDataSeedContributor, ITransientDependency public class HostDataSeeder : IDataSeedContributor, ITransientDependency
{ {
private readonly IRepository<DataSource, Guid> _dataSources; private readonly IRepository<DataSource, Guid> _dataSources;
private readonly IRepository<SettingDefinition, Guid> _settings;
private readonly IRepository<BackgroundWorker, Guid> _backgroundWorkerRepository;
public HostDataSeeder( public HostDataSeeder(IRepository<DataSource, Guid> dataSource)
IRepository<DataSource, Guid> dataSource,
IRepository<SettingDefinition, Guid> settings,
IRepository<BackgroundWorker, Guid> backgroundWorkerRepository,
IRepository<Route, Guid> routeRepository
)
{ {
_dataSources = dataSource; _dataSources = dataSource;
_settings = settings;
_backgroundWorkerRepository = backgroundWorkerRepository;
} }
private static IConfigurationRoot BuildConfiguration() private static IConfigurationRoot BuildConfiguration()
@ -72,40 +37,8 @@ public class HostDataSeeder : IDataSeedContributor, ITransientDependency
public async Task SeedAsync(DataSeedContext context) public async Task SeedAsync(DataSeedContext context)
{ {
var settings = await _settings.GetListAsync();
var dataSources = await _dataSources.GetListAsync(); var dataSources = await _dataSources.GetListAsync();
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(Path.Combine("Migrations", "HostData.json"))
.AddJsonFile(Path.Combine("Migrations", $"HostData.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? ""}.json"), true)
.Build();
var items = configuration.Get<HostSeederDto>();
foreach (var item in items.Settings)
{
if (!settings.Any(a => a.Code == item.Code))
{
await _settings.InsertAsync(new()
{
Code = item.Code,
NameKey = item.NameKey,
DescriptionKey = item.DescriptionKey,
DefaultValue = item.DefaultValue.Replace("\r\n", Environment.NewLine),
IsVisibleToClients = item.IsVisibleToClients,
IsInherited = item.IsInherited,
IsEncrypted = item.IsEncrypted,
MainGroupKey = item.MainGroupKey,
SubGroupKey = item.SubGroupKey,
RequiredPermissionName = item.RequiredPermissionName,
DataType = item.DataType,
Providers = item.Providers,
SelectOptions = item.SelectOptions,
Order = item.Order
});
}
}
if (!dataSources.Any(a => a.Code == SeedConsts.DataSources.DefaultCode)) if (!dataSources.Any(a => a.Code == SeedConsts.DataSources.DefaultCode))
{ {
var config = BuildConfiguration(); var config = BuildConfiguration();
@ -116,24 +49,5 @@ public class HostDataSeeder : IDataSeedContributor, ITransientDependency
ConnectionString = config.GetConnectionString(DefaultDatabaseProvider) ConnectionString = config.GetConnectionString(DefaultDatabaseProvider)
}); });
} }
foreach (var item in items.BackgroundWorkers)
{
if (!await _backgroundWorkerRepository.AnyAsync(x => x.Name == item.Name))
{
await _backgroundWorkerRepository.InsertAsync(new BackgroundWorker
{
Name = item.Name,
Cron = item.Cron,
WorkerType = Enum.Parse<WorkerTypeEnum>(item.WorkerType),
IsActive = item.IsActive,
DataSourceCode = item.DataSourceCode,
BeforeSp = item.BeforeSp,
AfterSp = item.AfterSp
});
}
}
} }
} }

View file

@ -12,6 +12,14 @@ using Volo.Abp.Domain.Repositories;
namespace Sozsoft.Platform.Data.Seeds; namespace Sozsoft.Platform.Data.Seeds;
public class LanguageTextsSeedDto
{
public string ResourceName { get; set; }
public string Key { get; set; }
public string En { get; set; }
public string Tr { get; set; }
}
public class LanguageSeederDto public class LanguageSeederDto
{ {
public List<Language> Languages { get; set; } public List<Language> Languages { get; set; }

View file

@ -27885,8 +27885,8 @@
{ {
"resourceName": "Platform", "resourceName": "Platform",
"key": "App.SettingDefinitions.Description", "key": "App.SettingDefinitions.Description",
"en": "Setting Definitions — the definition screen of application settings. Table: Sas_H_SettingDefinition · host scope · list screen. This screen defines the setting; the values are entered on Administration › Settings (/admin/settings).\nUsage: every value that must be configurable (url, token, limit, mode, default) is defined here instead of being hard-coded. The settings screen is produced from these rows: the grouping, the editor type and the permission all come from this record.\nFields:\n• Code → unique setting key; read from code with ISettingProvider.GetOrNullAsync(Code). Example: App.Sender.Telegram.BotToken\n• NameKey, DescriptionKey → language keys. The text is not written here but on Languages › Language Text\n• DefaultValue → the value used when no level holds one\n• DataType → the editor type on the settings screen: Text, List …\n• SelectOptions → key-value pairs for the List type; the value is again a language key\n• Providers → which levels may hold a value, pipe separated: D = Default, G = Global, T = Tenant, U = User. T|G|D means the tenant may override the global value\n• IsEncrypted → the value is stored encrypted and decrypted automatically while reading. Turn it on for every secret (token, password, key)\n• IsVisibleToClients → is it sent to the browser. Never turn it on together with IsEncrypted\n• IsInherited → does the tenant inherit the global value when it has none of its own\n• MainGroupKey, SubGroupKey → the heading and sub-heading on the settings screen; both are language keys\n• RequiredPermissionName → who may see and change the setting\n• Order → the ordering of the settings screen\nCaution: a definition added only from this screen is lost on a database reset — the same record is also written into Migrations/HostData.json. Never encrypt or decrypt an encrypted value yourself; ISettingManager encrypts while writing and ISettingProvider decrypts while reading.", "en": "Setting Definitions — the definition screen of application settings. Table: Sas_H_SettingDefinition · host scope · list screen. This screen defines the setting; the values are entered on Administration › Settings (/admin/settings).\nUsage: every value that must be configurable (url, token, limit, mode, default) is defined here instead of being hard-coded. The settings screen is produced from these rows: the grouping, the editor type and the permission all come from this record.\nFields:\n• Code → unique setting key; read from code with ISettingProvider.GetOrNullAsync(Code). Example: App.Sender.Telegram.BotToken\n• NameKey, DescriptionKey → language keys. The text is not written here but on Languages › Language Text\n• DefaultValue → the value used when no level holds one\n• DataType → the editor type on the settings screen: Text, List …\n• SelectOptions → key-value pairs for the List type; the value is again a language key\n• Providers → which levels may hold a value, pipe separated: D = Default, G = Global, T = Tenant, U = User. T|G|D means the tenant may override the global value\n• IsEncrypted → the value is stored encrypted and decrypted automatically while reading. Turn it on for every secret (token, password, key)\n• IsVisibleToClients → is it sent to the browser. Never turn it on together with IsEncrypted\n• IsInherited → does the tenant inherit the global value when it has none of its own\n• MainGroupKey, SubGroupKey → the heading and sub-heading on the settings screen; both are language keys\n• RequiredPermissionName → who may see and change the setting\n• Order → the ordering of the settings screen\nCaution: a definition added only from this screen is lost on a database reset — the same record is also written into configs/seeds/host/data/App.SettingDefinitions.json. Never encrypt or decrypt an encrypted value yourself; ISettingManager encrypts while writing and ISettingProvider decrypts while reading.",
"tr": "Ayar Tanımları — uygulama ayarlarının tanım ekranı. Tablo: Sas_H_SettingDefinition · host kapsamlı · liste ekranı. Bu ekran ayarı tanımlar; değerler Administration › Ayarlar (/admin/settings) ekranından girilir.\nKullanım: ayarlanabilir olması gereken her değer (url, token, limit, mod, varsayılan) koda gömülmez, burada tanımlanır. Ayar ekranı bu satırlardan üretilir: gruplama, editör tipi ve yetki bu kayıttan gelir.\nAlanlar:\n• Code → benzersiz ayar anahtarı; koddan ISettingProvider.GetOrNullAsync(Code) ile okunur. Örnek: App.Sender.Telegram.BotToken\n• NameKey, DescriptionKey → dil anahtarları. Metin buraya değil Languages › Language Text ekranına yazılır\n• DefaultValue → hiçbir seviyede değer yoksa kullanılan değer\n• DataType → ayar ekranındaki editör tipi: Text, List …\n• SelectOptions → List tipi için anahtar-değer çiftleri; değer yine dil anahtarıdır\n• Providers → değerin hangi seviyede tutulabileceği, dikey çizgi ile: D = Default, G = Global, T = Tenant, U = User. T|G|D, kiracının global değeri ezebileceği anlamına gelir\n• IsEncrypted → değer şifreli saklanır ve okunurken otomatik çözülür. Gizli olan her değerde (token, parola, anahtar) açılır\n• IsVisibleToClients → tarayıcıya gönderilir mi. IsEncrypted ile birlikte asla açılmaz\n• IsInherited → kiracının kendi değeri yoksa global değeri devralır mı\n• MainGroupKey, SubGroupKey → ayar ekranındaki başlık ve alt başlık; ikisi de dil anahtarıdır\n• RequiredPermissionName → ayarı kimin görüp değiştirebileceği\n• Order → ayar ekranının sıralaması\nDikkat: yalnızca bu ekrandan eklenen tanım veritabanı sıfırlandığında kaybolur — aynı kayıt Migrations/HostData.json dosyasına da yazılır. Şifreli değeri elle şifreleme/çözme; yazarken ISettingManager şifreler, okurken ISettingProvider çözer." "tr": "Ayar Tanımları — uygulama ayarlarının tanım ekranı. Tablo: Sas_H_SettingDefinition · host kapsamlı · liste ekranı. Bu ekran ayarı tanımlar; değerler Administration › Ayarlar (/admin/settings) ekranından girilir.\nKullanım: ayarlanabilir olması gereken her değer (url, token, limit, mod, varsayılan) koda gömülmez, burada tanımlanır. Ayar ekranı bu satırlardan üretilir: gruplama, editör tipi ve yetki bu kayıttan gelir.\nAlanlar:\n• Code → benzersiz ayar anahtarı; koddan ISettingProvider.GetOrNullAsync(Code) ile okunur. Örnek: App.Sender.Telegram.BotToken\n• NameKey, DescriptionKey → dil anahtarları. Metin buraya değil Languages › Language Text ekranına yazılır\n• DefaultValue → hiçbir seviyede değer yoksa kullanılan değer\n• DataType → ayar ekranındaki editör tipi: Text, List …\n• SelectOptions → List tipi için anahtar-değer çiftleri; değer yine dil anahtarıdır\n• Providers → değerin hangi seviyede tutulabileceği, dikey çizgi ile: D = Default, G = Global, T = Tenant, U = User. T|G|D, kiracının global değeri ezebileceği anlamına gelir\n• IsEncrypted → değer şifreli saklanır ve okunurken otomatik çözülür. Gizli olan her değerde (token, parola, anahtar) açılır\n• IsVisibleToClients → tarayıcıya gönderilir mi. IsEncrypted ile birlikte asla açılmaz\n• IsInherited → kiracının kendi değeri yoksa global değeri devralır mı\n• MainGroupKey, SubGroupKey → ayar ekranındaki başlık ve alt başlık; ikisi de dil anahtarıdır\n• RequiredPermissionName → ayarı kimin görüp değiştirebileceği\n• Order → ayar ekranının sıralaması\nDikkat: yalnızca bu ekrandan eklenen tanım veritabanı sıfırlandığında kaybolur — aynı kayıt configs/seeds/host/data/App.SettingDefinitions.json dosyasına da yazılır. Şifreli değeri elle şifreleme/çözme; yazarken ISettingManager şifreler, okurken ISettingProvider çözer."
}, },
{ {
"resourceName": "Platform", "resourceName": "Platform",

View file

@ -3575,6 +3575,10 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.SettingDefinition)), SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.SettingDefinition)),
KeyFieldName = "Id", KeyFieldName = "Id",
KeyFieldDbSourceType = DbType.Guid, KeyFieldDbSourceType = DbType.Guid,
SeedFilePath = SeedPathResolver.GetDataFilePath(listFormName),
SeedSyncInsert = true,
SeedSyncUpdate = true,
SeedSyncDelete = true,
DefaultFilter = DefaultFilterJson, DefaultFilter = DefaultFilterJson,
SortMode = GridOptions.SortModeSingle, SortMode = GridOptions.SortModeSingle,
FilterRowJson = DefaultFilterRowJson(), FilterRowJson = DefaultFilterRowJson(),
@ -5827,6 +5831,10 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.BackgroundWorker)), SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.BackgroundWorker)),
KeyFieldName = "Id", KeyFieldName = "Id",
KeyFieldDbSourceType = DbType.Guid, KeyFieldDbSourceType = DbType.Guid,
SeedFilePath = SeedPathResolver.GetDataFilePath(listFormName),
SeedSyncInsert = true,
SeedSyncUpdate = true,
SeedSyncDelete = true,
DefaultFilter = DefaultFilterJson, DefaultFilter = DefaultFilterJson,
SortMode = GridOptions.SortModeSingle, SortMode = GridOptions.SortModeSingle,
FilterRowJson = DefaultFilterRowJson(), FilterRowJson = DefaultFilterRowJson(),
@ -5873,7 +5881,13 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new() { Order=1, ColCount=2, ColSpan=1, ItemType="group" }, new() { Order=1, ColCount=2, ColSpan=1, ItemType="group" },
new() { Order=2, ColCount=2, ColSpan=1, ItemType="group" }, new() { Order=2, ColCount=2, ColSpan=1, ItemType="group" },
}), }),
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(), // Ekranda veri kaynagi alani yok; is varsayilan veri kaynaginda calisir.
InsertFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
new() { FieldName = "CreationTime", FieldDbType = DbType.DateTimeOffset, Value = "@NOW", CustomValueType = FieldCustomValueTypeEnum.CustomKey },
new() { FieldName = "CreatorId", FieldDbType = DbType.Guid, Value = "@USERID", CustomValueType = FieldCustomValueTypeEnum.CustomKey },
new() { FieldName = "Id", FieldDbType = DbType.Guid, Value = "@NEWID", CustomValueType = FieldCustomValueTypeEnum.CustomKey },
new() { FieldName = "DataSourceCode", FieldDbType = DbType.String, Value = SeedConsts.DataSources.DefaultCode, CustomValueType = FieldCustomValueTypeEnum.Value }
}),
FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] { FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
new() { FieldName = "IsActive", FieldDbType = DbType.Boolean, Value = "true", CustomValueType = FieldCustomValueTypeEnum.Value } new() { FieldName = "IsActive", FieldDbType = DbType.Boolean, Value = "true", CustomValueType = FieldCustomValueTypeEnum.Value }
}) })

View file

@ -29,19 +29,6 @@
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<None Remove="Migrations\HostData.json" />
<Content Include="Migrations\HostData.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Migrations\HostData.Dev.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Migrations\HostData.Production.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="Migrations\LanguagesData.json" /> <None Remove="Migrations\LanguagesData.json" />
<Content Include="Migrations\LanguagesData.json"> <Content Include="Migrations\LanguagesData.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>

View file

@ -9,7 +9,6 @@ using Microsoft.Extensions.Logging;
using Sozsoft.Platform.DynamicData; using Sozsoft.Platform.DynamicData;
using Sozsoft.Platform.Entities; using Sozsoft.Platform.Entities;
using Sozsoft.Platform.Enums; using Sozsoft.Platform.Enums;
using Sozsoft.Platform.ListForms;
using Sozsoft.Platform.Queries; using Sozsoft.Platform.Queries;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;

View file

@ -264,9 +264,11 @@ Bir çelişki varsa sıra: `ai.instructions.md` → `dotnet.instructions.md` →
`Abp.Identity.Permission{Groups,s}.json`; platformun kendi menü/yetki kayıtları da diğer liste `Abp.Identity.Permission{Groups,s}.json`; platformun kendi menü/yetki kayıtları da diğer liste
verisiyle aynı mekanizmadan (`ListFormSeedDataApplier`) geçer, ayrı bir seeder yoktur. `Order` verisiyle aynı mekanizmadan (`ListFormSeedDataApplier`) geçer, ayrı bir seeder yoktur. `Order`
alanı bağımlılık sırasını kurar: route → modül → menü, yetki grubu → yetki, ülke grubu → ülke → alanı bağımlılık sırasını kurar: route → modül → menü, yetki grubu → yetki, ülke grubu → ülke →
şehir → ilçe (`App.Definitions.{CountryGroup,Country,City,District}.json`); para birimi ve hitap şehir → ilçe (`App.Definitions.{CountryGroup,Country,City,District}.json`), bildirim tipi → kuralı
(`App.Definitions.{Currency,ContactTitle,AiBot}.json`) ile bildirim tipi → kuralı (`App.Notifications.Notification{Types,Rules}.json`). Para birimi, hitap, AI bot
(`App.Notifications.Notification{Types,Rules}.json`) da `HostData.json` yerine buradadır. Dosyalar ekranın (`App.Definitions.{Currency,ContactTitle,AiBot}.json`), ayar tanımları (`App.SettingDefinitions.json`)
ve zamanlanmış işler (`App.BackgroundWorkers.RecurringJobs.json`) da buradadır; `HostData.json`
kaldırıldı, `HostDataSeeder` yalnızca bağlantı cümlesi appsettings'ten gelen varsayılan veri kaynağını kurar. Dosyalar ekranın
anahtarını (`KeyFieldName`) kullanır; `Guid` anahtarlı satırın `Id`'si iş anahtarından türetilmiş anahtarını (`KeyFieldName`) kullanır; `Guid` anahtarlı satırın `Id`'si iş anahtarından türetilmiş
sabit bir GUID'dir, satır eklerken aynı kuralla üret. `App.Menus.Routes.json` dosyasına dokunma. sabit bir GUID'dir, satır eklerken aynı kuralla üret. `App.Menus.Routes.json` dosyasına dokunma.
- **Public site** → menü `Menu` tablosunda `ModuleId = "Pub"` altında (`PlatformConsts.PublicSite`); - **Public site** → menü `Menu` tablosunda `ModuleId = "Pub"` altında (`PlatformConsts.PublicSite`);

View file

@ -0,0 +1,43 @@
{
"ListFormCode": "App.BackgroundWorkers.RecurringJobs",
"KeyFieldName": "Id",
"GeneratedAt": "2026-09-18T06:18:50.444370Z",
"Rows": [
{
"Id": "2f4d1fac-313c-53a6-8f75-60e37c0b8025",
"Name": "Session Cleanup Worker",
"Cron": "*/5 * * * *",
"WorkerType": 4,
"BeforeSp": null,
"AfterSp": null,
"IsActive": true
},
{
"Id": "205dd86c-df6e-54c9-9aa9-72840ad2d84f",
"Name": "Notification Worker",
"Cron": "*/5 * * * *",
"WorkerType": 3,
"BeforeSp": null,
"AfterSp": null,
"IsActive": true
},
{
"Id": "7d6778b5-e0bd-5c07-afdf-f22d19c36b43",
"Name": "Backup Databases",
"Cron": "0 1 * * *",
"WorkerType": 5,
"BeforeSp": "Adm_T_DatabaseBackupAll",
"AfterSp": "Adm_T_DatabaseBackupFilesDeleteAll",
"IsActive": true
},
{
"Id": "70f4d9ef-6b9b-5a91-a0dc-23e6d251754c",
"Name": "AI Save DbTableColumns",
"Cron": "0 3 * * *",
"WorkerType": 2,
"BeforeSp": "Sas_H_ListFormFieldsDictionaryJson_SaveDbTableColumns",
"AfterSp": null,
"IsActive": true
}
]
}

File diff suppressed because one or more lines are too long