Amikor egy ERP-t szétszedünk Admin + Finance + Logistics + Storefront modulokra, a legnehezebb kérdés nem az, hogy hogyan beszélnek egymással, hanem hogy ki tulajdonol mit. Egy entitásból csak EGY igazságforrás lehet, máskülönben hetente borítjuk fel a könyvelést. Megírjuk a tulajdonlási térképet és a hozzá tartozó eventual-consistency ablakokat.
A tulajdonlási térkép
| Entitás | Tulajdonos modul | Olvasó modulok | Konzisztencia ablak |
|---|---|---|---|
| Vevő-törzs | Admin | Finance, Logistics, Storefront | Azonnali (sync write-through) |
| Termék-törzs | Admin | Finance, Logistics, Storefront | Azonnali |
| Készlet | Logistics | Storefront, Admin | 15 másodperc |
| Főkönyv (GL) | Finance | Admin (csak riportra) | 60 másodperc |
| Áfa kód definíciók | Finance | Admin, Storefront | Azonnali |
| Rendelés (sales order) | Storefront → Logistics | Finance | 15 másodperc |
| Számla | Finance | Admin, Storefront | Azonnali |
A tulajdonos modul az, aki írhat rá. Mindenki más kizárólag olvashat — és csak a publikus API-n keresztül.
Miért nem egy közös DB
A klasszikus monolit ERP egy közös PostgreSQL-en él, és minden modul közvetlenül JOIN-olja egymás tábláit. Ez gyors, ez egyszerű — és ez a legrosszabb ellensége a moduláris rendszernek. Miért:
- Implicit függőség. Ha a Logistics modul direkt
JOIN-olja azaccounting_entrytáblát, akkor Finance nem tud sémát változtatni anélkül, hogy Logistics-ot is deployolnia kéne. - Tranzakciós kuplung. Egy nagy SQL tranzakció Finance + Logistics írással azt jelenti, hogy ha az egyik modul kiesik (lock, deadlock), mindkettő ledől.
- Schema-versioning kavarc. Migrációk hat helyen, koordinált deploy-jal? A modulok izolált release-ciklusa szétesik.
Ezért egy fizikai PostgreSQL clusteren is logikailag külön sémát kapnak a modulok, és csak API-n keresztül beszélnek.
Az eventual-consistency ablakok
Nem mindenhol kell az azonnali konzisztencia. Az ablakokat tudatosan választottuk:
Vevő-törzs, termék-törzs, áfa kódok, számla: azonnali. Ezek vagy ritkán változnak (termék-törzs új SKU), vagy kritikusan időérzékenyek (egy számla nem létezhet részlegesen). Sync write-through: amíg a forrás-modul nem nyugtázta minden read-only replikán a frissítést, az API hívás nem ad vissza 200-at.
Készlet: 15 másodperc. A Logistics modul a tulajdonos. A Storefront UI-on a vásárló látja, hogy „raktáron 4 db” — ez a szám maximum 15 mp-ig lehet elavult. Black Friday-en is. Tapasztalat: a 15 mp ablakban szemernyi átfedés van (két vásárló egyszerre rendel ugyanarra a 4 db-ra), ezt a checkout-on egy reservation-lock kapja el. Az API tehát optimista, a kosár-finalizálás pesszimista.
Főkönyv: 60 másodperc. Az Admin riport-felülete megengedi, hogy az adatok 60 mp-ig korábbiak legyenek a Finance-ban tárolt aktuális állapothoz képest. Riport-tipikus query-ket nem futtatunk valós idejű replikán; egy 60 mp-os késleltetésű replika sokkal olcsóbb és skálázhatóbb. A könyvelő, aki most rögzített egy tételt, és azonnal lekér egy riportot, max. 1 perc múlva látja megjelenni.
A nightly scrubber
Minden éjjel 03:00 UTC-kor lefut egy data-integrity scrubber. 11 független keresztellenőrzést végez:
- Vevő-törzs konzisztens-e Admin, Finance, Logistics replikái között.
- Termék-törzs ugyanaz.
- Készlet összesen (Logistics) = elérhető + foglalt (raktár-szintű bontás).
- Főkönyvi egyenleg szumma = 0 (kettős könyvelés alapszabálya).
- Áfa kód → áfa fizetési tartozás összesen egyezik a NAV bevallással.
- Stb.
Ha bármelyik mérés 0,1% feletti drift-et talál, azonnali alert megy (PagerDuty → Slack + e-mail). Az elmúlt 18 hónapban három alkalommal csördült meg élesben, mindhárom egy adott modulnál clock skew (NTP drift) miatti updated_at ütközés volt, nem üzleti adathiba. De a scrubber léte miatt a könyvvizsgálók is megnyugodva nézik a rendszert.
Mit jelent ez egy migrációs projektben
A monolit ERP-ből érkező tenantnál a legnagyobb adaptáció ez: el kell fogadni, hogy bizonyos olvasások 15–60 másodperces késéssel jönnek. A gyakorlatban senki nem veszi észre — egy könyvelő nem 60 másodpercen belül kér le riportot egy tétel rögzítése után. De a kommunikációt megtesszük: a moduláris ERP nem egy közös DB, hanem négy modul, akik tisztelettel beszélnek egymással.