Files
octopus/myproject/TENANT_REGISTRATION_GUIDE.md
Andrey Smakotin 097d4ea304 feat: Добавить систему мультитенантности с регистрацией магазинов
Реализована полноценная система мультитенантности на базе django-tenants.
Каждый магазин получает изолированную схему БД и поддомен.

Основные компоненты:

Django-tenants интеграция:
- Модели Client (тенант) и Domain в приложении tenants/
- Разделение на SHARED_APPS и TENANT_APPS
- Public schema для общей админки
- Tenant schemas для изолированных данных магазинов

Система регистрации магазинов:
- Публичная форма регистрации на /register/
- Модель TenantRegistration для заявок со статусами (pending/approved/rejected)
- Валидация schema_name (латиница, 3-63 символа, уникальность)
- Проверка на зарезервированные имена (admin, api, www и т.д.)
- Админ-панель для модерации заявок с кнопками активации/отклонения

Система подписок:
- Модель Subscription с планами (триал 90 дней, месяц, квартал, год)
- Автоматическое создание триальной подписки при активации
- Методы is_expired() и days_left() для проверки статуса
- Цветовая индикация в админке (зеленый/оранжевый/красный)

Приложения:
- tenants/ - управление тенантами, регистрация, подписки
- shops/ - точки магазинов/самовывоза (tenant app)
- Обновлены миграции для всех приложений

Утилиты:
- switch_to_tenant.py - переключение между схемами тенантов
- Обновлены image_processor и image_service

Конфигурация:
- urls_public.py - роуты для public schema (админка + регистрация)
- urls.py - роуты для tenant schemas (магазины)
- requirements.txt - добавлены django-tenants, django-environ, phonenumber-field

Документация:
- DJANGO_TENANTS_SETUP.md - настройка мультитенантности
- TENANT_REGISTRATION_GUIDE.md - руководство по регистрации
- QUICK_START.md - быстрый старт
- START_HERE.md - общая документация

Использование:
1. Пользователь: http://localhost:8000/register/ → заполняет форму
2. Админ: http://localhost:8000/admin/ → активирует заявку
3. Результат: http://{schema_name}.localhost:8000/ - готовый магазин

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 19:13:10 +03:00

325 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Руководство по системе регистрации тенантов
## Что реализовано
Создана полноценная система регистрации новых магазинов (тенантов) с ручной модерацией администратором.
### 1. Модели данных ([tenants/models.py](myproject/tenants/models.py))
#### Client (обновлена)
- Добавлен `db_index` для поля `name` (ускорение поиска)
- Изменено поле `phone` на `PhoneNumberField` (поддержка РБ/РФ форматов)
- Обновлен `help_text` для `owner_email` (один email может быть у нескольких магазинов для супер-админа)
#### TenantRegistration (новая)
Модель заявки на регистрацию:
- `shop_name` - название магазина
- `schema_name` - желаемый поддомен (с валидацией regex)
- `owner_email`, `owner_name`, `phone` - контактные данные
- `status` - статус заявки: pending/approved/rejected
- `processed_at`, `processed_by` - данные обработки
- `tenant` - ссылка на созданный тенант после активации
#### Subscription (новая)
Модель подписки:
- `plan` - тип плана (триал 90 дней, месяц, квартал, год)
- `started_at`, `expires_at` - период действия
- `is_active`, `auto_renew` - статус и автопродление
- Методы: `is_expired()`, `days_left()`, `create_trial(client)`
#### RESERVED_SCHEMA_NAMES
Список зарезервированных поддоменов (admin, api, www, и т.д.)
---
### 2. Админ-панель ([tenants/admin.py](myproject/tenants/admin.py))
#### ClientAdmin (обновлена)
- Добавлена колонка `subscription_status` с цветовой индикацией
- Разрешено редактирование `schema_name` при создании нового тенанта
- Запрещено удаление тенантов через админку (для безопасности)
#### TenantRegistrationAdmin (новая)
Функции:
- Список заявок с фильтрами по статусу и дате
- Кнопки "Активировать" / "Отклонить" для каждой заявки
- Массовые действия для обработки нескольких заявок
- При активации:
- Создается тенант (Client)
- Создается домен (например: myshop.localhost)
- Создается триальная подписка на 90 дней
- Заявка помечается как "Одобрено"
#### SubscriptionAdmin (новая)
- Просмотр и управление подписками
- Цветовая индикация истекающих подписок (красный < 0 дней, оранжевый < 7 дней)
---
### 3. Публичная форма регистрации
#### [tenants/forms.py](myproject/tenants/forms.py) - TenantRegistrationForm
Валидация:
- `schema_name`: приведение к lowercase, проверка длины (3-63 символа), проверка на зарезервированные имена, проверка уникальности
- `owner_email`: проверка на дубликаты pending заявок
#### [tenants/views.py](myproject/tenants/views.py)
- `TenantRegistrationView` - форма регистрации
- `RegistrationSuccessView` - страница благодарности
#### HTML шаблоны
- [base.html](myproject/tenants/templates/tenants/base.html) - базовый шаблон с Bootstrap 5
- [registration_form.html](myproject/tenants/templates/tenants/registration_form.html) - красивая форма с валидацией
- [registration_success.html](myproject/tenants/templates/tenants/registration_success.html) - страница с инструкциями
---
## Как использовать
### Для пользователей (владельцев будущих магазинов)
1. Откройте публичную форму регистрации:
```
http://localhost:8000/register/
```
2. Заполните форму:
- Название магазина
- Желаемый поддомен (только латиница, цифры, дефис)
- Ваше имя
- Email
- Телефон
3. После отправки увидите страницу благодарности
4. Ожидайте активации администратором (в течение 24 часов)
---
### Для администратора
1. Войдите в админ-панель:
```
http://localhost:8000/admin/
```
2. Перейдите в раздел "Заявки на регистрацию"
3. Увидите список заявок со статусом "Ожидает проверки"
4. Для активации заявки:
- Кликните на кнопку "Активировать" справа от заявки
- ИЛИ выберите несколько заявок и используйте массовое действие
5. Что происходит при активации:
- Создается новый тенант (Client) с указанным schema_name
- Создается домен `{schema_name}.localhost`
- Создается триальная подписка на 90 дней
- Заявка помечается как "Одобрено"
- В поле "Созданный тенант" появляется ссылка на тенант
6. Для отклонения:
- Кликните "Отклонить"
- Заявка помечается как "Отклонено"
---
## Доступ к магазинам
После активации магазин доступен по адресу:
```
http://{schema_name}.localhost:8000/
```
Например, для магазина с `schema_name=myshop`:
```
http://myshop.localhost:8000/
```
---
## Управление подписками
### Просмотр подписок
1. Админ-панель → "Подписки"
2. Видны все подписки с информацией:
- Тип плана
- Дата начала/окончания
- Осталось дней
- Истекла или нет
### Продление подписки
1. Откройте подписку тенанта
2. Измените:
- `expires_at` - новую дату окончания
- `plan` - новый тип плана (если меняется)
3. Сохраните
### Типы планов
- **Триальный (90 дней)** - автоматически при создании
- **Месячный** - 30 дней
- **Квартальный** - 90 дней
- **Годовой** - 365 дней
---
## Технические детали
### Валидация schema_name
Regex: `^[a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9])?$`
Правила:
- Только латинские буквы в нижнем регистре
- Цифры и дефис разрешены
- Длина 3-63 символа
- Не может начинаться или заканчиваться дефисом
- Не совпадает с зарезервированными именами
### Зарезервированные имена
```python
RESERVED_SCHEMA_NAMES = [
'public', 'admin', 'api', 'www', 'mail', 'ftp', 'smtp',
'static', 'media', 'assets', 'cdn', 'app', 'web',
'billing', 'register', 'login', 'logout', 'dashboard',
'test', 'dev', 'staging', 'production', 'demo'
]
```
### Email для супер-админа
Один email может использоваться для нескольких магазинов (полезно для вас как супер-админа для входа в разные тенанты).
Для обычных пользователей форма проверяет наличие pending заявок с таким же email.
---
## Что дальше (рекомендации)
### 1. Email-уведомления
Добавить отправку писем:
- Пользователю при активации заявки
- Пользователю при истечении подписки (за 7 дней, за 1 день)
- Админу при новой заявке
### 2. Биллинг
Создать страницу `/billing/` где владелец магазина может:
- Посмотреть текущую подписку
- Продлить подписку
- Оплатить через платежную систему
### 3. Middleware для is_active
Если нужна жесткая блокировка доступа к деактивированным магазинам, создать middleware:
```python
# tenants/middleware.py
class TenantStatusMiddleware:
def __call__(self, request):
if hasattr(request, 'tenant'):
if not request.tenant.is_active:
# Показать страницу "Магазин заблокирован"
pass
sub = request.tenant.subscription
if sub.is_expired():
# Редирект на /billing/renew/
pass
return self.get_response(request)
```
### 4. Автоматическая очистка
Создать команду для удаления старых отклоненных заявок:
```bash
python manage.py cleanup_old_registrations --days=30
```
---
## Структура файлов
```
myproject/tenants/
├── models.py # Модели Client, TenantRegistration, Subscription
├── admin.py # Админ-панель с функционалом активации
├── forms.py # Форма регистрации с валидацией
├── views.py # Views для публичной регистрации
├── urls.py # Роуты /register/ и /register/success/
└── templates/tenants/
├── base.html # Базовый шаблон
├── registration_form.html # Форма регистрации
└── registration_success.html # Страница благодарности
```
---
## Тестирование
### 1. Регистрация магазина
```bash
# Запустите сервер
python manage.py runserver
# Откройте браузер
http://localhost:8000/register/
# Заполните форму:
Название: Тестовый магазин
Поддомен: testshop
Имя: Иван Иванов
Email: test@example.com
Телефон: +375291234567
# Отправьте заявку
```
### 2. Активация через админку
```bash
# Войдите в админку
http://localhost:8000/admin/
# Логин/пароль супер-админа
# Перейдите в "Заявки на регистрацию"
# Нажмите "Активировать" напротив заявки
```
### 3. Проверка созданного магазина
```bash
# Откройте браузер
http://testshop.localhost:8000/
# Должна открыться страница магазина
```
---
## Поддержка
При возникновении проблем проверьте:
1. Миграции применены: `python manage.py migrate_schemas --shared`
2. В `settings.py` приложение `tenants` в `SHARED_APPS`
3. В `urls_public.py` подключены роуты tenants
4. Виртуальное окружение активировано
5. `phonenumber_field` установлен
---
**Система готова к использованию!**
Теперь вы можете:
- Принимать заявки на регистрацию
- Модерировать их через админку
- Управлять подписками
- Контролировать доступ к магазинам