# Неделя #3 Начинаем выполнять домашнюю работу №5


# Подготовка к выполнению задания

Изучить все материалы третьей недели курса в Личном кабинете

# Что нужно сделать?

# Выполнить домашнюю работу №5 (Корпоративная система "LoftSystem")

Обратите внимание: Данное задание вы будете выполнять на протяжении 3 последних недель курса. Каждую неделю отправляйте выполненную часть проекта на проверку наставнику. К итоговому дедлайну проект должен быть выполнен полностью.

Для запуска:

  1. git clone https://github.com/satansdeer/loftschool-nodejs-project

Макет для домашней работы №5 можно скачать по ссылке

Ознакомиться с примером

# LoftSystem

Большая домашняя работа курса по Node.js - Корпоративная система "LoftSystem".

Задача

В папке ./build находится подготовленная frontend-часть проекта, ваша задача - реализовать backend.

  1. Выберите фреймворк - Express.js или Koa.js.
  2. Выберите базу данных - MongoDB (рекомендуемая ORM - Mongoose) или PostgreSQL (рекомендуемая ORM - Sequelize).
  3. Подготовьте http-сервер, который на любой get-запрос вернет index.html (маршрутизация выполняется на frontend'e средствами библиотеки react-router).
  4. Реализуйте логику обработки 12 различных запросов:
  • POST-запрос на /api/registration - создание нового пользователя (регистрация). Сигнатура запроса: { username, surName, firstName, middleName, password }. Необходимо вернуть объект авторизовавшегося пользователя.
  • POST-запрос на /api/login - авторизация после пользовательского ввода. Cигнатура запроса: { username, password } Необходимо вернуть объект авторизовавшегося пользователя.
  • POST-запрос на /api/refresh-token - обновление access-токена. В headers['authorization'] прикрепить refresh-токен. Вернуть объект с токенами
  • GET-запрос на /api/profile - авторизация при наличии токена. Необходимо вернуть объект пользователя.
  • PATCH-запрос на /api/profile - обновление информации о пользователе. Сигнатура запроса:
{
    firstName: String,
    middleName: String,
    surName: String,
    oldPassword: String,
    newPassword: String,
    avatar: File
}

Необходимо вернуть объект обновленного пользователя.

  • DELETE-запрос на /api/users/:id - удаление пользователя.
  • GET-запрос на /api/news - получение списка новостей. Необходимо вернуть список всех новостей из базы данных.
  • POST-запрос на /api/news - создание новой новости. Сигнатура запроса: { text, title }. Необходимо вернуть обновленный список всех новостей из базы данных.
  • PATCH-запрос на /api/news/:id - обновление существующей новости. Сигнатура запроса: { text, title }. Необходимо вернуть обновленный список всех новостей из базы данных.
  • DELETE-запрос на /api/news/:id - удаление существующей новости. Необходимо вернуть обновленный список всех новостей из базы данных.
  • Автоматический GET-запрос на /api/users - получение списка пользователей. Необходимо вернуть список всех пользоватлей из базы данных.
  • PATCH-запрос на /api/users/:id/permission - обновление существующей записи о разрешениях конкретного пользователя. Сигнатура:
{
    permission: {
        chat: { C: Boolean, R: Boolean, U: Boolean, D: Boolean },
        news: { C: Boolean, R: Boolean, U: Boolean, D: Boolean },
        settings: { C: Boolean, R: Boolean, U: Boolean, D: Boolean }
    }
}

Объект пользователя:

{
    firstName: String,
    id: Primary key,
    image: String,
    middleName: String,
    permission: {
        chat: { C: Boolean, R: Boolean, U: Boolean, D: Boolean },
        news: { C: Boolean, R: Boolean, U: Boolean, D: Boolean },
        settings: { C: Boolean, R: Boolean, U: Boolean, D: Boolean }
    }
    surName: String,
    username: String
}

Объект авторизованного пользователя:

{
    firstName: String,
    id: Primary key,
    image: String,
    middleName: String,
    permission: {
        chat: { C: Boolean, R: Boolean, U: Boolean, D: Boolean },
        news: { C: Boolean, R: Boolean, U: Boolean, D: Boolean },
        settings: { C: Boolean, R: Boolean, U: Boolean, D: Boolean }
    }
    surName: String,
    username: String,

    accessToken: String,
        refreshToken: String,
        accessTokenExpiredAt: Date (ms),
        refreshTokenExpiredAt: Date (ms)
}

Объект новости:

{
    id: Primary key,
    created_at: Date,
    text: String,
    title: String,
    user: {
        firstName: String,
        id: Key,
        image: String,
        middleName: String,
        surName: String,
        username: String
    }
}

Объект с токенами:

{
    accessToken: String,
    refreshToken: String,
    accessTokenExpiredAt: Date (ms),
    refreshTokenExpiredAt: Date (ms)
}

(Более подробную информацию об url, дополнительных параметрах и передаваемых данных запроса вы можете получить через средства разработчика при взаимодействии с интерфейсом).

  1. Реализуйте логику взаимодействия frontend и backend частей между собой с помощью socket. Необходимо для реализации чата. У вас должен быть хеш-объект, в который вы запишите все активные подключения в формате:
{ #socketId: {
  username: #username,
  socketId: #socketId,
  userId: #userId,
  activeRoom: null // По умолчанию
  },
  ...
}

Ваше socket-подключение должно обрабатывать следующие события:

  • users:connect, инициируется при подключении пользователя. Необходимо создать объект пользователя и сохранить в нем socketId сокета, userId пользователя и имя пользователя, как свойства, обновить общий объект, и отправить его, в виде массива, только что подключившемуся пользователю (с помощью события users:list). Разослать всем подключенным сокетам объект нового пользователя (с помощью события users:add).

  • message:add, инициируется при отправке одним из пользователей сообщения другому. Нужно передать пользователю-получателю в параметрах текст сообщения (text) и senderId отправителя и recipientId получателя с помощью события message:add.

  • message:history, инициируется при открытии пользователем чата. Нужно вернуть пользователю список сообщений диалога с выбранным пользователем. Параметры: recipientId - id пользователя-получателя (чат с которым мы открыли), userId - id пользователя (свой). Список сообщений диалога отправить с помощью события message:history.

  • disconnect, инициируется при отключении пользователя. Нужно передать всем подключенным пользователям socketId отключившегося пользователя (с помощью события users:leave), и удалить пользователя из объекта всех подключенных пользователей.

  1. Подготовьте окружение и запустите проект на выбранном вами хостинге (например, heroku).

Сдаем домашнюю работу №5 на проверку:

# 1. Сделайте коммит и пуш изменений

# 2. Создайте пулл реквест и отправьте его на проверку наставнику

# Как всё успеть?

Данный план является примерным ориентиром. Вы всегда можете работать в удобном для себя темпе

# 🗓 Понедельник

Изучаем методичку по теме "REST API"

# 🗓 Вторник

Изучаем материалы по теме "REST API"

Перечитываем методичку по теме "REST API"

# 🗓 Среда

Начинаем работу над домашней работой №5

Изучаем методичку по теме "Работа с реляционными БД"

# 🗓 Четверг

Перечитываем методичку по теме "Работа с реляционными БД"

Изучаем материалы по теме "Работа с реляционными БД"

Подготовьте вопросы и запишитесь на консультацию к наставнику (тариф "Уютный")

# 🗓 Пятница

Изучаем материалы по теме "Работа с нереляционными БД” (на примере MongoDB)

Продолжаем выполнять домашнюю работу №5 и отправляем ее на проверку

# 🗓 Суббота

Изучаем методичку по теме "Работа с нереляционными БД” (на примере MongoDB)"

Изучаем материалы воркшопа

Отдыхаем и набираемся сил