{"id":31985704,"url":"https://github.com/architectv/estate-task","last_synced_at":"2026-05-03T01:40:48.298Z","repository":{"id":55128915,"uuid":"326788814","full_name":"architectv/estate-task","owner":"architectv","description":"🏨 Тестовое задание Avito.Недвижимость | Сервис для управления номерами отеля и бронированиями","archived":false,"fork":false,"pushed_at":"2021-01-09T11:13:32.000Z","size":149,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-25T01:41:40.923Z","etag":null,"topics":["clean-architecture","docker","docker-compose","fiber","go","golang","makefile","mock-test","postgresql","rest-api","sql","sqlx","testify","travis-ci","unit-testing"],"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/architectv.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}},"created_at":"2021-01-04T19:35:19.000Z","updated_at":"2024-05-14T18:05:54.000Z","dependencies_parsed_at":"2022-08-14T12:50:48.091Z","dependency_job_id":null,"html_url":"https://github.com/architectv/estate-task","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/architectv/estate-task","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/architectv%2Festate-task","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/architectv%2Festate-task/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/architectv%2Festate-task/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/architectv%2Festate-task/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/architectv","download_url":"https://codeload.github.com/architectv/estate-task/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/architectv%2Festate-task/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32555839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T00:31:16.350Z","status":"ssl_error","status_checked_at":"2026-05-03T00:31:15.546Z","response_time":132,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["clean-architecture","docker","docker-compose","fiber","go","golang","makefile","mock-test","postgresql","rest-api","sql","sqlx","testify","travis-ci","unit-testing"],"created_at":"2025-10-15T06:33:21.612Z","updated_at":"2026-05-03T01:40:48.292Z","avatar_url":"https://github.com/architectv.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# :hotel: Тестовое задание Avito.Недвижимость\n\n[![Build Status](https://travis-ci.com/architectv/estate-task.svg?branch=main)](https://travis-ci.com/architectv/estate-task)\n[![Go Report Card](https://goreportcard.com/badge/github.com/architectv/estate-task)](https://goreportcard.com/report/github.com/architectv/estate-task)\n[![CodeFactor](https://www.codefactor.io/repository/github/architectv/estate-task/badge)](https://www.codefactor.io/repository/github/architectv/estate-task)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/architectv/estate-task/badges/quality-score.png?b=main)](https://scrutinizer-ci.com/g/architectv/estate-task/?branch=main)\n[![Code Coverage](https://scrutinizer-ci.com/g/architectv/estate-task/badges/coverage.png?b=main)](https://scrutinizer-ci.com/g/architectv/estate-task/?branch=main)\n![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/architectv/estate-task)\n![Lines of code](https://img.shields.io/tokei/lines/github/architectv/estate-task)\n![Github Repository Size](https://img.shields.io/github/repo-size/architectv/estate-task)\n![License](https://img.shields.io/badge/license-MIT-green)\n![GitHub last commit](https://img.shields.io/github/last-commit/architectv/estate-task)\n\nСервис для управления номерами отеля и бронированиями.\n\n\u003c!-- ToC start --\u003e\n# Содержание\n\n1. [Запуск](#Запуск)\n1. [Юнит-тесты](#Юнит-тесты)\n1. [API](#API)\n1. [Реализация](#Реализация)\n\u003c!-- ToC end --\u003e\n\n# Запуск\n\n```\nmake build\nmake run\n```\n\nЕсли приложение запускается впервые, необходимо применить миграции к базе данных:\n\n```\nmake migrate_up\n```\n\nДля миграций используется [golang-migrate/migrate CLI](https://github.com/golang-migrate/migrate/tree/master/cmd/migrate#installation).\n\n# Юнит-тесты\n\n```\nmake run_test\n```\n\n# API\n\n\u003e 1) Тело запроса/ответа - в формате JSON.\n\u003e 2) В случае ошибки возвращается необходимый HTTP код, в теле содержится описание ошибки (пример: ```{\"error\": \"something went wrong\"}```).\n\n## POST /rooms/\n\nДобавление номера отеля.\n\n- Параметры тела запроса:\n    - description - текстовое описание,\n    - price - цена за ночь.\n- Тело ответа:\n    - room_id - идентификатор номера отеля.\n\n**Пример**\n\nЗапрос:\n\n```\ncurl -X POST localhost:9000/rooms/ \\\n-H \"Content-Type: application/json\" \\\n-d '{\n\t\"description\": \"The Best Room\",\n\t\"price\": 9000\n}'\n```\n\nОтвет:\n\n```\n{\n    \"room_id\": 144\n}\n```\n\n## DELETE /rooms/:id\n\nУдаление номера отеля.\n\n- Параметры пути запроса:\n    - id - идентификатор номера отеля.\n\n**Пример**\n\nЗапрос:\n\n```\ncurl -X DELETE localhost:9000/rooms/144\n```\n\n## GET /rooms/\n\nПолучение списка номеров отеля.\n\n- Параметры строки запроса:\n    - sort - поле, по которому производится сортировка:\n        - id - по идентификатору (по дате добавления),\n        - price - по цене.\n- Тело ответа:\n    - список номеров отеля.\n\n\u003e 1) Для сортировки по убыванию необходимо добавить знак минус перед значением поля (-id или -price).\n\u003e 2) По умолчанию (если параметр sort пуст или отсутствует) сортировка осуществляется по id по возрастанию.\n\n**Пример**\n\nЗапрос:\n\n```\ncurl -X GET localhost:9000/rooms/?sort=-price\n```\n\nОтвет:\n\n```\n[\n    {\n        \"room_id\": 2,\n        \"description\": \"description2\",\n        \"price\": 5000\n    },\n    {\n        \"room_id\": 3,\n        \"description\": \"description3\",\n        \"price\": 3000\n    },\n    {\n        \"room_id\": 1,\n        \"description\": \"description1\",\n        \"price\": 1000\n    },\n]\n```\n\n## POST /bookings/\n\nДобавление бронирования номера отеля.\n\n- Параметры тела запроса:\n    - room_id - идентификатор номера отеля,\n    - date_start - дата начала бронирования,\n    - date_end - дата окончания бронирования.\n- Тело ответа:\n    - booking_id - идентификатор бронирования.\n\n\u003e Ограничения (из условия): нет проверки на доступность номера отеля в выбранное время.\n\n**Пример**\n\nЗапрос:\n\n```\ncurl -X POST localhost:9000/bookings/ \\\n-H \"Content-Type: application/json\" \\\n-d '{\n\t\"room_id\": 144,\n\t\"date_start\": \"2021-12-30\",\n\t\"date_end\": \"2022-01-02\"\n}'\n```\n\nОтвет:\n\n```\n{\n    \"booking_id\": 121\n}\n```\n\n## DELETE /bookings/:id\n\nУдаление бронирования номера отеля.\n\n- Параметры запроса:\n    - id - идентификатор бронирования.\n\n**Пример**\n\nЗапрос:\n\n```\ncurl -X DELETE localhost:9000/bookings/121\n```\n \n## GET /bookings/\n\nПолучение списка бронирований номера отеля.\n\n- Параметры строки запроса:\n    - room_id - идентификатор номера отеля.\n- Тело ответа:\n    - список бронирований.\n\n\u003e Список сортируется по дате начала (date_start).\n\n**Пример**\n\nЗапрос:\n\n```\ncurl -X GET localhost:9000/bookings/?room_id=144\n```\n\nОтвет:\n\n```\n[\n    {\n        \"booking_id\": 289,\n        \"date_start\": \"2021-01-04\",\n\t\"date_end\": \"2021-01-08\"\n    },\n    {\n        \"booking_id\": 121,\n        \"date_start\": \"2021-12-30\",\n\t\"date_end\": \"2022-01-02\"\n    },\n    {\n        \"booking_id\": 256,\n        \"date_start\": \"2022-03-01\",\n\t\"date_end\": \"2022-03-12\"\n    },\n]\n```\n\n# Реализация\n\n- Следование дизайну REST JSON API.\n- Подход \"Чистой Архитектуры\" и техника внедрения зависимости.\n- Работа с фреймворком [fiber](https://github.com/gofiber/fiber).\n- Работа с БД Postgres с использованием библиотеки [sqlx](https://github.com/jmoiron/sqlx) и написанием SQL запросов.\n- Конфигурация приложения - библиотека [viper](https://github.com/spf13/viper).\n- Реализация Graceful Shutdown.\n- Запуск из Docker.\n- Юнит-тестирование с помощью моков - библиотеки [testify](https://github.com/stretchr/testify), [mock](https://github.com/golang/mock).\n- Непрерывная интеграция, запуск тестов в Travis CI, анализ и покрытие в Scrutinizer CI.\n\n**Структура проекта**\n```\n.\n├── pkg\n│   ├── model       // основные структуры\n│   ├── handler     // обработчики запросов\n│   ├── service     // бизнес-логика\n│   └── repository  // взаимодействие с БД\n├── cmd             // точка входа в приложение\n├── scripts         // SQL файлы с миграциями\n└── configs         // файлы конфигурации\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchitectv%2Festate-task","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farchitectv%2Festate-task","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchitectv%2Festate-task/lists"}