7.6 KiB
7.6 KiB
ADR 0002: Környezet-infrastruktúra (BaseUrl, szerver-adatkörnyezet, env-badge) keretbe emelése
Status
Accepted (2026-07-15) — végrehajtás lépésenként, per-lépés review-val; 1. lépés (BaseUrl → AcEnv) kész.
Context
- Kiváltó incidens: a fbHub és a loggerHub URL-je két külön forrásból élt (
AcHubConnection:Urlappsettings vs.FruitBankConstClient.BaseUrlkód-konstans) → a kliens a helyi nop helyett a PRODshop.fruitbank.hu-ra töltötte fel a logokat, órákig félrevitt nyomozással. A gyökér: az URL-infrastruktúra a fogyasztói const-osztályon, több igazságforrással. - Frissen épült env-lánc (2026-07): szerver-adatkörnyezet (PROD/DEV) kliens-oldali ismerete — first-connect kapu (await, fail-closed), szerver push-on-connect announce (env-váltás riasztással),
[PROD]/[DEV]title-badge, MSTest prod-guard. Élesben igazolva (DEV→PROD DB-váltás restarttal: announce + riasztás + title-váltás működött). Mindez FruitBank-oldalon született, pedig app-agnosztikus. - Redundancia: ugyanaz a fogalom kétszer — szerver
FruitBankConst.SetIsProd+ kliensFruitBankConstClient.IsProd; a teszt-guard, badge, jövőbeli destruktív-védelem mind külön-külön kötné be. - „IsProd" tengely-probléma: három független „prod"-tengely létezik — (1) build-konfiguráció (Debug/Release), (2) adat-környezet (melyik DB-katalógus), (3) hosting env (ASPNETCORE_ENVIRONMENT). A Debug-build + PROD-DB + Development-hosting kombináció élő teszttel bizonyított — egyetlen
IsProdnév ezeket összemosná. - Időzítés: a közös nagyker-réteg terv (VeggieVoyage) előtt; a ház-mintában van közvetlen precedens: GridLayout-roaming (framework-fenntartott tagek
AcSignalRTags9001x + framework-kliens-logika + fogyasztói endpoint-implementáció). - Scope IN: AcEnv állapotok (BaseUrl, IsProdDb); framework-tagek; kliens-base env-gépezet; hub-base announce; Blazor title-réteg; FruitBank-vékonyítás delegátokkal. Scope OUT: hosting-env tengely (később, read-only diagnosztika);
IsProdBuild(független bónusz);AcEnv.SetConfigurationconfig-egységesítés (ACCORE-LOG-T-N2D8 — szinergia, nem feltétel).
Decision
A környezet-infrastruktúra a keretbe kerül — a fogyasztó csak opt-inel, endpointot implementál és domain-konstansokat tart:
- Egy-forrás állapotok az
AcEnv-en (AyCode.Core):BaseUrl✅ (kész) ésIsProdDb(+Set/Hydrated/Changedesemény) — a szervernél a DB-katalógus-besorolás tölti (fail-closed), a kliens tükrözi (kapu + announce). A megosztás legitim: a kliensnek nincs saját DB-je, az ő adatkörnyezete a szerveré. - Tengelyenkénti nevezés:
IsProdDb(adat-tengely, wire-en szinkronizált) ≠IsProdBuild(build-tengely, processenkénti, SOHA nem megy wire-ra) ≠ hosting env. Nincs csupaszIsProda kereten. - Framework-fenntartott SignalR-tagek (
AcSignalRTags, a GridLayout 9001x mintájára): query 90020, announce 90021 — a fogyasztói 210/211 kivezetve (wire-váltás: kliens+szerver együtt-deploy). - Kliens-gépezet az
AcSignalRClientBase-be: first-connect kapu (await + dedup: pontosan 1 wire-hívás),EnsureEnvironmentAsync, fail-closed nyers query (timeout ≠default(bool)!), announce-elfogás a dispatch-ben (a fogyasztóiMessageReceivednem is látja). Opt-in:EnvironmentFeatureEnabled => falsedefault — más fogyasztók (pl. TourIAm) szervere nem ismeri az endpointot, default-on fail-closed törést okozna. - Hub-base announce: push-on-connect az
AcEnv.IsProdDb-ből (best-effort, a kapcsolatot nem dönti). - Blazor title-réteg (AyCode.Blazor.Components):
IAcAppTitleService+ browser-implementáció +<AcEnvironmentTitleBadge AppName="..."/>; MAUI-implementáció fogyasztói marad (a keretnek nincs MAUI-assemblyje). - Delegát-minta a fogyasztón: a
FruitBankConstClientérintett tagjai átlátszó delegátként maradnak (BaseUrl✅) — nulla törés, a hívóhelyek változatlanok, a felfedezhetőség megmarad (static class nem örökölhet → tag-migráció + delegát, nem literál öröklés). - Fogyasztónál marad: domain-konstansok (táblanevek, DomainDescription, email-sablonok), a katalógus-besorolás hívási helye, a query-endpoint implementáció (framework-taggel, GridLayout-minta), MAUI title-impl, AppName.
Consequences
Positive:
- Minden jövőbeli app (VeggieVoyage, közös nagyker-réteg) ingyen kapja a teljes env-láncot: kapu, announce+riasztás, badge, teszt-guard.
- A szerver/kliens redundancia megszűnik (egy állapot, egy esemény, sok olvasó); a BaseUrl-divergencia osztálya strukturálisan kizárt.
- Egységes fail-fast (hidratálatlan olvasás dob) + fail-closed (nem igazolható env = tiltás) szemantika keret-szinten.
Negative:
- Wire-tag átszámozás (210/211 → 9002x): kliens + szerver együtt-deploy kötelező a váltáskor.
AcEnvstatikus állapot: process-szintű — párhuzamos teszt-kollekciók osztoznak rajta (a jelen MSTest-felállásban nem gond, de tudni kell róla).- Az opt-in flag elfelejtése = a feature némán off — a keret-doksiban kiemelten dokumentálandó.
- A delegát-réteg fegyelmet kér: új infra-tag a KERETRE kerüljön, ne a fogyasztói const-ra.
Follow-ups required:
-
- lépés:
IsProdDb→AcEnv(FruitBank-oldaliIsProd-tagok delegátként).
- lépés:
-
- lépés:
AcSignalRTags90020/90021 + kliens-base gépezet + opt-in flag + teszt-guard helper a keretbe.
- lépés:
-
- lépés: hub-base announce.
-
- lépés: Blazor title-réteg + FruitBank-átkötés (MainLayout →
<AcEnvironmentTitleBadge>).
- lépés: Blazor title-réteg + FruitBank-átkötés (MainLayout →
- Bónusz/később:
IsProdBuild(+ opcionális build↔DB keresztellenőrzés, opt-in);AcEnv.SetConfiguration(N2D8); SignalR-intervallum konstansok configba (aSignarlRtypóval együtt kivezetve); MAUI-Android10.0.2.2BaseUrl-kérdés.
Alternatives considered
- Fogyasztói szinten hagyni (rejected): minden app újraimplementálná; a redundancia már most élő bugot szült (BaseUrl-divergencia).
- Teljes átnevezés homlokzat nélkül (a fogyasztói kód mindenhol
AcEnv.*-ot hív) (rejected): ~12 hívóhely churn, és a csapat a megszokott helyen (FruitBankConstClient) keresi az értéket — a delegát ugyanazt az egy-forrást adja nulla töréssel.- Reversibility: a delegát később bármikor kivezethető, ha a csapat átszokott.
- Egyetlen
AcEnv.IsProdnév tengely-bontás nélkül (rejected): a build/adat/hosting tengelyek összemosása — a Debug-build + PROD-DB élő eset bizonyítja, hogy függetlenek; a névnek a forrást kell mondania (IsProdDb). - Reconnect-enkénti újra-lekérdezés a push-on-connect helyett (rejected mint végállapot): működik, de ellentmond a „csak az elején 1x" elvnek; a push-on-CHANGE pedig konstrukciósan halott (az env-váltás csak restarttal jöhet, ami bontja a csatornát, amin a push utazna) — ezért query-once + announce-on-connect a végleges alak.
- Külön köztes osztály (
AcEnvironmentAwareSignalRClientBase) (rejected): felesleges hierarchia-szint; az opt-in flag azAcSignalRClientBase-en ugyanazt adja ceremónia nélkül.
Related
- Related ADRs: —
- Related TODOs/Issues:
ACCORE-LOG-T-N2D8(AcEnv.SetConfiguration — szinergia),ACCORE-LOG-T-D7S3(protokoll-diagnosztikai logger, átgondolandó),ACCORE-SBP-T-T5R2(protokoll-trace Trace-szintre),ACBLAZOR-GRID-T-E3B6(template-ErrorBoundary). - Precedens: GridLayout-roaming (framework-tag
AcSignalRTags9001x + fogyasztói endpoint) —Nop.Plugin.Misc.AIPlugin/docs/SIGNALR/README.md„Grid Layout Roaming". - External references: —