Skip to content

Repository files navigation

Campus & Code

Учебный проект интернет-магазина IT- и университетского мерча. Приложение позволяет просматривать каталог товаров, работать с корзиной и избранным, оформлять заказ, подтверждать статус студента и управлять товарами через административный раздел.

Быстрый запуск через Docker

Для запуска нужен только установленный и запущенный Docker Desktop. После клонирования репозитория выполните в его корне:

docker compose up -d --build

Создавать .env, устанавливать npm-зависимости и отдельно запускать миграции не требуется. Docker Compose автоматически поднимет приложение, PostgreSQL, локальную почту и S3-совместимое хранилище, применит миграции и добавит демонстрационные товары.

После запуска доступны:

  • приложение — http://localhost:3001;
  • письма с кодами регистрации — http://localhost:8025;
  • консоль MinIO — http://localhost:9001 (логин и пароль: minioadmin).

Оплата работает в демонстрационном режиме без ключей ЮKassa. Для просмотра состояния контейнеров и остановки используйте:

docker compose ps
docker compose down

Подробности и production-настройки приведены в DOCKER.md.

Что реализовано

  • Главная страница с промо-блоками, категориями и визуальными баннерами.
  • Каталог товаров с fuzzy-поиском, подсказками, фильтрами, карточками и страницами товара. Товары без университетского тега попадают в раздел IT-merch, университетские коллекции отображаются отдельно.
  • Адаптивная страница товара с галереей, выбором размера, цвета и добавлением конкретного варианта в корзину.
  • Корзина с выбором позиций, изменением количества, удалением, очисткой, студенческой скидкой, итоговой суммой и выбором размера в рекомендациях.
  • Страница оформления заказа /checkout с контактными данными, доставкой и оплатой.
  • Избранное с синхронизацией для авторизованного пользователя.
  • Регистрация с подтверждением email шестизначным кодом, вход и авторизация через NextAuth.
  • Профиль пользователя с просмотром и редактированием имени, email и телефона.
  • Синхронизация корзины и избранного с базой данных для авторизованных пользователей.
  • Подтверждение статуса студента через корпоративную почту или загрузку студенческого билета.
  • Административный раздел с дашбордом, управлением товарами и их вариантами, заявками на верификацию и журналом действий.
  • Страницы бонусной программы, истории бонусов и правил начисления.
  • Страница поддержки /profile/support с категориями обращений, FAQ, контактами и демонстрационным чатом.
  • Страница таблиц размеров.
  • Адаптивный интерфейс для мобильных устройств: каталог, карточка товара, корзина, профиль, бонусные страницы и поддержка.
  • Светлая и темная тема через ThemeContext.

Технологии

  • Next.js 16 с App Router.
  • React 19.
  • TypeScript.
  • SCSS / Sass для глобальных и постраничных стилей.
  • Prisma как ORM.
  • PostgreSQL как база данных.
  • Docker Compose, Mailpit и MinIO для автономного демонстрационного запуска.
  • NextAuth.js для авторизации.
  • bcryptjs для хеширования паролей.
  • Nodemailer для отправки кодов подтверждения email через SMTP.
  • AWS SDK for JavaScript для работы с S3-совместимым объектным хранилищем.
  • Sharp для проверки, уменьшения и преобразования изображений товаров в WebP.
  • React Icons для иконок.
  • Zustand и React Context для клиентского состояния.

Данные

Основные сущности описаны в prisma/schema.prisma:

  • User - пользователи, роли, контакты и связь с университетом.
  • University - университеты, домены email и связанные товары.
  • Product - товары, изображения, цены, размеры, цвета, остатки и публикация.
  • Favorite - избранные товары пользователя.
  • CartItem - позиции корзины с количеством, размером и цветом.
  • RegistrationVerification - временные данные регистрации, хеш кода, срок действия и число попыток подтверждения.
  • VerificationRequest - заявки на подтверждение статуса студента.
  • AuditLog - реальные действия администраторов, связанные объекты, изменения и IP-адреса.

Товары и университеты для публичного каталога загружаются из PostgreSQL через Prisma. Базовый справочник университетов добавляется безопасной миграцией 20260718190000_add_university_reference_data. prisma/seed.ts идемпотентно добавляет демонстрационные товары при локальном или Docker-запуске и не удаляет существующие данные.

Структура проекта

  • src/app/ - страницы, layouts и API routes.
  • src/app/admin/ - административный интерфейс.
  • src/app/api/ - серверные маршруты авторизации, профиля, корзины, избранного, товаров, загрузки файлов и верификации.
  • src/components/ - переиспользуемые компоненты интерфейса.
  • src/context/ - провайдеры корзины, избранного, темы и общих состояний.
  • src/store/ - Zustand-хранилища.
  • src/lib/ - Prisma client, валидация загрузок, расчет цен и утилиты.
  • src/types/ - общие TypeScript-типы.
  • public/ - изображения, логотипы и статические ассеты.
  • prisma/ - схема базы данных, миграции и seed-данные.

Локальный запуск без Docker

  1. Установить зависимости:

    npm install
  2. Создать .env в корне проекта:

    DATABASE_URL="postgresql://user:password@localhost:5432/uni_practice_app?schema=public"
    NEXTAUTH_SECRET="your-secret-key"
    NEXTAUTH_URL="http://localhost:3000"
    SMTP_HOST="smtp.example.com"
    SMTP_PORT="587"
    SMTP_USER="mailer@example.com"
    SMTP_PASSWORD="smtp-password"
    SMTP_FROM="Campus & Code <mailer@example.com>"
    S3_ENDPOINT="https://s3.example.com"
    S3_REGION="region"
    S3_BUCKET="campuscode-products"
    S3_ACCESS_KEY_ID="s3-access-key"
    S3_SECRET_ACCESS_KEY="s3-secret-key"
    S3_PUBLIC_URL="https://cdn.example.com"
    S3_FORCE_PATH_STYLE="false"
    YOOKASSA_API_URL="https://api.yookassa.ru/v3"
    YOOKASSA_SHOP_ID="test-shop-id"
    YOOKASSA_SECRET_KEY="test-secret-key"
    APP_URL="http://localhost:3000"

    Для SMTP_PASSWORD используйте отдельный пароль приложения почтового сервиса, а не основной пароль от аккаунта. Обычно порт 465 используется для SSL, а 587 — для STARTTLS. Адрес в SMTP_FROM должен соответствовать отправителю, разрешённому SMTP-сервисом.

  3. Применить миграции и сгенерировать Prisma Client:

    npx prisma migrate dev
    npx prisma generate
  4. При необходимости заполнить локальную базу демонстрационными данными:

    npx tsx prisma/seed.ts

    На production seed запускать не следует: он добавляет демонстрационные товары.

  5. Запустить проект:

    npm run dev
  6. Открыть http://localhost:3000.

Команды

npm run dev
npm run build
npm run lint
npm test
npm run start
npx tsc --noEmit

На Windows, если PowerShell блокирует npm.ps1, можно использовать npm.cmd:

npm.cmd run lint
npm.cmd test
npm.cmd run build

Поиск по каталогу

Поиск доступен в шапке сайта. После ввода минимум двух символов отображаются подсказки с товарами, отсортированные по точности совпадения. Нажатие Enter открывает все результаты в каталоге.

Поиск выполняется по названию, описанию, категории, материалам, тегам, университету и артикулу. Fuzzy-сопоставление учитывает регистр, символ ё, окончания слов, пропущенные и переставленные буквы. Например, запрос фболка находит товары категории «Футболки».

Загрузка файлов

Маршрут POST /api/upload поддерживает два сценария:

  • загрузка изображений товаров для SUPERADMIN и UNIVERSITY_ADMIN с преобразованием в WebP и сохранением в S3;
  • загрузка студенческого билета для авторизованного пользователя с purpose=verification-document.

Для студенческого билета разрешены JPG, PNG и PDF до 10 МБ. Файлы сохраняются в public/uploads/verifications.

Для фотографий товаров разрешены JPG, PNG и WEBP до 5 МБ. Перед отправкой в S3 изображения уменьшаются максимум до 2000x2000 и преобразуются в WebP с качеством 80.

S3_PUBLIC_URL должен указывать на публичный адрес бакета или CDN, с которого браузер может получить объект по пути products/<имя-файла>.webp. Для префикса products/* необходимо разрешить публичную операцию s3:GetObject; иначе загруженные изображения будут отвечать 403 Forbidden.

Секретный ключ S3 используется только сервером и не должен попадать в Git, клиентский код или публичные переменные окружения.

Тестовая оплата через ЮKassa

Создайте тестовый магазин в личном кабинете ЮKassa, скопируйте его идентификатор и секретный ключ в YOOKASSA_SHOP_ID и YOOKASSA_SECRET_KEY. После изменения схемы примените миграцию npx prisma migrate dev.

Checkout создаёт заказ на сервере, повторно проверяет цены и остатки, затем перенаправляет пользователя на тестовую платёжную страницу ЮKassa. В тестовом режиме доступна оплата картой; реальные деньги не списываются.

Для уведомлений настройте в кабинете ЮKassa публичный HTTPS-адрес:

https://YOUR-DOMAIN/api/payments/yookassa/webhook

При локальной разработке webhook требует публичный tunnel URL. Страница результата также сверяет статус напрямую через API ЮKassa, поэтому после возврата из платёжной формы заказ обновится даже без webhook.

Текущее состояние

Проект можно запускать локально или через Docker и использовать как адаптивный прототип магазина: смотреть IT- и университетский мерч, добавлять выбранные варианты товаров в корзину и избранное, регистрироваться с подтверждением email, редактировать профиль, обращаться в поддержку, отправлять заявку на подтверждение статуса студента, управлять товарами и заявками в админке.

Основные ограничения текущей версии:

  • заказы сохраняются в моделях Order, OrderItem и Payment, тестовая оплата работает через ЮKassa;
  • для production необходимо подключить настоящий магазин ЮKassa, HTTPS webhook и решение для чеков по 54-ФЗ;
  • форма поддержки и чат работают как демонстрационный интерфейс без серверного хранения обращений и подключения реального оператора;
  • автоматическими тестами покрыта часть логики корзины, избранного, поиска, синхронизации API routes и кодов подтверждения регистрации; checkout пока не покрыт;
  • CI для lint, typecheck и build пока не настроен.

Ближайшие задачи

  • Добавить изменение статусов заказа из административной панели.
  • Добавить повторную оплату и возвраты.
  • Добавить промокоды и расчет скидок.
  • Подключить API обращений поддержки и реальный транспорт для онлайн-чата.
  • Перенести fuzzy-поиск на сервер и добавить сортировку и пагинацию при росте каталога.
  • Расширить тестовые сценарии для checkout и ключевых пользовательских потоков.
  • Настроить CI: lint, typecheck и build.

About

A full-stack learning platform that connects a modern frontend with persistent data and supporting services.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages