Update GrossWeight logic, add wholesale framework plan
Changed GrossWeight in OrderItemDto to sum GrossWeight instead of NetWeight and updated its ToonDescription. Added WHOLESALE_FRAMEWORK_PLAN.md as a draft design summary for a future shared wholesale framework, outlining architecture, layering, and migration strategy.
This commit is contained in:
parent
451e029869
commit
5c20b3a04c
|
|
@ -79,12 +79,12 @@ public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
[ToonDescription(BusinessRule = "get => double.Round(OrderItemPallets.Sum(x => x.NetWeight), 1)")]
|
[ToonDescription(BusinessRule = "get => double.Round(OrderItemPallets.Sum(x => x.GrossWeight), 1)")]
|
||||||
public double GrossWeight
|
public double GrossWeight
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return double.Round(OrderItemPallets.Sum(x => x.NetWeight), 1);
|
return double.Round(OrderItemPallets.Sum(x => x.GrossWeight), 1);
|
||||||
//CommonHelper.To<double>(GenericAttributes.SingleOrDefault(x => x.Key == nameof(IMeasuringGrossWeight.GrossWeight))?.Value ?? "0");
|
//CommonHelper.To<double>(GenericAttributes.SingleOrDefault(x => x.Key == nameof(IMeasuringGrossWeight.GrossWeight))?.Value ?? "0");
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,324 @@
|
||||||
|
# Wholesale Framework — tervezési összefoglaló (handoff-mag)
|
||||||
|
|
||||||
|
> **Status:** Proposed (Draft) — 2026-07-14
|
||||||
|
> **Jelleg:** Ez NEM ADR és NEM végleges doksi. Provizórikus gondolkodási összefoglaló, ideiglenesen a
|
||||||
|
> FruitBankHybridApp `docs/` mappájában. A tárgyalt Wholesale framework-repo **még nem létezik**, a neve
|
||||||
|
> **változhat**, és **semmilyen döntés nem végleges**. Amint a repo létrejön, ez a fájl a forrása a rendes
|
||||||
|
> struktúrának (ADR-ek + repo-doksik) — lásd a záró "Mi lesz ebből" szakaszt.
|
||||||
|
> **Előzmény:** két korábbi session terv-összegzése (app-oldal + nop-plugin-oldal) + ez a session konszolidációja.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Cél és kiváltó ok
|
||||||
|
|
||||||
|
A FruitBank (zöldség-gyümölcs nagyker, nopCommerce-plugin + Blazor Hybrid app) mellé indul a **VeggieVoyage**
|
||||||
|
(veggievoyage.hu), egy közel azonos nagyker-rendszer apró eltérésekkel. Emellett **több további zöldséges nagyker
|
||||||
|
érdeklődő** is van a rendszerre. Cél: egy **közös nagyker-framework réteg**, amelyből minden nagyker-termék
|
||||||
|
származik, hogy egy új terméknél a lehető legkevesebbet kelljen újraírni.
|
||||||
|
|
||||||
|
Jelenleg (2026-07-14) csak a FruitBank-oldal létezik; sem a Wholesale-repo/könyvtár, sem a VeggieVoyage-projekt
|
||||||
|
nincs még létrehozva.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Architektúra-döntés: base-class minta (maximalista pull-up)
|
||||||
|
|
||||||
|
**Öröklés-alapú, NEM típus-átköltöztetés.** A közös rétegbe **szinte minden osztály felkerül** — abstract vagy
|
||||||
|
virtual formában (base class-ok, virtual method-ok/property-k). A konkrét (gyakran szinte üres) záró osztályok a
|
||||||
|
termék-repóban élnek és származnak a base-ből.
|
||||||
|
|
||||||
|
- **Amit lehet, a közös rétegben implementálunk** (virtual default üzleti logika); ami termék-specifikus, az a
|
||||||
|
származtatottban override-ol.
|
||||||
|
- **Az eltérés a fejlesztés közben derül ki, nem előre.** Default: minden felmegy közös virtual defaultként. Amikor
|
||||||
|
a VeggieVoyage (vagy egy későbbi termék) fejlesztése **bizonyítja**, hogy valami mégsem közös, akkor az a member
|
||||||
|
lemegy ("demote") a záró rétegbe. Amíg csak egy termék használ egy membert, a lehúzása senkit nem tör.
|
||||||
|
- Ez a **meglévő házi minta** kiterjesztése: `MgStockTakingItem<TStockTaking, TProduct> : MgEntityBase`,
|
||||||
|
`PartnerBase → CargoPartner`, `MeasuringItemPalletBase → 3 pallet`, `AcConst` abstract-constants minta.
|
||||||
|
|
||||||
|
### Miért ez nyert (a mozgatásos alternatívával szemben)
|
||||||
|
|
||||||
|
| Aggály | Feloldás |
|
||||||
|
|---|---|
|
||||||
|
| Tábla-nevek (`fbShipping`…) | `[Table(Name=…)]` a **származtatott** osztályon, termék-konstansból — nincs migráció, nincs runtime-konfig |
|
||||||
|
| AcBinary wire-compat (`SignalDataType` = AssemblyQualifiedName) | Konkrét típusok **helyben maradnak** a termék-assembly-ben → AQN változatlan, nincs lockstep-kényszer |
|
||||||
|
| `AcBinaryForcedInit` (AssemblyLoadContext-quirk) | Generált szerializálók a konkrét típusokra → meglévő ForceRegister érintetlen |
|
||||||
|
| LinqToDB `NameCompatibility` | Termék-pluginban marad, konkrét típusokra |
|
||||||
|
|
||||||
|
**Következmény:** a FruitBank-oldal minden pull-up lépésnél **fordítás-azonos** marad; a VeggieVoyage viszont
|
||||||
|
"majdnem készen" indul, mert a scaffold záró osztályai szinte üresek.
|
||||||
|
|
||||||
|
### Új DB + új plugin a VeggieVoyage-nek
|
||||||
|
|
||||||
|
- A VeggieVoyage **teljesen új adatbázist** kap → a `[Table(Name=…)]` (identitás) így is a záró rétegen marad; a
|
||||||
|
base hordozza az összes `[Column]`-t, a tábla-NÉV termék-konstans. A `vv`/`fb` prefix szabad termék-döntés, nem
|
||||||
|
framework-ügy.
|
||||||
|
- A VeggieVoyage **új nopCommerce-plugin** is → nem csak az üzleti logikát, hanem a **plugin-infrastruktúrát** is
|
||||||
|
base-formában ki kell szervezni: install/uninstall, locale-resource telepítés, admin-menü regisztráció,
|
||||||
|
settings-defaultok, schedule task-ok, `MgwPluginStartupBase` virtual DI-regisztrációkkal. A Veggie-pluginban
|
||||||
|
ideálisan csak `plugin.json` (SystemName), a záró osztályok és a konstansok maradnak.
|
||||||
|
- **Zöldmezős schema-generálás:** a friss install-nak a teljes sémát egy menetben kell felhúznia üres DB-n (a
|
||||||
|
FruitBank táblái évek alatt, lépésenként jöttek létre). Ellenőrizendő, hogy a meglévő install/tábla-létrehozó út
|
||||||
|
(MgDbContext-vonal) teljes és determinisztikus-e nulláról — GenericAttribute-kulcsok és seed-adatok is.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Rétegzés / célstruktúra
|
||||||
|
|
||||||
|
Rétegtérkép a legáltalánosabbtól (legmélyebb) a legspecifikusabbig:
|
||||||
|
|
||||||
|
```
|
||||||
|
L0 AyCode.Core (Ac*) + AyCode.Blazor — tech-framework, domain-mentes, bármely projekt
|
||||||
|
SignalR, AcBinary + SourceGenerator, logolás, NAV/EKÁER-protokoll, MgGrid/komponens-base-ek
|
||||||
|
L2 Mango.Nop Libraries (Mg*) — nop-generikus, nop-VERZIÓFÜGGŐ (4.70 mappa alatt)
|
||||||
|
L2.5 Mango.Nop.Wholesale.Core / .Services — nagyker-domain, nop-VERZIÓFÜGGŐ, prefix: Mgw
|
||||||
|
(Libraries alatt, 4.70) entitás-bázisok, DbTable/DbContext-bázisok, endpoint-bázisok, EKÁER-riport
|
||||||
|
L2.5 Wholesale.Common / .Common.Server — nagyker-domain, nop-verzió-FÜGGETLEN (ÚJ repo)
|
||||||
|
domain-modell, interfészek, enumok, DTO-bázisok, SignalR-tag core-tartomány, mérés-helperek,
|
||||||
|
service-bázisok (a Mango.Nop DLL-jei UTÁN build-el — pont mint ma a Common-ok)
|
||||||
|
L2.5 Wholesale.Shared (Blazor, ÚJ repo) — grid-/komponens-base-ek, SignalR-kliens base
|
||||||
|
L3 Termékek: FruitBank / VeggieVoyage / … — vékony záró osztályok + identitás + termék-delta
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kétotthonos base-réteg — a besorolás kritériuma
|
||||||
|
|
||||||
|
A "hova kerüljön" kritérium **NEM az, hogy használ-e Mango.Nop-ot** (a Common-ok ma is jogosan használják),
|
||||||
|
hanem hogy **nop-verziófüggő-e**:
|
||||||
|
|
||||||
|
- **nop-verziófüggő** (Mg*/linq2db/nopCommerce-entitásokra épül, a nop belső API-ját tükrözi) → `Mango.Nop.Wholesale`
|
||||||
|
(Libraries, verziómappa alatt).
|
||||||
|
- **nop-verzió-független** nagyker-domain → `Wholesale.Common` / `.Common.Server` (új repo).
|
||||||
|
|
||||||
|
> Fontos: a mai `FruitBank.Common.Server` "nopCommerce integration"-t is tartalmaz. Pull-upnál a nop-ot érintő
|
||||||
|
> részek a `Mango.Nop.Wholesale.Services`-be mennek, nem a `Wholesale.Common.Server`-be. A kritérium szigorúan
|
||||||
|
> "nop-verziófüggő?", nem projektnév.
|
||||||
|
|
||||||
|
### Build-lánc (interleaved — ma is így épül, csak beékelődik két réteg)
|
||||||
|
|
||||||
|
```
|
||||||
|
AyCode → Mango.Nop Libraries → Mango.Nop.Wholesale.Core (entitás-bázisok)
|
||||||
|
→ Wholesale.Common / .Common.Server (domain- és service-bázisok, Mgw.Core-ra épülve)
|
||||||
|
→ Mango.Nop.Wholesale.Services (DbTable/DbContext/endpoint-bázisok, Wholesale.Common-ra épülve)
|
||||||
|
→ termékek (HybridApp + plugin)
|
||||||
|
```
|
||||||
|
|
||||||
|
Ezért a `Mango.Nop.Wholesale` **Core/Services szétvágása kötelező**, nem ízlés: a Core a Wholesale.Common ALATT,
|
||||||
|
a Services FELETTE — különben körkörös függőség.
|
||||||
|
|
||||||
|
### Per-app bin-profil
|
||||||
|
|
||||||
|
A referencia-minta már ma per-app build-profilos: az AyCode és Mango.Nop.Core DLL-jei
|
||||||
|
`bin\FruitBank\$(Configuration)\net9.0`-ból jönnek (HintPath). Lesz `bin\VeggieVoyage\…` is. TFM-ek: Common=net9.0
|
||||||
|
(WASM-kliens is fogyasztja, szerver-only függőség nélkül), Shared=net10.0. A `FruitBankHybrid.Shared.Common`
|
||||||
|
projekt ma üres váz — felhasználható.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Placement-kánon (a legfontosabb szabály)
|
||||||
|
|
||||||
|
**A kód a legmélyebb rétegbe kerül, amelynek a domain-hatóköre még jogosan magába foglalja a fogalmat.**
|
||||||
|
|
||||||
|
Két teszt együtt dönt:
|
||||||
|
|
||||||
|
1. **Kimenő-függőség teszt (szükséges, objektív):** egy típus akkor *mehet* mélyebbre, ha a függőségei engedik.
|
||||||
|
AyCode-ba csak az kerülhet, ami *nulla* nagyker/nop fogalomra hivatkozik (a `using`-ok és hivatkozott típusok
|
||||||
|
döntik el, nem érzés). Ez adja meg, milyen mélyre **mehetne** a kód.
|
||||||
|
2. **Hatókör-kohézió teszt (elégséges, logikai):** hova **való** a fogalom. Ez megállíthatja a kódot, mielőtt a
|
||||||
|
függőségei alapján túl mélyre süllyedne.
|
||||||
|
|
||||||
|
**Kanonikus példa — tálca/tare-aritmetika:** tiszta `decimal`-matematika, nulla domain-függőséggel *lefordulna*
|
||||||
|
AyCode.Core-ban. Mégis a **Wholesale**-be való, mert a fogalom hatóköre "nagyker-mérés". Core-ba nem azért nem
|
||||||
|
kerül, mert nem fordulna, hanem mert a Core hatóköre (*minden* projekt) tágabb, mint a fogalom valódi közönsége.
|
||||||
|
|
||||||
|
### Két hibamód
|
||||||
|
|
||||||
|
- **Túl mélyre** (nagyker-fogalom Core-ban): a univerzális réteg beszennyeződik, a nagyker-fejlesztő nem is ott
|
||||||
|
keresi. Ez a *csábító* hiba ("ez matek, mehet Core-ba"). **Fordul, csak koszol** → csendes hiba, ezt kell fogni.
|
||||||
|
- **Túl sekélyen** (a termékben): redundancia — a következő zöldséges projekt újraírja. Ezt a framework szünteti meg.
|
||||||
|
|
||||||
|
Iránytű: a redundancia-kerülés **lefelé** (általánosabb felé) tol; a hatókör-kohézió a **fék**. A hiba-irány
|
||||||
|
aszimmetrikus: túl mélyre tett domain-kód *nem fordul* (a rendszer önvédő); túl magasra tett specifikus kód
|
||||||
|
*fordul, csak koszol*. Ezért a default "a legmélyebb, ami fordul", és a **feljebb-tétel** az, ami indoklást igényel.
|
||||||
|
|
||||||
|
### Redundancia-ellensúly (hogy a DRY ne forduljon visszájára)
|
||||||
|
|
||||||
|
"Ne írd le kétszer ugyanazt a **fogalmat**" — NEM "vonj össze mindent, ami hasonlít". Ha két dolog csak *véletlenül*
|
||||||
|
hasonlít (nem ugyanaz a fogalom) és közös base-be húzod, hamis csatolást hozol létre — a legrosszabb fajta
|
||||||
|
redundancia-"javítás". A **rule-of-two/N** a védőkorlát: legalább két valódi fogyasztó bizonyítsa, hogy a közösség
|
||||||
|
valódi és nem esetleges.
|
||||||
|
|
||||||
|
### Identitás soha nem megy fel (checklist a záró réteghez)
|
||||||
|
|
||||||
|
- `[Table(Name=…)]` tábla-nevek (termék-konstansból)
|
||||||
|
- `[AcBinarySerializable]` konkrét típusok
|
||||||
|
- SignalRTag termék-tartománybeli értékei
|
||||||
|
- plugin SystemName, route-URL-ek, locale-fájlok, branding
|
||||||
|
- appsettings **értékek** (nem a séma)
|
||||||
|
|
||||||
|
### Hol él a kánon (doc-layering)
|
||||||
|
|
||||||
|
A placement-kánon kánonja a legmélyebb rétegben (AyCode.Core) él; minden alsóbb réteg copilot-instructions.md-je
|
||||||
|
erre **mutat** + a saját befogadási kritériumát mondja ki (AyCode = "domain-mentes"; Wholesale = "nagyker-domain,
|
||||||
|
nop-verzió-független"; Mango.Nop = "nop-verziófüggő"). A doksi vigyen 3-4 **levezetett** határeset-példát (a
|
||||||
|
tare-képlet a kanonikus) — az absztrakt szabály nem elég horgony, a *gondolkodásmódot* a példák tanítják.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Zöldség-kalibráció + jövőbeli továbbbontás (elhalasztott)
|
||||||
|
|
||||||
|
Az érdeklődők **egyelőre mind zöldséges nagykerek**, közel azonos igénnyel. Ezért a Wholesale-réteg **mai valódi
|
||||||
|
hatóköre "zöldséges nagyker"**, nem "általános nagyker" — a "zöldséges-specifikus vs. általános-nagyker" hasítás
|
||||||
|
**jövőbeli, szándékosan még meg nem tett rétegvágás**.
|
||||||
|
|
||||||
|
Következmények:
|
||||||
|
- **A zöldséges-specifikusság ma NEM tolja fel a kódot a termékbe.** Egy kimondottan zöldséges logika (érettség,
|
||||||
|
osztályozás, zöldség-mérés) jogosan a framework-rétegé — bármely másik zöldséges nagyker újra használná. Óvakodni
|
||||||
|
attól, hogy "ez túl zöldség-specifikus, hagyjuk a termékben" — ez **kiéheztetné a framework-öt**.
|
||||||
|
- **NE annotáld előre** a "zöldséges vs. általános" varratot — nincs második nem-zöldséges domain, ami bizonyítaná,
|
||||||
|
tehát bármilyen jelölés spekuláció (ugyanaz a korai-triázs-csapda). A jövőbeli *nem*-zöldséges nagyker fogja
|
||||||
|
felfedni a varratot, ugyanúgy, ahogy a Veggie-scaffold felfedi a termék-hardcode-ot.
|
||||||
|
- Ha egyszer jön nem-zöldséges nagyker: ugyanaz a mechanikus pull-up egy szinttel lejjebb (pl. `Trade`/`Distribution`
|
||||||
|
réteg), a Wholesale maga válik vékony leszármazottá. Mivel minden abstract/virtual, ez is fordítás-azonos lesz.
|
||||||
|
- A rétegnév lehet jövő-álló ("Wholesale", prefix `Mgw`), de a doksinak ki kell mondania a mai zöldség-kalibrációt,
|
||||||
|
hogy egy jövőbeli session ne nézze design-hibának és ne kezdjen kéretlenül általánosítani.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. nopCommerce-verzió probléma + karantén-stratégia
|
||||||
|
|
||||||
|
**Kiváltó félelem:** a nopCommerce design sok hibája miatt gyakran nop-kódot kell másolni/átírni → nagyon nehéz a
|
||||||
|
FruitBank upgrade-je. A VeggieVoyage viszont már **új nop-verzióval** készülne. Kockázat: ha a catalog-táblák
|
||||||
|
változtak, az gond lehet.
|
||||||
|
|
||||||
|
**A rétegzés maga a válasz — csak explicit szabályként kell kimondani:**
|
||||||
|
|
||||||
|
1. **A verziófüggés karanténban van.** A `Mango.Nop Libraries` + `Mango.Nop.Wholesale` definíció szerint
|
||||||
|
nop-verziófüggő (ezért él verziómappa alatt). Új nop-verziónál **ez a két réteg forkol** (`4.90/Libraries`,
|
||||||
|
`4.90/…Wholesale`), és a per-app bin-profil ezt kiszolgálja: a FruitBank a 4.80-as fork ellen build-el, a
|
||||||
|
VeggieVoyage a 4.90-es ellen — **ugyanabból a Wholesale-forrásból**. Feltétel: a Mg*/Mgw típusok **publikus
|
||||||
|
felülete** forrás-kompatibilis maradjon a forkok között. A Mango.Nop réteg így **anti-korrupciós réteg**: a nop
|
||||||
|
churn a fork belsejében marad, a Wholesale nem látja.
|
||||||
|
|
||||||
|
2. **Másolt/átírt nop-kód** (a tényleges upgrade-fájdalom): jól megjelölt helyre (pl. `NopOverrides/` a verziófüggő
|
||||||
|
rétegben), mindegyik mellé kötelező jegyzet: *miért kellett, melyik nop-fájlból, mit kell újranézni port-nál*.
|
||||||
|
Így a 4.90-port checklist lesz, nem régészet.
|
||||||
|
|
||||||
|
3. **Catalog-tábla drift:** (a) minden catalog-hozzáférés a verziófüggő rétegben, a Wholesale csak interfészt/DTO-t
|
||||||
|
lát; (b) a **GenericAttribute-minta** (IsMeasurable, Tare, AverageWeight, IncomingQuantity, NetWeight mind GA-ban,
|
||||||
|
nem catalog-oszlopban) verzió-rezisztens — a GA a nop legstabilabb mechanizmusa. A kitettség arra szűkül, amit
|
||||||
|
tényleg a Product/Order/Customer **natív oszlopaiból** olvastok.
|
||||||
|
|
||||||
|
4. **A két nagy műveletet ne egyszerre.** Előbb pull-up a **mostani** nop-verzión (FruitBank fordítás-azonos, a
|
||||||
|
Veggie-scaffold ugyanazon a verzión bizonyítja a framework-öt), **utána** a verziófüggő réteg portja az új
|
||||||
|
verzióra. Egyszerre futtatva minden hiba kétesélyes lenne ("framework-bug vagy port-bug?").
|
||||||
|
|
||||||
|
5. **Reframe:** a VeggieVoyage **kifizeti a FruitBank upgrade-adósságát**. Ha a Veggie kikényszeríti a
|
||||||
|
Mango.Nop(+Wholesale) új-verziós portját, a FruitBank későbbi upgrade-je már csak "bin-profil átállítás a kész
|
||||||
|
forkra + termékrétegbeli maradék".
|
||||||
|
|
||||||
|
**Konkrét vizsgálat, amivel a catalog-félelem végessé tehető** (még nem futott le):
|
||||||
|
- (a) **Kitettség-térkép:** végigmenni a plugin + Libraries kódon, mely nop-entitásokat/service-eket/natív
|
||||||
|
oszlopokat használtok közvetlenül.
|
||||||
|
- (b) **Séma-diff** a cél nop-verzióval, a ténylegesen használt táblákra (a nop upgrade-migrációiból).
|
||||||
|
→ Cél nop-verzió megadása után elvégezhető.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Eltérés-taxonómia: settings vs. override (rule-of-N)
|
||||||
|
|
||||||
|
Több terméknél a "rule-of-two" **rule-of-N** lesz. Ökölszabály:
|
||||||
|
|
||||||
|
- **parametrikus eltérés → settings/config** (EkaerSettings-minta, DI mögé)
|
||||||
|
- **strukturális eltérés → virtual override**
|
||||||
|
- **identitás → abstract const a záró rétegen**
|
||||||
|
|
||||||
|
Ha ugyanazt a metódust minden termék máshogy override-olja, az annak a jele, hogy **paraméternek** kellett volna
|
||||||
|
lennie. Minél több megy settings-be, annál kevesebb kódot kell egy új terméknél megírni. Nem kell előre kitalált
|
||||||
|
settings-taxonómia — **demote-to-settings on evidence**, ugyanaz a workflow, mint a kódnál: minden fent marad közös
|
||||||
|
defaultként, és az első valódi termék-eltérésnél dől el, override vagy setting lesz.
|
||||||
|
|
||||||
|
**Demote-ablak szűkül N-nel:** amíg egy termék használ egy membert, a lehúzása fájdalommentes; a 2. fogyasztónál már
|
||||||
|
közös és fent marad. Ezért a Veggie-fázisban agresszíven demote-olni.
|
||||||
|
|
||||||
|
**Termék-scaffold = template.** A Veggie "új termék felhúzása" maga is termék: minden scaffold-lépést checklistként
|
||||||
|
dokumentálni a Wholesale-repo doksijába — a 3. terméknél már ez A termék-létrehozási folyamat. (Nem kell most
|
||||||
|
dotnet-template; a jól dokumentált Veggie-scaffold az első draft.)
|
||||||
|
|
||||||
|
**Framework-evolúció N fogyasztóval:** minden wholesale-változás N terméket érint. Per-app bin-profil jó izoláció
|
||||||
|
(mindenki a saját build-jét pinneli), de wire-formátumot (AcBinary) és base-séma `[Column]`-okat érintő változásnál
|
||||||
|
`CONSUMERS.md` szerinti végigfuttatás kell (P1).
|
||||||
|
|
||||||
|
**SignalRTag-tartomány kiosztás** (hogy két termék soha ne ütközzön közös infrastruktúrán): közös core-tartomány +
|
||||||
|
termék-tartományok, pl. FruitBank 0–9999, VeggieVoyage 10000–19999, 3. termék 20000+…
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Pilotban igazolandó mechanizmusok (a maximalista minta ezekre tesz fel mindent)
|
||||||
|
|
||||||
|
Az első pull-up ELŐTT explicit tesztelendő:
|
||||||
|
|
||||||
|
1. **`[Association]` keresztreferenciák öröklésnél** — interfész-kulcsú társítás
|
||||||
|
(`OtherKey = nameof(IShipping.Id)`) VAGY a navigációk a leszármazottban maradnak (base = skalárok + FK int-ek),
|
||||||
|
entitásonként döntve.
|
||||||
|
2. **AcBinary öröklött property-kkel** — a `MeasuringItemPalletBase` minta szerint; az első költözőnél explicit teszt.
|
||||||
|
3. **`[SignalR]` attribútum öröklött kontroller-metóduson** — az AyCode dispatcher végpont-felderítése lássa a
|
||||||
|
base-metódusokat.
|
||||||
|
4. **Razor `@typeparam` a DevExpress template-ekkel** — hol megy, hol marad vékony app-razor.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Migrációs fázisterv ("pull-up", lépésenként, FruitBank végig fordítás-azonos)
|
||||||
|
|
||||||
|
0. Skeleton repo + per-app bin-profil bekötés + mechanikus bázis-kiemelés (interfészek, enumok, konstans-bázisok) —
|
||||||
|
compile+wire-identical.
|
||||||
|
1. **Pilot:** a legkisebb/legtisztább gráf végigvitele (jelölt: Cargo — legkisebb; vagy EKÁER-lánc — legfrissebb).
|
||||||
|
Itt bizonyítjuk a 8. szakasz mechanizmusait.
|
||||||
|
2. Data-réteg bázisok (DbContext/DbTable).
|
||||||
|
3. Service-ek domain-enként (mérés → preorder → cargo → invoicing), FruitBank-osztályok vékony leszármazottá.
|
||||||
|
4. VeggieVoyage-plugin scaffold záró-osztályokkal — itt bukik ki a maradék hardcode.
|
||||||
|
5. Blazor Shared (grid-/komponens-base-ek).
|
||||||
|
6. Verziófüggő réteg portja az új nop-verzióra (a pull-up UTÁN, külön lépés).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Meta-protokoll teendők (amikor a repo létrejön)
|
||||||
|
|
||||||
|
- Új repo: `.github/copilot-instructions.md` + `@repo` blokk, **repo-prefix** (self-service a `REPO_PREFIXES.md`
|
||||||
|
szerint; korábbi javaslatok: nop-oldali libre `MGNOPWHOLE`, a nop-független Wholesale repóra pl. `MGWHOLE` —
|
||||||
|
eldöntendő), layer-szám.
|
||||||
|
- **Class-prefix:** `Mgw` (Mango Wholesale) — collision-check lefutott, tiszta (a `Ws`, `Wh/Whs`, `Nk` elvetve).
|
||||||
|
A doksi tisztázza: a prefix jövő-álló, de a mai tartalom zöldség-kalibrált.
|
||||||
|
- **Doc-layering:** a defining layerrel a doksik is költöznek — a FruitBank-plugin `PREORDER/` doksija + a
|
||||||
|
`PREO`/`EKAER`/`ORDD` topic-kódok a wholesale-registry-be; a termék-pluginban pointer + delta marad.
|
||||||
|
- **`CONSUMERS.md`** a Wholesale-repóban (FruitBank, VeggieVoyage, …).
|
||||||
|
- **`LLMP-DEC` bejegyzés** az új repo létéről (workspace-szignifikáns).
|
||||||
|
- **ADR-ek** a végleges struktúrában (lásd lent).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Nyitott kérdések
|
||||||
|
|
||||||
|
- Wholesale-repo **neve** és pontos szeparációja (egy repo Common + Common.Server + Shared, vagy több?).
|
||||||
|
- **Cél nop-verzió** a VeggieVoyage-hez (ez indítja a 6/(b) séma-diffet).
|
||||||
|
- Repo-**prefix**(ek) véglegesítése.
|
||||||
|
- Generic-paraméter-robbanás mély gráfoknál (`MgwShippingDocumentBase<TShipping, TPartner, TShippingItem, …>`) —
|
||||||
|
a házi minta elfogadta, de ez az ára; entitásonként figyelni.
|
||||||
|
- `Mango.Nop` vs `Wholesale` határ entitásonként: ami bármely nop-projektnek jó → Mango.Nop; ami nagyker-domain →
|
||||||
|
Wholesale.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Mi lesz ebből (amint van repo)
|
||||||
|
|
||||||
|
Ez a fájl a **forrás**; a rendes struktúrába szétszedve:
|
||||||
|
|
||||||
|
- **ADR-ek** (`<repo>/docs/adr/NNNN-*.md`, Nygard-stílus):
|
||||||
|
- `base-class-pull-up-vs-type-move` (2. szakasz)
|
||||||
|
- `wholesale-layer-split-and-nop-version-quarantine` (3. + 6. szakasz)
|
||||||
|
- `placement-canon` (4. szakasz) — vagy CONVENTIONS.md-be, a repo szokása szerint
|
||||||
|
- **Repo-doksik:** ARCHITECTURE (rétegtérkép + build-lánc), CONVENTIONS (placement-kánon + tare-példa +
|
||||||
|
zöldség-kalibráció), CONSUMERS.md, termék-scaffold checklist.
|
||||||
|
- **LLMP-DEC** sor: az új repo léte + a protokoll-relevanciák.
|
||||||
|
- A FruitBank-oldali doc-layering pointer-ek frissítése.
|
||||||
|
|
||||||
|
Ez a `WHOLESALE_FRAMEWORK_PLAN.md` a szétszedés után **archiválható vagy törölhető** (a tartalma a végleges
|
||||||
|
helyekre kerül).
|
||||||
Loading…
Reference in New Issue