Главная> Кейсы> Справочная архитектура SaaS-платформы для нескольких клиентских организаций

Справочная архитектура SaaS-платформы для нескольких клиентских организаций

Тип референсаСправочная архитектура
Материалы для ознакомленияNext.js · Go · PostgreSQL · Redis · Docker · Stripe
Справочная архитектура SaaS-платформы для нескольких клиентских организаций

Справочная архитектура. Это иллюстративная архитектура и контрольный список объёма работ, а не подтверждённый клиентский проект и не результат измеренного внедрения. Технологии, объём интеграции и результаты поставки согласовываются для конкретного технического задания.

Сценарий и ограничения

Продукт обслуживает множество клиентских организаций в рамках одного развёртывания. Решение, которое определяет всю архитектуру, — модель изоляции: общие таблицы с колонкой tenant, отдельная схема для каждого арендатора или отдельная база данных для каждого арендатора. Выбор варианта по умолчанию вместо осознанного проектирования — самая дорогостоящая ошибка в этой категории, поскольку последующее изменение требует миграции актуальных данных клиентов.

Архитектура

Слои и зоны ответственности

СлойТехнологияЗона ответственности
WebNext.js (SSR для маркетинговых страниц и SEO, SPA после входа)Публичные страницы используют серверный рендеринг для видимости в поиске; авторизованному продукту он не требуется, поэтому он остаётся клиентским приложением.
APIGo + Gin, арендатор определяется для каждого запросаКонтекст арендатора определяется по субдомену или токену до запуска любого обработчика, а затем передаётся через каждый запрос к данным.
ХранилищеPostgreSQL, общая схема с ограничением строк по арендаторуОдна база данных с tenant_id в каждой таблице, принадлежащей арендатору, с обеспечением на уровне репозитория и, где поддерживается, с помощью row-level security как дополнительного уровня защиты.
КэшRedis, ключи с префиксом арендатораСессии, ограничения частоты запросов и часто используемая конфигурация. Префиксы ключей предотвращают классическое столкновение ключей кэша, при котором данные одной клиентской организации могут попасть к другой.
БиллингStripe или региональный платёжный шлюзСостояние подписки дублируется локально, поэтому проверки доступных возможностей никогда не зависят от активного обращения к платёжному провайдеру.
ЗаданияВоркеры очереди с контекстом арендатораПлановые и асинхронные задачи; контекст арендатора передаётся вместе с данными задания, а не определяется во время выполнения.

Модель данных

В приведённых ниже таблицах зафиксированы правила, от которых зависит всё остальное. Именно ошибки на этом уровне превращают работающий демонстрационный прототип в систему, которую невозможно расширять.

Основные сущности

СущностьКлючевые поля, связи и правила
tenantЗапись об организации с тарифом, статусом, регионом и флагами функций. Каждая таблица, принадлежащая арендатору, содержит tenant_id, и ни один запрос не может обходиться без него.
user / membershipПользователь может состоять в нескольких организациях с разными ролями в каждой из них, поэтому идентичность является глобальной, а права доступа определяются для каждого членства. Моделирование user и membership в одной таблице делает поддержку нескольких организаций невозможной в будущем.
role / permissionПрава назначаются ролям, роли назначаются для каждого членства, а каждая проверка выполняется на backend. Скрытие элементов во frontend является только представлением и никогда не заменяет контроль доступа.
subscription / entitlementТариф, количество пользовательских мест или лицензий, период и производные доступные возможности. Доступ к функциям определяется на основе локально сохранённых доступных возможностей по подписке, поэтому сбой платёжного провайдера не блокирует клиентов в продукте.
audit_logИнициатор, арендатор, действие, цель или объект аудита и данные до/после. Поддерживает проверку безопасности и анализ инцидентов; требования к сроку хранения, доступу и аудиту необходимо согласовать до начала реализации.
tenant_configНастройки, брендинг и переопределения функций для каждого арендатора, разрешаемые с документированным приоритетом относительно настроек тарифа по умолчанию.

Ключевые интерфейсы

Конечные точки, содержащие бизнес-правила

Конечная точкаНазначение и особенности конкурентного доступа
POST /api/v1/auth/loginАутентифицирует пользователя, а затем возвращает доступные ему членства в организациях; арендатор выбирается явно, а не определяется по последней сессии.
GET /api/v1/{resource}Каждое чтение в рамках арендатора проходит через репозиторий, который добавляет tenant_id. Ограничение области действия находится в одном месте, поэтому обработчик не может забыть о нём — это самый распространённый источник утечек между клиентскими организациями.
POST /api/v1/webhooks/billingWebhook платёжного провайдера, идемпотентный по идентификатору события и обновляющий локальное состояние подписки и доступных возможностей по подписке.
POST /api/v1/tenants/{id}/inviteПроцесс приглашения, создающий членство с ролью; частота запросов ограничивается для каждого арендатора, чтобы предотвратить злоупотребления приглашениями.
GET /api/v1/auditЗапрос журнала аудита с ограничением по арендатору и постраничной выдачей, доступный администраторам арендатора как самостоятельный способ подтвердить соответствие требованиям.

Технические решения

  • Общая схема с tenant_id, выбранная осознанно. Это наиболее экономичный вариант с точки зрения эксплуатации и миграции, подходящий для большинства продуктов. Если договор с клиентом требует физического разделения, та же кодовая база может работать в выделенном развёртывании — этот путь проектируется с самого начала, а не обнаруживается во время переговоров о продаже.
  • Ограничение области арендатора реализовано на одном уровне репозитория. Расчёт на то, что каждый разработчик будет помнить о добавлении условия WHERE, приводит к утечкам между клиентскими организациями. Централизация делает случайное написание небезопасного запроса затруднительным.
  • Доступные возможности по подписке дублируются локально. Проверка платёжного провайдера при каждом запросе добавляет задержку и создаёт жёсткую зависимость. Локальное дублирование означает, что сбой провайдера ухудшает операции биллинга, но не работу самого продукта.
  • Журнал аудита с первого релиза. Восстановить историю аудита задним числом невозможно. Подтвердите требования покупателя к аудиту и сохраняйте согласованную историю начиная с первого релиза.
  • SSR только для публичных страниц. Маркетинговым страницам и документации нужна видимость в поиске; авторизованному продукту она не требуется, а принудительное использование SSR добавляет затраты без отдачи.

Гипотетические целевые показатели проектирования

Приведённые ниже значения являются гипотетическими примерами для планирования ёмкости, а не измеренными результатами для клиента, подтверждённой рекомендацией по конфигурации или SLA. Устанавливайте проектные критерии приёмки после определения нагрузки, устройств, данных, оборудования и зависимостей от сторонних систем; проверяйте их с помощью пилотного запуска и нагрузочных тестов до принятия целевого показателя для промышленной эксплуатации.

Целевые показатели ёмкости и производительности

ЦельЗначение и допущение
Задержка APIp95 менее 250 мс для чтения в рамках арендатора при наличии корректных составных индексов, начинающихся с tenant_id.
Изоляция арендаторовТребуется автоматизированный набор тестов, который пытается получить доступ между арендаторами для каждой конечной точки и прерывает сборку при несанкционированном доступе. Реализация должна проходить эти проверки; данный справочный материал не является доказательством завершённого тестирования безопасности.
ПодключениеСоздание и подготовка нового арендатора выполняются за секунды, поскольку это добавление строки и записи конфигурации, а не инфраструктурная работа.
МасштабированиеРассчитано на несколько тысяч арендаторов на одном экземпляре PostgreSQL; после этого предусматривается переход к репликам для чтения, а затем к шардированию по арендаторам, но эти этапы планируются без преждевременной реализации.

Что входит в поставку

  • Исходный код frontend на Next.js, backend на Go и панели администратора в вашем репозитории
  • Документированная схема базы данных с ограничением области по арендатору, индексами и таблицами аудита, а также история миграций
  • Набор тестов изоляции между арендаторами, который можно запускать в вашей системе непрерывной интеграции
  • Интеграция биллинга, обработка webhook и документация по доступным возможностям подписки
  • Инструкции по развёртыванию Docker и Nginx, конфигурация окружения, процедура резервного копирования и восстановления

Планирование под ваш бизнес

Описанные выше модули являются отправной точкой, а не фиксированным пакетом. Обычно мы ограничиваем первый релиз одним основным рабочим процессом и одним административным процессом, а затем расширяем продукт, когда реальное использование показывает, где находятся фактическая нагрузка и нестандартные случаи. Отправьте описание объёма работ, и мы сопоставим его с этой архитектурой и сообщим, какие части пока не понадобятся.

Запрос оценки проекта

Опишите цель продукта, текущий процесс, целевые платформы, ограничения и сроки решения. Мы оценим объём и предложим практичный следующий шаг.

Добавить требования к проекту (необязательно — для оценки объёма и стоимости)
Мы используем эти данные только для рассмотрения и ответа на ваш запрос по проекту. Ознакомьтесь с политикой конфиденциальности. Пожалуйста, не отправляйте пароли и секретные ключи API.

Demo Solutions