Scheiding
De grens die de database bewaakt, niet de code
Elke CRM beweert multi-tenant te zijn. Die bewering is goedkoop; wat telt is welke laag de lijn bewaakt. Als het antwoord is "onze applicatie voegt altijd de juiste filter toe", dan is de garantie slechts zo goed als de minst uitgeruste developer die ooit een query schreef.
iKonekt was multi-tenant vanaf de eerste migratie in plaats van er achteraf op gepast, wat klinkt als een trots maar eigenlijk een bekentenis is: het achteraf toevoegen is vrijwel niet overtuigend te doen, en iedereen die het geprobeerd heeft heeft er een verhaal over.
De scheiding zit in de database. Elk van de zesentwintig tabellen bevat de tenant waartoe het hoort, en het beleid dat dat controleert draait bij elke lees- en schrijfactie, volledig onder de applicatie. Een query die de grens vergeet, geeft niet de klanten van iemand anders terug. Die geeft niets terug.
Beveiliging op rijniveau, afgedwongen
Geen conventie, geen codereview-regel. De database weigert. Tweeënzeventig beleidsregels, één voor één uitgeschreven in plaats van gegenereerd — want een gegenereerd beleid is een beleid dat niemand heeft gelezen.
Samengestelde sleutels
Een kindrecord verwijst naar zijn tenant en zijn ouder samen, als een paar. Een verdwaalde identifier van het verkeerde bedrijf lost niet op — het is simpelweg geen geldige verwijzing.
Nooit een standaardtenant
Een verzoek zonder scope wordt niet stilletjes een verzoek voor tenant nul. Het gooit een fout voordat het de database bereikt. Er is geen "unscoped"-modus om te vergeten uit te zetten.
De bug die zich niet kon melden
Tijdens het tenancy-werk waren de meeste fouten luid. Geef twee bedrijven hetzelfde klantdomein en de database weigert direct, met een foutcode en een stack trace; je lost het op voor de lunch.
Eén weigerde niet. Een tabel met bewerkbare prompt-overschrijvingen was gekoppeld op alleen het soort prompt — niet op soort en tenant. Een tweede bedrijf dat zijn eigen exemplaar bewerkte, zou stilletjes dat van het eerste bedrijf hebben overschreven, via volkomen geldige SQL, zonder fout, zonder waarschuwing en zonder falende test. Het werd gevonden door na het wijzigen van een sleutel elke resterende unieke index één voor één te lezen, op het vermoeden dat de luidruchtige gezelschap hadden.
We noemen het omdat het de eerlijke vorm van dit werk is. Scheiding is geen functie die je aanzet; het is een gewoonte om de saaie delen van het schema te lezen in de veronderstelling dat daar iets het niet met je eens is.
De tests, voor de goede orde: 942 stuks, gedraaid tegen een database die bij elke wijziging vanaf nul wordt opgebouwd. Ze zijn er niet om te bewijzen dat het ontwerp slim is. Ze zijn er omdat het faalgedrag van dit specifieke ontwerp stil is, en stille fouten iemand nodig hebben die voor hen schreeuwt.
Wat scheiding een gewoon mens oplevert
- Een groep kan meerdere bedrijven draaien vanaf één installatie, en een verkoper bij het ene bedrijf ziet nooit een klant van het andere — niet via beleid, maar door constructie.
- Een partnerprogramma, een set prompts, een claim op een klant: allemaal per bedrijf afgebakend, zodat de configuratie van één tenant niet die van iedereen wordt.
- Een verwijderverzoek wordt binnen een grens gehonoreerd in plaats van over een gedeelde hoop heen, en dat is precies wat het mogelijk maakt er eerlijk over te zijn.
- En niemand hoeft eraan te denken. Dat is het punt — een garantie die ervan afhangt dat je eraan denkt, is geen garantie.
Nog één regel die niet over databases gaat
Elke zusjesservice in de familie bewaart zijn eigen benoemde credential. Niets spreekt met een gedeelde, dus geen enkele service kan per ongeluk als een andere optreden — een kleine discipline die rechtstreeks voortkwam uit het ooit hebben gehad van een gedeelde token, en het niet leuk vinden.
Het is dezelfde instinct als de databaseregel. Maak het verkeerde onmogelijk in plaats van afgeraden, en je besteedt je aandacht aan klanten in plaats van aan waakzaamheid.
- 126 tabellenElke bevat zijn tenant, met de controle afgedwongen aan.
- 272 beleidsregelsEén voor één uitgeschreven, zodat elk door een persoon is gelezen.
- 3942 testsTegen een database die vanaf nul wordt opgebouwd, bij elke wijziging.
- 40 standaardtenantsEen verzoek zonder scope bereikt de data nooit.
Gemeten op de live build

“Onze applicatie filtert altijd op bedrijf.”
Dat "altijd" doet zwaar werk in die zin.
Zet de grens omlaag in de database en een vergeten WHERE-clausule geeft niets terug in plaats van de klanten van iemand anders. Een leeg scherm is een betere fout dan een ongemakkelijke kennismaking.
Voor groepen die meerdere merken runnen →