# Развёртывание Romanian Trainer — полный гайд

Что получится в итоге: один HTML-файл, залитый на хостинг, с облачной БД, входом через Google и поддержкой множества пользователей. Каждый пользователь видит только свои карточки.

---

## Шаг 1. Supabase — создать проект

1. Зайти на **https://supabase.com**, зарегистрироваться (через GitHub или email).
2. **New project** → выбрать организацию → придумать имя (например `romanian-trainer`) → задать пароль БД (сохранить в менеджер паролей) → выбрать регион поближе (**Frankfurt** для Европы).
3. Подождать 1–2 минуты, пока проект создастся.
4. В левом меню: **Project Settings → API**. Там понадобятся два значения:
   - **Project URL** — типа `https://xxxxxxxxxxxx.supabase.co`
   - **anon public** ключ — длинная строка `eyJ...`

Эти два значения пойдут в настройки тренажёра (раздел «Облачная синхронизация»).

---

## Шаг 2. Supabase — создать таблицу и политики

В левом меню: **SQL Editor → New query**. Вставить и запустить этот SQL целиком:

```sql
-- Таблица профилей пользователей
create table if not exists public.ro_profiles (
  id         bigserial primary key,
  user_id    uuid not null references auth.users(id) on delete cascade,
  name       text not null,
  data       jsonb not null,
  updated_at timestamptz not null default now(),
  unique(user_id, name)
);

-- Индекс для быстрой выборки
create index if not exists ro_profiles_user_idx on public.ro_profiles(user_id);

-- Включить Row Level Security (ключевое для изоляции пользователей!)
alter table public.ro_profiles enable row level security;

-- Политики: каждый видит и правит ТОЛЬКО свои записи
create policy "users read own profiles"
  on public.ro_profiles for select
  using (auth.uid() = user_id);

create policy "users insert own profiles"
  on public.ro_profiles for insert
  with check (auth.uid() = user_id);

create policy "users update own profiles"
  on public.ro_profiles for update
  using (auth.uid() = user_id)
  with check (auth.uid() = user_id);

create policy "users delete own profiles"
  on public.ro_profiles for delete
  using (auth.uid() = user_id);
```

Нажать **Run**. Должно появиться `Success. No rows returned`.

Что это даёт: хоть все пользователи пишут в одну таблицу, Row Level Security на уровне Postgres гарантирует, что Маша физически не может прочитать строки Пети — даже если бы очень хотела. Даже через прямой SQL через anon-ключ.

---

## Шаг 3. Google Cloud Console — OAuth клиент

1. Зайти на **https://console.cloud.google.com/**
2. Создать новый проект (кнопка сверху) или выбрать существующий.
3. В поиске сверху: **APIs & Services → OAuth consent screen**
   - User Type: **External** → Create
   - App name: `Romanian Trainer` (любое)
   - User support email: свой gmail
   - Developer contact: свой gmail
   - Остальное можно пропустить → Save and Continue → Save and Continue → Back to Dashboard
   - **Test users**: добавить свой gmail и жены (пока приложение в режиме Testing, только они смогут входить; можно потом опубликовать)
4. В левом меню: **Credentials → Create Credentials → OAuth client ID**
   - Application type: **Web application**
   - Name: `Romanian Trainer`
   - **Authorized JavaScript origins**: `https://<твой-домен>` (тот, куда зальёшь HTML; если пока не знаешь — добавь позже)
   - **Authorized redirect URIs**: тут ОЧЕНЬ важно — вставить URL из Supabase. Взять его в Supabase: **Authentication → Providers → Google → Callback URL (for OAuth)**. Выглядит как: `https://xxxxxxxxxxxx.supabase.co/auth/v1/callback`
   - Create
5. Всплывёт окно с **Client ID** и **Client Secret** — скопировать оба.

---

## Шаг 4. Supabase — включить Google провайдер

1. В Supabase: **Authentication → Providers → Google** → Enable
2. Вставить **Client ID** и **Client Secret** из предыдущего шага.
3. **Save**.
4. Там же, в **Authentication → URL Configuration**:
   - **Site URL**: основной адрес твоего сайта (например `https://trainer.twoj-domen.ru`)
   - **Redirect URLs**: добавить все адреса, откуда пользователи могут логиниться:
     - `https://trainer.twoj-domen.ru/**`
     - `http://localhost:5500/**` (для локальной разработки, если будешь тестить)

Звёздочки `/**` важны — без них redirect после OAuth может не сработать.

---

## Шаг 5. Хостинг HTML-файла

Файл `romanian-trainer-cloud.html` — это самодостаточный SPA, не нужен бэкенд, сборка или Node.js. Варианты:

### Вариант А: Cloudflare Pages (бесплатно, быстро)

1. **https://dash.cloudflare.com/** → Workers & Pages → Create → Pages → Upload assets
2. Project name: `romanian-trainer`
3. Перетащить файл (можно папку с одним файлом — тогда его надо переименовать в `index.html`)
4. Deploy
5. Через 30 секунд дадут адрес вида `romanian-trainer.pages.dev`
6. Можно привязать свой домен в настройках проекта.

### Вариант B: Netlify (похоже на Cloudflare)

1. **https://app.netlify.com/drop** — просто перетащить файл (переименовав в `index.html`).
2. Готово, дадут адрес `xxx.netlify.app`.

### Вариант C: Свой VPS / Beget (у тебя уже есть хостинг)

Раз у тебя есть Beget и опыт с WordPress/VPS — просто положи `romanian-trainer-cloud.html` как `index.html` в любую поддиректорию, например `trainer.tvoi-domen.ru`. Готово. Никаких настроек PHP, БД, кэша не нужно.

**Важно**: обязательно HTTPS. Google OAuth не работает на голом HTTP (кроме `localhost`). У Cloudflare/Netlify HTTPS по умолчанию, у Beget включается галочкой в панели.

### После деплоя

Зайти на сайт → Настройки → блок «Облачная синхронизация» → вставить:
- **Supabase URL** (из шага 1.4)
- **anon key** (из шага 1.4)
- Сохранить (страница перезагрузится)

Появится кнопка **Войти через Google**. Нажать → выбрать гугл-аккаунт → вернуться на сайт уже авторизованным.

---

## Шаг 6. Многопользовательская работа

Дальше всё работает само:

- **Каждый гугл-аккаунт = отдельный `user_id`** в Supabase.
- Внутри одного аккаунта можно создавать несколько **локальных профилей** («Иван», «Жена», «Сын» — как уже реализовано в шапке приложения).
- Все профили одного гугл-аккаунта синхронизируются в облако под одним `user_id`, но разными строками таблицы (по полю `name`).
- Разные гугл-аккаунты друг друга **не видят вообще** — RLS-политики из шага 2 физически запрещают.
- Автосинхронизация работает с задержкой 4 секунды после последнего изменения, кнопки «Скачать» / «Загрузить» — для ручного принудительного сохранения.

### Сценарий «одна семья — два человека»

Вариант 1 (рекомендую): оба входят под **одним** гугл-аккаунтом (например, заведите специально `romana.family@gmail.com`). Внутри создают два локальных профиля «Иван» и «Жена». Оба синхронизируются через одну учётку в Supabase. Проще всего.

Вариант 2: каждый под **своим** гугл-аккаунтом. Тогда прогресс полностью изолирован — никто не видит карточки другого. Удобно если у вас сильно разный уровень и не хотите мешать стрики друг другу.

### Сценарий «много незнакомых пользователей»

Работает из коробки, никаких изменений не нужно. Ограничения бесплатного Supabase:
- 500 МБ БД (сотни пользователей уместятся легко — каждый профиль это ~10–50 КБ JSON)
- 50 000 MAU (monthly active users) на Authentication
- 5 ГБ трафика / мес

Для домашнего/дружеского использования хватает с огромным запасом. Если станет тесно — Pro план $25/мес поднимает лимиты в 10–20 раз.

---

## Шаг 7. Опубликовать Google OAuth (если нужны внешние пользователи)

Пока приложение в режиме **Testing**, входить могут только те, кого ты добавил в **Test users** (максимум 100 человек). Это нормально для семьи/друзей.

Если нужно открыть регистрацию всем:
1. **Google Cloud Console → OAuth consent screen → Publish app**
2. Google запросит верификацию, если запрашиваются sensitive scopes. Для базового входа (email + profile) верификация **не нужна** — приложение сразу становится публичным.

---

## Что если что-то не работает

**«Войти через Google» не открывает окно**
- Проверить консоль браузера (F12). Обычно ошибка в `Redirect URI mismatch` — значит URL в Google Console не совпадает с тем, что отправляет Supabase. Скопировать Callback URL из Supabase → вставить 1-в-1 в Google Console → сохранить.

**После логина выкидывает обратно без сессии**
- В Supabase → Authentication → URL Configuration — проверить что **Site URL** совпадает с адресом, откуда заходишь, и в **Redirect URLs** есть `https://tvoj-domen/**` со звёздочками.

**Ошибка `new row violates row-level security policy`**
- Значит SQL из шага 2 не выполнился полностью. Перезапустить его в SQL Editor.

**Данные не синхронизируются**
- Открыть DevTools → Network → отфильтровать по `supabase.co`. Посмотреть, какие запросы уходят и с какой ошибкой. Чаще всего это `401 Unauthorized` — значит сессия протухла, надо выйти и войти заново.

**Google OAuth просит верификацию для личного gmail**
- Значит приложение уже в Production-режиме. Вернуть в Testing: Google Cloud → OAuth consent screen → Back to Testing.

---

## TL;DR чек-лист

- [ ] Supabase проект создан, URL и anon key записаны
- [ ] SQL из шага 2 выполнен
- [ ] Google Cloud OAuth client создан, redirect URI = supabase callback
- [ ] Supabase → Google provider включен, client id/secret вставлены
- [ ] Supabase → URL Configuration настроены (Site URL + Redirect URLs)
- [ ] HTML залит на хостинг по HTTPS
- [ ] В настройках тренажёра вставлены URL и anon key
- [ ] Кнопка «Войти через Google» работает
- [ ] Прогресс синхронизируется между устройствами

Удачи в румынском 🇷🇴
