Диплом: Создание современной системы управления с использованием последних трендов геймификации

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам
72
контейнеру атрибута “title”, которая позволит узнать описание бейджа при
наведении на него пользователем мышкой.
Помимо личного кабинета, бейджи отображаются также на аватаре
пользователя, который в представлении встречается на карточках задач в
качестве ответственного, а также в вариантах выбора пользователей в
селектах при назначении задач, выборе лидера для ставки или для
перечисления средств. В этих случаях никаких дополнительных полей не
отправляется, только в числе прочих свойств объектов массива
пользователей приходит свойство badges типа array:string, состоящий
только из строк, являющихся ссылками на картинки бейджей.
Чтобы не дублировать функционал отображения бейджей, был
создан специальный AvatarComponent, который в методе created проверяет
доступность указанных картинок и отображает первые три доступные
картинки бейджей лидерства снизу аватара пользователя.
Добавление
Каждый бейдж имеет собственный сценарий добавления его
пользователю, но при этом некоторые из этих сценариев могут быть почти
идентичны, поэтому мы разделим их описание на несколько групп.
Бейджи лидерства:
1. Самое раннее начало рабочего дня. Для отслеживания этого
лидерства мы добавляем в store проекта Vue объект workDay со
свойствами started типа boolean и date типа Date, которая
обозначает, была ли уже начата пользователем работа с
приложением. В методе created компонента kanbanComponent
происходит проверка этой переменной, и если она равна false, то
происходит POST-запрос на сервер для отметки начала
пользователем рабочего дня. При этом проверяется также и дата
73
рабочего дня, и если настоящая дата (new Date()) больше
указанной в workDay, то на сервер отправляется такой же запрос.
В случае, если сервер определил, что пользователь оказался
первым за сегодняшний день, кто начал работу, он отдает в ответе
свойство workDayStatus с типом string и значением ‘first’. Ответ от
сервера асинхронно запускает обновление компонента
уведомлений, в который добавляется новая запись о получении
пользователем бейджа.
2. Самое позднее начало рабочего дня. Весь процесс полностью
идентичен описанному выше, только в данном случае сервер,
рассчитав, что он последний из команды начал работу, отдаёт в
свойстве workDayStatus значение ‘last’ и компонент нотификаций
получает новую запись с соответствующей информацией.
3. Наибольшее и наименьшее количество задач за день, неделю,
месяц. Расчёт этих значений лидерства происходит полностью на
серверной стороне приложения. Пользователь только получает
соответствующие уведомления при входе в систему или во время
работы с ней.
Рис. 3.9 Схема получения бейджей лидерства
74
Бейджи достижений:
1. «Один раз живём!» бейдж получает сотрудник, потративший
все свои байты до последнего. После того, как пользователь
отправил POST-запрос на покупку определённого бонуса, на
сервере происходит проверка, является ли его баланс
положительным, и если нет, пользователь получает этот бейдж.
2. «Ранняя пташка» бейдж получает сотрудник, выполнивший
задачу в период с 05:00 до 07:00 часов ночи. После того, как
пользователь перевёл задачу в колонку статуса «На тестирование»
или «Выполнено», на стороне клиента происходит проверка,
имеет ли этот пользователь соответствующий бейдж, и если нет,
происходит проверка времени, пройдя которую, код отправляет
POST-запрос на url ‘/users/{userId}/badges’, в котором указан тип
бейджа, который должен получить сотрудник. Проверка времени
происходит на стороне клиента, так как локальное время
участника команды может отличаться от времени сервера,
например, в случае удалённой работы.
3. «Город засыпает. Просыпается айтишник» бейдж получает
сотрудник, выполнивший задачу в период с 00:00 до 03:00 часов
ночи. Сценарий присвоения этого бейджа идентичен
предыдущему, за исключением другого интервала времени.
4. Бейджи за получение виртуальной валюты от коллег. Когда на
сервер приходит запрос о перечислении другим пользователем
виртуальной валюты, происходит пересчёт баланса и, что нам
важно в данный момент, статистики поступлений. Так, если
общее количество полученной пользователем валюты превышает
одну из границ, этому пользователю добавляются
75
соответствующий бейдж и новое уведомление, сообщающее об
этом.
Рис. 3.10 Схема получения бейджей достижений
Как видно на схеме, перед получением бейджа система должна
провести две проверки: соответствуют ли свойства пользователя,
сохранённые в БД, условиям получения, и имеется ли уже бейдж такого
типа у пользователя.
3.4. Создание серверной части приложения
В подразделе об установке зависимостей подробно описано, каким
образом мы конфигурируем систему для того, чтобы с ней уже можно
было работать, отправлять запросы и получать ответы. Ниже представлено
описание последующего процесса разработки нашего приложения на
стороне сервера.
3.4.1. Настройка роутинга
В первую очередь важно сформировать роутинг сервера, чтобы все
входящие запросы корректно обрабатывались и направлялись на те
участки кода, где будут производиться расчёты и взаимодействие с базой
данных. Для этого создана папка routes и в ней - несколько файлов, по
76
одному файлу на каждый участок работы с приложением: users.js, teams,js,
sprints.js, stories.js, tasks.js, badges.js. В каждом их этих файлов создаётся
новый объект router с помощью встроенной функции фреймворка express:
express.Router(). К этим роутам будут привязываться адреса запросов с
клиента через функцию, соответствующей типу запроса. В случае GET-
запроса строка будет выглядеть как router.get('/', …)’, а в случае POST-
запроса - router.post('/', …)’. После настройки всех необходимых для
корректной работы приложения роутов в конце каждого из этих файлов
прописывается экспорт для их использования другими файлами:
‘module.exports = router’. Именно это значение будет использовано в
основном файле приложение app.js, где каждый файл с роутингом будет
импортирован и встроен в систему обработки запросов. Первым шагом для
этого является использование метода node.js require(): ‘const usersRoutes
= require('./api/routes/users')’, после чего эту переменную нужно включить в
проект: ‘app.use('/api/users', usersRoutes)’. Такую же операцию нужно
произвести с каждым из файлов, созданных в папке routes.
В примерах адресом запроса является один косой слэш, и это
означает, что эта функция будет обрабатывать запросы, идущие в корень
соответствующего роута. Например, при регистрации нового пользователя,
со стороны клиента идёт POST-запрос на url ‘{адрес сайта}/users. Этот
запрос попадёт в корень роутов пользователей. Если с клиента придет
POST-запрос ‘{адрес сайта}/users/{userId}/badges’, это будет означать, что
запрос необходимо обработать другой функцией.
В синтаксисе node.js, чтобы не пихать весь код в одну кучу в файлах
роутов, имеется возможность указания конкретной функции, которую
можно импортировать из другого файла, например: ‘router.get('/',
checkAuth, UsersController.users_get_list)’. В примере мы видим
77
использование метода ‘users_get_list’ объекта ‘UsersController’, который
мы импортировали из другого файла.
Для минимальной работы с запросами клиента уже достаточно
созданной системы, поэтому мы перейдём к наиболее объёмной части
работы по настройке серверной части приложения – созданию
контроллеров, один из которых – UsersController – был помянут в
предыдущем примере. Но перед этим необходимо разработать небольшую
прослойку программного кода, который мы будем использовать очень
часто: практически каждый раз, когда будет происходить запрос на сервер.
3.4.2. Добавление middleware
Прослойка, или средняя часть серверной части приложения, нужна
нам в первую очередь для того, чтобы отслеживать наличие специального
токена, который клиент получает при регистрации или авторизации, и без
этого токена невозможна работа с системой.
Для этого создана папка middleware и в ней файл check-auth.js, где
будет происходит эта проверка. Внутри файла мы импортируем
библиотеку jsonwebtoken и используем её для проверки приходящего
токена. Как описано выше, токен приходит в виде строки “bearer {token}”,
поэтому в качестве токена мы берём второе значение разобранной
пробелом-разделителем строки, полученной из свойства запроса
req.headers.authorization. Помимо этого, необходимо декодировать это
значение, и для этого мы используем секретный ключ, сохранённый в
конфигурационном файле nodemon.json, и проведём верификацию
соответствующей функцией библиотеки: jsonwebtoken.verify(token,
process.env.JWT_KEY). Схема перехода на нужный роут, проверки токена
и обработка контроллеров представлена в приложении 3.
78
Как видно на схеме, в случае если верификация пройдет успешно,
декодированная информация о пользователе добавляется в каждый запрос
в свойства userData: это необходимо, так как в большинстве контроллеров
нам необходимо знать, с каким пользователем нужно провести работу.
Если верификация не пройдет, то необходимо вернуть клиенту ошибку с
кодом 401 и текстом объяснения этой ошибки: “Auth failed”: авторизация
не удалась.
3.4.3. Создание контроллеров
Пользователи, url /users
Как и в случае клиентской стороны, разработка серверной части
начинается с создания пользователей и работы с этими сущностями. В
общем для этого адреса запросов нам потребуются следующие
контроллеры:
1. /signup – POST, создание пользователя. В теле запроса приходит
пароль и email, и прежде, чем проходит создание нового
пользователя, происходит выбора всех пользователей из базы
данных с email’ом, идентичным пришедшему в теле запроса. Если
с сервера приходит массив с по крайней мере одним элементом,
значит, в БД уже существует пользователь с таким email’ом, и мы
возвращаем на клиент код 409 со строкой информации “ User with
this email is already exists”. В противном случае мы начинаем
процесс создания пользователя. Для этого мы производим
следующие действия:
a. хэшируем пришедший в теле запроса пароль с помощью
импортированной библиотеки bcrypt. Таким образом мы
обеспечиваем безопасность хранения пароля на нашей
стороне,
79
b. присваиваем создаваемому пользователю уникальный
идентификатор с помощью встроенного Mongo-метода: new
mongoose.Types.ObjectId().
c. сохраняем новый объект User в базе данных,
d. Возвращаем на клиент код 200 с информационной строкой
User created” и данными пользователями: email и id – на
случай, если эти данные понадобятся клиенту для
дальнейшей работы в приложении.
2. /login – POST, авторизация. В этом контроллере мы так же
производим выборку пользователей по пришедшему в теле
запроса email, но возвращаем ошибку в том случае, если ни
одного пользователя не найдено. Следующая проверка
происходит с помощью сравнивания пришедшего с клиента
пароля с хешированным на сервере. Для этого используется
функция compare всё той же библиотеки bcrypt:
bcrypt.compare({пароль в теле запроса}, {пароль найденного
пользователя}, …). Если пароли идентичны, создается токен:
jsonwebtoken.sign({email, id}) и возвращается на клиент вместе с
другими данными пользователя. Этот токен должен отправляться
клиентом при каждом запросе, и он же проверяется в созданной
прослойке middleware.
За исключением системы начисления виртуальной валюты и
бейджей, все контроллеры серверной части приложения являются простой
обработкой входящих запросов, проверкой корректности введённых
данных, проверкой токена и выдачей, сохранением, удалением или
обновлением информации в БД, поэтому в работе не будет развёрнутого
описания процесса их разработки, поскольку они не только просты, но и во
многом похожи друг на друга. Отдельно расширим описание тех
80
контроллеров, в которых происходят расчёты валюты и проверки для
награждения бейджами.
Ниже мы перечислим контроллеры, обрабатывающие прочие
запросы клиента по пользователям:
3. /update – PUT, обновление данных пользователя;
4. /delete – DELETE, обновление данных пользователя;
Команды, url /teams
1. /create – POST, создание команды;
2. /update – PUT, обновление информации по команде;
3. /delete – DELETE, удаление команды;
4. /{teamId}/user – PATCH, добавление пользователя в команду. При
добавлении нового пользователя ему немедленно начисляется
бейдж «Зелёный», и этот же бейдж удаляется у предпоследнего
участника команды.
5. /{teamId}/user – DELETE, исключение пользователя из команды.
Перед этим исключением происходит проверка на наличие у
пользователя бейджа «Бывалый», при наличии которого он
удаляется, и после удаления пользователя из команды этот бейдж
добавляется первому пользователю в массиве участников
команды.
Спринты, url /sprints
1. /create – POST, создание спринта;
2. /update – PUT, обновление информации по спринту.
3. /delete – DELETE, удаление спринта;
4. /start – PATCH, запуск спринта: изменение свойства launched;
81
5. /finish – PATCH, остановка спринта: изменение свойства launched.
После обновления спринта в БД происходит расчёт количества
задач, выполненных каждым участником спринта. Сумма всех
user points этих задач, делённая на 8, начисляется пользователю на
его личный баланс, после чего, как и всегда, добавляется запись
истории транзакций и пересчёт статистики поступлений. Для
этого сначала получаем среднее значение userpoints по каждому
участнику спринта с помощью mongo команды $avg, делим на
восемь и начисляем соответственным пользователям.
6. /{sprintId}/story – PATCH, добавление истории к спринту;
7. /{sprintId}/story – DELETE, исключение истории из спринта;
Истории, url ‘/stories
1. /create – POST, создание истории;
2. /update – PUT, обновление информации по истории;
3. /finish – PATCH, изменение свойства ‘status’ на ‘finished’, после
чего происходит расчёт количества задач, относящихся к истории,
и выборка участников, работавших с этими задачами. Каждому из
них на личный баланс начисляется количество валюты, равное
четверти от суммы всех user points всех задач, выполненных
пользователем. Также добавляются записи в историю и
перерасчёт статистики.
4. /delete – DELETE, удаление истории;
Задачи, url ‘/tasks
1. /create – POST, создание задачи;
2. /update – PUT, обновление информации по задаче;
3. /delete – DELETE, удаление задачи;

Смотрите также:

"Автоматизация обработки заявок ООО "Проектно-Строительная Компания"
"Автоматизация процесса аттестации персонала для ООО "Нэт Бай Нэт Холдинг"
"Анализ интернет-активности конкурентов ( на примере конкурентов "Газпром нефть")
"Бухгалтерский учёт и аудит расчётов с подотчётними лицами в организации на примере ООО "ЛОЦ 10""
«Психологическое сопровождение персонала в организации на примере ООО «Крокус»
Cовершенствование деловой оценки персонала в организации (на примере ООО "Даймонд кейтеринг развитие")
PR как средство продвижения организации (на примере ПАО "Тамбовский завод "Комсомолец им. Н.С. Артемова")
PR-коммуникации в сфере общественного питания (на примере кафе-кондитерской «Cream Cheese»)
SMM как средство повышения эффективности работы учреждений социокультурной сферы (на примере Малого театра)
Value-based education: ценности в системе образования и способы их реализации на уроке английского языка. Опыт Европейских стран