Полностью самостоятельное (self-contained) веб-приложение для диагностики и отслеживания «Образовательного партнёрства» семей на всех этапах приёма в школу — от первого звонка до завершения испытательного срока.
Интерфейс полностью на русском языке. Никаких внешних CRM — весь стек (backend + frontend + БД) написан с нуля и работает независимо.
- Backend: Node.js + Express + PostgreSQL (
pg), JWT-авторизация, PDFKit (генерация договора), интеграция с Whisper API (Speech-to-Text). - Frontend: React (Vite) + TailwindCSS + Recharts (радар компетенций).
- БД: PostgreSQL c JSONB для динамических форм и гибких данных (см.
backend/database/schema.sql).
anketa/
backend/ # REST API
database/ # schema.sql + seed.sql
src/
constants/ # веса этапов, компетенции, банки вопросов, справочники рисков
db/ # подключение к PostgreSQL, миграции
middleware/ # JWT-авторизация, обработка ошибок
routes/ # эндпоинты по каждому этапу (stage0..stage6) + auth/passport/public
services/ # движок скоринга (ИОП), маршрутизация, договор, Whisper
frontend/ # React SPA
src/
pages/ # экраны: Dashboard, NewFamily, FamilyWorkspace, FamilyPassport...
pages/stages/ # панели каждого этапа (Stage0Panel..Stage6Panel)
components/ui/ # переиспользуемые UI-компоненты (Badge, Switch, Slider, StarRating...)
docker-compose.yml # PostgreSQL для локальной разработки
Поднимите PostgreSQL любым способом:
docker compose up -dЛибо укажите свою существующую БД в backend/.env (см. DATABASE_URL).
cd backend
cp .env.example .env # заполните DATABASE_URL, JWT_SECRET и т.д.
npm install
npm run migrate # применяет schema.sql + seed.sql (пункты договора)
npm run seed:admin # создаёт первого администратора (см. переменные DEFAULT_ADMIN_*)
npm run dev # http://localhost:4000Опционально: заполните OPENAI_API_KEY в .env, чтобы включить распознавание
речи (Whisper) в диктофоне на Этапе 0. Без ключа остальной функционал работает
без ограничений — просто кнопка «Диктовать» вернёт понятную ошибку.
cd frontend
cp .env.example .env # VITE_API_URL=http://localhost:4000/api
npm install
npm run dev # http://localhost:5173Войдите под учётными данными, созданными командой npm run seed:admin
(по умолчанию admin@school.ru / admin12345, если не переопределено в .env).
| Этап | Название | Кто заполняет | Вес в ИОП |
|---|---|---|---|
| 0 | Первичный контакт | Администратор (звонок) | 10% |
| 1 | Онлайн-знакомство (SJT + анкета) | Родители (мать/отец по отдельным ссылкам) | 15% |
| 2 | Очная встреча | Интервьюер/психолог | 25% |
| 3 | Вечерняя рефлексия | Родители | 15% |
| 4 | Контрактный контур | Администратор + родители (подпись) | 10% |
| 5 | Задание-тест | Куратор/учитель | 10% |
| 6 | Испытательный срок | Классный руководитель (еженедельно) | 15% |
Каждый этап блокируется, пока предыдущий не переведён в статус
Completed — это реализовано и на backend (проверка stage_statuses перед
записью), и на frontend (замки в степпере, редирект при попытке открыть
недоступный этап напрямую по URL).
ИОП = Σ (Wᵢ × Sᵢ), i = 0..6
Sᵢ — нормализованная оценка этапа (0.00–4.00), рассчитываемая автоматически
из оценок компетенций (stage_evaluations.competency_scores) и/или весов
ответов анкет (questionnaire_responses.q_and_a[].weight). Пересчёт
происходит при каждом завершении этапа и доступен в реальном времени в
Паспорте семьи (GET /api/passport/:familyId).
Флаги риска (CONSUMER, HIGH_ANXIETY, HYPER_CUSTODY, PARENTAL_DISAGREEMENT,
BOUNDARY_VIOLATION, AGGRESSION, CRISIS_WARNING и др.) расставляются
автоматически по ходу пайплайна (быстрые теги на Этапе 0, разногласия в
Анкете 1, наблюдения на встрече, два подряд «красных» недельных отчёта на
испытательном сроке) и вручную администратором. На основании флагов и ИОП
рассчитывается маршрут поддержки: Стандартный / Профилактический /
Усиленный / Кризисный (см. backend/src/services/routeService.js).
Ссылки на Анкету 1 (Этап 1) и вечернюю рефлексию (Этап 3) генерируются
автоматически при завершении предыдущего этапа и не требуют авторизации —
доступ по одноразовому токену (access_links):
/public/questionnaire/:token/public/reflection/:token
- Схема БД в
backend/database/schema.sqlрасширяет предложенную в задаче структуру двумя необходимыми для работы приложения элементами:users(учётные записи персонала) иaccess_links(одноразовые ссылки для родителей), а также добавляетrisk_evidenceвfamilies— без него невозможен клик-drill-down цитат в Паспорте семьи (Часть 4 задания). - Договор генерируется в PDF (
PDFKit) с динамическим набором приложений, подобранных по активным флагам риска; администратор может вручную включать/выключать любые пункты перед генерацией.