Создание собственной системы электронной коммерции на базе 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. Просто добавьте следующее:

Открыть Github Gist

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

Открыть Github Gist

Я уже добавил переменные, необходимые для интеграции 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 этим кодом:

Открыть Github Gist

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

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

yarn create keystone-app

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

Открыть Github Gist

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

mkdir consts enums schema

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

FROM node:16
WORKDIR /usr/app
CMD yarn dev
Открыть Github Gist

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

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

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

Открыть Github Gist

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

Вот код:

Открыть Github Gist

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

Открыть Github Gist

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

Открыть Github Gist

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

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

Открыть Github Gist

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

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

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

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

Открыть Github GistОткрыть Github GistОткрыть Github Gist

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

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

Открыть Github GistОткрыть Github GistОткрыть Github Gist

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

Открыть Github GistОткрыть Github GistОткрыть Github Gist

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

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

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

Открыть Github Gist

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

Открыть Github Gist

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

Открыть Github Gist

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

Открыть Github Gist

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

Открыть Github Gist

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

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

Получение данных из формы с помощью JavaScript - краткое руководство
Получение данных из формы с помощью JavaScript - краткое руководство

17.11.2022 16:30

Получить данные из формы с помощью JS очень просто: вы запрашиваете элемент формы, передаете его конструктору new FormData() и, наконец, получаете нужную информацию с помощью метода .get().

Пользовательские правила валидации в Laravel
Пользовательские правила валидации в Laravel

16.11.2022 13:12

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

3 метода стилизации элементов HTML
3 метода стилизации элементов HTML

15.07.2022 14:37

Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно является внешний метод. Это помогает сохранить код незагроможденным и организованным. Однако ситуация может диктовать использование двух других методов....

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly

16.05.2022 21:25

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

Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)

18.04.2022 13:17

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

Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React

13.04.2022 15:26

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