Browse Source
- Роли: viewer и editor - Функциональные требования: навигация, компоненты, эксперименты, авторизация - Интеграция с API oclinica.ru (прокси через NestJS, кэш 15 мин) - Схема БД: User, ExperimentalComponent - Стек: Next.js + NestJS + PostgreSQL + Prisma - Открытые вопросы по API сайта и хостингу Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>sprint/1
1 changed files with 462 additions and 0 deletions
@ -0,0 +1,462 @@
|
||||
# Техническое задание |
||||
## Цифровой брендбук Клиники ухо, горло, нос им. проф. Е.Н. Оленевой |
||||
### `oclinica-brandbook` |
||||
|
||||
--- |
||||
|
||||
**Версия:** 1.0-draft |
||||
**Дата:** 2026-03-22 |
||||
**Статус:** На согласовании |
||||
|
||||
--- |
||||
|
||||
## Содержание |
||||
|
||||
1. [Общие сведения](#1-общие-сведения) |
||||
2. [Назначение и цели](#2-назначение-и-цели) |
||||
3. [Пользователи системы](#3-пользователи-системы) |
||||
4. [Границы системы](#4-границы-системы) |
||||
5. [Функциональные требования](#5-функциональные-требования) |
||||
6. [Требования к интеграциям](#6-требования-к-интеграциям) |
||||
7. [Требования к данным](#7-требования-к-данным) |
||||
8. [Нефункциональные требования](#8-нефункциональные-требования) |
||||
9. [Технический стек](#9-технический-стек) |
||||
10. [Архитектура системы](#10-архитектура-системы) |
||||
11. [Безопасность и авторизация](#11-безопасность-и-авторизация) |
||||
12. [Требования к окружению](#12-требования-к-окружению) |
||||
13. [Ограничения и допущения](#13-ограничения-и-допущения) |
||||
14. [Открытые вопросы](#14-открытые-вопросы) |
||||
|
||||
--- |
||||
|
||||
## 1. Общие сведения |
||||
|
||||
| Параметр | Значение | |
||||
|------------------------|-----------------------------------------------------------------------| |
||||
| Полное название | Цифровой брендбук Клиники ухо, горло, нос им. проф. Е.Н. Оленевой | |
||||
| Краткое название | oclinica-brandbook | |
||||
| Сайт клиники | https://oclinica.ru | |
||||
| Тип системы | Веб-приложение (Living Styleguide) | |
||||
| Режим работы | Локальная разработка + деплой на сервер | |
||||
| Аудитория | Внутренние дизайнеры клиники, внешние подрядчики | |
||||
| Хостинг | TBD — будет прописан отдельно | |
||||
|
||||
--- |
||||
|
||||
## 2. Назначение и цели |
||||
|
||||
### 2.1 Назначение |
||||
|
||||
`oclinica-brandbook` — интерактивное веб-приложение, которое служит единым источником правды о визуальном языке клиники. Оно содержит все UI-компоненты, блоки страниц и полные страницы сайта в живом виде — с кодом, документацией и реальными данными. |
||||
|
||||
Дополнительно система позволяет дизайнерам создавать экспериментальные компоненты и страницы непосредственно в интерфейсе брендбука, сохранять их в базе данных и переводить в статус «утверждено». |
||||
|
||||
### 2.2 Цели |
||||
|
||||
| № | Цель | |
||||
|---|----------------------------------------------------------------------------------------| |
||||
| 1 | Обеспечить единый визуальный стандарт для всех, кто работает над сайтом | |
||||
| 2 | Ускорить работу дизайнеров и разработчиков за счёт готовых компонентов с кодом | |
||||
| 3 | Дать возможность безопасно экспериментировать с новыми компонентами без риска для сайта| |
||||
| 4 | Показывать компоненты с реальными данными (врачи, новости, цены) с сайта клиники | |
||||
| 5 | Создать живой инструмент, который обновляется вместе с сайтом | |
||||
|
||||
--- |
||||
|
||||
## 3. Пользователи системы |
||||
|
||||
### 3.1 Роли |
||||
|
||||
Система поддерживает две роли пользователей: |
||||
|
||||
#### Роль: `viewer` (Наблюдатель) |
||||
|
||||
Предназначена для внешних подрядчиков и всех, кому нужно ознакомиться с брендбуком. |
||||
|
||||
**Доступные действия:** |
||||
- Просмотр всех разделов брендбука (цвета, типографика, компоненты, блоки, страницы) |
||||
- Просмотр кода компонентов (HTML/CSS) |
||||
- Копирование кода компонента в буфер обмена |
||||
- Просмотр экспериментальных компонентов со статусом `approved` |
||||
- Скачивание дизайн-токенов (JSON) |
||||
|
||||
**Недоступные действия:** |
||||
- Создание / редактирование / удаление компонентов |
||||
- Изменение статуса компонентов |
||||
- Управление пользователями |
||||
|
||||
--- |
||||
|
||||
#### Роль: `editor` (Редактор) |
||||
|
||||
Предназначена для внутренних дизайнеров клиники. |
||||
|
||||
**Доступные действия** (всё из `viewer`, плюс): |
||||
- Создание экспериментального компонента методом дублирования существующего |
||||
- Редактирование атрибутов компонента через интерактивную форму |
||||
- Сохранение компонента в БД со статусом `draft` |
||||
- Смена статуса компонента: `draft` → `review` → `approved` |
||||
- Удаление компонента со статусом `draft` |
||||
- Просмотр всех экспериментальных компонентов (включая `draft` и `review`) |
||||
|
||||
**Недоступные действия:** |
||||
- Управление пользователями (добавление / удаление аккаунтов) |
||||
- Прямое редактирование базового кода компонентов (только через форму атрибутов) |
||||
|
||||
--- |
||||
|
||||
### 3.2 Управление пользователями |
||||
|
||||
- Создание и удаление пользователей выполняется администратором системы вручную (через API или seed-скрипт) — в рамках v1.0 административный UI не предусмотрен. |
||||
- Пользователи хранятся в БД с хешированным паролем (bcrypt). |
||||
|
||||
--- |
||||
|
||||
## 4. Границы системы |
||||
|
||||
### Что входит в систему |
||||
|
||||
- Фронтенд брендбука (Next.js) — визуальная документация всех компонентов |
||||
- Бэкенд API (NestJS) — управление экспериментальными компонентами, авторизация |
||||
- База данных (PostgreSQL + Prisma) — хранение пользователей и экспериментальных данных |
||||
- Интеграция с API сайта oclinica.ru — получение реальных данных для отображения в компонентах |
||||
|
||||
### Что не входит в систему (v1.0) |
||||
|
||||
- Административный UI для управления пользователями |
||||
- Drag-and-drop конструктор страниц |
||||
- История версий компонентов |
||||
- Тёмная тема |
||||
- Экспорт в Figma |
||||
- CMS-функции (редактирование контента самого сайта oclinica.ru) |
||||
|
||||
--- |
||||
|
||||
## 5. Функциональные требования |
||||
|
||||
### 5.1 Навигация и структура брендбука |
||||
|
||||
**ФТ-01.** Брендбук имеет постоянную левую (или верхнюю) навигацию с разделами: |
||||
- Фундамент → Цвета, Типографика, Логотип |
||||
- Компоненты → Кнопки, Форм-контролы, Карточки, Бейджи, Алерты, Модальные окна, Таблицы, Навигация |
||||
- Блоки → Hero, CEO-текст, Наши врачи, Отзывы, Новости, Формы контакта, Контакт, Услуги |
||||
- Страницы → Главная, Заболевание, Все врачи, Врач, Цены, Контакты |
||||
- Эксперименты |
||||
|
||||
**ФТ-02.** Навигация поддерживает прямые URL для каждого раздела (deep linking). |
||||
|
||||
**ФТ-03.** На каждой странице раздела отображается: |
||||
- Живой пример компонента/блока |
||||
- Все варианты (размеры, состояния, цветовые схемы) |
||||
- HTML-код компонента с кнопкой «Скопировать» |
||||
- Краткое описание и правила применения |
||||
|
||||
--- |
||||
|
||||
### 5.2 Раздел «Цвета» |
||||
|
||||
**ФТ-10.** Отображаются все цвета палитры: плашка цвета, название, HEX, RGB, HSL. |
||||
|
||||
**ФТ-11.** Клик на цвет — копирует HEX в буфер. |
||||
|
||||
**ФТ-12.** Для каждой пары цветов (текст / фон) отображается коэффициент контрастности и метка WCAG AA / AAA / Fail. |
||||
|
||||
**ФТ-13.** Кнопка «Скачать токены» — выгружает все цвета в JSON-формате, совместимом с Figma Tokens. |
||||
|
||||
--- |
||||
|
||||
### 5.3 Раздел «Типографика» |
||||
|
||||
**ФТ-20.** Отображаются все текстовые стили: h1–h6, body-large, body, body-small, caption, label, overline. |
||||
|
||||
**ФТ-21.** Для каждого стиля показаны: font-family, font-weight, font-size, line-height, letter-spacing. |
||||
|
||||
**ФТ-22.** Живые примеры текста отображаются шрифтом Fira Sans с реальным контентом. |
||||
|
||||
--- |
||||
|
||||
### 5.4 Компоненты — общие требования |
||||
|
||||
**ФТ-30.** Каждый компонент отображается со всеми своими вариантами и состояниями одновременно на одной странице. |
||||
|
||||
**ФТ-31.** Под каждым вариантом показан HTML-код с кнопкой «Скопировать». |
||||
|
||||
**ФТ-32.** Состояния интерактивных компонентов (hover, focus, disabled) доступны живым взаимодействием — не скриншотами. |
||||
|
||||
--- |
||||
|
||||
### 5.5 Страницы |
||||
|
||||
**ФТ-40.** Каждая страница брендбука показывает полноразмерный макет, собранный из утверждённых блоков. |
||||
|
||||
**ФТ-41.** Страницы отображаются с реальными данными, полученными через API oclinica.ru (врачи, новости, услуги, цены). |
||||
|
||||
**ФТ-42.** В брендбуке доступен переключатель «Desktop / Tablet / Mobile» для предпросмотра адаптивности. |
||||
|
||||
--- |
||||
|
||||
### 5.6 Экспериментальная секция |
||||
|
||||
**ФТ-50.** В разделе «Эксперименты» отображается список экспериментальных компонентов: |
||||
- Для `viewer`: только со статусом `approved` |
||||
- Для `editor`: все (draft, review, approved) |
||||
|
||||
**ФТ-51.** `editor` может создать новый экспериментальный компонент через кнопку «Дублировать» на любом существующем компоненте брендбука. |
||||
|
||||
**ФТ-52.** После дублирования открывается интерактивная форма редактирования атрибутов компонента: |
||||
- Текстовые поля (заголовки, описания, подписи) |
||||
- Выбор цвета из палитры токенов (colour picker ограничен токенами бренда) |
||||
- Выбор размера (из допустимых значений) |
||||
- Предпросмотр компонента обновляется в реальном времени при изменении атрибутов |
||||
- Кнопки: «Сохранить как черновик», «Отмена» |
||||
|
||||
**ФТ-53.** Созданный компонент сохраняется в БД со статусом `draft` и привязкой к автору. |
||||
|
||||
**ФТ-54.** `editor` может изменить статус компонента: |
||||
- `draft` → `review` (передать на согласование) |
||||
- `review` → `approved` (утвердить) |
||||
- `review` → `draft` (вернуть на доработку) |
||||
|
||||
**ФТ-55.** Удаление возможно только для компонентов со статусом `draft`. |
||||
|
||||
**ФТ-56.** Каждый экспериментальный компонент имеет карточку: название, автор, дата создания, статус, базовый компонент (от которого дублирован), превью. |
||||
|
||||
--- |
||||
|
||||
### 5.7 Авторизация |
||||
|
||||
**ФТ-60.** При входе на защищённые страницы неавторизованный пользователь перенаправляется на `/login`. |
||||
|
||||
**ФТ-61.** Форма входа: поле email + поле пароль + кнопка «Войти». |
||||
|
||||
**ФТ-62.** После успешного входа пользователь перенаправляется на страницу, с которой был перенаправлен. |
||||
|
||||
**ФТ-63.** В шапке брендбука отображается: имя пользователя, роль, кнопка «Выйти». |
||||
|
||||
**ФТ-64.** Токен сессии хранится в httpOnly cookie. |
||||
|
||||
--- |
||||
|
||||
## 6. Требования к интеграциям |
||||
|
||||
### 6.1 API сайта oclinica.ru |
||||
|
||||
Брендбук получает реальные данные с сайта клиники для отображения в компонентах и страницах. |
||||
|
||||
**Необходимые данные и источники:** |
||||
|
||||
| Данные | Раздел брендбука | Тип запроса | |
||||
|------------------|-------------------------------------|-----------------| |
||||
| Список врачей | Блок «Наши врачи», страница «Врачи» | GET | |
||||
| Профиль врача | Страница «Врач» | GET by ID | |
||||
| Список новостей | Блок «Новости» | GET | |
||||
| Список услуг | Блок «Услуги / Заболевания» | GET | |
||||
| Цены | Страница «Цены» | GET | |
||||
| Отзывы | Блок «Отзывы» | GET | |
||||
|
||||
**ИНТ-01.** Сайт oclinica.ru работает на Drupal. Для получения данных используется Drupal JSON:API (если доступен) или стандартный REST API Drupal (`/node?_format=json`). |
||||
|
||||
> **Требует уточнения:** наличие и формат API на стороне oclinica.ru — необходимо проверить доступные эндпоинты до начала Sprint 1. |
||||
|
||||
**ИНТ-02.** Запросы к API oclinica.ru выполняются на стороне бэкенда (NestJS), не из браузера — для обхода возможных CORS-ограничений. |
||||
|
||||
**ИНТ-03.** Данные кэшируются на бэкенде с TTL 15 минут, чтобы не создавать нагрузку на сайт клиники. |
||||
|
||||
**ИНТ-04.** Если API oclinica.ru недоступен — компоненты отображаются с заглушками (mock data), брендбук не падает. |
||||
|
||||
--- |
||||
|
||||
## 7. Требования к данным |
||||
|
||||
### 7.1 Схема базы данных (основные модели) |
||||
|
||||
#### `User` |
||||
| Поле | Тип | Описание | |
||||
|--------------|------------|-----------------------------------| |
||||
| id | UUID | Первичный ключ | |
||||
| email | String | Уникальный, логин | |
||||
| name | String | Имя для отображения | |
||||
| passwordHash | String | bcrypt-хеш пароля | |
||||
| role | Enum | `viewer` / `editor` | |
||||
| createdAt | DateTime | | |
||||
|
||||
#### `ExperimentalComponent` |
||||
| Поле | Тип | Описание | |
||||
|-----------------|------------|----------------------------------------------| |
||||
| id | UUID | Первичный ключ | |
||||
| name | String | Название компонента | |
||||
| baseComponent | String | Идентификатор базового компонента-источника | |
||||
| attributes | JSON | Атрибуты компонента (цвет, текст, размер...) | |
||||
| status | Enum | `draft` / `review` / `approved` | |
||||
| authorId | UUID | FK → User | |
||||
| createdAt | DateTime | | |
||||
| updatedAt | DateTime | | |
||||
|
||||
#### `ExperimentalPage` *(планируется в backlog)* |
||||
| Поле | Тип | Описание | |
||||
|------------|----------|----------------------------------| |
||||
| id | UUID | | |
||||
| name | String | | |
||||
| blocks | JSON | Упорядоченный список блоков | |
||||
| status | Enum | `draft` / `review` / `approved` | |
||||
| authorId | UUID | FK → User | |
||||
|
||||
--- |
||||
|
||||
## 8. Нефункциональные требования |
||||
|
||||
### 8.1 Производительность |
||||
- Страница брендбука загружается менее чем за 3 секунды при стабильном соединении. |
||||
- Предпросмотр компонента при редактировании атрибутов обновляется без задержки (оптимистичный рендер на клиенте). |
||||
|
||||
### 8.2 Адаптивность |
||||
- Брендбук корректно отображается на: Desktop (1440px), Tablet (768px), Mobile (375px). |
||||
- Компоненты и страницы имеют встроенный переключатель viewport для предпросмотра. |
||||
|
||||
### 8.3 Доступность (Accessibility) |
||||
- Все базовые компоненты соответствуют стандарту **WCAG 2.1 AA**. |
||||
- Клавиатурная навигация поддерживается для всех интерактивных элементов. |
||||
- Контрастность текста проверяется автоматически в разделе «Цвета». |
||||
|
||||
### 8.4 Кроссбраузерность |
||||
- Поддерживаемые браузеры: Chrome 120+, Firefox 120+, Safari 17+, Edge 120+. |
||||
|
||||
### 8.5 Надёжность |
||||
- При отсутствии данных от API oclinica.ru — graceful degradation (заглушки, нет ошибок). |
||||
- Все API-эндпоинты возвращают понятные коды ошибок (4xx, 5xx) с описанием. |
||||
|
||||
### 8.6 Масштабируемость |
||||
- Архитектура monorepo позволяет добавлять новые пакеты (`packages/`) без переработки ядра. |
||||
- База данных спроектирована с возможностью расширения моделей без breaking changes. |
||||
|
||||
--- |
||||
|
||||
## 9. Технический стек |
||||
|
||||
| Слой | Технология | Версия | Обоснование | |
||||
|-------------------|-----------------------|----------|--------------------------------------------------| |
||||
| Фронтенд | Next.js (App Router) | 15.x | SSR/SSG, оптимизация, экосистема React | |
||||
| Бэкенд | NestJS | 10.x | Типизированный Node.js фреймворк, DI, модули | |
||||
| База данных | PostgreSQL | 16.x | Надёжная реляционная БД, JSON-поля для атрибутов | |
||||
| ORM | Prisma | 5.x | Type-safe запросы, миграции, seed | |
||||
| Стилизация | CSS Modules | — | Изоляция стилей, нет рантайм-зависимостей | |
||||
| Дизайн-токены | CSS Custom Properties | — | Нативно поддерживается всеми браузерами | |
||||
| Шрифт | Fira Sans | — | Google Fonts, кириллица, веса 300 и 400 | |
||||
| Авторизация | JWT + httpOnly cookie | — | Безопасное хранение токена | |
||||
| Пакетный менеджер | pnpm | 9.x | Monorepo workspaces, скорость | |
||||
| Контейнеризация | Docker + Compose | — | Единообразное окружение dev/prod | |
||||
|
||||
--- |
||||
|
||||
## 10. Архитектура системы |
||||
|
||||
### 10.1 Структура monorepo |
||||
|
||||
``` |
||||
oclinica-brandbook/ |
||||
├── apps/ |
||||
│ ├── web/ # Next.js — фронтенд брендбука |
||||
│ │ ├── app/ # App Router (страницы брендбука) |
||||
│ │ ├── components/ # UI-компоненты брендбука |
||||
│ │ │ ├── base/ # Базовые компоненты (Button, Input...) |
||||
│ │ │ ├── blocks/ # Блоки страниц (Hero, DoctorGrid...) |
||||
│ │ │ └── experimental/ # Движок экспериментальных компонентов |
||||
│ │ └── lib/ # Утилиты, API-клиент |
||||
│ └── api/ # NestJS — REST API |
||||
│ ├── src/ |
||||
│ │ ├── auth/ # JWT авторизация |
||||
│ │ ├── users/ # Управление пользователями |
||||
│ │ ├── components/ # CRUD экспериментальных компонентов |
||||
│ │ └── oclinica/ # Прокси к API oclinica.ru (с кэшем) |
||||
│ └── prisma/ |
||||
│ ├── schema.prisma |
||||
│ └── seed.ts |
||||
├── packages/ |
||||
│ └── tokens/ # Дизайн-токены (цвета, типографика) — shared |
||||
├── docs/ # Проектная документация |
||||
├── .env.example |
||||
├── docker-compose.yml |
||||
├── pnpm-workspace.yaml |
||||
└── README.md |
||||
``` |
||||
|
||||
### 10.2 Потоки данных |
||||
|
||||
``` |
||||
Браузер (Next.js) |
||||
│ |
||||
├── Статичные компоненты ──────────► Рендер из кода (нет запросов) |
||||
│ |
||||
├── Реальные данные клиники ───────► NestJS API ──► кэш ──► oclinica.ru API |
||||
│ |
||||
└── Экспериментальные компоненты ──► NestJS API ──────────► PostgreSQL |
||||
``` |
||||
|
||||
--- |
||||
|
||||
## 11. Безопасность и авторизация |
||||
|
||||
**БЕЗ-01.** Авторизация реализована на JWT-токенах, хранящихся в httpOnly cookie (не localStorage). |
||||
|
||||
**БЕЗ-02.** Пароли хранятся только в виде bcrypt-хешей (cost factor 12). |
||||
|
||||
**БЕЗ-03.** Все мутирующие эндпоинты API (`POST`, `PATCH`, `DELETE`) защищены Guard-ами NestJS и требуют роль `editor`. |
||||
|
||||
**БЕЗ-04.** CORS настроен явно — разрешены только домены фронтенда. |
||||
|
||||
**БЕЗ-05.** Входные данные форм валидируются на бэкенде через `class-validator` (NestJS Pipes). |
||||
|
||||
**БЕЗ-06.** В production `.env` файл не попадает в репозиторий (`.gitignore`). |
||||
|
||||
--- |
||||
|
||||
## 12. Требования к окружению |
||||
|
||||
### 12.1 Локальная разработка |
||||
|
||||
| Требование | Версия | |
||||
|--------------|----------| |
||||
| Node.js | >= 20 LTS | |
||||
| pnpm | >= 9 | |
||||
| Docker | >= 24 | |
||||
| Docker Compose | >= 2 | |
||||
|
||||
### 12.2 Production-сервер |
||||
|
||||
> TBD — параметры хостинга будут прописаны отдельно. |
||||
|
||||
Минимальные ожидаемые требования: |
||||
- ОС: Ubuntu 22.04+ |
||||
- RAM: 2 GB |
||||
- Disk: 20 GB |
||||
- PostgreSQL 16 (или managed database) |
||||
- Node.js 20 LTS |
||||
|
||||
--- |
||||
|
||||
## 13. Ограничения и допущения |
||||
|
||||
| № | Ограничение / допущение | |
||||
|----|----------------------------------------------------------------------------------------------------| |
||||
| 1 | Логотип клиники в векторном формате будет предоставлен позже — раздел «Логотип» реализуется отдельно | |
||||
| 2 | Наличие и структура API oclinica.ru требуют проверки до начала разработки интеграции | |
||||
| 3 | В v1.0 нет административного UI — управление пользователями через seed-скрипт или прямые запросы к API | |
||||
| 4 | Экспериментальные компоненты создаются только методом дублирования — прямое написание HTML/CSS не предусмотрено | |
||||
| 5 | Drag-and-drop конструктор страниц — в backlog, не в v1.0 | |
||||
| 6 | Тёмная тема — в backlog, не в v1.0 | |
||||
|
||||
--- |
||||
|
||||
## 14. Открытые вопросы |
||||
|
||||
| № | Вопрос | Ответственный | Срок | |
||||
|----|--------------------------------------------------------------------------------------|---------------|----------| |
||||
| ОВ-01 | Доступен ли JSON API или REST API на oclinica.ru? Каков формат ответов? | Клиника | Sprint 1 | |
||||
| ОВ-02 | Параметры хостинга для production-деплоя | Клиника | TBD | |
||||
| ОВ-03 | Нужна ли страница «Заболевание» как отдельный тип, или это подвид страницы «Услуга»? | Клиника | Sprint 9 | |
||||
| ОВ-04 | Список иконок — какую стороннюю библиотеку утвердить? (Lucide, Heroicons, и др.) | Совместно | Sprint 2 | |
||||
| ОВ-05 | Нужен ли раздел «Логотип» в v1.0 или ждём вектор? | Клиника | Sprint 2 | |
||||
|
||||
--- |
||||
|
||||
*Документ будет обновляться по ходу проекта. Изменения фиксируются в git-истории.* |
||||
Loading…
Reference in new issue