Перейти к содержанию

Tech Stack

ADR-light: что выбрано, версия, почему (если понятно из кода/контекста). Источник: recon-report.md + анализ кода.


Frontend (основной SPA)

Технология Версия Назначение Почему выбрано
React 19.2 UI framework Стандарт индустрии, большая экосистема
TypeScript ~5.x Типизация Безопасность типов, IDE support
Vite 6.3 Bundler + dev server Быстрый HMR, нативный ESM
Tailwind CSS 4.1 Utility-first CSS Быстрая верстка, консистентный дизайн
shadcn/ui (Radix) UI компоненты (~40 шт) Accessible, composable, не vendor lock-in
react-router-dom 7.12 SPA routing Стандарт для React SPA
i18next 25.8 Интернационализация Поддержка ru + kk (казахский), необходима для KZ рынка
recharts 2.15 Графики Аналитика провайдера
react-hook-form 7.55 Формы Производительность (uncontrolled), валидация
date-fns 3.6 Работа с датами Легковесная альтернатива moment.js
qrcode.react 4.2 QR-коды Генерация QR для ссылки на запись
react-google-recaptcha-v3 1.11 Anti-spam Защита публичных форм
lucide-react 0.487 Иконки Tree-shakeable, замена heroicons
react-helmet-async 2.0 SEO meta-теги SSR-ready head management
motion (framer-motion) 12.23 Анимации Плавные переходы в UI

Frontend (Telegram Mini App)

Технология Версия Назначение Почему выбрано
Next.js 16.1 SSR framework Server components, app router
React 19.2 UI Единый стек с основным SPA
Zustand 5.0 State management Минималистичный, без boilerplate
Axios 1.13 HTTP client Interceptors для JWT
Tailwind CSS 4 Стили Консистентность с основным SPA

Backend (FastAPI)

Технология Версия Назначение Почему выбрано
Python 3.11 Runtime async/await, type hints, широкая экосистема
FastAPI latest Web framework Async, автогенерация OpenAPI, Pydantic интеграция
SQLAlchemy 2.0 (async) ORM Mapped columns, async session, mature
asyncpg PostgreSQL async driver Высокая производительность для async
Alembic Миграции БД Стандарт для SQLAlchemy
Pydantic v2 Validation + Settings Нативная интеграция с FastAPI, BaseSettings
httpx 0.28 HTTP client Async, замена requests
PyJWT JWT tokens HS256, access tokens
passlib (bcrypt) Password hashing Индустриальный стандарт
Pillow + qrcode QR генерация Server-side QR с текстом
clickhouse-connect ClickHouse client Нативный HTTP клиент
uvicorn ASGI server Production-grade, uvloop

Решение о миграции с Node.js на FastAPI: Проект начинался на Node.js + Express + Prisma (см. _archived/backend_nodejs/). Миграция на FastAPI произошла для: async-first подход, Pydantic validation, автогенерация OpenAPI, лучшая типизация с Python type hints.

Базы данных

БД Версия Назначение Почему выбрано
PostgreSQL 16 Alpine Основная OLTP БД Надёжность, JSON, full-text search
ClickHouse 24.3 Alpine Аналитика (OLAP) Быстрые агрегации по bookings для dashboard провайдера

PostgreSQL schema (основные таблицы): businesses, users, categories, services, masters, master_services_association (M2M), schedules, bookings, clients, reschedule_proposals, subscriptions, accounts.

ClickHouse: Таблица cita_pg.bookings — предположительно PostgreSQL engine или materialized view. Используется только для read-only аналитики (revenue, bookings_count, clients_count, daily chart). Fallback: если ClickHouse недоступен, аналитика возвращает нули.

Инфраструктура

Компонент Технология Конфигурация
VPS Hetzner 159.69.28.60
OS Linux
Контейнеризация Docker + Docker Compose 3 контейнера: backend, db, clickhouse
Reverse proxy Nginx SSL termination, SPA fallback, API proxy
SSL Let's Encrypt (certbot) Auto-renewal, managed by Certbot
Домен cita.kz DNS → 159.69.28.60
Frontend hosting Nginx static /var/www/cita/dist/
API proxy Nginx /api/ → localhost:8000

Nginx конфигурация (ключевое): - Gzip: включён (text, css, js, json, svg, xml) - Security headers: X-Frame-Options, X-Content-Type-Options, CSP, Referrer-Policy - Static caching: /assets/ и /fonts/ — 365d immutable - SPA: try_files \ \/ /index.html

Внешние интеграции

Сервис API Назначение Ключ/конфиг
Telegram Bot API HTTPS REST Уведомления (inline buttons), webhook BOT_TOKEN в .env, бот: @citakz_bot
Telegram WebApp JS SDK + HMAC Mini App аутентификация initData validation
2GIS Suggest API HTTPS REST Автокомплит городов и адресов (KZ) API_KEY в config.py
Google reCAPTCHA v3 HTTPS REST Anti-spam на публичных формах SITE_KEY (frontend) + SECRET_KEY (backend)

CI/CD

Компонент Статус Примечание
GitHub Actions Есть GITHUB_ACTIONS_SETUP.md Не проверялся в рамках recon
Деплой Ручной git pull + docker compose up --build + vite build
Миграции Автоматические при старте CMD: alembic upgrade head && uvicorn
Тесты Есть структура src/tests/, backend/tests/ — покрытие не проверялось

Архитектурные решения

Монолит, не микросервисы

Один FastAPI app обслуживает всё: auth, bookings, notifications, analytics. Для текущего масштаба (один VPS, Казахстан) — оправданно.

Async everywhere

Backend полностью async: asyncpg, httpx, SQLAlchemy async session. Позволяет обрабатывать Telegram webhook + API запросы эффективно.

Slug-based multitenancy

Каждый бизнес идентифицируется по slug в URL. Все данные изолированы по business_id (row-level filtering, не schema isolation).

Двухуровневое расписание

Business schedule (дефолт) + Master schedule (override). Простая модель, покрывает 95% кейсов салонов красоты.

Lazy expiration

RescheduleProposal не имеет cron-job для expiration. Статус EXPIRED проставляется при GET-запросе (lazy check). Плюс: нет фонового процесса. Минус: proposal может висеть до первого GET.