Přeskočit obsah

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ě.