Dentora — техническое описание

0. Бизнес-цели и успех (обязательно)

  • Цель бизнеса (12–24 мес): Получать 300+ онлайн-записей в месяц и загрузить кресла клиники на 85% за 18 мес.
  • Кто платит vs кто пользуется: Платит владелец/главврач клиники; пользуются пациенты и администраторы.
  • Ценность для пользователя (одной фразой): Выбрать врача и записаться на удобное время за 1 минуту, понимая цену заранее.
  • KPI успеха v1 (3–7 измеримых):
    • ≥ 25% обращений через онлайн-запись
    • Конверсия в запись ≥ 4%
    • Доля неявок ≤ 10% за счёт напоминаний
    • Время загрузки < 2,5 с
    • Рейтинг на картах ≥ 4,8 при 100+ отзывах
  • Монетизация / экономика: Доход клиники — лечение (средний чек 8–40 тыс. ₽); имплантация и брекеты — основная маржа.
  • Go-to-market: Яндекс Карты и 2ГИС, ПроДокторов, контекст по услугам, акции на первичную консультацию.
  • SEO / контент / маркетинг в v1: Отдельная страница на каждую услугу и врача, прайс в HTML, микроразметка Dentist/MedicalClinic/Physician, раздел статей.
  • Конкуренты / аналоги (1–3) и отличие: Сайты сетевых клиник (СМ-Клиника, Дентал Фэнтези), агрегаторы ПроДокторов/СберЗдоровье. Отличие: запись к конкретному врачу без звонка, прозрачный прайс, понятные лицензии.
  • Анти-цели v1: Не делаем телемедицину, онлайн-оплату лечения и медкарту пациента в v1.

1. Название и суть

  • Название проекта: Dentora — сайт стоматологической клиники с онлайн-записью
  • Одной фразой: Сайт клиники с услугами, врачами, ценами и онлайн-записью.
  • Для кого: Взрослые и родители детей в радиусе 5 км от клиники.
  • Проблема: Пациенты боятся скрытых цен и не могут записаться вечером, когда администратор не отвечает.
  • Связь с §0: каждый сценарий v1 ведёт к KPI конверсии и измеряется целями в аналитике.

2. Границы

IN SCOPE (обязательно в v1):

  • Главная: hero, преимущества, услуги, врачи, отзывы, лицензии, контакты
  • Каталог услуг с ценами «от»
  • Карточки врачей: стаж, специализация, образование
  • Онлайн-запись: услуга → врач → дата/время → контакты
  • Блок лицензий и реквизитов
  • Медицинские оговорки и согласие по 152-ФЗ
  • Админка: расписание слотов, заявки

OUT OF SCOPE:

  • Онлайн-оплата
  • Медкарта и результаты снимков
  • Телемедицина
  • Интеграция с МИС (в v1 — ручная)

Позже (v2+):

  • Интеграция с МИС (IDENT, Medods)
  • SMS-напоминания
  • Личный кабинет пациента
  • Онлайн-оплата

3. Стек

  • Frontend: React 19 + Vite (продакшен); макет — чистый HTML/CSS/JS без сборки
  • Стили UI: CSS Modules / собственная дизайн-система по INPUT/DESIGN.html
  • Backend: Node.js 20 LTS + Express
  • БД OLTP: PostgreSQL 16
  • Аналитика / OLAP: Яндекс Метрика; OLAP не требуется в v1
  • Кэш / очереди / observability: не требуется в v1; логи pino, uptime-мониторинг
  • Хостинг / облако: VPS в РФ (Timeweb Cloud / Selectel), Nginx, Docker Compose
  • Монолит / модульный монолит / сервисы: модульный монолит

4. Ключевые сценарии

  1. Пациент выбирает «Профгигиена», врача-гигиениста и слот на четверг 18:30, получает подтверждение на email.
  2. Мама записывает ребёнка к детскому стоматологу через мобильный, указывая возраст.
  3. Администратор видит новые записи в админке, подтверждает и при необходимости переносит.

5. Сущности и данные

СущностьПоля (примерно)СвязиЗаметки
Servicetitle, slug, category, price_from, duration_min, descriptionM:N DoctorКатегории: терапия, гигиена, имплантация, ортодонтия, детская
Doctorname, photo, specialty, experience_years, education, bioM:N Service, 1:N SlotФото — с согласием
Slotdoctor_id, starts_at, ends_at, is_bookedN:1 DoctorГенерируются по шаблону графика
Appointmentpatient_name, phone, email, service_id, slot_id, comment, consent_at, statusN:1 Slot, ServiceПД, срок хранения 3 года
Licensenumber, issued_by, issued_at, file_url—PDF-скан

6. Интеграции

  • SMTP — подтверждение записи
  • Telegram — уведомление администратору
  • Яндекс Карты — схема проезда
  • Яндекс Метрика — цель «appointment_created»
  • Опционально v2: МИС IDENT/Medods API

7. Нефункциональные требования

  • Ожидаемая нагрузка: До 10 000 посетителей и 1 000 записей в месяц
  • Latency / доступность: TTFB < 300 мс, LCP < 2,5 с на mobile, доступность 99,5%
  • Retention EventLog / evidence / audit: логи 30 дней, заявки/заказы 3 года, бэкап БД ежедневно с хранением 14 дней
  • Compliance: 152-ФЗ (медицинские ПД — специальная категория: минимизация, отдельное согласие), закон о рекламе медуслуг (пометка «Имеются противопоказания»), лицензия на сайте

8. Безопасность

  • Пациенты без регистрации; админка с ролями admin/registrator через JWT; HTTPS, rate-limit, капча; не собирать диагнозы через форму.
  • HTTPS (Let's Encrypt), helmet, CSP, валидация входных данных на сервере, секреты в .env вне репозитория.

9. UX / клиенты

  • Web, mobile-first; админка desktop/планшет.
  • Доступность: контраст AA, фокус-состояния, подписи полей форм.

9b. Дизайн

  • HTML-референс: INPUT/DESIGN.html (картинки в INPUT/assets/, описания в INPUT/assets/DESCRIPTIONS.md)

9c. CI/CD и окружения

  • Окружения: local / ci / staging / production
  • CI: GitHub Actions — lint, тесты, сборка Docker-образа; деплой на staging по merge в main, на production по тегу
  • Хостинг: VPS в РФ, Docker Compose, Nginx reverse proxy

10. Ограничения

  • Язык кода: TypeScript (strict) на фронте и бэке; автотесты Vitest + Playwright для ключевых сценариев
  • Запрещённые практики: хранение секретов в репозитории, ПД в логах, inline-SQL без параметров

11. Готовые модули

  • logging-pino
  • rate-limiting
  • caching-redis
  • auth-jwt
  • websocket-socketio
  • admin-panel
  • file-upload
  • crud-table
  • payments-stripe
  • search
  • email-nodemailer

12. Критерии приёмки v1

  • Запись невозможна на занятый слот (проверка на сервере)
  • Пациент получает email-подтверждение
  • На каждой странице услуги есть дисклеймер о противопоказаниях
  • Лицензия и реквизиты доступны с главной
  • Форма требует отдельного согласия на обработку ПД
  • Lighthouse Accessibility ≥ 90

13. Свободные заметки

Проект Webcraftly

Нужен такой же продукт?

Сайт стоматологии: услуги, врачи, онлайн-запись со слотами и оговорки по 152-ФЗ.