using AMREZ.EOP.Domain.Entities.Tenancy; using AMREZ.EOP.Domain.Shared.Tenancy; using AMREZ.EOP.Infrastructures.Data; using AMREZ.EOP.Infrastructures.Options; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; namespace AMREZ.EOP.Infrastructures.Tenancy; /// /// โหลดค่า Tenants / Domains ที่ IsActive=true จาก meta.* ใส่ TenantMap ตอนสตาร์ต /// และ bootstrap 'public' ถ้ายังไม่มี /// public sealed class TenantMapLoader : IHostedService { private readonly IServiceProvider _sp; public TenantMapLoader(IServiceProvider sp) => _sp = sp; public async Task StartAsync(CancellationToken ct) { using var scope = _sp.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); var map = scope.ServiceProvider.GetRequiredService(); var opt = scope.ServiceProvider.GetRequiredService>().Value; // 1) Load tenants (active เท่านั้น) var tenants = await db.Set() .AsNoTracking() .Where(x => x.IsActive) .ToListAsync(ct); foreach (var t in tenants) { map.UpsertTenant( t.TenantKey, new TenantContext { Id = t.TenantKey, Schema = string.IsNullOrWhiteSpace(t.Schema) ? t.TenantKey : t.Schema, ConnectionString = string.IsNullOrWhiteSpace(t.ConnectionString) ? null : t.ConnectionString, Mode = t.Mode } ); } // 2) Load domains (active เท่านั้น) var domains = await db.Set() .AsNoTracking() .Where(d => d.IsActive) .ToListAsync(ct); foreach (var d in domains) { if (d.IsPlatformBaseDomain) { map.AddBaseDomain(d.Domain); } else if (!string.IsNullOrWhiteSpace(d.TenantKey)) { map.MapDomain(d.Domain, d.TenantKey!); } } // 3) Bootstrap 'public' ถ้ายังไม่มี (กัน chicken-and-egg) if (!map.TryGetBySlug("public", out _)) { map.UpsertTenant( "public", new TenantContext { Id = "public", Schema = "public", ConnectionString = string.IsNullOrWhiteSpace(opt.DefaultConnection) ? null : opt.DefaultConnection, Mode = TenantMode.Rls } ); } } public Task StopAsync(CancellationToken ct) => Task.CompletedTask; }