invix_test_task/README.md

40 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Магазин
Минимальный интернет-магазин: каталог, карточка, корзина и заказ без оплаты.
Сайт открывается на [http://localhost:8088](http://localhost:8088). Порт 8080 на этой машине уже занят, поэтому gateway выведен на 8088. Консоль хранилища: [http://localhost:9001](http://localhost:9001) (`minio` / `minioadmin`). Образ `pgsty/silo` — публичная сборка MinIO: исходный `minio/minio` с Docker Hub больше не скачивается без аккаунта.
## Запуск
Нужен Docker.
```bash
docker compose up --build
```
API, веб и бот поднимаются в двух репликах. Снаружи опубликован только gateway на порту 8080: он заново резолвит имя `web` и распределяет запросы по копиям.
Бот молчит, пока в окружении нет токена. Чтобы включить его:
```bash
set BOT_TOKEN=123456:telegram-token
docker compose up --build
```
В Telegram: `/catalog`, `/cart`, `/checkout`. Имя и телефон бот хранит в Postgres, не в памяти процесса.
## Что специально сделано stateless
- Сессия сайта — строка в `web_sessions` и HttpOnly-кука. Её принимает любая реплика API.
- Корзина и заказ лежат в Postgres. Повторное добавление одного товара — `INSERT ... ON CONFLICT`, две реплики не создают две строки.
- Оформление блокирует строки корзины `FOR UPDATE` и в той же транзакции пишет заказ.
- Картинки читаются из MinIO. На диск контейнера они не сохраняются.
- Бот в режиме polling: одна реплика держит advisory lock и вызывает `getUpdates`, вторая ждёт. Telegram не принимает два poller на один токен. Повторный `update_id` отсекается первичным ключом `telegram_updates`. Сообщения одного чата сериализуются `pg_advisory_xact_lock`.
- `BOT_MODE=webhook` и `WEBHOOK_URL` переключают бота на webhook: lock не берётся, работают все реплики, дедупликация та же. Нужен публичный HTTPS, который Telegram достучится до `bot:8081`.
Пароли в compose — только для локального демо.
## Запущенный пример
на веб - invix-test.bratskih.tech
бот тг - @invix_test12345_task_bot