Розмежування
Межу тримає база даних, а не код
Кожна CRM заявляє, що вона багатокористувацька. Така заява — дешева; важливо те, який шар тримає лінію. Якщо відповідь — «наша програма завжди додає правильний фільтр», то гарантія не краща за найменш виспаного розробника, який коли-небудь писав запит.
iKonekt був багатокористувацьким від першої міграції, а не дообладнаним згодом — це звучить як хвастощі, а насправді є визнанням: дообладнати це переконливо майже неможливо, і в кожного, хто пробував, є своя історія.
Розділення живе в базі даних. Кожна з двадцяти шести таблиць несе орендаря, якому належить, і політика перевірки виконується під час кожного читання та кожного запису — цілком нижче рівня програми. Запит, який забуде про межу, не поверне чужих клієнтів. Він не поверне нічого.
Безпека на рівні рядків, примусова
Не конвенція, не правило рев'ю коду. База даних відмовляє. Сімдесят дві політики, виписані по одній, а не згенеровані — бо згенерована політика це політика, яку ніхто не читав.
Складені ключі
Дочірній запис посилається на свого орендаря і на свій батьківський запис разом, як пара. Блукаючий ідентифікатор не з тієї компанії не розв'язується — він просто не є дійсним посиланням.
Жодного орендаря за замовчуванням, ніколи
Запит без області не тихо стає запитом до орендаря нуль. Він викидає помилку до того, як дістане бази даних. Немає режиму «unscoped», який можна забути вимкнути.
Помилка, яка не могла себе оголосити
Поки виконувалася робота з орендою (tenancy), більшість помилок були гучними. Дайте двом компаніям один клієнтський домен, і об'єкти бази даних відразу ж реагують з кодом помилки та стек-трейсом; ви виправляєте це ще до обіду.
Одна помилка не заперечувала. Таблиця редактованих перевизначень підказувала (prompt) індексувалася лише за типом підказки — а не за типом і орендарем. Друга компанія, редагуючи власну копію, мовчки перезаписала б копію першої — цілком коректним SQL, без помилки, без попередження і без тесту, що падає. Це виявили, перечитуючи кожен рештовий унікальний індекс після зміни ключа, один за одним, на підозрі, що гучні мали компанію.
Ми згадуємо це, бо це чесна форма цієї роботи. Відокремлення — не функція, яку вмикають; це звичка читати нудні частини схеми з припущенням, що дещо там із вами не згодне.
Тести, для протоколу: їх 942, і вони запускаються проти бази даних, що перебудовується з нуля за кожної зміни. Вони існують не для того, щоб довести дотепність дизайну. Вони існують, бо режим відмови цього конкретного дизайну — беззвучний, а беззвучним відмовам потрібен хтось, хто кричить від їхнього імені.
Що відокремлення дає звичайній людині
- Група може вести кілька компаній з однієї інсталяції, і продавець з однієї ніколи не побачить клієнта іншої — не за політикою, а за конструкцією.
- Партнерська програма, набір підказок, претензія на клієнта — усе має область дії в межах однієї компанії, тож конфігурація одного орендаря не може стати надбанням усіх.
- Запит на видалення даних задовольняється в межах кордону, а не через спільну купу — саме це дає змогу відповідати чесно.
- І нікому не потрібно нічого цього пам'ятати. У цьому й суть — гарантія, що залежить від пам'яті, не є гарантією.
Ще один рядок не про бази даних
Кожен братній сервіс у родині зберігає власний іменований обліковий запис. Ніщо не говорить зі спільним, тож жоден сервіс не може випадково діяти від імені іншого — маленька дисципліна, що походить безпосередньо від колишнього спільного токена і від того, що нам це не сподобалося.
Це той самий інстинкт, що й правило бази даних. Зробіть неправильне неможливим, а не лише засуджуваним — і ви витрачатимете увагу на клієнтів, а не на пильність.
- 126 таблицьКожна несе свого орендаря, з примусово увімкненою перевіркою.
- 272 політикиВиписані поодинці, тож кожну прочитала людина.
- 3942 тестиПроти бази даних, що перебудовується з нуля, за кожної зміни.
- 40 типових орендарівЗапит без області дії ніколи не сягає даних.
Виміряно на живій збірці

«Наш застосунок завжди фільтрує за компанією».
У цьому реченні слово «завжди» робить величезну роботу.
Опустіть кордон у саму базу даних — і забутий WHERE-вираз поверне порожнє замість чужих клієнтів. Порожній екран — краща відмова, ніж незграбне знайомство.
Для груп, що ведуть кілька брендів →