This commit is contained in:
Thanakarn Klangkasame
2025-09-30 11:01:02 +07:00
commit 92e614674c
182 changed files with 9596 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
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;
/// <summary>
/// โหลดค่า Tenants / Domains ที่ IsActive=true จาก meta.* ใส่ TenantMap ตอนสตาร์ต
/// และ bootstrap 'public' ถ้ายังไม่มี
/// </summary>
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<AppDbContext>();
var map = scope.ServiceProvider.GetRequiredService<TenantMap>();
var opt = scope.ServiceProvider.GetRequiredService<IOptions<AuthOptions>>().Value;
// 1) Load tenants (active เท่านั้น)
var tenants = await db.Set<TenantConfig>()
.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<TenantDomain>()
.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;
}