Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели

RedDeveloper
18.03.2022 16:24
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели

Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели

На этой неделе мы собираемся испачкать руки и начать кодить.

Введение

Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом требованиям к системе и ее базовой архитектуре. На этой неделе мы собираемся немного испачкать руки и начать кодировать. Сначала мы поговорим о среде разработки и ее настройке. Затем о настройке Keystone и Next, и, наконец, о настройке основных моделей. Кроме того, готовый код для этой статьи доступен на моем GitHub.

Настройка среды разработки

Давайте начнем и создадим папку проекта для нашей системы, в моем случае keystone-e-commerce, и создадим несколько необходимых файлов. Выполните следующую команду в консоли:

mkdir keystone-e-commerce && cd keystone-e-commercetouch
README.md docker-compose.dev.yml .gitignore .env.example .env

Согласно предыдущей статье, слой данных этой системы содержит два элемента: базу данных и поисковую систему. Самый простой способ использовать их локально в нашей среде разработки - использовать для этого Docker. Итак, пришло время обновить наш файл docker-compose.dev.yaml. Просто добавьте следующее:

Также я добавил сюда pgAdmin. Это хороший и очень полезный инструмент, особенно в среде dev. Далее необходимо настроить переменные окружения для системы. Самый простой способ сделать это - создать один файл .env и использовать его во всех контейнерах. Хорошо, давайте добавим все необходимые переменные, как показано ниже:

Я уже добавил переменные, необходимые для интеграции Cloudinary; мы
вернемся к ним позже. Затем обновите файл .gitgnore. На данный момент этого достаточно. Следующий код поможет:

**/node_modules
.env

Теперь, с этой базовой настройкой, мы можем запустить наши контейнеры с помощью этой команды:

docker-compose -f docker-compose.dev.yml up

Настройка Kesytone.js и Next.js

С этой настройкой мы можем сосредоточиться на других частях системы. Во-первых, давайте создадим наше клиентское приложение Next.js. Честно говоря, здесь мы только создадим его и добавим в нашу Docker-установку. Более подробная работа с ним будет проведена в последующих статьях этого цикла. Давайте выполним соответствующую команду:

yarn create next-app --typescript

Скрипт спросит нас об имени приложения. Я назвал свое client. После установки нам нужно создать Dockerfile.dev для этого приложения, чтобы использовать его с другими контейнерами. Он довольно простой, как вы видите:

FROM node:16
WORKDIR /usr/app
CMD yarn dev -p 3000

Кроме того, обновите файл docker-compose.dev.yml в разделе services этим кодом:

Подобное решение позволяет использовать один главный файл .env, что очень удобно и дает централизованный контроль над всеми системными секретами. Кроме того, это инкапсулирует всю систему в одну закрытую сеть docker. И на данный момент это все об этой части приложения. Итак, давайте перейдем к бэкенду и настроим Kesytone.js.

Сначала запустите скрипт для создания приложения. В качестве имени папки для него я выбрал backend.

yarn create keystone-app

После этого оно практически готово к использованию, но сначала нам нужно обновить базу данных и другие конфигурации. В keystone.ts добавьте учетные данные и обновите импорт для списков:

Затем создайте дополнительные папки, чтобы получить красивую и понятную структуру, с помощью этого кода:

mkdir consts enums schema

Кроме того, импорт в главном конфигурационном файле требует, чтобы мы добавили index.ts в папку schema для правильной работы. Осталось сделать последний элемент настройки - создать файл Dockerfile.dev и обновить docker-compose.dev.yml. Он будет довольно похож на предыдущий, как показано ниже:

FROM node:16
WORKDIR /usr/app
CMD yarn dev

Это также позволит нам запустить всю систему одной командой.

Настройка моделей

Когда работа по настройке завершена, мы можем начать и создать все необходимые списки Keystone (и модели данных в нашем случае). Начнем с модели User. По сути, она будет хранить все данные о пользователях, включая роли и привилегии внутри системы. Создайте файл user.schema.ts в папке schema. Пока что нас интересует только свойство fields списка. Мы должны добавить туда все необходимые поля, как вы можете видеть ниже:

Поля name, email и password достаточно очевидны. Их назначение - идентифицировать пользователя, и они необходимы для процесса авторизации и аутентификации. Все три поля являются обязательными. Кроме того, email должен быть уникальным, и в Admin UI его можно использовать для фильтрации всех пользователей. Более интересным является поле роли. Его тип - select, и оно содержит информацию о привилегиях пользователя в системе. Чтобы сохранить чистоту, в базе данных будет создан столбец enum. Я перенес значения опций в отдельный файл в папке consts.

Вот код:

Также я перенес все значения в файл в папке enums:

На данный момент этих двух ролей достаточно. Позже нам понадобится больше. Последнее поле содержит ссылку на список адресов. Точнее, это отношение "один-ко-многим". Следующий список содержит все адреса, связанные с пользователями; у каждого из них их может быть несколько. Итак, создайте address.schema.ts, как показано ниже:

Этот список содержит всю необходимую адресную информацию, которая понадобится при отправке заказов пользователей. Большинство полей являются обязательными для предоставления достаточной информации о доставке. Также в этом списке хранятся временные метки создания записи и ее последнего изменения. Последнее поле - это ссылка на пользователя, владельца данного адреса, и в данном случае это отношение "многие-к-одному".

Следующей, тесно связанной со списком пользователей, является модель Cart. Она содержит всю информацию о товарах, добавленных пользователем в корзину, их сумму и дату последней модификации. Каждый пользователь имеет одну корзину, так что это отношение один-к-одному. Вот код:

В каждую корзину может быть добавлено множество товаров, и один и тот же товар может быть добавлен в несколько корзин, поэтому создается связь "многие-ко-многим".

Убрав это, мы можем сосредоточиться на других моделях. Следующая модель, связанная с User и слабо связанная с Cart, - это Order list. Он содержит всю информацию о заказах, находящихся в обработке и уже обработанных. Первое поле - это ссылка на пользователя, владельца этого заказа, отношение "один к одному". Каждый пользователь может иметь несколько заказов, но каждый заказ имеет только одного владельца.

Следующее поле содержит информацию о товарах в этом заказе, сериализованную в JSON. Таким образом, мы можем хранить информацию обо всех товарах в заказе, не только о тех, которые в данный момент есть в наличии, но и о снятых с предложения.

Далее, два поля содержат связь со списками Payment и Shipment, оба отношения один-к-одному. Последние три поля содержат информацию о дате создания, последней модификации и статусе заказа. Последнее поле имеет тип select, я перенес все опции и значения в отдельные файлы, как это было раньше с ролями пользователей.

Следующие два списка дополняют модель заказа и содержат информацию об оплате и отправке, связанных с ним. Оба списка содержат основную информацию о временных метках и статусах обоих бизнес-процессов (создаются так же, как и статус заказа) и их связи с заказом.

Первая из них дополнительно хранит информацию о сумме заказов, ее валюте и ID транзакции от стороннего провайдера. Я еще не думал о конкретной интеграции в этом вопросе, но, вероятно, это будет Stripe, так как я с ним наиболее хорошо знаком.

С другой стороны, модель Shipment содержит информацию о сотрудниках, ответственных за обработку груза, его упаковку и отправку. Также, как и в предыдущей модели, здесь есть информация о внешнем ID из сторонней системы, ответственной за обработку доставки.

На данный момент все поля статуса содержат только один вариант - Создан. В следующих частях этой серии, более сфокусированных на этих разделах системы, мы собираемся добавить другие необходимые опции.

Последняя группа моделей сосредоточена на продуктах. Основной список Product содержит основную информацию о продукте, такую как название, описание, SEO-описание, цена, рейтинг (звезды) и метки времени. Остальные поля устанавливают различные связи с более конкретной информацией о продукте, такой как изображения продукта, категории и запасы.

Первое из них создает отношения "один ко многим", второе - "многие ко многим", а последнее - "один к одному". В принципе, у товара может быть несколько изображений, но изображение принадлежит только одному товару. У каждого товара могут быть категории, а у категорий много товаров, и, наконец, у каждого товара только одна информация о складе (как я уже упоминал в предыдущей статье, я решил поддерживать только один склад).

Следующий список содержит изображения товаров. Здесь есть два важных поля: alt и image. Первое содержит информацию, необходимую для заполнения HTML-атрибута alt для каждого изображения. Второе позволяет загружать изображения непосредственно в CDN Cloudinary. Все это дополняется полями временных меток.

Следующий список, Stock, содержит информацию о количестве доступных для заказа товаров. Кроме того, здесь есть информация о следующей ожидаемой поставке и количестве продуктов в ней. Это необходимо для случаев, когда пользователь пытается заказать больше товаров, чем есть в наличии.

Последняя модель, Category, хранит информацию о категориях товаров и их взаимосвязях друг с другом. Поля здесь включают название категории, связанные продукты, родительскую категорию (если она есть) и обычные временные метки. Эти внутренние отношения позволяют легко создавать дерево категорий, что будет полезно при создании фронтенда нашей системы.

Последнее, что нужно сделать здесь, это импортировать все модели в index.ts, который импортируется в основной конфигурационный файл keystone.ts, показанный ниже:

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

ER-диаграмма
ER-диаграмма

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

docker-compose -f docker-compose.dev.yml up database

После этого запустите в отдельном терминале наш бэкенд:

cd backend && yarn dev

Скрипт запросит имя новой миграции, введите initial_models и нажмите enter. Он обработает создание таблицы и сгенерирует файлы миграции. Теперь мы можем остановить оба процесса и запустить всю систему.

docker-compose -f docker-compose.dev.yml up database

Резюме

Теперь у нас есть рабочее dev-окружение и базовая настройка моделей, так что это дает нам прочный фундамент для нашей системы. В следующий раз мы начнем создавать дополнительные функции, необходимые для системы электронной коммерции. Сначала мы сосредоточимся на контроле доступа и привилегиях пользователей для доступа к различным частям системы.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?

20.08.2023 18:21

Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией

20.08.2023 17:46

В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox

19.08.2023 18:39

Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest

19.08.2023 17:22

В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для чтения благодаря своей простоте. Кроме того, мы всегда хотим проверить самые последние возможности в наших проектах!

Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️

18.08.2023 20:33

Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий их языку и культуре.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL

14.08.2023 14:49

Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип предназначен для представления неделимого значения.