An open API service indexing awesome lists of open source software.

https://github.com/lmoroz/beauty-book

Beauty salon booking platform protopype with AI-powered LLM chat agent, real-time scheduling, and admin dashboard. Yii2 REST API + Vue 3 SPA.
https://github.com/lmoroz/beauty-book

ai-agent booking-system docker function-calling javascript llm php redis rest-api spa sse vite vue3 yii2

Last synced: 2 months ago
JSON representation

Beauty salon booking platform protopype with AI-powered LLM chat agent, real-time scheduling, and admin dashboard. Yii2 REST API + Vue 3 SPA.

Awesome Lists containing this project

README

          

# BeautyBook

Платформа онлайн-записи для салонов красоты с моделью коворкинга — мастера арендуют рабочие места, а салон предоставляет инфраструктуру для работы с клиентами: расписание, онлайн-запись, уведомления и аналитику.

## Бизнес-модель

Трёхсторонняя система с разделением ролей:

- **Салон** — управляет пространством, контролирует мастеров, отслеживает общую эффективность
- **Мастер** — независимый специалист, арендующий рабочее место, управляет своими услугами, расписанием и клиентами
- **Клиент** — просматривает каталог, записывается на приём, получает напоминания

## Стек технологий

| Слой | Технология |
|----------------------------|----------------------------------|
| Бэкенд | PHP 7.4+ / Yii2 (Basic Template) |
| База данных | MySQL 8.0 |
| Кеш / Очередь / Блокировки | Redis 7.x |
| Фронтенд | Vue 3 + Vite |
| HTTP-сервер | Nginx |
| Инфраструктура | Docker Compose |

## Архитектура

Приложение построено по принципу разделения — Yii2 предоставляет версионированный REST API, Vue 3 SPA потребляет его как самостоятельный клиент.

```
beautybook/

├── docker/ # Конфигурация Docker
│ ├── nginx/default.conf # Nginx reverse proxy
│ ├── php/Dockerfile # PHP-FPM с расширениями
│ └── redis/redis.conf # Конфигурация Redis

├── api/ # Yii2 Basic Template — REST API
│ ├── config/
│ │ ├── db.php # Подключение к MySQL
│ │ ├── redis.php # Подключение к Redis
│ │ └── web.php # Конфигурация приложения, URL-правила
│ ├── controllers/api/v1/ # Версионированные API-контроллеры
│ │ ├── BookingController.php
│ │ ├── MasterController.php
│ │ ├── ScheduleController.php
│ │ └── ServiceController.php
│ ├── models/ # ActiveRecord-модели
│ │ ├── Booking.php
│ │ ├── Master.php
│ │ ├── Salon.php
│ │ ├── Service.php
│ │ └── TimeSlot.php
│ ├── components/ # Redis-компоненты
│ │ ├── RedisLock.php # Распределённая блокировка при бронировании
│ │ ├── RedisQueue.php # Очередь уведомлений
│ │ └── RateLimiter.php # Ограничение частоты запросов
│ ├── workers/
│ │ └── NotificationWorker.php # Обработчик очереди (консольная команда)
│ └── migrations/ # Схема базы данных

├── frontend/ # Vue 3 SPA (Vite)
│ └── src/
│ ├── views/ # Страницы
│ ├── components/ # Переиспользуемые UI-компоненты
│ ├── composables/ # Хуки Composition API
│ ├── stores/ # Pinia — управление состоянием
│ ├── router/ # Vue Router
│ └── api/ # Axios HTTP-слой

├── docker compose.yml
└── README.md
```

## Основные возможности

### Онлайн-запись

Клиент выбирает мастера, услугу, свободный тайм-слот и подтверждает запись. Процесс бронирования использует **распределённую блокировку Redis** (`SETNX` с TTL), чтобы предотвратить гонку при одновременном бронировании одного слота двумя клиентами.

### Умное расписание

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

### Очередь уведомлений

Подтверждения бронирований и напоминания о записях обрабатываются асинхронно через **очередь на Redis** (Lists с `LPUSH`/`BRPOP`). Выделенный консольный воркер потребляет очередь и отправляет уведомления.

### Ограничение частоты запросов (Rate Limiting)

Публичные эндпоинты защищены **Sliding Window Rate Limiter** на основе Redis Sorted Sets. Это предотвращает спам бронирований и злоупотребление API без влияния на легитимный трафик.

### Обновления в реальном времени

Изменения расписания транслируются через **Redis Pub/Sub → SSE (Server-Sent Events)**, обеспечивая мгновенную синхронизацию для всех участников:

- **Дашборд мастера** — новые бронирования и отмены отображаются в расписании без перезагрузки страницы
- **Виджет бронирования клиента** — если другой клиент забронировал слот, пока первый выбирает время, занятый слот плавно исчезает из списка доступных, а если он был уже выбран — сбрасывается с предупреждением

### Ролевой доступ

| Роль | Доступ |
|--------|------------------------------------------------------------------------------------|
| Клиент | Просмотр каталога, запись на приём, проверка статуса записи |
| Мастер | Управление расписанием, просмотр услуг, подтверждение и отмена записей |
| Админ | Управление мастерами, услугами и категориями, настройки салона, базовая статистика |

### 🤖 AI-агент (Booking Assistant)

В приложении встроен **AI-агент** — интеллектуальный помощник в онлайн-чате, который помогает клиентам подобрать мастера, услугу и удобное время для записи в естественно-языковом диалоге.

**Как это работает:**

```text
Клиент (Vue Chat Widget)
↕ WebSocket / SSE
Yii2 API (POST /api/v1/chat)
↕ HTTP
LLM-провайдер (OpenAI / Ollama)
↕ Function Calling
Инструменты агента → БД / Redis
```

Агент умеет:

- Искать мастеров по специализации или имени
- Показывать услуги и цены конкретного мастера
- Проверять свободные слоты на нужную дату
- Создавать и отменять бронирования
- Сообщать статус записи

Контекст разговора хранится в **Redis** (TTL 1 час) на стороне сервера и в **localStorage** на стороне клиента. Диалог сохраняется между вкладками и перезагрузками; новый разговор начинается после 4 часов неактивности.

Если агент не может обработать запрос — предлагает связаться с администратором салона.

Демонстрация AI-ассистента

## API

Базовый путь: `/api/v1/`

| Метод | Эндпоинт | Описание |
|---------|--------------------------------|----------------------------|
| `GET` | `/masters` | Список мастеров салона |
| `GET` | `/masters/{id}` | Профиль мастера с услугами |
| `GET` | `/masters/{id}/schedule?date=` | Свободные тайм-слоты |
| `POST` | `/bookings` | Создать бронирование |
| `GET` | `/bookings/{id}` | Статус бронирования |
| `PATCH` | `/bookings/{id}/cancel` | Отмена бронирования |
| `GET` | `/master/dashboard` | Дашборд мастера |
| `PATCH` | `/master/schedule` | Управление расписанием |
| `GET` | `/admin/analytics` | Аналитика салона |
| `POST` | `/chat` | Чат с AI-агентом |

## Использование Redis

Redis в проекте — **не просто кеш**, а выполняет шесть различных ролей:

| Роль | Структура данных | Назначение |
|---------------------------|-------------------------|--------------------------------------|
| Распределённая блокировка | `SETNX` + TTL | Предотвращение двойного бронирования |
| Очередь задач | Lists (`LPUSH`/`BRPOP`) | Асинхронная обработка уведомлений |
| Rate Limiter | Sorted Sets | Sliding window защита API |
| Pub/Sub | Каналы | Трансляция изменений расписания |
| Кеш | Strings/Hashes + TTL | Кеширование расписания и каталога |
| Хранилище сессий | Yii2 Redis Session | Серверные сессии |

## Быстрый старт

### Предварительные требования

- Docker & Docker Compose v2
- Git

### Запуск

```bash
# Клонировать репозиторий
git clone https://github.com/lmoroz/beautybook.git
cd beautybook

# Запустить все сервисы
docker compose up -d --build

# Выполнить миграции
docker compose exec php php yii migrate --interactive=0

# Приложение доступно:
# - Фронтенд: http://localhost:3000
# - API: http://localhost:8080/api/v1/
# - MySQL: localhost:3306
# - Redis: localhost:6379
```

### Остановка

```bash
docker compose down
```

### Сброс базы данных

```bash
docker compose exec php php yii migrate/redo --interactive=0
```

### Запуск воркера уведомлений

```bash
docker compose exec php php yii queue/listen
```

## Схема базы данных

```text
┌──────────┐ ┌──────────┐ ┌──────────┐
│ salons │────<│ masters │────<│ services │
└──────────┘ └────┬─────┘ └────┬─────┘
│ │
┌────┴─────┐ │
│time_slots│ │
└────┬─────┘ │
│ │
┌────┴─────┐ │
│ bookings │─────────┘
└──────────┘

salons 1 ──< N masters
masters 1 ──< N services
masters 1 ──< N time_slots
time_slots 1 ──< 1 bookings
services 1 ──< N bookings
```

## Разработка

### Бэкенд (Yii2 API)

```bash
# Зайти в PHP-контейнер
docker compose exec php bash

# Выполнить миграции
php yii migrate

# Создать новую миграцию
php yii migrate/create create_bookings_table
```

### Фронтенд (Vue 3)

```bash
cd frontend
npm install
npm run dev
```

### Стандарты кода

- **PHP:** PSR-12, автоформатирование через [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer)
- **Vue:** Composition API (``), без Options API
- **Коммиты:** [Conventional Commits](https://www.conventionalcommits.org/)
- **Язык:** английский для кода, комментариев и документации

#### PHP-CS-Fixer

```bash
# Проверка стиля (dry-run)
docker compose exec php composer cs-check

# Автоформатирование
docker compose exec php composer cs-fix
```

Конфигурация: `api/.php-cs-fixer.php` (PSR-12 + упорядочивание импортов, single quotes, trailing commas).

#### Git-хуки

Pre-commit хук автоматически проверяет стиль PHP-файлов при коммите.

Активация (один раз после клонирования):

```bash
git config core.hooksPath .githooks
```

> Если `composer install` выполняется на хосте (не в контейнере), хуки активируются автоматически.

## Лицензия

MIT