Ранее разделы с perm=None (Новости, Задачи, Дислокация, Документы, Чат,
Календарь, HR-портал, Справка) были доступны любому вошедшему — сотрудник
без назначенной группы видел почти весь портал. Теперь такие разделы
требуют хотя бы одной группы; без групп доступны только базовые:
Главная, Профиль, Поддержка IT.
- user_can_access: BASELINE_OPEN_KEYS + gate «есть ли группа» для perm=None
- PortalSectionAccessMiddleware: барьер по префиксу URL (в т.ч. вложенные
страницы вроде /tasks/5/), /settings/ не гейтим (редирект на свой профиль)
- index.html: пункты меню под can_section (сайдбар, дропдаун, bottom-nav),
секция «Управление» скрывается целиком, если пусто
- тесты: политика без-группы + прямой заход по URL; тест-фабрики выдают
группу (реальный сотрудник её имеет)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Отдельное право на редактирование карточки аптеки, формы, пресеты колонок
дислокации и правки видимости карточки.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Let admins set per-section access levels so operational data on pharmacy detail is no longer all-or-nothing for every logged-in user.
Co-authored-by: Cursor <cursoragent@cursor.com>
Вариант А — пароль ящика хранится обратимо-зашифрованным, чтобы показать
заведующему для входа:
- Pharmacy.carbonio_password (EncryptedCharField) — шифруется в БД
- sync_service при создании ящика генерирует пароль, отдаёт его в Carbonio
и сохраняет свою зашифрованную копию; на update-пути пароль не трогается
- Пароль виден в админке аптеки (readonly, расшифрованный) — вкладка Carbonio
- 2 теста (мок CarbonioService): пароль сохранён, совпадает с отданным в
Carbonio, в БД лежит шифртекстом; update не перетирает пароль
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Фундамент интеграции Carbonio на уровне модели Pharmacy (без обращений к серверу):
- Поля Pharmacy: carbonio_email, carbonio_account_id, carbonio_sync_enabled
(default False), carbonio_sync_status, carbonio_last_sync, carbonio_sync_error
- Генерация адреса <mail_prefix организации><номер>@домен (a1@, t1@, p1@...);
префикс из Directory.extra_data['mail_prefix'], домен из ConnectorConfig(carbonio)
с дефолтом aks-apteka.com.ua
- Ручной override адреса не перетирается автогенерацией
- Уникальность carbonio_email: clean() + частичный unique-констрейнт в БД
(пустые не конфликтуют); автоген при коллизии оставляет поле пустым
- 10 тестов (apps.locations.tests) — у приложения было 0
API-слой (клиент/sync/сигналы/задачи) — следующим шагом.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>