{"id":46031061,"url":"https://github.com/iliazaraysky/distributed-expression-calculator","last_synced_at":"2026-03-01T03:43:43.498Z","repository":{"id":223131683,"uuid":"753075118","full_name":"iliazaraysky/distributed-expression-calculator","owner":"iliazaraysky","description":"Распределенный вычислитель арифметических выражений","archived":false,"fork":false,"pushed_at":"2024-04-11T21:26:26.000Z","size":2887,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-12T06:12:39.858Z","etag":null,"topics":["docker","golang","react"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iliazaraysky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-02-05T12:24:14.000Z","updated_at":"2024-04-14T22:36:01.578Z","dependencies_parsed_at":"2024-04-14T22:46:12.667Z","dependency_job_id":null,"html_url":"https://github.com/iliazaraysky/distributed-expression-calculator","commit_stats":null,"previous_names":["iliazaraysky/distributed-expression-calculator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/iliazaraysky/distributed-expression-calculator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliazaraysky%2Fdistributed-expression-calculator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliazaraysky%2Fdistributed-expression-calculator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliazaraysky%2Fdistributed-expression-calculator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliazaraysky%2Fdistributed-expression-calculator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iliazaraysky","download_url":"https://codeload.github.com/iliazaraysky/distributed-expression-calculator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliazaraysky%2Fdistributed-expression-calculator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29959520,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T01:47:18.291Z","status":"online","status_checked_at":"2026-03-01T02:00:07.437Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","golang","react"],"created_at":"2026-03-01T03:43:42.773Z","updated_at":"2026-03-01T03:43:43.475Z","avatar_url":"https://github.com/iliazaraysky.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Распределенный вычислитель арифметических выражений\n\n## Оглавление\n\n1. [Описание проекта](#описание-проекта)\n\n2. [Установка и настройка](#установка-и-настройка)\n\n \t2.1. [Установка Docker](#установка-docker)\n\n\t2.2 [Клонирование репозитория](#клонирование-репозитория)\n \n \t2.3. [Запуск проекта](#запуск-проекта)\n\t\n \t2.4. [Возможные ошибки](#возможные-ошибки)\n\t\n \t2.5. [Два воркера не ошибка](#два-воркера-не-ошибка)\n\t\n \t2.6. [Выключение проекта](#выключение-проекта)\n\n3. [Пример использования](#пример-использования)\n\t\n \t3.1. [Запросы в curl](#запросы-в-curl)\n\n   \t3.2. [Работа в GUI](#работа-в-GUI)\n\n4. [Схема работы Worker](#схема-работы-worker)\n\n5. [Схема работы Backend](#схема-работы-backend)\n\n6. [Вторая часть. Инструкция](#вторая-часть-инструкция)\n\n7. [Схема работы Регистрации/Авторизации](#схема-работы-reg-auth)\n\n## 1. Описание проекта\n\u003ca name=\"описание-проекта\"\u003e\u003c/a\u003e\nПользователь хочет считать арифметические выражения. Он вводит строку 2 + 2 * 2 и хочет получить в ответ 6. Но наши операции сложения и умножения (также деления и вычитания) выполняются \"очень-очень\" долго. Поэтому вариант, при котором пользователь делает http-запрос и получает в качестве ответа результат, невозможна. Более того: вычисление каждой такой операции в нашей \"альтернативной реальности\" занимает \"гигантские\" вычислительные мощности. Соответственно, каждое действие мы должны уметь выполнять отдельно и масштабировать эту систему можем добавлением вычислительных мощностей в нашу систему в виде новых \"машин\". Поэтому пользователь, присылая выражение, получает в ответ идентификатор выражения и может с какой-то периодичностью уточнять у сервера \"не посчиталось ли выражение\"? Если выражение наконец будет вычислено - то он получит результат. Помните, что некоторые части арифметического выражения можно вычислять параллельно.\n\n### Используемые технологии\n1. Backend и Workers написаны на Golang\n2. Frontend написан на React + Bootstrap\n3. База данных для сохранения состояния Postgresql\n4. Брокер сообщений, для организации очереди RabbitMQ\n5. Считает арифметические выражения библиотека github.com/maja42/goval\n\n## 2. Установка и настройка\n\u003ca name=\"установка-и-настройка\"\u003e\u003c/a\u003e\n\nПроект ставится в несколько шагов:\n\n0. Устанавливаем Docker (если нет)\n1. Клонируем репозиторий\n2. Переходим в папку с программой в командной строке\n3. Запускаем Docker для создания образов и запуска контейнеров\n\n### 2.1. Установка Docker\n\u003ca name=\"установка-docker\"\u003e\u003c/a\u003e\nДля работы с сервисом необходимо установить на компьютер Docker\n\nВерсии для Mac, Windows, Linux доступны по следующему адресу:\nhttps://docs.docker.com/get-docker/\n\n1. Скачиваем установочный файл под вашу операционную систему\n2. Запускаем / Устанавливаем / Перезагружаем компьютер\n\n### 2.2. Клонирование репозитория\n\u003ca name=\"клонирование-репозитория\"\u003e\u003c/a\u003e\n\nКлонируем себе на компьютер репозиторий. Набираем в терминале:\n```bash\ngit clone https://github.com/iliazaraysky/distributed-expression-calculator.git\n```\n\nПереходим в папку с проектом на компьютере\n```bash\ncd distributed-expression-calculator\n```\n\n## 2.3. Запуск проекта\n\u003ca name=\"запуск-проекта\"\u003e\u003c/a\u003e\nДля создания образов и запуска контейнеров набираем:\n```bash\ndocker-compose up --build\n```\n\nПервый раз проект запускается долго. Нужно дождаться, чтобы скачались необходимые образы (я постарался прописать везде alpine образы с минимальным набором компонентов, но получилось все равно много). Если вы запускаете проект без флага `-d` , сигналом к началу проверки приложения, могут послужить сообщения в терминале, что воркеры ждут заданий из очереди:\n\n```\nworker1   | 2024/02/18 10:08:35 No messages in the queue, waiting\nworker2   | 2024/02/18 10:08:37 No messages in the queue, waiting\nworker1   | 2024/02/18 10:08:40 No messages in the queue, waiting\nworker2   | 2024/02/18 10:08:42 No messages in the queue, waiting\nworker1   | 2024/02/18 10:08:45 No messages in the queue, waiting\n```\n\n## 2.4. Возможные ошибки\n\u003ca name=\"возможные-ошибки\"\u003e\u003c/a\u003e\nЯ попробовал запускать проект на разных стендах, на 1 из 3 вылезла ошибка:\n```\nERROR: for postgres  Cannot create container for service postgres: Conflict.\nThe container name \"/postgres\" is already in use by container \"ac58e56714bbf18014776cfa3e47ae31d597db721cf00d0c0b36c0621dffd10a\".\nYou have to remove (or rename) that container to be able to reuse that name.\n```\n\nИз текста сообщения понятно, в системе уже есть контейнер с названием `postgres`. Я исправил это тем, что удалил контейнер с этим названием командой:\n```bash\ndocker rm postgres\n```\n\nТакже один раз вылезла ошибка сборки frontend, только у меня и только после того как я зачистил буквально весь Docker от всех Containers, Images, Volumes.\n\nЕсли встретите подобное, огромная просьба попробовать еще раз пересобрать проект.\n\nТестирование проводилось на следующих стендах:\n1. Десктоп Intel(R) Core(TM) i5 CPU 760 2.80GHz 16,0 ГБ RAM ОС Windows 10 x64 22H2 Сборка 19045.4046\n2. Десктоп Intel(R) Core(TM) i5 CPU 4440 3.10GHz 16,0 ГБ RAM ОС Windows 10 x64 22H2 Сборка 19045.4046\n3. Ноутбук Intel(R) Core(TM) i3 CPU 7100U 2.40GHz 8,0 ГБ RAM ОС Ubuntu x64 22.04.3 LTS\n\n## 2.5. Два воркера не ошибка\n\u003ca name=\"два-воркера-не-ошибка\"\u003e\u003c/a\u003e\nЗнаю, в проекте заявлено три воркера. В моей базе данных также предварительно записываются три воркера и в списке на таймауты можно выбрать третий.\n\nОднако я решил его не добавлять, так как код в первых двух максимально схож, а вот ресурсы расходуются знатно. Я очень хочу, чтобы проект запустился и каждый кто будет проверять, не испытывал с этим трудности.\n\nЗаодно можно увидеть статус \"Offline\" в таблице монитонга воркеров. Это не заглушка, frontend честно пытается его пинговать\n\n## 2.6. Выключение проекта\n\u003ca name=\"выключение-проекта\"\u003e\u003c/a\u003e\nНабрать из консоли, находясь в той же директории откуда запускался проект\n\n```bash\ndocker-compose down\n```\n\n## 3. Пример использования\n\u003ca name=\"пример-использования\"\u003e\u003c/a\u003e\nВ проекте реализован GUI. Удобнее всего посмотреть работу из него. Но первым пунктом описания сделаны примеры запросов, через `curl`. \nВо второй части проекты мы добавляли регистрацию и авторизацию. Поэтому в качестве примера, одна из ранее открытых областей, стала закрытой. Теперь нельзя получить доступ к \"Списку операций\" без токена в заголовке.\n\n### 3.1 Регистрация пользователя\n\u003ca name=\"регистрация-пользователя\"\u003e\u003c/a\u003e\n\nСтраница отвечает на GET-запрос, приветствием. Пример запроса:\n```bash\ncurl -X GET -H \"Content-Type: application/json\" http://127.0.0.1:8080/registration\n```\n\nОтправляем POST-запрос по адресу:\n```bash\nhttp://localhost:8080/registration\n```\nТело запроса в формате JSON, структура:\n```bash\n{\n  \"login\": \"user\",\n  \"password\": \"password123\"\n}\n```\n\nПример запроса:\n```bash\ncurl -X POST -H \"Content-Type: application/json\" -d \"{\\\"login\\\": \\\"user1\\\", \\\"password\\\":\\\"password123\\\"}\" http://127.0.0.1:8080/registration\n```\n\n### 3.2. Авторизация. Получение токена\n\u003ca name=\"регистрация-пользователя\"\u003e\u003c/a\u003e\n\nСтраница отвечает на GET-запрос, приветствием. Пример запроса:\n```bash\ncurl -X GET -H \"Content-Type: application/json\" http://127.0.0.1:8080/login\n```\n\nОтправляем POST-запрос по адресу:\n```bash\nhttp://localhost:8080/login\n```\n\nПример запроса:\n```bash\ncurl -X POST -H \"Content-Type: application/json\" -d \"{\\\"login\\\": \\\"user1\\\", \\\"password\\\":\\\"password123\\\"}\" http://127.0.0.1:8080/login\n```\n\nВ ответ сервер присылает Token. Пример токена:\n```bash\n{\"token\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTMyNzYwNzcsImlhdCI6MTcxMzI3NTQ3NywibG9naW4iOiJ1c2VyMSIsIm5iZiI6MTcxMzI3NTQ3N30.zseZouXKkOlNL7X7mmOrVIFtu-Ekp2nb0lZ7Wnw_SVE\"}\n```\n### 3.3. Запросы в curl. Добавление вычисления арифметического выражения.\n\u003ca name=\"запросы-в-curl\"\u003e\u003c/a\u003e\n\nОтправляем POST-запрос по адресу:\n```bash\nhttp://localhost:8080/add-expression\n```\n\nТело запроса в формате JSON, структура:\n```json\n{\"text\": \"2+2+2\"}\n```\n\nПример запроса:\n```bash\ncurl -X POST -H \"Content-Type: application/json\" -d \"{\\\"text\\\": \\\"3 + 1\\\"}\" http://127.0.0.1:8080/add-expression\n```\n\t\n### Получение списка выражений со статусами\n\nОтправляем GET-запрос по адресу:\n```bash\nhttp://localhost:8080/get-operations\n```\n\nОтвет получаемый от сервера в формате JSON, структура:\n```json\n{\n    \"data\": [\n        {\n            \"unique_id\": \"abb1f26f-2014-43f6-9f88-22fd6bf7aedc\",\n            \"query_text\": \"2 + 1 + 3 + 1\",\n            \"creation_time\": {\n                \"Time\": \"2024-02-11T21:17:24.764203Z\",\n                \"Valid\": true\n            },\n            \"completion_time\": {\n                \"Time\": \"2024-02-11T21:17:36.870463Z\",\n                \"Valid\": true\n            },\n            \"execution_time\": \"00:00:12.10626\",\n            \"server_name\": {\n                \"String\": \"worker3\",\n                \"Valid\": true\n            },\n            \"result\": {\n                \"String\": \"7\",\n                \"Valid\": true\n            },\n            \"status\": \"Done\"\n        }\n    ],\n    \"total_items\": 4,\n    \"total_pages\": 1,\n    \"current_page\": 1,\n    \"items_per_page\": 5\n}\n```\n\nОтвет содержит информацию о пагинации, которую мы высчитываем на стороне backend и возвращаем для frontend.\n\nДанные берутся из БД Postgresql - таблица requests \n\nТак как во второй части задания у нас появилась авторизация. Простой GET-запрос, будет возвращать `Unauthorized`\n\nПример запроса без авторизации:\n```bash\ncurl -X GET -H \"Content-Type: application/json\" http://127.0.0.1:8080/get-operations\n```\n\nПример запроса с авторизацией\n```bash\ncurl -H \"Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTMyNzY1MTEsImlhdCI6MTcxMzI3NTkxMSwibG9naW4iOiJ1c2VyMSIsIm5iZiI6MTcxMzI3NTkxMX0.GL1bbHRijfDo1BortkJMCMrxQwRxexHP8sHEX98bDaA\" http://localhost:8080/get-operations\n```\nТак как у этого запроса есть пагинация, следует указать как получать следующие страницы:\n```bash\nhttp://localhost:8080/get-operations?page=2\n```\n\n### Получение значения выражения по его идентификатору.\n\nИнформацию о каждой операции также можно получить по GET-запросу по адресу:\n```bash\nhttp://localhost:8080/get-request-by-id/{uuid}\n```\n\nОтвет получаемый от сервера в формате JSON, структура:\n```json\n{\n    \"unique_id\":\"abb1f26f-2014-43f6-9f88-22fd6bf7aedc\",\n    \"query_text\":\"2 + 1 + 3 + 1\",\n    \"server_name\":\"worker3\",\n    \"result\":\"7\",\n    \"status\":\"Done\"\n}\n```\n\nПример запроса:\n```bash\ncurl -X GET -H \"Content-Type: application/json\" http://localhost:8080/get-request-by-id/abb1f26f-2014-43f6-9f88-22fd6bf7aedc\n```\n\n### Получение списка доступных операций со временем их выполнения.\n\nУ нас в задании говорится о разделении времени выполнения на операции (это я понял, когда уже было поздно), поэтому тут только запрос на установление таймаута для каждого воркера. В принципе, функционал о том же самом, и можно сделать отдельную таблицу в БД, написать отдельный запрос, и все это будет работать по ТЗ. Но в виде самого наипростейшего решения, сойдет и мой вариант... Ведь он работает =)\n\nДанный эндпойнт умеет обрабатывать как GET так и POST запросы.\nЕсли мы хотим узнать настройки воркеров, делаем GET-запрос по адресу:\n```bash\nhttp://localhost:8080/setup-workers\n```\n\nОтвет получаемый от сервера в формате JSON, структура:\n```json\n[\n    {\n        \"worker_name\": \"worker2\",\n        \"last_task\": \"70d9df9f-84ec-426a-b408-31fe7fe8380f\",\n        \"status\": \"ready\",\n        \"last_timeout_setup\": \"2024-02-17T21:10:21.870463Z\",\n        \"current_timeout\": 11\n    },\n    {\n        \"worker_name\": \"worker3\",\n        \"last_task\": \"abb1f26f-2014-43f6-9f88-22fd6bf7aedc\",\n        \"status\": \"ready\",\n        \"last_timeout_setup\": \"2024-02-17T21:11:37.870463Z\",\n        \"current_timeout\": 12\n    },\n    {\n        \"worker_name\": \"worker1\",\n        \"last_task\": \"f3715129-63f5-44a6-ac42-adbfb186ba60\",\n        \"status\": \"ready\",\n        \"last_timeout_setup\": \"2024-02-17T21:16:31.870463Z\",\n        \"current_timeout\": 10\n    }\n]\n```\n\nПример GET - запроса\n```bash\ncurl -X GET -H \"Content-Type: application/json\" http://localhost:8080/setup-workers\n```\n\nЕсли мы хотим поменять настройку у воркера, делаем POST-запрос по адресу:\n```bash\nhttp://localhost:8080/setup-workers\n```\n\nТело запроса в формате JSON, структура:\n```json\n{\n \"worker_name\":\"worker1\",\n \"timeout_data\":10\n}\n```\n\nПример POST - запроса\n```bash\ncurl -X POST -H \"Content-Type: application/json\" -d \"{\\\"worker_name\\\": \\\"worker1\\\", \\\"timeout_data\\\": 19}\" http://localhost:8080/setup-workers\n```\n\n## 3.2. Работа в GUI\n\u003ca name=\"работа-в-GUI\"\u003e\u003c/a\u003e\nПосле запуска проекта он доступен по адресу:\n```bash\nhttp://localhost:3000/\n```\n\n### Главная страница\nНа главной странице находится строка отправки выражения в которую мы вбиваем данные для вычисления и нажимаем кнопку \"Отправить\". Сигналом о том, что выражение отправлено, является всплывающее окно.\n\nТакже на главной странице располагается таблица состояния воркеров. Принцип действия этой таблицы заключается в следующем. Frontend делает регулярные запросы на главные страницы воркеров, если страница доступна, в таблице отображается \"Online\" и время последнего запроса. Иначе отображается Offline. \n\nСсылки на работу воркеров, активные, ведут на их главные страницы\n\n### Список выражений\nНа этой вкладке отображаются все выражения, которые были посчитаны воркерами в упрощенном виде. Здесь мы можем получить уникальный идентификатор и запрос с результатом\n\n\n### Список операций\nНа этой вкладке показаны расширенные таблицы всех операций: \n```\nUUID запроса, Запрос, Время создания, Время завершения, Время выполнения, Сервер, Результат, Статус\n```\n\nТут же реализована пагинация, и возможность перейти на конкретную операцию (по uuid)\n\n### Вычислительные мощности\nСостоит трех блоков. Смена таймаута на воркерах, статус воркеров и получение сведений о текущем состоянии воркеров. \n\nПоменять таймаут очень просто, выбираем в выпадающем списке нужного нам воркера, вводим ниже число, нажимаем кнопку \"Отправить\".\n\nТекущие настройки воркеров, это постоянный GET запрос на backend, `curl -X GET -H \"Content-Type: application/json\" http://localhost:8080/setup-workers`, увидеть изменения в настройках воркеров можно довольно быстро. Не уверен, что так делают в реальных проектах, делал исключительно для демонстрации возможностей\n\n\n## 4. Схема работы Worker\n\u003ca name=\"схема-работы-worker\"\u003e\u003c/a\u003e\n![Схема Worker](https://github.com/iliazaraysky/distributed-expression-calculator/blob/main/%D0%A1%D1%85%D0%B5%D0%BC%D0%B0%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B%20Workers.png)\n\n## 5. Схема работы Backend\n\u003ca name=\"схема-работы-backend\"\u003e\u003c/a\u003e\n![Схема Backend](https://github.com/iliazaraysky/distributed-expression-calculator/blob/main/%D0%A1%D1%85%D0%B5%D0%BC%D0%B0%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B%20backend.png)\n\n\u003ca name=\"вторая-часть-инструкция\"\u003e\u003c/a\u003e\n## 6. Вторая часть. Изминения. Инструкция\nМаленькое пояснение для проверяющих. Я не реализовал gRPC. Не успел. Конечно я могу доделать сейчас, но это нарушает правила. Не успел. Не страшно. Остальное на месте. =)\n\nДля начала стоит указать полный список изменений внесенных во второй части проекта:\n\n### На стороне Backend\n1. Добавлен эндпойнт `/registration`\n2. Добавлен эндпойнт `/login`\n3. Добавлен эндпойнт `/get-operation-by-user-id`. Нужен для того, чтобы сортировать данные по конкретному пользователю\n4. Добавлен **Middleware** `authMiddleware`, который проверяет наличие токена в заголовке `Authorization`\n5. Изменен **Middleware** `corsHandler`, так как теперь у нас есть дополнительный заголовок `Authorization`\n6. База данных, таблица `requests`, добавлен столбец `username`, в котором теперь записывается пользователь отправивший задание\n7. База данных, добавлена таблица `users`, в которой хранятся `login` и `password`, необходимые для получения токена\n8. Изменена `database_schema` для docker, с учетом появившейся таблицы `users`, и дополнительной колонки `username` в `requests`\n9. Изменена схема работы **RabbitMQ**, так как теперь в очередь попадают не только сведения об операции, но и о пользователе, который инициировал операцию\n\n### На стороне Frontend\n1. Изменено меню. Добавлены кнопка `Регистрация`\n2. Изменено меню. Добавлены кнопка `Логин`\n3. Изменено меню. Когда пользователь авторизирован `Регистрация`, меняется на его `Логин`, который в свою очередь ведет на все операции пользователя\n4. Создан компонент в **React**, отвечающий за страницу операций пользователя `UserRequestDetails` \n5. Создан компонент в **React**, отвечающий за регистрацию пользователя `Register`\n6. Создан компонент в **React**, отвечающий за авторизацию пользователя `Login`\n7. Страница `Список операций`, теперь доступна только авторизированным пользователям\n8. Отправлять задания с Frontend могут только авторизированные пользователи\n9. В `App.js` ведется проверка токена, контролируется время когда он истекает\n10. При инициализации `App.js` из токена сохраняется `username` и передается на главную страницу, для последующего добавление при инициализации операции \n\n### Тесты\nФайл с тестами лежит в директории `Backend`. Запускать лучше всего после запуска сервиса.\nПолное описание тестов лежит в отдельном файле. [TESTS_DESCRIPTION.md](TESTS_DESCRIPTION.md)\n\n### Инструкция v2.0\n1. Скачиваем репозиторий \n\t```bash\n\tgit clone https://github.com/iliazaraysky/distributed-expression-calculator.git\n\t```\n2. Переходим в скаченную директорию `distributed-expression-calculator`\n\n3. Запускаем проект\n\t```bash\n\tdocker-compose up -d --build\n\t```\n4. После запуска проект доступен по адресу:\n\t```bash\n\thttp://localhost:3000 \n\t```\n5. Перейдя на главную страницу видим информацию о том, что отправка выражений доступна только после авторизации, также нет доступа к списку операций. Тут следует пояснить:\n   5.1. На главной странице блок отправки выражений не показывается пока нет токена, это прописано на Frontend\n   5.2. На странице `Список операций`, блокировка идет на уровне Backend, средствами **Middleware** `authMiddleware`\n6. Обратим внимание на правый верхний угол **Регистрация** -\u003e Вводим `Логин` и `Пароль` -\u003e Создать. Так вы создадите пользователя, от имени которого можно будет совершать операции\n   6.1. **Примечание**. Когда заполнены поля и нажата кнопка `Создать`, **React** делает редирект на страницу авторизации, но почему-то не всегда =). Frontend - это сложно, я с ним намучался\n7. Переходим на страницу `Вход в кабинет` -\u003e вводим регистрационные данные -\u003e Вход\n8. После авторизации, в правом верхнем углу будет оторажаться `Login` и `Выход`.\n   8.1. `Выход` удаляет токен из локального хранилища, и обновляет страницу\n   8.2. `Login` является ссылкой к списку операций пользователя\n9. На странице `Список операций`, теперь доступны к просмотру сделанные ранее операции\n10. На `Главной` странице теперь доступно поле ввода выражений\n11. Вводим -\u003e Отправляем -\u003e нажимаем на `Логин` -\u003e Видим появившуюся операцию\n12. Нажимаем выход -\u003e идем на главную страницу -\u003e строка отправки недоступна -\u003e идем в `Список операций` -\u003e снова недоступно\n13. Набираем в терминале\n\t```bash\n\tdocker-compose down \n\t```\n14. Снова заходим под своей учетной записью, пользователь на месте, данные сохранены\n15. Можно завершить работу `docker-compose` с флагом `-v`, тогда данные не сохранятся, а новый запуск будет с \"чистым\" сервисом\n\n\u003ca name=\"схема-работы-reg-auth\"\u003e\u003c/a\u003e\n## 7. Схема работы Регистрации/Авторизации\n\n![Схема Регистрации-Авторизации](https://github.com/iliazaraysky/distributed-expression-calculator/blob/main/%D0%A1%D1%85%D0%B5%D0%BC%D0%B0%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B%20%D0%A0%D0%B5%D0%B3%D0%B8%D1%81%D1%82%D1%80%D0%B0%D1%86%D0%B8%D0%B8-%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8.png?raw=true)\n\n### На этом все! Спасибо, что потратили свое время на проверку!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filiazaraysky%2Fdistributed-expression-calculator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filiazaraysky%2Fdistributed-expression-calculator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filiazaraysky%2Fdistributed-expression-calculator/lists"}