onboarding

Onboarding Page

Страница онбординга показывается когда на сайте нет ни одной заметки. Помогает новому пользователю начать работу.

Логика

Пользователь заходит на сайт
    ↓
notes.Size() == 0?
    ↓ да
Показать страницу онбординга
    ↓
Пользователь - админ?
    ↓ нет                          ↓ да
"Войдите как админ              Показать ссылку на скачивание
 чтобы начать настройку"        /_system/onboarding-vault
    ↓
После загрузки архива появится index-страница → онбординг исчезнет

Где добавить условие

Вариант 1: Backend (internal/case/rendernotepage/resolve.go)

В функции Resolve() проверить notes.Size() == 0 перед поиском страницы:

if notes.Size() == 0 {
    return &Response{OnboardingMode: true, IsAdmin: isAdmin}, nil
}

Плюсы:

  • Одна точка проверки
  • Работает для любого пути

Минусы:

  • Нужен новый шаблон или флаг в Response

Вариант 2: Frontend (отдельный компонент)

Добавить проверку в JS при рендеринге страницы.

Минусы:

  • Сложнее интегрировать с SSR
  • Дублирование логики

Рекомендация

Вариант 1 (Backend). Добавить:

  1. Поле OnboardingMode bool в Response
  2. Проверку в Resolve() до поиска страницы
  3. Условие в view.html для рендеринга онбординг-контента

UI онбординга

Для гостя/читателя

┌─────────────────────────────────────┐
│                                     │
│    🚀 Сайт в процессе настройки     │
│                                     │
│    Войдите как администратор        │
│    чтобы начать работу              │
│                                     │
│         [Войти]                     │
│                                     │
└─────────────────────────────────────┘

Для админа

┌─────────────────────────────────────┐
│                                     │
│    🎉 Добро пожаловать!             │
│                                     │
│    Скачайте стартовый архив         │
│    и откройте его в Obsidian        │
│                                     │
│    [Скачать архив]                  │
│    /_system/onboarding-vault        │
│                                     │
│    Архив содержит:                  │
│    • Настроенный плагин синхронизации │
│    • API-ключ для вашего сайта      │
│    • Демо-заметки для старта        │
│                                     │
└─────────────────────────────────────┘

Нюансы и подводные камни

1. Когда именно показывать онбординг?

Проблема: notes.Size() == 0 — но какие notes? LatestNoteViews или LiveNoteViews?

Решение: Проверять LatestNoteViews — если даже черновиков нет, значит сайт пустой.

2. Что если пользователь удалил все заметки?

Проблема: Пользователь случайно удалил всё → снова показывается онбординг.

Решение: Это нормальное поведение. Онбординг — это просто "нет контента", неважно почему.

3. Авторизация на странице онбординга

Проблема: Нужен компонент $trip2g_user_space для кнопки входа, но страница рендерится на backend.

Варианты:

  • A) Включить минимальный JS с компонентом авторизации
  • B) Ссылка на /admin (там есть авторизация)
  • C) Простая форма email/code прямо в HTML

Решение: Вариант B — ссылка на /admin. Простейшее решение, работает уже сейчас.

4. Локализация

Проблема: Как определить язык пользователя для онбординга?

Решение: Использовать Accept-Language header или показывать на обоих языках.

5. SEO и индексация

Проблема: Поисковики могут проиндексировать страницу онбординга.

Решение: Добавить <meta name="robots" content="noindex"> для страницы онбординга.

6. Кэширование

Проблема: Страница онбординга может закэшироваться.

Решение: Не кэшировать онбординг (Cache-Control: no-store).

7. Пути кроме /

Проблема: Пользователь заходит на /some-page → что показывать?

Решение: Показывать онбординг на любом пути если notes.Size() == 0. Неважно какой путь запросили — контента всё равно нет.

8. API и GraphQL

Проблема: Онбординг влияет только на HTML-страницы или на API тоже?

Решение: Только HTML. API должен работать как обычно (возвращать пустые списки).

9. /_system/* пути

Проблема: Системные пути не должны показывать онбординг.

Решение: Проверка notes.Size() == 0 должна быть ПОСЛЕ проверки системных путей. В текущем коде системные пути уже фильтруются раньше.

10. Endpoint /_system/onboarding-vault

Проблема: Этот endpoint требует авторизации админа?

Решение: Проверить и убедиться что да. Нельзя давать API-ключ неавторизованным.

Существующие компоненты

  • assets/ui/admin/onboardingvault/ — админская страница (удалить после реализации)
  • /_system/onboarding-vault — endpoint для скачивания архива

Файлы для изменения

  1. internal/case/rendernotepage/resolve.go — добавить проверку
  2. internal/case/rendernotepage/view.html — добавить шаблон онбординга
  3. e2e/setup.spec.js — добавить тест онбординга в начало (до загрузки данных)
  4. assets/ui/admin/onboardingvault/ — удалить после реализации

E2E тестирование

Тест онбординга нужно добавить в начало e2e/setup.spec.js до создания API ключа и загрузки данных:

test('shows onboarding page when no notes', async ({ page }) => {
  await page.goto('/');

  // Должен показаться онбординг, а не 404
  await expect(page.locator('[data-onboarding]')).toBeVisible();
  await expect(page.getByText('Войдите как администратор')).toBeVisible();
});

test('shows download link for admin', async ({ page }) => {
  // ... авторизоваться как админ ...
  await page.goto('/');

  await expect(page.getByText('Скачать архив')).toBeVisible();
  await expect(page.locator('a[href="/_system/onboarding-vault"]')).toBeVisible();
});