Több-bérlős SaaS építése: Munkaterületek, szerepkörök, számlázás és elkülönítés

Hogyan tervezzünk munkaterületeket, szerepkör-alapú hozzáférést, számlázási szinteket és bérlői elkülönítést skálázható SaaS-hez. Gyakorlati architektúra a DigiForge-tól.

DFDigiForge TeamJul 20, 20267 perc olvasás
Absztrakt, világító, összekapcsolt blokkok sötét háttéren, amelyek a több-bérlős SaaS architektúrát ábrázolják.

A több-bérlős SaaS az alapértelmezett architektúra minden olyan B2B platform számára, amely néhány ügyfélnél többre számít. A részletekben rejlik az ördög: hogyan modellezed a munkaterületeket, osztod ki a szerepköröket, strukturálod a számlázást és izolálod a bérlőket – ez határozza meg, hogy a platformod simán skálázódik-e, vagy összeomlik a komplexitás alatt. A DigiForge-nál több tucat SaaS-termékben építettük és építettük újra ezeket a rendszereket. Íme, amit megtanultunk.

Munkaterületek: A szervezet alapegysége

A munkaterület egy logikai tároló, amely egyetlen ügyfél (vagy egy ügyfél csapatának) felhasználóit, adatait és konfigurációját csoportosítja. Láttuk, hogy csapatok összemossák a munkaterületeket a számlázási fiókokkal vagy akár projektekkel – ne tedd. Tartsd meg a munkaterületet az alapvető bérlői hatókörként, és rétegezz rá más fogalmakat.

Kulcsfontosságú tervezési döntések:

  • Hierarchikus vagy lapos? Egyes platformoknak munkaterületekre van szükségük munkaterületeken belül (pl. egy vállalat több részleggel). Kétszintű hierarchiát ajánlunk: szervezet (számlázási entitás) és munkaterület (csapat egység). Kerüld a mélyebb egymásba ágyazást, hacsak nem feltétlenül szükséges – bonyolítja a szerepkörök öröklődését és az adathozzáférést.
  • Egyedi azonosítók: Használj ember által olvasható slug-ot (pl. acme vagy acme-marketing) a munkaterület URL-jeiben, de belsőleg mindig UUID-re támaszkodj. A slug-ok változhatnak; a UUID-k nem.
  • Soft-delete türelmi idővel: Egy munkaterület törlése drasztikus lépés. Vezess be 30 napos soft-delete-t, hogy a felhasználók visszaállíthassák az adatokat. A számlázást azonnal állítsd le, de az adatokat tartsd meg a türelmi idő lejártáig.

Amikor egy új felhasználó regisztrál, érdemes átgondolni a bevezető folyamatot. Először hozzon létre egy munkaterületet, vagy inkább egy homokozót fedezzen fel? Mi a vezetett folyamatot részesítjük előnyben, ahol a felhasználó létrehoz egy szervezetet, majd az első munkaterületét, és azonnal felszólítást kap a csapattársak meghívására. Ez csökkenti a súrlódást, és egyértelművé teszi, hogy a platform együttműködésre épül.

Gyakori hiba, hogy a számlázási csomagokat közvetlenül a munkaterületekhez kötik. Ehelyett a számlázást olyan szervezethez érdemes kapcsolni, amely egy vagy több munkaterületet tartalmaz. Ez lehetővé teszi a vállalatok számára, hogy egyetlen számlát kapjanak, miközben minden csapat saját munkaterülettel rendelkezik.

Szerepkörök és jogosultságok: finomhangolt, de nem túl részletes

A szerepkör-alapú hozzáférés-vezérlés (RBAC) iparági szabvány, de a részletesség mértéke számít. A DigiForge-nál általában három beépített szerepkörrel kezdünk – Adminisztrátor, Tag, Megtekintő –, és lehetővé tesszük egyéni szerepkörök létrehozását a fejlett csomagokhoz. Az Adminisztrátor teljes munkaterület-vezérléssel rendelkezik, a Tagok létrehozhatnak és szerkeszthetnek erőforrásokat, a Megtekintők pedig csak olvashatnak.

Ahol a dolog bonyolulttá válik, az a jogosultságok hatóköre. A jogosultságok alapértelmezés szerint a munkaterületre korlátozódjanak, de szükség lehet szervezeti szintű jogosultságokra (pl. számlázás kezelése) vagy akár munkaterületek közötti olvasási hozzáférésre az összesített jelentésekhez. Modellezzük a jogosultságokat action:resource párok halmazaként, és rendeljük hozzá őket szerepkörökhöz. A hozzárendeléseket egy kapcsolótáblában tároljuk: (workspace_id, user_id, role_id).

Profi tipp: Ne csak az alkalmazási rétegben ellenőrizd a jogosultságokat. Törekedj arra, hogy a lehető legtöbb jogosultsági logikát az adatbázisba helyezd át sor-szintű biztonság (RLS) vagy egy OPA-szerű szabálymotor segítségével. Ez csökkenti annak esélyét, hogy a webes réteg hibája miatt más adataihoz férjenek hozzá.

Az egyik jól bevált minta, hogy a felhasználó szerepkörét egy munkamenet-tokenben (JWT) gyorsítótárazzuk, ahelyett, hogy minden kérésnél lekérdeznénk az adatbázist. De vigyázz: ha a szerepköröket JWT-ben gyorsítótárazod, szükséged van egy mechanizmusra a tokenek érvénytelenítésére, ha a szerepkör változik (pl. rövid token lejárat vagy tiltólista).

Gondolj a szerepkör-öröklésre is: egy szervezeti Admin automatikusan Admin legyen az összes munkaterületen? A mi irányelvünk: a szervezeti szerepkörök egy felső korlátot adnak, de a munkaterületi szerepkörök lehetnek korlátozóbbak. Például egy Org Admin hozzáférhet bármely munkaterülethez, de egy munkaterület Admin nem férhet hozzá a számlázáshoz.

Számlázás és árazási modellek: metaadatok, nem üzleti logika

A számlázás az a terület, ahol a több-bérlőség igazán valósággá válik. Az árazási modell – felhasználónként, munkaterületenként, használatalapú vagy szintezett – tükröződnie kell az adatmodellben, de a számlázási rendszert le kell választani az alapalkalmazásról. Használj harmadik féltől származó számlázási szolgáltatót (Stripe, Recurly, Chargebee), és csak az előfizetés-azonosítót és a csomagazonosítót tárold az adatbázisban.

A következő adatbázis-megközelítést javasoljuk:

  1. Egy plans tábla, amely meghatározza a terv slug-ját, árát és funkciójelzőit (pl. max_users, storage_gb, api_rate_limit).
  2. Egy organizations tábla current_plan_id és billing_provider_subscription_id mezőkkel. A szervezeteket egy kapcsolótáblán keresztül kösse össze a munkaterületekkel.
  3. Egy features tábla (vagy egyszerű JSON oszlop), amely felülbírálásokat tárol. Például, ha egy ügyfél egyedi árat alkudott ki, a terv ára felülírható szervezeti szinten.

A legnehezebb rész a terv alapú hozzáférés korlátozása. Két lehetősége van: a korlátozások érvényesítése az alkalmazásban (ellenőrizze a max_users értéket a meghívás előtt), vagy adatbázis szintű sorok számlálásával és triggerekkel. Mi az alkalmazásszintű érvényesítést részesítjük előnyben, mert jobb felhasználói hibaüzeneteket eredményez, de mindig hozzáadunk egy éjszakai egyeztető feladatot, amely jelzi a korlátaikat túllépő szervezeteket.

A terv frissítése és visszaminősítése körültekintő kezelést igényel. Amikor egy ügyfél frissít, azonnal biztosítson hozzáférést az új funkciókhoz, de a számlázást a szolgáltatón keresztül arányosítsa. Visszaminősítéskor döntenie kell: blokkolja a hozzáférést az új tervet meghaladó funkciókhoz, vagy adjon türelmi időt? Javasoljuk a jelenlegi számlázási ciklusra vonatkozó türelmi időt, amely után érvényesítse a korlátozásokat.

Egy lecke a frontvonalból: soha ne hagyja, hogy a számlázási hibák adatvesztéshez vezessenek. Ha egy fizetés sikertelen, fokozatosan korlátozzon (pl. írási műveletek tiltása), de ne töröljön adatokat. Az ügyfél előbb-utóbb fizetni fog.

Bérlői elkülönítés: megosztott vs. szeparált

Az elkülönítés a legnagyobb horderejű architekturális döntés. A szokásos kompromisszum a megosztott adatbázis (egy adatbázis az összes bérlő számára, minden táblában tenant_id oszloppal) és a bérlőnkénti adatbázis (minden munkaterület saját adatbázist kap) között van. Mindkettőt kipróbáltuk, és végül egy hibrid megközelítés mellett döntöttünk a legtöbb projekt esetében.

  • Megosztott, szigorú RLS-sel: Kis és közepes bérlők számára jó (egyenként 10 ezer felhasználó alatt). A sorszintű biztonság beépített a Postgresbe, és egy munkamenet-változót (app.tenant_id) használunk minden lekérdezés szűrésére. Ez a legegyszerűbb üzemeltetni és frissíteni.
  • Bérlőnkénti adatbázis: Akkor szükséges, ha a bérlők szigorú megfelelőséget igényelnek (HIPAA, SOC 2, GDPR adattárolás), vagy ha az alkalmazás bérlőnként I/O-intenzív. Az üzemeltetési többletterhelés valós – a séma-migrációkat több száz adatbázisra kell alkalmazni –, de az olyan eszközök, mint a Flyway és az automatizált CI, kezelhetővé teszik.
  • Bérlőnkénti séma: Köztes megoldás, amely külön sémákat használ egy adatbázison belül. Nagyobb elkülönítést nyújt, mint a megosztott tábla, de kisebb üzemeltetési terhet, mint a teljes adatbázisok. Ezt használjuk alacsonyabb szintű csomagjainkhoz, és szükség esetén bérlőnkénti adatbázisra frissítjük az ügyfeleket.

Az elkülönítési stratégiától függetlenül soha ne engedélyezze a közvetlen adatbázis-hozzáférést a kliens oldaláról. Mindig irányítson át egy API-rétegen, amely kikényszeríti a bérlői azonosságot. És az ügyeletes csapat kedvéért: soha, de soha ne használja a tenant_id-t URL-ekben anélkül, hogy ellenőrizné, hogy a hitelesített felhasználó ahhoz a bérlőhöz tartozik-e.

Az elkülönítési szintek közötti adatmigráció valóság. Például amikor egy bérlő kinövi a megosztott adatbázist, előfordulhat, hogy át kell helyezni egy dedikált adatbázisba. Tervezze ezt előre: írjon egy migrációs szkriptet, amely exportálja és importálja az adatokat, és tesztelje éles adatokkal. Lehetővé kell tenni, hogy állásidő nélkül fusson, kék-zöld megközelítéssel.

Automatizált kiépítés: bízzuk a gépre

Az első tíz ügyfélnél még működhet a bérlők kézi felhúzása, de ez nem skálázható. Ahogy a ContractorHUB nemrégiben benyújtott szabadalmi bejelentése is rámutat, a nulla érintésű megvalósítás kulcsfontosságú megkülönböztető tényező a több-bérlős SaaS-ben [1]. Olyan kiépítési munkafolyamatokat építettünk, amelyek automatizálnak mindent az adatbázis létrehozásától (vagy séma klónozásától) az alapértelmezett adatok feltöltésén át a üdvözlő e-mailek kiküldéséig.

Egy tipikus automatizált kiépítési folyamat:

  1. A felhasználó regisztrál, létrehoz egy szervezetet és kiválaszt egy csomagot.
  2. A számlázási szolgáltató webhookja elindít egy kiépítési feladatot (pl. egy szerver nélküli függvényt vagy egy Kubernetes Job-ot).
  3. A feladat létrehozza a bérlő elkülönítési rétegét (séma vagy adatbázis), lefuttatja a kezdeti migrációkat, és feltölti az alapértelmezett szerepköröket és beállításokat.
  4. Egy második feladat e-mailt küld a bejelentkezési útmutatóval és a következő lépésekkel.
  5. A felhasználó átirányításra kerül az új munkaterületre – amely másodperceken belül teljesen működőképes.

Az idempotencia itt nem alku tárgya. Ha a kiépítési feladat félúton meghiúsul, biztonságosan újra kell tudni próbálni. A teljes folyamatot egy állapotgéppel burkoljuk be, a szervezet sorában egy provisioning_status oszloppal: pending → creating → active → failed. A sikertelen állapotok egy holtlevél-sorba kerülnek emberi beavatkozásra.

Ne feledkezz meg a támogató infrastruktúra kiépítéséről: DNS-rekordok egyéni domainekhez, CDN-gyorsítótár-melegítők, API-sebességkorlátok bérlőnként és monitoring-riasztások. Automatizálj mindent, ami szkriptelhető, mert a manuális lépések nyomás alatt el fognak felejtődni.

Következtetés: A több-bérlős gondolkodásmód

A több-bérlős kialakítás nem olyasmi, amit utólag lehet ráaggatni a rendszerre. Már az első naptól kezdve vezérelnie kell az adatmodellt, a hozzáférés-vezérlést, a számlázási integrációt és a telepítési stratégiát. A jó hír: ha ezt a négy pillért – munkaterületek, szerepkörök, számlázás, elkülönítés – jól eltalálod, a SaaS többi része feltűnően könnyebbé válik az építés és karbantartás során.

Minden SaaS más, de a fenti minták jól beváltak számunkra különböző iparágakban. Akár most kezded az MVP-det, akár több ezer bérlőre skálázol, bátorítunk, hogy gondold át alaposan ezeket a döntéseket. Ha pedig szeretnéd, hogy egy másik szempárt is rávessünk az architektúrádra, örömmel átnézzük.

#több-bérlős#saas#munkaterületek#szerepkörök#számlázás#elkülönítés#kiépítés
DF

DigiForge Team

A DigiForge mérnökcsapata — modern weboldalakat, modulokat és automatizálást építünk, és a gyors, tartós webes termékek készítésének művészetéről írunk.

Beszélgessünk

Van egy projektje
a fejében?

Mondja el, mit épít — mi felvázolunk egy világos tervet és a megfelelő megközelítést a termékéhez.

Projekt indítása