Tapis.Core.Portal 1.0.2

dotnet add package Tapis.Core.Portal --version 1.0.2
                    
NuGet\Install-Package Tapis.Core.Portal -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tapis.Core.Portal" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tapis.Core.Portal" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Tapis.Core.Portal" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tapis.Core.Portal --version 1.0.2
                    
#r "nuget: Tapis.Core.Portal, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tapis.Core.Portal@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tapis.Core.Portal&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Tapis.Core.Portal&version=1.0.2
                    
Install as a Cake Tool

Tapis.Core.Portal

Müşteri portalı modül paketi (Reminders gibi: tek paket, ürün *.Services + *.Infrastructure projelerinden referanslar; *.Core referans vermez). Her ürün (HostelManagement, ServiceManagement) bu paketi kendi API'sinde barındırır ve kendi tenant veritabanında kendi tablolarını tutar. Paket tenant bağlantısı çözmez, CariHesap bilmez, veri okuma uçlarını ve maskelemeyi içermez: ihtiyaç duyduğu her şeyi port üzerinden alır.

İçerik ve yön tablosu

Klasör İçerik Bağımlı olamaz
Entities/ MusteriCihaz, MusteriCihazPlatformu, MusteriDogrulamaKaydi, MusteriRizasi Services, Ports, Persistence, AspNetCore
Ports/ IPortalVeritabani, PortalVeritabaniOturumu, IPortalMusteriKaynagi, IPortalYerelSaat, IPortalAydinlatmaKaynagi, IPortalBaglam Persistence, AspNetCore
Services/ PortalKod, kimlik/rıza/davet çekirdeği, DTO'lar, PortalDavetEpostasi; iç dikiş arayüzleri (internal) Persistence, AspNetCore, Microsoft.AspNetCore.*, Microsoft.EntityFrameworkCore.*, Tapis.Core.Infrastructure.*
Persistence/ EF yapılandırmaları, ApplyTapisPortalModel, depolar, IPortalVeritabani sarmalayıcısı (internal) AspNetCore
AspNetCore/ PortalToken şeması, çerez, controller tabanları, rıza kapısı, PortalUcDenetimi Persistence

Yön tablosu PortalPaketYuzeyiTests ile imza ve metot gövdesi (IL) taramasıyla doğrulanır. Pakette somut controller yoktur.

Kayıt noktaları

// *.Infrastructure/DependencyInjection.cs (Reminders'ın AddRemindersModule emsali)
services.AddTapisPortal(configuration, o =>
{
    o.UrunHarfi = 'H';                    // HM 'H', SM 'S'  (KALICI)
    o.AnahtarBaglami = "hm";              // HM "hm", SM "sm" (KALICI); ilk harf UrunHarfi'nin küçüğü olmak zorunda
    o.VarsayilanIssuer = "HostelManagement";
    o.VarsayilanAudience = "HostelManagement.Portal";
    o.VarsayilanCerezYolu = "/api/hostel/PortalKimlik";
});
services.AddScoped<IPortalVeritabani, UrunPortalVeritabani>();
services.AddSingleton<IPortalYerelSaat, UrunPortalYerelSaat>();
services.AddSingleton<IPortalAydinlatmaKaynagi, UrunAydinlatmaKaynagi>();

// *.HttpAPI/Program.cs
builder.Services.AddTapisPortalAspNetCore(builder.Configuration, builder.Environment);

// DbContext.OnModelCreating  (SIRA ZORUNLU)
builder.ApplyConfigurationsFromAssembly(...);
builder.ApplyRemindersModel();
builder.ApplyTapisPortalModel();
if (Database.IsNpgsql()) { builder.ConfigureXminConcurrency(); builder.ConfigureTurkishCaseInsensitive(); }

PortalSecenekleri varsayılansızdır ve kalıcıdır: UrunHarfi + AnahtarBaglami yayımdan sonra değişirse açık oturumlar ve davetler düşer. Eksik/uyumsuz değer başlangıçta InvalidOperationException; ürün portları kayıtlı değilse uygulama açılmaz.

Port sözleşmesi (güvenlik)

IPortalVeritabani (ihlali tenant karışmasıdır):

  • TenantIcinAcAsync(tenantId): yalnız bu sürecin uygulaması (Tenancy:UygulamaId) için, tenant'ı Master üzerinden çözer. Çözülemezse (tenant yok, başka uygulama, pasif, bağlantı yok) null döner; istisna sızdırmaz. Dönen oturumun TenantId'si istenen tenant olmak zorundadır: paket bunu doğrular, uyuşmazsa oturumu kapatıp reddeder.
  • IstektenAcAsync(): tenant'ı yalnız doğrulanmış principal'in TenantId claim'inden ve AppId eşitliğinden alır; header, sorgu dizesi, gövde asla.
  • İkisi de kurucuda (DI çözülürken) tenant çözmez ve bağlantı açmaz.
  • Açılan context denetim interceptor'ı olmadan kurulur (hash/özet işlemleri audit'e girmesin).
  • Paket istisnalarda yalnız tür adını loglar (ex.Message ve tenant DB adı asla); port da bağlantı dizesini mesajına koymamalıdır.

Diğer portlar: IPortalMusteriKaynagi (cari kart okuma, işletme adı, işlem geçmişi izi: kod/telefon/token içermeyen sabit metin; yazılamazsa akış bozulmaz), IPortalYerelSaat (işletme yerel saati), IPortalAydinlatmaKaynagi (ürüne özgü metin ve varsayılan sürüm; Portal:AydinlatmaSurumu önceliklidir).

PortalDavetIslemleri (IPortalDavetIslemleri) yetkisizdir: yalnız yetkili personel servisleri buna bağımlı olmalıdır (ürün mimari testi). Tenant parametresi yoktur; koda gömülen tenant IstektenAcAsync oturumunun tenant'ıdır.

Kayıt temizliği (1.0.1)

IPortalKayitTemizligi yetkisizdir ve IPortalDavetIslemleri'nden ayrıdır (o arayüze üye eklemek ürün test sahtelerini kırardı). Yetki ve çağrı yeri ürünün işidir; ürün mimari testi çağıranları sabitler: SaklamaTemizleAsync(tenantId) yalnız ürünün Provision ucundan (ClientToken, tenant eşitliği denetlenmiş), KartKayitlariniTemizleAsync(cariHesapId, ...) yalnız yetkili personel servisinden.

  • SaklamaTemizleAsync: tenant IPortalVeritabani.TenantIcinAcAsync ile açılır. Çözülemezse PortalSaklamaSonucu.Atlandi == true döner (başarı değildir: ürün ucu 2xx dışı bir kod dönmelidir). Eşikler TimeProvider UTC'sinden Portal:DavetSaklamaGun (30, en az 7) ve Portal:CihazSaklamaGun (90, en az 30) ile hesaplanır; altındaki değer başlangıçta hata verir. İdempotenttir.
  • KartKayitlariniTemizleAsync: tenant IstektenAcAsync'ten gelir; eşik yok. En az bir satır silindiyse işlem geçmişine tek satır yazılır ("Müşteri portalı kayıtları temizlendi: {n} cihaz, {m} davet"; yalnız sayılar). Kartın var olduğunu ve müşteri kartı olduğunu çağıran denetler.
  • KartCihazlariniSilAsync(cariHesapId, cihazIdler, ...) (1.0.2): personelin listede seçtiği cihazlardan yalnız kartın kapanmış cihazları silinir (aynı KartKapaliCihaz kriteri DELETE'te de taşınır); aktif cihaz, başka kartın cihazı ve olmayan kimlik atlanır. Davetlere dokunmaz. En az bir satır silindiyse işlem geçmişine tek satır ("Müşteri portalı: seçilen {n} cihaz kaydı silindi"). Liste boyutunu çağıran sınırlar.
  • Loglar yalnız tenant ve sayıları içerir; hash, ChallengeId, cihaz adı, IP ve cari hesap Id'si yazılmaz.

Tanımlar (tek kaynak: Services/PortalSaklamaKurallari.cs; iki yol için de geçerlidir, OlusturmaTarihi hiçbir kriterde yoktur):

Kavram Tanım Silinir mi
Açık davet !Tuketildi && IptalTarihi == null && SonGecerlilik > simdi Asla
Aktif cihaz IptalTarihi == null && YenilemeSonGecerlilik > simdi Asla
Otomatik: eski davet (Tuketildi && TuketimTarihi < e) \|\| IptalTarihi < e \|\| SonGecerlilik < e (e = şimdi − DavetSaklamaGun) Eşikten kesin eskiyse
Otomatik: eski cihaz (IptalTarihi != null && IptalTarihi < e) \|\| (IptalTarihi == null && YenilemeSonGecerlilik < e) (e = şimdi − CihazSaklamaGun) Eşikten kesin eskiyse
Elle: kartın kapalı daveti açık olmayan (tüketilmiş, iptal edilmiş ya da süresi dolmuş) Evet
Elle: kartın kapalı cihazı iptal edilmiş ya da YenilemeSonGecerlilik <= simdi − 5 dk (yenilemeyle yarışmaya karşı pay) Evet

Silme koşulu, yapılandırmadan bağımsız olarak kaydın kapalı olmasını ister: otomatik kriterler eşik karşılaştırmasına ek olarak açık "kapalı" (açık davet / aktif cihaz değil) koşulunu da taşır. Saklama günleri kullanım anında da asgari değerle denetlenir; altındaysa InvalidOperationException fırlar ve hiçbir şey silinmez.

MusteriRizalar (rıza) hiçbir yolda silinmez; İşlem Geçmişi ürünündür. Silme 1000'lik partilerle yapılır: önce partinin Id'leri seçilir, sonra DELETE kriterin tamamını yeniden taşır (PostgreSQL kriteri satırın güncel hâlinde yeniden denetler; seçimle silme arasında yenilenen, iptal edilen ya da bağlanan satır silinmez).

Ürün kontrol listesi

  1. PortalSecenekleri tüm alanlar; HM H/hm, SM S/sm.
  2. ApplyTapisPortalModel sırası: ConfigureXminConcurrency/ConfigureTurkishCaseInsensitive'ten önce.
  3. 3 FK CariHesaplar (Restrict): MusteriDogrulamaKayitlari, MusteriCihazlar, MusteriRizalar (CariHesapId); paket FK taşımaz.
  4. IPortalVeritabani sözleşmesi (yukarıda), audit interceptor'sız.
  5. Maskeleme / allow-list DTO: veri uçları üründe; iç alan sızıntısı reflection testi ürün işi.
  6. Somut PortalController / PortalKimlikController aynı adla PortalControllerBase / PortalKimlikControllerBase'ten türer; veri uçları PortalControllerBase altında rıza kapısıyla gelir. Ürün testi PortalUcDenetimi.Dogrula(endpointDataSource) çağırır (hata listesi boş olmalı).
  7. Hız sınırı politikaları ürün kaydeder: PortalHizSiniri.KimlikPolitikasi / VeriPolitikasi, bölüm anahtarları KimlikAnahtari / VeriAnahtari. UseRateLimiter, UseAuthentication ve UseAuthorization'dan SONRA çağrılmalıdır (cihaz bölümü doğrulanmış claim'e bakar).
  8. PortalJwt:Key ürüne özgü, ortam değişkeniyle; Master (MasterJwt:Key), tenant (Tenancy:SymmetricKey), istemci (Tenancy:ClientSecret) ve diğer ürünün anahtarından farklı.
  9. Portal:CerezYolu dar (/api/<ürün>/PortalKimlik); korumalı ortamda başlangıç denetimi zorunlu kılar.
  10. Tek kopya varsayımı: negatif tenant önbelleği süreç içidir (singleton örnek); çok kopyada kopya başına tutulur, güvenlik kararı değildir.
  11. Gateway'de ürün başına uç listesi (HM Konaklamalar, SM Servisler).
  12. Tenancy:UygulamaId geçerli Guid.
  13. PortalAyarlari Portal bölümü, PortalJwtAyarlari PortalJwt bölümü; paket Tenancy:UygulamaId, MasterJwt:*, Tenancy:* anahtar adlarını okur.

Hata kodları ve iletiler

100xx kodları SharedErrorCodes'tan (not bulundu 10001, doğrulama 10009, iş kuralı 10020); pakette yalnız farklılar: PortalHataKodlari.Unauthorized = 10010 (HM değeri, SharedErrorCodes.Unauthorized = 10006'dan farklıdır) ve RizaGerekli = 12050 (portal ortak; ürün enum'ları başka anlamda kullanmaz). İletiler düz Türkçe sabit (PortalIletileri), yerelleştirme yok.

Bağımlılıklar

Tapis.Core.Shared (2.0.20), Tapis.Core.Verification (>= 1.0.0), EF Core 10.0.10, Npgsql EF 10.0.0, Microsoft.AspNetCore.Authentication.JwtBearer 10.0.10 (public yüzeyde JwtBearer tipi yoktur).

Tapis.Core.Infrastructure'a bağımlılık yoktur; HarfDuyarli anotasyonu (Tapis:HarfDuyarli) pakette tekrarlanır (PortalHarfDuyarli), Infrastructure ile eşitliği testle kilitlidir (PortalHarfDuyarliTests); host'un ConfigureTurkishCaseInsensitive için Infrastructure >= 1.0.6 kullanması kendi şema kuralıdır. Derlenmiş pakette Tapis.Core.Infrastructure assembly başvurusu da yoktur (test kilitli).

Hata davranışı ve başlangıç sıkılığı

  • Bağlantı ilk sorguda açılır: EF bağlantıyı context oluşunca değil ilk komutta açar, bu yüzden "database tenant_x does not exist" gibi sürücü hataları ilk depo çağrısında çıkar. Paket bunları yakalar: JWT doğrulamasında context.Fail (401), Baglan/Yenile yolunda HM'deki genel red kodları (400 / 401), Cikis 204; log'da yalnız istisna tür adı.
  • PortalJwt:Issuer/Audience doluysa PortalSecenekleri.VarsayilanIssuer/VarsayilanAudience ile aynı olmak zorundadır (başlangıç hatası).
  • PortalKod kurucusu ürün harfi ile bağlam eşleşmesini PortalSecenekleri.Dogrula ile aynı kuralla doğrular.
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 238 10/22/2026
1.0.1 80 10/22/2026
1.0.0 75 10/21/2026

1.0.2: secili cihaz silme (eklemeli): IPortalKayitTemizligi.KartCihazlariniSilAsync; listeden secilen cihazlardan yalniz kartin kapanmis (iptal/suresi dolmus) cihazlari silinir, aktif cihaz silinmez, davetlere dokunulmaz; islem gecmisine yalniz sayi. Sema degismez. 1.0.1: portal kayit temizligi (eklemeli): IPortalKayitTemizligi (SaklamaTemizleAsync otomatik saklama, KartKayitlariniTemizleAsync elle temizlik; yetkisiz), PortalSaklamaSonucu, Portal:DavetSaklamaGun (30, en az 7) ve Portal:CihazSaklamaGun (90, en az 30). Acik davet, aktif cihaz ve riza kayitlari silinmez. Sema degismez. 1.0.0: ilk surum. Musteri portali modulu (HostelManagement portal cekirdeginin paketlenmis hali): MusteriCihaz/MusteriDogrulamaKaydi/MusteriRizasi entity'leri ve ApplyTapisPortalModel, HMAC etiketli davet kodu (PortalKod, urun harfi + HKDF baglami), kimlik/riza/davet cekirdegi, PortalToken JWT semasi ve Portal policy, HttpOnly cerez, controller taban siniflari ve riza kapisi filtresi, PortalUcDenetimi. Urun IPortalVeritabani, IPortalMusteriKaynagi, IPortalYerelSaat, IPortalAydinlatmaKaynagi saglar. Kalici sabitler (HM: H + hm) hicbir surumde degismez.