Metadata-Version: 2.4
Name: yeti3-guidance
Version: 0.1.1
Summary: Role-aware help, business playbooks and resumable onboarding for enterprise sites
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: yeti3-core<0.5,>=0.4.4
Provides-Extra: django
Requires-Dist: Django<6.1,>=5.2; extra == "django"

# YETI³ Guidance 0.1.1

Переиспользуемый SDK-модуль `guidance.enterprise` для ERP, корпоративных порталов
и рабочих кабинетов. Ядро на Python не зависит от Django. Не открывает базу,
не делает сетевых запросов и не запускает бизнес-команды при импорте.

## Что включено

15 русскоязычных руководств, 64 шага: знакомство, профиль, организация, доступы,
MS AD / FreeIPA / OpenLDAP, счета и периоды, первая операция, сторно, закрытие
периода, ежедневный контроль, описание бизнес-процесса, масштаб внедрения,
аудит, модули и устранение проблем. Бизнес-гайды не являются страновыми
налоговыми правилами. Отсутствующие возможности отмечены в тексте.

Помощь всегда открывается по запросу: нет автоматических модальных окон,
рассылок, таймеров и повторных напоминаний. Активный мастер показывает
компактную полосу на рабочих страницах. Пауза сохраняет шаг, продолжение
возвращает к нему. Отмена сбрасывает шаги, сохраняя бизнес-данные; перезапуск
начинает с первого шага. Подтверждение отмены/перезапуска расположено внутри
раскрываемого блока управления. Отдельное руководство можно читать целиком.

## Установка

```sh
python -m pip install --index-url https://engine.yeti3.ru/sdk/simple/ yeti3-guidance==0.1.1
```

Для HTTP-адаптера установите Django 5.2–6.0 из принятого в вашем проекте
источника зависимостей. В ERP используется PostgreSQL 17. Пакет не создаёт
SQLite и не выбирает базу автоматически.

```python
from yeti3_guidance.module import Package
engine.register(Package())
engine.boot()
guidance = engine.capabilities.get('guidance.enterprise')
pack = guidance.load_pack()
```

Манифест обнаруживается через entry point `yeti3.packages`. Capability содержит
`load_pack`, `available` и чистую функцию `transition`. Без HTTP-адаптера
состояние хранит вызывающий проект; `Progress` — неизменяемый dataclass.

## Подключение Django

1. Добавьте `yeti3_guidance` в `INSTALLED_APPS`.
2. Подключите `path('help/', include('yeti3_guidance.urls'))`.
3. Задайте `YETI3_GUIDANCE_CONTEXT = 'your_app.guidance.context'`.
4. Добавьте `yeti3_guidance.context_processors.guidance` в context processors.
5. Подключите CSS `yeti3_guidance/guidance.css` и шаблон
   `yeti3_guidance/inline.html` в рабочую оболочку. Добавьте постоянную ссылку
   «Помощь» в навигацию, на вход и на публичную страницу.
6. Выполните миграции отдельной ролью владельца, разрешите runtime-роли
   SELECT/INSERT/UPDATE на `yeti3_guidance_guideprogress`, работу с её sequence
   и блокировку собственной auth user row. Затем collectstatic и проверку.
7. Разрешите чтение `/help/` до допуска к бизнес-данным. POST требует входа,
   CSRF и серверной проверки доступности руководства. Сами бизнес-разделы
   продолжают проверять роли независимо от помощи.

Контекст проекта возвращает обычный template context и обязательные поля:

```python
def context(request):
    return {
        'guidance_role': 'guest',  # owner/admin/finance/viewer/member/guest
        'guidance_role_label': 'Знакомство с платформой',
        'guidance_scope': 'personal',  # серверный user/workspace context
        'guidance_routes': {'profile': '/profile/', 'home': '/'},
        'guidance_base': 'public_base.html',
    }
```

`guidance_scope` всегда выводится из проверенного сервером членства пользователя,
а не напрямую из query/POST. Для multi-tenant проекта используйте UUID рабочего
пространства. Сохранение изолировано по user + scope + guide. Host routes:
`profile`, `home`, `companies`, `access`, `integrations`, `directory_login`,
`entity_setup`, `ledger`, `ledger_new`, `audit`, `modules`. Не передавайте ссылки
на недоступные функции; отсутствующий route не становится кнопкой. `entity_setup`
должен вести к выбранной компании либо к списку выбора, а не к чужому юрлицу.
Host base содержит блок `content`, русский язык, responsive viewport и CSRF.
Стили используют общие CSS tokens, с резервными значениями.

## Состояние и безопасность

Состояния: new → active → paused/resumed/completed; cancel → cancelled,
restart → active на первом шаге. Следующий шаг — подтверждение пользователя,
а не автоматическая проверка выполненной настройки. Не выдавайте статус
completed за бизнес-готовность или юридическую аттестацию.

POST принимает `action`, `revision`, для cancel/restart — `confirmed=yes`.
Каждый переход увеличивает revision; устаревшая вкладка получает HTTP 409.
Блокировка auth user row сериализует управление мастерами одного пользователя.
Новый мастер ставит предыдущий на паузу в том же scope. При смене версии гайда
продолжение требует явного перезапуска. GET не меняет прогресс. Внешний redirect
не принимается. Хранятся только ID гайда, его версия, шаг, статус и timestamp,
без ответов на формы, паролей и контактных данных.

## Контент и проверка

`packs/enterprise.json`: схема `yeti3.guidance-pack/v1`, ID, версия, локаль,
роли, название, краткое описание, подготовка, шаги, критерии проверки и ссылки
на документацию поставщиков. При изменении семантики шагов повышайте версию
руководства и пакета, затем выпускайте новую immutable wheel-версию.

```sh
python -m unittest discover -s tests -v
# В ERP, только на отдельной PostgreSQL test database:
python manage.py test core.test_guidance core.test_sdk --noinput
```

SDK-проверки покрывают переходы, роли, версии и полноту pack. ERP-проверки
покрывают CSRF, раннюю помощь без обхода допуска, scope, чужие роли,
конфликт вкладок, смену мастера, отсутствие изменения бизнес-данных,
поиск и рендер всех доступных руководств. Проверка LDAP на реальном каталоге
является отдельным этапом подключения, а не результатом прохождения мастера.
