From 5cf8dd1bb12daaeb1847ffbe445901cf02d89d78 Mon Sep 17 00:00:00 2001 From: Dmitriy Bondarenko Date: Thu, 27 Mar 2025 22:08:46 +0000 Subject: [PATCH] endpoint /routes/{route_id}/transport --- README.md | 9 +++++---- cmd/api/main.go | 7 +------ internal/handlers/errorresponse.go | 23 +++++++++++++++++++++++ internal/handlers/handlers.go | 30 ++++++++++++++++++++++++++++-- internal/repository/postgres.go | 23 +++++++++++++++++++++++ internal/usecase/usecase.go | 4 ++++ 6 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 internal/handlers/errorresponse.go diff --git a/README.md b/README.md index 5fbe3a9..0401961 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,13 @@ # В ПРОЦЕССЕ РАЗРАБОТКИ +# Задание [Задание](Task15.md) +## Рабочие Endpoints: -# Схема БД +- `/routes` - Получить список маршрутов; +- `/routes/{route_id}/transport` - Список транспорта, занятого на данном маршруте; +## Схема БД ![Схема БД](docs/Diagram.png) -# Рабочие Endpoints: - -- `/routes` - Получить список маршрутов \ No newline at end of file diff --git a/cmd/api/main.go b/cmd/api/main.go index 7459073..9d2a33d 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -15,11 +15,6 @@ import ( ) func main() { - // Загружаем переменные из .env - // err := godotenv.Load() - // if err != nil { - // log.Fatal("Ошибка загрузки .env файла") - // } // Читаем переменные dbHost := os.Getenv("DB_HOST") @@ -43,7 +38,7 @@ func main() { err = db.Ping() if err != nil { - log.Fatal("БД не отвечает:", err, dsn) + log.Fatal("БД не отвечает:", err) } log.Println("Подключение к PostgreSQL успешно!") diff --git a/internal/handlers/errorresponse.go b/internal/handlers/errorresponse.go new file mode 100644 index 0000000..36e8e9f --- /dev/null +++ b/internal/handlers/errorresponse.go @@ -0,0 +1,23 @@ +package handlers + +import ( + "encoding/json" + "net/http" +) + +type ErrorResponse struct { + Code int `json:"code"` + Message string `json:"message"` + Error string `json:"error"` +} + +func sendErrorResponse(w http.ResponseWriter, code int, message string, err string) { + response := ErrorResponse{ + Code: code, + Message: message, + Error: err, + } + + w.WriteHeader(response.Code) + json.NewEncoder(w).Encode(response) +} diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 2d536ae..40b2b62 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -3,6 +3,7 @@ package handlers import ( "encoding/json" "net/http" + "strconv" "truck-company/internal/usecase" "github.com/gorilla/mux" @@ -21,7 +22,7 @@ func NewTruckCompanyHandler(u *usecase.UseCase) *TruckCompanyHandler { func (h *TruckCompanyHandler) RegisterRoutes(r *mux.Router) { r.HandleFunc("/routes", h.GetRoutes).Methods("GET") - // r.HandleFunc("/routes/{route_id}/transport", h.GetTransportByRoute).Methods("GET") + r.HandleFunc("/routes/{route_id}/transport", h.GetTransportByRoute).Methods("GET") // r.HandleFunc("/routes/{route_id}/transport-types", h.GetTransportTypesByRoute).Methods("GET") // r.HandleFunc("/shipments/cost", h.GetShipmentCost).Methods("GET") // r.HandleFunc("/routes/{route_id}/cargo-turnover", h.GetCargoTurnoverByRoute).Methods("GET") @@ -31,10 +32,35 @@ func (h *TruckCompanyHandler) RegisterRoutes(r *mux.Router) { } func (h *TruckCompanyHandler) GetRoutes(w http.ResponseWriter, r *http.Request) { + routes, err := h.uc.GetAllRoutes() if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + sendErrorResponse(w, http.StatusInternalServerError, "", err.Error()) return } + w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(routes) } + +func (h *TruckCompanyHandler) GetTransportByRoute(w http.ResponseWriter, r *http.Request) { + + vars := mux.Vars(r) + routeID, err := strconv.ParseInt(vars["route_id"], 10, 64) + + if err != nil { + sendErrorResponse(w, http.StatusBadRequest, "Invalid route ID", err.Error()) + + return + } + + transport, err := h.uc.GetTransportByRoute(routeID) + if err != nil { + + sendErrorResponse(w, http.StatusInternalServerError, "", err.Error()) + + return + } + + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(transport) +} diff --git a/internal/repository/postgres.go b/internal/repository/postgres.go index debc7b3..aeb5d5f 100644 --- a/internal/repository/postgres.go +++ b/internal/repository/postgres.go @@ -37,3 +37,26 @@ func (r *AppRepo) GetAllRoutes() ([]domain.Route, error) { } return routes, nil } + +func (t *AppRepo) GetTransportByRoute(routeID int64) ([]domain.Transport, error) { + rows, err := t.db.Query(` + SELECT t.id, t.model, t.capacity, tt.name + FROM transport t + JOIN shipment s ON t.id = s.transport_id + JOIN transport_type tt ON t.type_id = tt.id + WHERE s.route_id = $1`, routeID) + if err != nil { + return nil, err + } + defer rows.Close() + + var transports []domain.Transport + for rows.Next() { + var transport domain.Transport + if err := rows.Scan(&transport.ID, &transport.Model, &transport.Capacity, &transport.Type); err != nil { + return nil, err + } + transports = append(transports, transport) + } + return transports, nil +} diff --git a/internal/usecase/usecase.go b/internal/usecase/usecase.go index 28bff64..1b0e034 100644 --- a/internal/usecase/usecase.go +++ b/internal/usecase/usecase.go @@ -18,3 +18,7 @@ func NewUseCase(r repository.AppRepo) *UseCase { func (u *UseCase) GetAllRoutes() ([]domain.Route, error) { return u.AppRepo.GetAllRoutes() } + +func (u *UseCase) GetTransportByRoute(routeID int64) ([]domain.Transport, error) { + return u.AppRepo.GetTransportByRoute(routeID) +}