Architektonické vzory¶
Viz Průvodce vývojáře → Architektura a vzory pro kompletní dokumentaci s kódovými příklady.
Přehled vzorů¶
| Vzor | Kde | Popis |
|---|---|---|
| Result\<T> | Eva.Data | Obaluje výsledky servisních operací |
| BaseDataService\<T> | Eva.Data | Generický CRUD pro všechny entity |
| IDbContextFactory | Eva.Data | Thread-safe přístup k DbContext |
| NoTracking | Eva.Data | Pro všechny read operace |
| MVVM | Eva.Mobile | CommunityToolkit.Mvvm |
| WeakReferenceMessenger | Eva.Mobile | Komunikace mezi ViewModels |
| Blazor Components | Eva.Manager | DevExpress gridy a formuláře |
Multitenancy¶
Architektura: Shared Schema + Row-level TenantID — jedna PostgreSQL databáze, sdílené schéma dbo, každá doménová tabulka obsahuje sloupec TenantID.
Přepínač Enabled / Disabled¶
Chování řídí Multitenancy:Enabled v appsettings.json:
| Hodnota | Režim | Kdy použít |
|---|---|---|
false (výchozí) |
Single-tenant | On-premise instalace, vlastní server |
true |
Multi-tenant (SaaS) | Cloud, více organizací v jedné instanci |
Při Enabled = false se Global Query Filters nepřidávají — chování je identické se stavem před implementací multitenancy.
Klíčové komponenty¶
| Komponenta | Popis |
|---|---|
ITenantAware |
Interface; entita má long? TenantID |
ICurrentTenantAccessor |
Vrací TenantID z JWT claims (WebApi) nebo Identity claims (Manager) |
| EF Core Global Query Filters | EvaDataContext.OnModelCreating automaticky přidá WHERE TenantID = @current pro všechny ITenantAware entity |
BaseDataService.CreateAsync |
Auto-inject TenantID při vytváření záznamu |
Postup pro nové entity¶
Pokud přidáváš novou doménovou entitu, implementuj ITenantAware:
public class NovaEntita : ITenantAware
{
public long OID { get; set; }
public long? TenantID { get; set; }
// ...
}
BaseDataService.CreateAsync nastaví TenantID automaticky — žádná ruční akce není potřeba.
Dapper dotazy
Dapper dotazy (mimo EF Core) nepoužívají Global Query Filters. V metodách s Dapper je nutné přidat WHERE "TenantID" = @tenantId ručně.
Stored procedures — nahrazeny C# metodami (od v1.4.2)¶
Původní stored procedures byly nahrazeny C# metodami, které správně respektují TenantID filtr a zapisují audit log.
| Původní SP | Nová C# metoda | Poznámka |
|---|---|---|
sg_CreateInventoryItems |
InventoryDataService.CreateInventoryItemsFromLocationAsync(inventoryId, locationId, force) |
BFS přes Location hierarchii, vrací Result<int> s počtem položek nebo chybu CONFIRM_OVERWRITE |
sg_UpdateArticlesAfterInventory |
InventoryDataService.CloseInventoryWithAuditAsync(inventoryId) |
Označena [Obsolete] metoda CloseInventoryAsync |
sg_ExecuteArticleTransfer |
ArticleTransferDataService.ExecuteTransferWithAuditAsync(transfer) |
Vrací Result<TransferExecuteResult> s počty změněných lokací/stavů/uživatelů |
Staré metody (ExecuteAsync, CreateItemsAsync) jsou označeny [Obsolete] — nepoužívej je v novém kódu.
Dapper dotazy
Dapper dotazy (mimo EF Core) nepoužívají Global Query Filters. V metodách s Dapper je nutné přidat WHERE "TenantID" = @tenantId ručně.