Платформа для создания и прохождения опросов внутри своего круга — друзей и групп, а не анонимной массовой аудитории. Пользователь регистрируется, добавляет друзей (заявка → подтверждение) и заводит группы с ролями участник/админ; админ управляет составом и правами. Опрос собирается из вопросов трёх типов (одиночный/множественный выбор, текст) с флагом обязательности и делится по ссылке, приглашением в группу или напрямую другу. У каждой группы есть свой групповой чат в реальном времени (Socket.IO) с историей сообщений, mute-правами и бейджем непрочитанных.
Ключевая особенность — три режима анонимности ответов, зашитые не только в UI, но и в структуру БД: ANONYMOUS (личность отвечавшего нигде не связывается с ответом — таблица участия и таблица ответов физически не пересекаются), PUBLIC_LIST (видно, кто участвовал, но не видно, кто что ответил) и NAMED (ответы подписаны). Автор опроса видит агрегированную аналитику (счётчики/проценты по выборным вопросам, список текстовых ответов) без возможности деанонимизировать ANONYMOUS-опрос даже случайно.
Архитектура, модель данных и статус эпиков — в PLAN.md. Инфраструктура демо-развёртывания (Yandex Cloud, Kubernetes, CI/CD) — в INFRASTRUCTURE.md, живой стенд: https://app.alexey-sdvizhkov.ru.
- Экспорт в CSV — построчная выгрузка ответов (открывается в Excel/Google Sheets). Респондент указывается только для
NAMED-опросов — дляANONYMOUS/PUBLIC_LISTколонка отсутствует, так же как и в остальном приложении. - QR-код — генерируется на клиенте прямо рядом со ссылкой на прохождение, без обращения к бэкенду.
- Графики в результатах — bar chart по каждому вопросу с выбором вариантов, поверх уже имеющихся счётчиков/процентов.
- Напоминание неответившим — считает разницу между приглашённой аудиторией (прямые приглашения + участники групп, с которыми расшарен опрос) и уже прошедшими (
Participation), и рассылает уведомление каждому. Недоступно дляANONYMOUS— по дизайну анонимности узнать, кто не ответил, невозможно. - Уведомления в приложении — колокольчик в шапке с непрочитанными: заявка в друзья, приглашение на опрос, добавление в группу, новый ответ на свой опрос. Доставляются в реальном времени через тот же Socket.IO-канал, что и групповой чат.
- Дублирование опроса — кнопка «Клонировать» создаёт черновик-копию (заголовок, вопросы, варианты) для быстрого повторного использования, не трогая оригинал.
- Дедлайн — необязательная дата и время в конструкторе; фоновый шедулер раз в минуту закрывает опубликованные опросы с истёкшим дедлайном.
- Квиз-режим — у вопросов с выбором можно отметить правильные варианты; при прохождении считается балл, респондент видит счёт сразу после отправки, автор — средний балл в результатах и в CSV-экспорте.
- Live-режим результатов — автор запускает трансляцию, и страница результатов обновляется в реальном времени при каждом новом ответе (тот же Socket.IO-канал, что у уведомлений и чата).
- Backend: Express + TypeScript + Prisma + PostgreSQL, JWT-аутентификация
- Frontend: React + Vite + TypeScript + Zustand + React Router
- Монорепо: npm workspaces (
apps/backend,apps/frontend,packages/shared)
Требуется Node.js 20+ и Docker (для Postgres).
npm install
docker compose up -d postgres
cp apps/backend/.env.example apps/backend/.env
cp apps/frontend/.env.example apps/frontend/.env
npm run prisma:migrate --workspace=@forms-assistant/backend
npm run prisma:seed --workspace=@forms-assistant/backend # опционально, тестовые данные
npm run dev:backend # http://localhost:4000
npm run dev:frontend # http://localhost:5173Тестовые пользователи после seed: alice@example.com / bob@example.com, пароль password123.
cp apps/backend/.env.example apps/backend/.env # заменить секреты для прода
docker compose up -d --build
docker compose exec backend npx prisma migrate deployFrontend (nginx, проксирует /api на backend) — http://localhost:5173. Для продакшена — docker-compose.prod.yml поверх основного файла:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --buildПомимо docker-compose, в репозитории есть полноценный демо-стенд в Yandex Cloud — Terraform поднимает VM/сеть/DNS/Container Registry, на VM разворачивается k3s (Kubernetes), приложение упаковано в Docker-образы и задеплоено манифестами (infra/k8s/), снаружи — Traefik как Ingress/балансировщик с TLS от Let's Encrypt через cert-manager. Пуш в master прогоняет тесты, собирает образы, пушит их в Container Registry и раскатывает в кластер через GitHub Actions (.github/workflows/ci.yml).
Подробный разбор — с диаграммами, списком ресурсов, обоснованием решений (почему k3s, а не managed-кластер; как устроены секреты и разделение прав между сервисными аккаунтами; как работает выпуск сертификата) — в INFRASTRUCTURE.md. Код инфраструктуры — в infra/ (terraform/, k8s/, scripts/).
npm run lint
npm run typecheck
npm test
npm run build