commit 8a97ce6d54a81524d0d05bb50058433100b49d8a Author: talorr Date: Fri Mar 27 03:35:08 2026 +0300 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..4440fc2 --- /dev/null +++ b/README.md @@ -0,0 +1,129 @@ +# Alpinbet Signals Platform + +Платформа для сбора, обработки и доставки сигналов Alpinbet. + +## Состав проекта + +- `backend/` — Express + Prisma API, авторизация, сигналы, push, админские маршруты. +- `frontend/` — Nuxt-клиент, лента сигналов, настройки, PWA/mobile shell. +- `parser/` — парсер Alpinbet, который читает HTML, извлекает сигналы и синхронизирует их в PostgreSQL. +- `forecast-ocr-service/` — OCR-сервис для распознавания прогноза с изображения. +- `traefik/` — reverse proxy, TLS и роутинг доменов. +- `docker-compose.yml` — основной способ запуска. + +## Как это работает + +1. `parser` получает страницы Alpinbet через сохраненную сессию. +2. Из HTML извлекаются сигналы, коэффициенты, команды и изображения прогноза. +3. Если у сигнала есть картинка прогноза, `parser` скачивает ее и отправляет multipart-запросом в `forecast-ocr-service`. +4. OCR-сервис возвращает `rawForecast` и нормализованный `forecast`. +5. `parser` сохраняет сигнал в PostgreSQL. +6. `backend` отдает API и отправляет push-уведомления. +7. `frontend` показывает сигналы, доступы и настройки пользователя. + +## Безопасность в текущем состоянии + +- JWT для веба хранится в `HttpOnly` cookie. +- Веб-клиент больше не хранит токен в `localStorage`. +- OCR больше не принимает произвольный `imageUrl`, только файл. +- Наружу должны смотреть только `80` и `443`. +- `adminer` и `dockmon` сейчас закомментированы в `docker-compose.yml`. +- Traefik dashboard использует `usersFile`, а не пароль, зашитый в репозиторий. + +## Быстрый старт + +1. Скопируйте `.env.example` в `.env`. +2. Заполните `.env` реальными значениями. +3. Проверьте `parser/.env`. +4. Поднимите стек: + +```bash +docker compose up -d --build +``` + +5. Примените схему БД: + +```bash +docker compose exec backend npx prisma db push +``` + +## Полезные команды + +Сборка: + +```bash +npm run build +cd backend && npm run build +cd frontend && npm run build +``` + +Проверка итогового compose-конфига: + +```bash +docker compose config +``` + +Проверка OCR локально: + +```bash +curl http://localhost:4010/health +curl -X POST http://localhost:4010/ocr/forecast -F "image=@./forecast-ocr-service/tmp-forecast-test.png" +``` + +## Переменные окружения + +Корневой `.env`: + +- `POSTGRES_DB` +- `POSTGRES_USER` +- `POSTGRES_PASSWORD` +- `JWT_SECRET` +- `PARSER_INTERNAL_SECRET` +- `NUXT_PUBLIC_API_BASE` +- `APP_PUBLIC_URL` +- `CORS_ORIGIN` +- `TRAEFIK_ACME_EMAIL` +- `SMTP_*` +- `VAPID_*` +- `FIREBASE_*` + +`parser/.env`: + +- `DATABASE_URL` +- `ALPINBET_BASE_URL` +- `ALPINBET_TARGET_URL` +- `ALPINBET_BOTS` +- `AUTH_ENABLED` +- `AUTH_LOGIN_URL` +- `AUTH_USERNAME` +- `AUTH_PASSWORD` +- `SESSION_FILE` +- `STATE_FILE` +- `POLL_INTERVAL_MS` +- `FORECAST_OCR_URL` +- `FORECAST_OCR_TIMEOUT_MS` +- `FORECAST_OCR_ENABLED` +- `BACKEND_INTERNAL_URL` +- `PARSER_INTERNAL_SECRET` + +## Чеклист Перед Деплоем + +- Заполните `.env` реальными секретами и не оставляйте `change_me_*`. +- Смените `JWT_SECRET`, `PARSER_INTERNAL_SECRET`, `POSTGRES_PASSWORD`, SMTP и Firebase credentials, если они уже где-то светились. +- Создайте `traefik/secrets/dashboard-users` на сервере. +- Проверьте, что наружу открыты только `80` и `443`. +- Убедитесь, что `adminer` и `dockmon` остаются закомментированными. +- Выполните `docker compose config` перед запуском. +- Поднимите стек через `docker compose up -d --build`. +- После старта выполните `docker compose exec backend npx prisma db push`. +- Проверьте `https://antigol.ru`, `https://api.antigol.ru/health` и обычный логин. +- Автобэкап PostgreSQL включён сервисом `postgres-backup`, архивы складываются в `./backups`. +- Сделайте контрольный backup PostgreSQL перед следующими продовыми изменениями. + +## Полезные файлы + +- [docker-compose.yml](/C:/Users/vlad/Documents/Projects/alpinbet-parser/docker-compose.yml) +- [traefik/dynamic/routes.yml](/C:/Users/vlad/Documents/Projects/alpinbet-parser/traefik/dynamic/routes.yml) +- [backend/prisma/schema.prisma](/C:/Users/vlad/Documents/Projects/alpinbet-parser/backend/prisma/schema.prisma) +- [parser/src/forecast-ocr.js](/C:/Users/vlad/Documents/Projects/alpinbet-parser/parser/src/forecast-ocr.js) +- [forecast-ocr-service/src/index.js](/C:/Users/vlad/Documents/Projects/alpinbet-parser/forecast-ocr-service/src/index.js)