Для Windows используйте команды ниже в PowerShell (остальные команды в README в основном даны в bash).
Локальный запуск:
cd server
npm run env:init
npm install
npm run migrate
npm run start-dev
cd ../client
npm run env:init
npm install
npm startDocker:
node scripts/init-env.js .env.example .env
docker compose up -d --buildПриветствуются пулл-реквесты (PR) и сообщения об ошибках. Пожалуйста, добавляйте тесты для нового функционала.
Интернет-магазин на:
server- Node.js + Express + Sequelize + PostgreSQLclient- React 19 + Vite (единый клиент)
Node.js:^20.19.0 || >=22.12.0Express:^5.2.1Sequelize:^6.37.7PostgreSQL:15+(рекомендуется16, Docker по умолчанию:postgres:16-alpine)
- Node.js
^20.19.0или>=22.12.0 - npm 9+
- PostgreSQL
15+(рекомендуется 16) - Docker 24+ и Docker Compose v2 (опционально)
Проект поддерживает Ubuntu, macOS и Windows (PowerShell):
- все npm-скрипты запускаются одинаково на всех трёх ОС;
- для инициализации
.envиспользуйте кроссплатформенный скриптnode scripts/init-env.js; - Docker-команды из раздела ниже одинаково работают на Ubuntu, macOS и Windows (PowerShell).
- Создайте базу:
CREATE DATABASE online_store;- Сервер:
cd server
npm run env:init
npm install
npm run migrate
npm run start-devМинимально проверьте в server/.env:
DB_HOST,DB_NAME,DB_USER,DB_PASS,DB_PORTSECRET_KEY(минимум 32 символа, без значений по умолчанию)PAYMENT_WEBHOOK_SECRET(минимум 24 символа)
Пример генерации безопасных значений:
node -e "const c=require('crypto');console.log('SECRET_KEY='+c.randomBytes(32).toString('hex'));console.log('PAYMENT_WEBHOOK_SECRET='+c.randomBytes(24).toString('hex'))"Сервер: http://localhost:7000.
- Клиент:
cd ../client
npm run env:init
npm install
npm startКлиент: http://localhost:3000.
Важно: фикстуры пользователей, каталог и полный дамп database.sql не импортируются автоматически ни локально, ни в Docker.
Все команды для ручной загрузки данных собраны в разделе Ручная загрузка данных (фикстуры, каталог и полный дамп).
Запуск из корня:
node scripts/init-env.js .env.example .env
docker compose up -d --buildDocker автоматически использует:
server/.env.dockerдля backend- root
.envдля:POSTGRES_IMAGE(версия Postgres)SECRET_KEYPAYMENT_WEBHOOK_SECRET
Перед стартом обязательно задайте в root .env:
SECRET_KEY(минимум 32 символа)PAYMENT_WEBHOOK_SECRET(минимум 24 символа)
Генерация безопасных значений:
node -e "const c=require('crypto');console.log('SECRET_KEY='+c.randomBytes(32).toString('hex'));console.log('PAYMENT_WEBHOOK_SECRET='+c.randomBytes(24).toString('hex'))"Фикстуры пользователей, каталог и полный дамп database.sql не импортируются автоматически.
Используйте команды из раздела Ручная загрузка данных (фикстуры, каталог и полный дамп).
Сервисы:
- клиент:
http://localhost:3000 - API:
http://localhost:7000/api - health:
http://localhost:7000/health
Проверка после старта:
docker compose ps
curl http://localhost:7000/healthОстановка:
docker compose downПолный рестарт проекта с пересборкой:
docker compose down && docker compose up -d --buildС очисткой данных PostgreSQL:
docker compose down -vПо умолчанию используется образ postgres:16-alpine.
Можно переключить, например, на 15 (через .env):
POSTGRES_IMAGE=postgres:15-alpineИли разово без изменения .env:
POSTGRES_IMAGE=postgres:15-alpine docker compose up -d --buildPowerShell:
$env:POSTGRES_IMAGE='postgres:15-alpine'; docker compose up -d --buildЕсли меняете major-версию PostgreSQL на уже существующем volume, обычно нужен перезапуск с очисткой данных:
docker compose down -v
docker compose up -d --buildPOSTGRES_IMAGE=postgres:16-alpine
SECRET_KEY=
PAYMENT_WEBHOOK_SECRET=PORT=7000
DB_HOST=localhost
DB_NAME=online_store
DB_USER=postgres
DB_PASS=change_me
DB_PORT=5432
SECRET_KEY=__SET_STRONG_SECRET_KEY__
BCRYPT_SALT_ROUNDS=10
PAYMENT_WEBHOOK_SECRET=__SET_PAYMENT_WEBHOOK_SECRET__
CORS_ORIGINS=http://localhost:3000
RATE_LIMIT_MAX=300
UPLOAD_MAX_FILE_SIZE=5242880VITE_API_URL=http://localhost:7000/api/
VITE_IMG_URL=http://localhost:7000/npm run migrate- запуск SQL-миграцийnpm run start-dev- dev-запускnpm start- production-запускnpm test- API smoke-тестыnpm run seed:users- upsert фикстурных пользователей (только при явно заданных env)npm run restore:catalog- восстановление товаров и свойств изdatabase.sql
npm start/npm run dev- запуск Vitenpm run build- production-сборкаnpm run preview- preview сборкиnpm test- unit-тесты (Vitest)
В шапке сайта доступен переключатель валюты:
KZT(по умолчанию)RUB
Курс RUB -> KZT синхронизируется из внешних API через backend:
GET /api/currency/rub-kzt(поддерживает?refresh=1для принудительной актуализации)- при недоступности внешних источников используется безопасный fallback.
GET /api/product/getall поддерживает параметры:
q- строка поиска (до 80 символов, ищет по названию товара, бренду и категории)sort- сортировка (name_asc,price_asc,price_desc,rating_desc,newest)page- номер страницы (по умолчанию1)limit- элементов на страницу (по умолчанию3, максимум100)
Параметры можно комбинировать с маршрутами фильтрации:
/api/product/getall/categoryId/:categoryId/api/product/getall/brandId/:brandId/api/product/getall/categoryId/:categoryId/brandId/:brandId
GET /api/content/navbar— публично, данные шапки сайтаPUT /api/content/navbar— только администратор, обновляет шапкуGET /api/content/delivery— публично, страница доставки и список GPS-точекPUT /api/content/delivery— только администратор, обновляет страницу доставки и точкиGET /api/content/contacts— публично, данные страницы контактовPUT /api/content/contacts— только администратор, обновляет контактыGET /api/content/home— публично, hero-блок главной страницыPUT /api/content/home— только администратор, обновляет hero-блок главнойDELETE /api/content/home— только администратор, удаляет/сбрасывает hero-блок главной
GET /api/currency/rub-kzt— курс RUB → KZT (?refresh=1для принудительного обновления)GET /api/currency/overview— обзор курсов для виджетов кабинета- параметры:
base(напримерKZT),symbols(напримерUSD,EUR,RUB,KZT,CNY,GBP),refresh=1
- параметры:
POST /api/feedback/create— публично, отправка обращения из формы обратной связиGET /api/feedback/admin/getall— только администратор, список обращений (?status=new|read|spam)GET /api/feedback/admin/getone/:id— только администратор, чтение обращенияPATCH /api/feedback/admin/read/:id— только администратор, пометить как прочитанноеPATCH /api/feedback/admin/block/:id— только администратор, пометить как спам и заблокировать отправителяDELETE /api/feedback/admin/delete/:id— только администратор, удалить обращение
POST /api/payment/order/:orderId/initiate— инициация платежа (авторизованный владелец заказа или администратор)- обязательный header:
Idempotency-Key - body:
provider(mock),currency,returnUrl,metadata
- обязательный header:
GET /api/payment/order/:orderId— получить платеж заказа (авторизованный владелец заказа или администратор)POST /api/payment/webhook/:provider— webhook провайдера (raw JSON)- обязательный header:
x-webhook-signature(HMAC SHA-256 от raw body) - секрет подписи:
PAYMENT_WEBHOOK_SECRET
- обязательный header:
Локально:
cd server && npm test
cd ../client && npm test && npm run buildВ Docker:
docker compose run --rm --no-deps -e NODE_ENV=test -v "$PWD/server:/app" -v /app/node_modules server sh -lc "npm ci --include=dev && npm test"
docker compose run --rm --no-deps -e NODE_ENV=development -v "$PWD/client:/workspace/client" -v /workspace/client/node_modules server sh -lc "cd /workspace/client && npm ci --include=dev && npm test && npm run build"PowerShell:
docker compose run --rm --no-deps -e NODE_ENV=test -v "${PWD}/server:/app" -v /app/node_modules server sh -lc "npm ci --include=dev && npm test"
docker compose run --rm --no-deps -e NODE_ENV=development -v "${PWD}/client:/workspace/client" -v /workspace/client/node_modules server sh -lc "cd /workspace/client && npm ci --include=dev && npm test && npm run build"Примечание:
- предупреждение
No services to buildот Docker Compose дляrunдопустимо и не является ошибкой; - отдельный том
-v /.../node_modulesобязателен, чтобы изолировать Linux-зависимости контейнера от хостовогоnode_modules(особенно важно на Windows). - на первом запуске после строки
Container ... Creating/Createdвозможна пауза наnpm ci(это нормально, контейнер не завис).
По умолчанию данные не загружаются автоматически:
- фикстуры пользователей;
- каталог (товары + характеристики);
- полный дамп
database.sql.
Локально:
cd server
FIXTURE_ADMIN_EMAIL=admin@local.test \
FIXTURE_ADMIN_PASSWORD='set_strong_password' \
FIXTURE_USER_EMAIL=user@local.test \
FIXTURE_USER_PASSWORD='set_strong_password' \
npm run seed:usersPowerShell:
cd server
$env:FIXTURE_ADMIN_EMAIL='admin@local.test'
$env:FIXTURE_ADMIN_PASSWORD='set_strong_password'
$env:FIXTURE_USER_EMAIL='user@local.test'
$env:FIXTURE_USER_PASSWORD='set_strong_password'
npm run seed:usersDocker:
docker compose exec server sh -lc "FIXTURE_ADMIN_EMAIL=admin@local.test FIXTURE_ADMIN_PASSWORD='set_strong_password' FIXTURE_USER_EMAIL=user@local.test FIXTURE_USER_PASSWORD='set_strong_password' npm run seed:users"Локально:
cd server
npm run restore:catalogDocker:
docker compose exec server npm run restore:catalogИмпортируйте только в чистую БД. После импорта обязательно запустите миграции, чтобы добавить недостающие таблицы/индексы (включая payment-домен).
Локально:
psql -v ON_ERROR_STOP=1 -U postgres -d online_store -f database.sql
cd server
npm run migrateDocker:
docker compose down -v
docker compose up -d --wait db
docker compose cp database.sql db:/tmp/database.sql
docker compose exec db sh -lc "psql -v ON_ERROR_STOP=1 -U postgres -d online_store -f /tmp/database.sql"
docker compose up -d --wait server client