{"id":50533140,"url":"https://github.com/squ1ky/tmap-backend","last_synced_at":"2026-06-03T15:30:24.690Z","repository":{"id":359892809,"uuid":"1198149549","full_name":"squ1ky/tmap-backend","owner":"squ1ky","description":"Т-Банк Проектный практикум ИВМИИТ Команда 1","archived":false,"fork":false,"pushed_at":"2026-05-31T13:04:02.000Z","size":1038,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-31T15:03:36.768Z","etag":null,"topics":["flyway","grafana","h3","java","junit5","kafka","minio","mockito","openapi","postgresql","prometheus","redis","spring-boot","testcontainers"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/squ1ky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-01T06:52:23.000Z","updated_at":"2026-05-25T14:11:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/squ1ky/tmap-backend","commit_stats":null,"previous_names":["squ1ky/tmap-backend"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/squ1ky/tmap-backend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squ1ky%2Ftmap-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squ1ky%2Ftmap-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squ1ky%2Ftmap-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squ1ky%2Ftmap-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/squ1ky","download_url":"https://codeload.github.com/squ1ky/tmap-backend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squ1ky%2Ftmap-backend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33872297,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flyway","grafana","h3","java","junit5","kafka","minio","mockito","openapi","postgresql","prometheus","redis","spring-boot","testcontainers"],"created_at":"2026-06-03T15:30:23.704Z","updated_at":"2026-06-03T15:30:24.677Z","avatar_url":"https://github.com/squ1ky.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# T-Map – Карта живого города\n\nТепловая карта городской активности на основе обезличенных транзакционных данных.  \nВидишь в реальном времени — где сейчас людно, где пусто, где аномальный ажиотаж.\n\n\u003e Серверная часть проекта T-Map, разработанная командой бэкенда в рамках проектного практикума Т-Банка.\n\n[![CI](https://img.shields.io/github/actions/workflow/status/squ1ky/tmap-backend/ci.yaml?style=for-the-badge\u0026logo=github-actions\u0026logoColor=white\u0026label=CI)](https://github.com/squ1ky/tmap-backend/actions/workflows/ci.yaml)\n[![CD](https://img.shields.io/github/actions/workflow/status/squ1ky/tmap-backend/cd.yaml?style=for-the-badge\u0026logo=github-actions\u0026logoColor=white\u0026label=CD)](https://github.com/squ1ky/tmap-backend/actions/workflows/cd.yaml)\n![Java](https://img.shields.io/badge/Java-21-ED8B00?style=for-the-badge\u0026logo=openjdk\u0026logoColor=white)\n![Spring Boot](https://img.shields.io/badge/Spring_Boot-3.5-6DB33F?style=for-the-badge\u0026logo=springboot\u0026logoColor=white)\n![Kafka](https://img.shields.io/badge/Kafka-3.9-231F20?style=for-the-badge\u0026logo=apachekafka\u0026logoColor=white)\n![PostgreSQL](https://img.shields.io/badge/PostgreSQL-16-336791?style=for-the-badge\u0026logo=postgresql\u0026logoColor=white)\n\n---\n\n## Архитектура\n\n![Архитектура системы heatmap-api](docs/images/architecture.png)\n\nВнутренняя архитектура `heatmap-api` — **Hexagonal / DDD**: каждый домен делится на\n`domain → application → infrastructure → presentation`.\n\n---\n\n## Стек технологий\n\n| Компонент        | Технология                         | Зачем                                       |\n|------------------|------------------------------------|---------------------------------------------|\n| Язык / фреймворк | Java 21 + Spring Boot 3.5          | основа всего                                |\n| База данных      | PostgreSQL 16                      | основное хранилище                          |\n| Брокер сообщений | Apache Kafka 3.9 (KRaft)           | поток транзакционных событий                |\n| Кэш              | Redis                              | кэширование кластеров на карте              |\n| Object Storage   | MinIO                              | фото заведений                              |\n| Гео-индексация   | H3 4.1.1 (Uber)                    | шестиугольная сетка для тепловой карты      |\n| Миграции         | Flyway                             | версионирование схемы БД                    |\n| Аутентификация   | JWT (jjwt) + Refresh Token         | авторизация пользователей                   |\n| API-контракт     | OpenAPI Generator                  | spec-first, интерфейсы генерируются из yaml |\n| Мониторинг       | Prometheus + Grafana               | метрики и дашборды                          |\n| Тестирование     | JUnit 5 + Mockito + Testcontainers | тестирование кода                           |\n| Линтеры          | Checkstyle + PMD                   | качество кода                               |\n\n---\n\n## Требования\n\n- Java 21\n- Docker + Docker Compose\n- Make\n\n---\n\n## Быстрый старт\n\n```bash\ncp .env.example .env\nmake dev\n```\n\n`make dev` поднимает PostgreSQL, Kafka, Redis и MinIO в Docker, затем запускает приложение локально с профилем `local`.\n\nПосле старта:\n\n| Сервис | URL |\n|---|---|\n| Swagger UI | http://localhost:8080/swagger-ui |\n| MinIO Console | http://localhost:9001 |\n| Prometheus | http://localhost:9090 |\n| Grafana | http://localhost:3000 |\n\n---\n\n## Структура проекта\n\n```\ntmap-backend/\n├── heatmap-api/          # основной REST API (Spring Boot)\n│   └── src/main/java/ru/tbank/tmap/\n│       ├── auth/         # JWT-аутентификация, refresh-токены\n│       ├── heatmap/      # H3-тепловая карта, аномалии, история кластеров\n│       ├── venue/        # заведения (public / business / admin)\n│       ├── loyalty/      # QR-программы лояльности\n│       ├── profile/      # профиль пользователя, история\n│       └── shared/       # общие утилиты, error handling, geo-типы\n│\n├── data-generator/       # генератор транзакций (Kafka Producer)\n│   └── src/main/java/ru/tbank/tmap/generator/\n│       ├── scheduler/    # запуск по расписанию\n│       ├── service/      # генерация событий и кэш заведений\n│       └── kafka/        # публикация в топик transactions\n│\n├── docs/                 # стандарты команды (API, DB, Testing, Security, Git)\n├── grafana/              # provisioning дашбордов и datasources\n├── docker-compose.yaml   # полный стек (БД, Kafka, Redis, MinIO, Prometheus, Grafana, API)\n├── Makefile              # команды для разработки\n└── prometheus.yaml       # конфигурация Prometheus\n```\n\n---\n\n## API\n\nВсе эндпоинты доступны по базовому пути `/api/v1`. Полная спецификация — в Swagger UI.\n\n### Роли пользователей\n\n| Роль             | Доступ                                                   |\n|------------------|----------------------------------------------------------|\n| `Нет роли`       | просмотр карты и заведений                               |\n| `USER`           | профиль, qr-лояльность                                   |\n| `BUSINESS_OWNER` | + управление своими заведениями и программами лояльности |\n| `ADMIN`          | + модерация заведений и пользователей                    |\n\n---\n\n### Auth — `/api/v1/auth`\n\n| Метод | Путь | Описание |\n|---|---|---|\n| `POST` | `/auth/register` | Регистрация (email, password, nickname) |\n| `POST` | `/auth/login` | Вход — `accessToken` в теле, `refreshToken` в HTTP-only cookie |\n| `POST` | `/auth/refresh` | Обновление токена по refresh-cookie |\n| `POST` | `/auth/logout` | Выход — инвалидирует refresh-токен |\n\n---\n\n### Тепловая карта — `/api/v1/heatmap`\n\n| Метод | Путь                          | Описание                                                                        |\n|-------|-------------------------------|---------------------------------------------------------------------------------|\n| `GET` | `/heatmap/clusters`           | H3-кластеры в bbox (`swLat`, `swLng`, `neLat`, `neLng`, `resolution`, `window`) |\n| `GET` | `/heatmap/clusters/{h3Index}` | Детали кластера: история активности и флаг аномалии                             |\n\n---\n\n### Заведения (публичные) — `/api/v1/venues`\n\n| Метод | Путь                                     | Описание                                 |\n|-------|------------------------------------------|------------------------------------------|\n| `GET` | `/venues`                                | Заведения в bbox с фильтром по категории |\n| `GET` | `/venues/search`                         | Полнотекстовый поиск по названию (`?q=`) |\n| `GET` | `/venues/{id}`                           | Детальная страница заведения             |\n| `GET` | `/venues/{id}/loyalty-rules`             | Активные программы лояльности заведения  |\n| `GET` | `/venues/{id}/loyalty-rules/{ruleId}/qr` | Получить QR-код для активации (`USER`)   |\n\n---\n\n### Бизнес-кабинет — `/api/v1/business` (`BUSINESS_OWNER`)\n\n**Заведения:**\n\n| Метод    | Путь                          | Описание                                |\n|----------|-------------------------------|-----------------------------------------|\n| `POST`   | `/business/venues`            | Создать заведение (уходит на модерацию) |\n| `GET`    | `/business/venues`            | Список своих заведений                  |\n| `GET`    | `/business/venues/{id}`       | Детали своего заведения                 |\n| `PUT`    | `/business/venues/{id}`       | Обновить заведение                      |\n| `POST`   | `/business/venues/{id}/photo` | Загрузить фото (multipart)              |\n| `DELETE` | `/business/venues/{id}/photo` | Удалить фото                            |\n\n**Программы лояльности:**\n\n| Метод  | Путь                                        | Описание                                     |\n|--------|---------------------------------------------|----------------------------------------------|\n| `GET`  | `/business/venues/{id}/loyalty-rules`       | Все правила лояльности заведения             |\n| `POST` | `/business/venues/{id}/loyalty-rules`       | Создать программу лояльности                 |\n| `GET`  | `/business/loyalty-rules/{id}`              | Детали программы лояльности                  |\n| `PUT`  | `/business/loyalty-rules/{id}`              | Обновить программу                           |\n| `POST` | `/business/loyalty-rules/{ruleId}/activate` | Активировать QR клиента (сканирование)       |\n| `GET`  | `/business/loyalty-rules/{id}/history`      | История верификаций по программе (пагинация) |\n\n---\n\n### Администрирование — `/api/v1/admin` (`ADMIN`)\n\n**Пользователи:**\n\n| Метод   | Путь                        | Описание                                                                    |\n|---------|-----------------------------|-----------------------------------------------------------------------------|\n| `GET`   | `/admin/users/search`       | Поиск пользователей с фильтрами (nickname, email, role, blocked, пагинация) |\n| `PATCH` | `/admin/users/{id}/block`   | Заблокировать пользователя                                                  |\n| `PATCH` | `/admin/users/{id}/unblock` | Разблокировать пользователя                                                 |\n\n**Заведения:**\n\n| Метод  | Путь                        | Описание                                           |\n|--------|-----------------------------|----------------------------------------------------|\n| `GET`  | `/admin/venues`             | Список заведений с фильтром по статусу (пагинация) |\n| `GET`  | `/admin/venues/{id}`        | Детали заведения для модерации                     |\n| `POST` | `/admin/venues/{id}/verify` | Одобрить заведение                                 |\n| `POST` | `/admin/venues/{id}/reject` | Отклонить с причиной                               |\n\n---\n\n### Профиль — `/api/v1/profile`\n\n| Метод | Путь                       | Описание                                   |\n|-------|----------------------------|--------------------------------------------|\n| `GET` | `/profile`                 | Данные текущего пользователя               |\n| `PUT` | `/profile/password`        | Смена пароля                               |\n| `GET` | `/profile/loyalty/history` | История верификаций лояльности (пагинация) |\n\n---\n\n## Мониторинг\n\nПриложение экспортирует метрики через Spring Actuator в формате Prometheus. В compose поднимаются Prometheus и Grafana с преднастроенными дашбордами.\n\n| Сервис     | URL                   |\n|------------|-----------------------|\n| Prometheus | http://localhost:9090 |\n| Grafana    | http://localhost:3000 |\n\nЛогин Grafana: `admin` / значение `GRAFANA_ADMIN_PASSWORD` из `.env`.\n\n---\n\n## Конфигурация\n\nСкопируй `.env.example` в `.env` и при необходимости измени значения:\n\n| Переменная                    | По умолчанию            | Описание                 |\n|-------------------------------|-------------------------|--------------------------|\n| `SERVER_PORT`                 | `8080`                  | Порт приложения          |\n| `DB_HOST / DB_PORT / DB_NAME` | `localhost:5432/tmap`   | Подключение к PostgreSQL |\n| `KAFKA_BOOTSTRAP_SERVERS`     | `localhost:9094`        | Kafka bootstrap          |\n| `KAFKA_TRANSACTIONS_TOPIC`    | `transactions`          | Топик транзакций         |\n| `MINIO_ENDPOINT`              | `http://localhost:9000` | S3-совместимое хранилище |\n| `MINIO_BUCKET`                | `tmap`                  | Бакет для файлов         |\n| `JWT_SECRET`                  | `change-me-in-prod`     | JWT Secret               |\n| `JWT_ACCESS_EXPIRATION`       | `15m`                   | TTL access token         |\n| `JWT_REFRESH_EXPIRATION`      | `7d`                    | TTL refresh token        |\n| `GRAFANA_ADMIN_PASSWORD`      | `grafanapassword`       | Пароль Grafana           |\n\n---\n\n## Команды\n\n| Команда                          | Что делает                                        |\n|----------------------------------|---------------------------------------------------|\n| `make dev`                       | БД + Kafka + MinIO в докере + приложение локально |\n| `make up`                        | Всё в докере (прод-режим)                         |\n| `make down`                      | Остановить всё                                    |\n| `make db`                        | Поднять только БД                                 |\n| `make logs`                      | Логи приложения в докере                          |\n| `make build`                     | Собрать jar                                       |\n| `make migrate name=create_users` | Создать новую Flyway-миграцию                     |\n| `make lint`                      | Запустить все линтеры (Checkstyle + PMD)          |\n| `make lint-checkstyle`           | Только Checkstyle                                 |\n| `make lint-pmd`                  | Только PMD                                        |\n\n---\n\n## Тестирование\n\nТесты интеграционные — работают на реальных контейнерах через Testcontainers (PostgreSQL, Kafka).\n\n```bash\n./mvnw test\n```\n\n---\n\n## Профили окружения\n\n| Профиль | Когда используется                    |\n|---------|---------------------------------------|\n| `local` | локальная разработка (`make dev`)     |\n| `prod`  | продакшн и docker-compose (`make up`) |\n\n---\n\n## Документация команды\n\n| Документ                                        | Тема                                              |\n|-------------------------------------------------|---------------------------------------------------|\n| [CODING_STANDARDS.md](docs/CODING_STANDARDS.md) | Стандарты кода, соглашения по именованию, API     |\n| [GIT_CONVENTIONS.md](docs/GIT_CONVENTIONS.md)   | Ветвление, коммиты, процесс PR                    |\n| [docs/standards/](docs/standards/)              | Детальные стандарты: API, БД, тесты, безопасность |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsqu1ky%2Ftmap-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsqu1ky%2Ftmap-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsqu1ky%2Ftmap-backend/lists"}