first commit

This commit is contained in:
2023-10-20 13:41:39 +02:00
commit 6696cd3152
65 changed files with 11374 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@@ -0,0 +1,40 @@
.openapi-generator-ignore
Dockerfile
README.md
api/openapi.yaml
go.mod
go/api.go
go/api_bookings_filter.go
go/api_bookings_filter_service.go
go/api_driver_availability_and_schedule.go
go/api_driver_availability_and_schedule_service.go
go/api_interact.go
go/api_interact_service.go
go/api_passenger_trip_request.go
go/api_passenger_trip_request_service.go
go/api_search.go
go/api_search_service.go
go/error.go
go/helpers.go
go/impl.go
go/logger.go
go/model__passenger_post_400_response.go
go/model_booking.go
go/model_booking_request.go
go/model_booking_status.go
go/model_car.go
go/model_driver_journey.go
go/model_driver_punctual_availabilities_request.go
go/model_driver_regular_availabilities_request.go
go/model_driver_trip.go
go/model_get_bookings_404_response.go
go/model_journey_schedule.go
go/model_passenger_trip_request.go
go/model_post_connections_request.go
go/model_preferences.go
go/model_price.go
go/model_punctual_availability_slot.go
go/model_regular_availability_slot.go
go/model_user.go
go/routers.go
main.go

View File

@@ -0,0 +1 @@
7.0.1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"context"
"net/http"
)
// BookingsFilterAPIRouter defines the required methods for binding the api requests to a responses for the BookingsFilterAPI
// The BookingsFilterAPIRouter implementation should parse necessary information from the http request,
// pass the data to a BookingsFilterAPIServicer to perform the required actions, then write the service results to the http response.
type BookingsFilterAPIRouter interface {
FilterBookingsByStatus(http.ResponseWriter, *http.Request)
}
// DriverAvailabilityAndScheduleAPIRouter defines the required methods for binding the api requests to a responses for the DriverAvailabilityAndScheduleAPI
// The DriverAvailabilityAndScheduleAPIRouter implementation should parse necessary information from the http request,
// pass the data to a DriverAvailabilityAndScheduleAPIServicer to perform the required actions, then write the service results to the http response.
type DriverAvailabilityAndScheduleAPIRouter interface {
DriverPunctualAvailabilitiesPost(http.ResponseWriter, *http.Request)
DriverRegularAvailabilitiesPost(http.ResponseWriter, *http.Request)
}
// InteractAPIRouter defines the required methods for binding the api requests to a responses for the InteractAPI
// The InteractAPIRouter implementation should parse necessary information from the http request,
// pass the data to a InteractAPIServicer to perform the required actions, then write the service results to the http response.
type InteractAPIRouter interface {
GetBookings(http.ResponseWriter, *http.Request)
PatchBookings(http.ResponseWriter, *http.Request)
PostBookings(http.ResponseWriter, *http.Request)
PostConnections(http.ResponseWriter, *http.Request)
}
// PassengerTripRequestAPIRouter defines the required methods for binding the api requests to a responses for the PassengerTripRequestAPI
// The PassengerTripRequestAPIRouter implementation should parse necessary information from the http request,
// pass the data to a PassengerTripRequestAPIServicer to perform the required actions, then write the service results to the http response.
type PassengerTripRequestAPIRouter interface {
PassengerPost(http.ResponseWriter, *http.Request)
}
// SearchAPIRouter defines the required methods for binding the api requests to a responses for the SearchAPI
// The SearchAPIRouter implementation should parse necessary information from the http request,
// pass the data to a SearchAPIServicer to perform the required actions, then write the service results to the http response.
type SearchAPIRouter interface {
GetDriverJourneys(http.ResponseWriter, *http.Request)
}
// BookingsFilterAPIServicer defines the api actions for the BookingsFilterAPI service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can be ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type BookingsFilterAPIServicer interface {
FilterBookingsByStatus(context.Context, string, string, string, string) (ImplResponse, error)
}
// DriverAvailabilityAndScheduleAPIServicer defines the api actions for the DriverAvailabilityAndScheduleAPI service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can be ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type DriverAvailabilityAndScheduleAPIServicer interface {
DriverPunctualAvailabilitiesPost(context.Context, DriverPunctualAvailabilitiesRequest) (ImplResponse, error)
DriverRegularAvailabilitiesPost(context.Context, DriverRegularAvailabilitiesRequest) (ImplResponse, error)
}
// InteractAPIServicer defines the api actions for the InteractAPI service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can be ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type InteractAPIServicer interface {
GetBookings(context.Context, string, string) (ImplResponse, error)
PatchBookings(context.Context, string, string, BookingStatus, string) (ImplResponse, error)
PostBookings(context.Context, BookingRequest) (ImplResponse, error)
PostConnections(context.Context, PostConnectionsRequest) (ImplResponse, error)
}
// PassengerTripRequestAPIServicer defines the api actions for the PassengerTripRequestAPI service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can be ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type PassengerTripRequestAPIServicer interface {
PassengerPost(context.Context, PassengerTripRequest) (ImplResponse, error)
}
// SearchAPIServicer defines the api actions for the SearchAPI service
// This interface intended to stay up to date with the openapi yaml used to generate it,
// while the service implementation can be ignored with the .openapi-generator-ignore file
// and updated with the logic required for the API.
type SearchAPIServicer interface {
GetDriverJourneys(context.Context, float32, float32, int32, string) (ImplResponse, error)
}

View File

@@ -0,0 +1,82 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"net/http"
"strings"
)
// BookingsFilterAPIController binds http requests to an api service and writes the service results to the http response
type BookingsFilterAPIController struct {
service BookingsFilterAPIServicer
errorHandler ErrorHandler
}
// BookingsFilterAPIOption for how the controller is set up.
type BookingsFilterAPIOption func(*BookingsFilterAPIController)
// WithBookingsFilterAPIErrorHandler inject ErrorHandler into controller
func WithBookingsFilterAPIErrorHandler(h ErrorHandler) BookingsFilterAPIOption {
return func(c *BookingsFilterAPIController) {
c.errorHandler = h
}
}
// NewBookingsFilterAPIController creates a default api controller
func NewBookingsFilterAPIController(s BookingsFilterAPIServicer, opts ...BookingsFilterAPIOption) Router {
controller := &BookingsFilterAPIController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all the api routes for the BookingsFilterAPIController
func (c *BookingsFilterAPIController) Routes() Routes {
return Routes{
"FilterBookingsByStatus": Route{
strings.ToUpper("Get"),
"/bookings",
c.FilterBookingsByStatus,
},
}
}
// FilterBookingsByStatus - Filter and retrieve bookings by status, type, and ID.
func (c *BookingsFilterAPIController) FilterBookingsByStatus(w http.ResponseWriter, r *http.Request) {
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
if !authenticated {
response := ImplResponse{
Code: 401,
Body: "Unauthorized request. Check your operator / API Key.",
}
EncodeJSONResponse(response.Body, &response.Code, w)
return
}
query := r.URL.Query()
operatorParam := query.Get("operator")
statusParam := query.Get("status")
filterTypeParam := query.Get("filterType")
idParam := query.Get("Id")
result, err := c.service.FilterBookingsByStatus(r.Context(), operatorParam, statusParam, filterTypeParam, idParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}

View File

@@ -0,0 +1,111 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"context"
"fmt"
"github.com/spf13/viper"
"net/http"
"solidarity-service/handler"
"solidarity-service/internal"
"solidarity-service/storage"
"strings"
)
// BookingsFilterAPIService is a service that implements the logic for the BookingsFilterAPIServicer
// This service should implement the business logic for every endpoint for the BookingsFilterAPI API.
// Include any external packages or services that will be required by this service.
type BookingsFilterAPIService struct {
config *viper.Viper
handler *handler.SolidarityServiceHandler
storage storage.Storage
}
// NewBookingsFilterAPIService creates a default api service
func NewBookingsFilterAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) BookingsFilterAPIServicer {
return &BookingsFilterAPIService{
config: config,
handler: handler,
storage: storage,
}
}
// FilterBookingsByStatus - Filter and retrieve bookings by status, type, and ID.
func (s *BookingsFilterAPIService) FilterBookingsByStatus(ctx context.Context, operator string, status string, filterType string, id string) (ImplResponse, error) {
bookings, err := s.storage.FilterUserBookingsByStatus(filterType, internal.BookingStatus(status), id)
if err != nil {
fmt.Println(err)
if strings.Contains(err.Error(), " no rows in result set") {
return Response(http.StatusBadRequest, "ID not found in the database"), nil
} else {
return Response(http.StatusInternalServerError, nil), nil
}
}
responses := []Booking{}
for _, v := range bookings {
passenger, err := s.storage.GetPassenger(v.Passenger.ID)
if err != nil {
return Response(http.StatusInternalServerError, nil), nil
}
driver, err := s.storage.GetDriver(v.Driver.ID)
if err != nil {
return Response(http.StatusInternalServerError, nil), nil
}
duration, err := s.handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
if err != nil {
duration = 0
}
responses = append(responses, Booking{
Id: v.ID,
Status: BookingStatus(v.Status),
Driver: User{
Id: v.Driver.ID,
Operator: driver.Driver.Operator,
Alias: driver.Driver.Alias,
FirstName: driver.Driver.FirstName,
LastName: driver.Driver.LastName,
Grade: int32(driver.Driver.Grade),
Picture: driver.Driver.Picture,
Gender: driver.Driver.Gender,
VerifiedIdentity: driver.Driver.VerifiedIdentity,
},
Passenger: User{
Id: v.Passenger.ID,
Operator: passenger.Passenger.Operator,
Alias: passenger.Passenger.Alias,
FirstName: passenger.Passenger.FirstName,
LastName: passenger.Passenger.LastName,
Grade: int32(passenger.Passenger.Grade),
Picture: passenger.Passenger.Picture,
Gender: passenger.Passenger.Gender,
VerifiedIdentity: passenger.Passenger.VerifiedIdentity,
},
PassengerPickupDate: int32(passenger.Passenger_pickup_date),
PassengerPickupLat: passenger.Passenger_departure_address.Point().X(),
PassengerPickupLng: passenger.Passenger_departure_address.Point().Y(),
PassengerPickupAddress: passenger.Passenger_departure_address.Properties.MustString("name"),
PassengerDropLat: passenger.Passenger_destination_address.Point().X(),
PassengerDropLng: passenger.Passenger_destination_address.Point().Y(),
PassengerDropAddress: passenger.Passenger_destination_address.Properties.MustString("name"),
Duration: int32(duration),
Distance: int32(s.handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)),
Car: Car{
Model: driver.Car.Model,
Brand: driver.Car.Brand,
},
Price: Price{
Type: "FREE",
},
})
}
return Response(200, responses), nil
}

View File

@@ -0,0 +1,134 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"encoding/json"
"net/http"
"strings"
)
// DriverAvailabilityAndScheduleAPIController binds http requests to an api service and writes the service results to the http response
type DriverAvailabilityAndScheduleAPIController struct {
service DriverAvailabilityAndScheduleAPIServicer
errorHandler ErrorHandler
}
// DriverAvailabilityAndScheduleAPIOption for how the controller is set up.
type DriverAvailabilityAndScheduleAPIOption func(*DriverAvailabilityAndScheduleAPIController)
// WithDriverAvailabilityAndScheduleAPIErrorHandler inject ErrorHandler into controller
func WithDriverAvailabilityAndScheduleAPIErrorHandler(h ErrorHandler) DriverAvailabilityAndScheduleAPIOption {
return func(c *DriverAvailabilityAndScheduleAPIController) {
c.errorHandler = h
}
}
// NewDriverAvailabilityAndScheduleAPIController creates a default api controller
func NewDriverAvailabilityAndScheduleAPIController(s DriverAvailabilityAndScheduleAPIServicer, opts ...DriverAvailabilityAndScheduleAPIOption) Router {
controller := &DriverAvailabilityAndScheduleAPIController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all the api routes for the DriverAvailabilityAndScheduleAPIController
func (c *DriverAvailabilityAndScheduleAPIController) Routes() Routes {
return Routes{
"DriverPunctualAvailabilitiesPost": Route{
strings.ToUpper("Post"),
"/driver_punctual_availabilities",
c.DriverPunctualAvailabilitiesPost,
},
"DriverRegularAvailabilitiesPost": Route{
strings.ToUpper("Post"),
"/driver_regular_availabilities",
c.DriverRegularAvailabilitiesPost,
},
}
}
// DriverPunctualAvailabilitiesPost - Set Punctual Driver Availabilities
func (c *DriverAvailabilityAndScheduleAPIController) DriverPunctualAvailabilitiesPost(w http.ResponseWriter, r *http.Request) {
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
if !authenticated {
response := ImplResponse{
Code: 401,
Body: "Unauthorized request. Check your operator / API Key.",
}
EncodeJSONResponse(response.Body, &response.Code, w)
return
}
driverPunctualAvailabilitiesRequestParam := DriverPunctualAvailabilitiesRequest{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&driverPunctualAvailabilitiesRequestParam); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertDriverPunctualAvailabilitiesRequestRequired(driverPunctualAvailabilitiesRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
if err := AssertDriverPunctualAvailabilitiesRequestConstraints(driverPunctualAvailabilitiesRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.DriverPunctualAvailabilitiesPost(r.Context(), driverPunctualAvailabilitiesRequestParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}
// DriverRegularAvailabilitiesPost - Set Regular Driver Availabilities
func (c *DriverAvailabilityAndScheduleAPIController) DriverRegularAvailabilitiesPost(w http.ResponseWriter, r *http.Request) {
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
if !authenticated {
response := ImplResponse{
Code: 401,
Body: "Unauthorized request. Check your operator / API Key.",
}
EncodeJSONResponse(response.Body, &response.Code, w)
return
}
driverRegularAvailabilitiesRequestParam := DriverRegularAvailabilitiesRequest{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&driverRegularAvailabilitiesRequestParam); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertDriverRegularAvailabilitiesRequestRequired(driverRegularAvailabilitiesRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
if err := AssertDriverRegularAvailabilitiesRequestConstraints(driverRegularAvailabilitiesRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.DriverRegularAvailabilitiesPost(r.Context(), driverRegularAvailabilitiesRequestParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}

View File

@@ -0,0 +1,127 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"context"
"errors"
"github.com/paulmach/orb"
"github.com/paulmach/orb/geojson"
"github.com/spf13/viper"
"net/http"
"solidarity-service/handler"
"solidarity-service/internal"
"solidarity-service/storage"
)
// DriverAvailabilityAndScheduleAPIService is a service that implements the logic for the DriverAvailabilityAndScheduleAPIServicer
// This service should implement the business logic for every endpoint for the DriverAvailabilityAndScheduleAPI API.
// Include any external packages or services that will be required by this service.
type DriverAvailabilityAndScheduleAPIService struct {
config *viper.Viper
handler *handler.SolidarityServiceHandler
storage storage.Storage
}
// NewDriverAvailabilityAndScheduleAPIService creates a default api service
func NewDriverAvailabilityAndScheduleAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) DriverAvailabilityAndScheduleAPIServicer {
return &DriverAvailabilityAndScheduleAPIService{
config: config,
handler: handler,
storage: storage,
}
}
// DriverPunctualAvailabilitiesPost - Set Punctual Driver Availabilities
func (s *DriverAvailabilityAndScheduleAPIService) DriverPunctualAvailabilitiesPost(ctx context.Context, driverPunctualAvailabilitiesRequest DriverPunctualAvailabilitiesRequest) (ImplResponse, error) {
driver := internal.Driver{}
driver.Driver.ID = driverPunctualAvailabilitiesRequest.User.Id
driver.Driver.Operator = driverPunctualAvailabilitiesRequest.User.Operator
driver.Driver.Alias = driverPunctualAvailabilitiesRequest.User.Alias
driver.Driver.Grade = int64(driverPunctualAvailabilitiesRequest.User.Grade)
driver.Driver.Picture = driverPunctualAvailabilitiesRequest.User.Picture
driver.Driver.LastName = driverPunctualAvailabilitiesRequest.User.LastName
driver.Driver.FirstName = driverPunctualAvailabilitiesRequest.User.FirstName
driver.Driver.VerifiedIdentity = driverPunctualAvailabilitiesRequest.User.VerifiedIdentity
driver.Driver.Gender = driverPunctualAvailabilitiesRequest.User.Gender
driver.Preferences.Music = driverPunctualAvailabilitiesRequest.Preferences.Music
driver.Preferences.Is_talker = driverPunctualAvailabilitiesRequest.Preferences.IsTalker
driver.Preferences.Luggage_size = int64(driverPunctualAvailabilitiesRequest.Preferences.LuggageSize)
driver.Preferences.Smoking = driverPunctualAvailabilitiesRequest.Preferences.Smoking
driver.Preferences.Animals = driverPunctualAvailabilitiesRequest.Preferences.Animals
driver.Driver_departure_address = &geojson.Feature{
Type: "Feature",
Geometry: orb.Geometry(orb.Point{driverPunctualAvailabilitiesRequest.Latitude, driverPunctualAvailabilitiesRequest.Longitude}),
Properties: geojson.Properties{
"name": driverPunctualAvailabilitiesRequest.Address,
},
}
driver.Radius = driverPunctualAvailabilitiesRequest.Radius
driver.AvailabilitiesType = internal.Punctual
for _, v := range driverPunctualAvailabilitiesRequest.Availabilities {
driver.PunctualAvailabilities = append(driver.PunctualAvailabilities, internal.PunctualAvailabilities{
Date: int64(v.Date),
StartTime: v.StartTime,
EndTime: v.EndTime,
})
}
driver.Car.Brand = driverPunctualAvailabilitiesRequest.Car.Brand
driver.Car.Model = driverPunctualAvailabilitiesRequest.Car.Model
err := s.storage.CreateDriver(driver)
if err != nil {
return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
} else {
return Response(201, "Punctual driver availabilities set successfully"), nil
}
}
// DriverRegularAvailabilitiesPost - Set Regular Driver Availabilities
func (s *DriverAvailabilityAndScheduleAPIService) DriverRegularAvailabilitiesPost(ctx context.Context, driverRegularAvailabilitiesRequest DriverRegularAvailabilitiesRequest) (ImplResponse, error) {
driver := internal.Driver{}
driver.Driver.ID = driverRegularAvailabilitiesRequest.User.Id
driver.Driver.Operator = driverRegularAvailabilitiesRequest.User.Operator
driver.Driver.Alias = driverRegularAvailabilitiesRequest.User.Alias
driver.Driver.Grade = int64(driverRegularAvailabilitiesRequest.User.Grade)
driver.Driver.Picture = driverRegularAvailabilitiesRequest.User.Picture
driver.Driver.LastName = driverRegularAvailabilitiesRequest.User.LastName
driver.Driver.FirstName = driverRegularAvailabilitiesRequest.User.FirstName
driver.Driver.VerifiedIdentity = driverRegularAvailabilitiesRequest.User.VerifiedIdentity
driver.Driver.Gender = driverRegularAvailabilitiesRequest.User.Gender
driver.Driver_departure_address = &geojson.Feature{
Type: "Feature",
Geometry: orb.Geometry(orb.Point{driverRegularAvailabilitiesRequest.Latitude, driverRegularAvailabilitiesRequest.Longitude}),
Properties: geojson.Properties{
"name": driverRegularAvailabilitiesRequest.Address,
},
}
driver.Preferences.Music = driverRegularAvailabilitiesRequest.Preferences.Music
driver.Preferences.Is_talker = driverRegularAvailabilitiesRequest.Preferences.IsTalker
driver.Preferences.Luggage_size = int64(driverRegularAvailabilitiesRequest.Preferences.LuggageSize)
driver.Preferences.Smoking = driverRegularAvailabilitiesRequest.Preferences.Smoking
driver.Preferences.Animals = driverRegularAvailabilitiesRequest.Preferences.Animals
driver.Radius = driverRegularAvailabilitiesRequest.Radius
driver.AvailabilitiesType = internal.Regular
for _, v := range driverRegularAvailabilitiesRequest.Availabilities {
driver.RegularAvailabilities = append(driver.RegularAvailabilities, internal.RegularAvailabilities{
DayOfWeek: v.DayOfWeek,
StartTime: v.StartTime,
EndTime: v.EndTime,
})
}
driver.Car.Brand = driverRegularAvailabilitiesRequest.Car.Brand
driver.Car.Model = driverRegularAvailabilitiesRequest.Car.Model
err := s.storage.CreateDriver(driver)
if err != nil {
return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
} else {
return Response(201, "Regular driver availabilities set successfully"), nil
}
}

View File

@@ -0,0 +1,190 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"encoding/json"
"errors"
"github.com/gorilla/mux"
"io"
"net/http"
"strings"
)
// InteractAPIController binds http requests to an api service and writes the service results to the http response
type InteractAPIController struct {
service InteractAPIServicer
errorHandler ErrorHandler
}
// InteractAPIOption for how the controller is set up.
type InteractAPIOption func(*InteractAPIController)
// WithInteractAPIErrorHandler inject ErrorHandler into controller
func WithInteractAPIErrorHandler(h ErrorHandler) InteractAPIOption {
return func(c *InteractAPIController) {
c.errorHandler = h
}
}
// NewInteractAPIController creates a default api controller
func NewInteractAPIController(s InteractAPIServicer, opts ...InteractAPIOption) Router {
controller := &InteractAPIController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all the api routes for the InteractAPIController
func (c *InteractAPIController) Routes() Routes {
return Routes{
"GetBookings": Route{
strings.ToUpper("Get"),
"/bookings/{bookingId}",
c.GetBookings,
},
"PatchBookings": Route{
strings.ToUpper("Patch"),
"/bookings/{bookingId}",
c.PatchBookings,
},
"PostBookings": Route{
strings.ToUpper("Post"),
"/bookings",
c.PostBookings,
},
"PostConnections": Route{
strings.ToUpper("Post"),
"/messages",
c.PostConnections,
},
}
}
// GetBookings - Retrieves an existing Booking request.
func (c *InteractAPIController) GetBookings(w http.ResponseWriter, r *http.Request) {
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
if !authenticated {
response := ImplResponse{
Code: 401,
Body: "Unauthorized request. Check your operator / API Key.",
}
EncodeJSONResponse(response.Body, &response.Code, w)
return
}
params := mux.Vars(r)
query := r.URL.Query()
operatorParam := query.Get("operator")
bookingIdParam := params["bookingId"]
result, err := c.service.GetBookings(r.Context(), operatorParam, bookingIdParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}
// PatchBookings - Updates status of an existing Booking request.
func (c *InteractAPIController) PatchBookings(w http.ResponseWriter, r *http.Request) {
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
if !authenticated {
response := ImplResponse{
Code: 401,
Body: "Unauthorized request. Check your operator / API Key.",
}
EncodeJSONResponse(response.Body, &response.Code, w)
return
}
params := mux.Vars(r)
query := r.URL.Query()
operatorParam := query.Get("operator")
bookingIdParam := params["bookingId"]
statusParam := query.Get("status")
messageParam := query.Get("message")
result, err := c.service.PatchBookings(r.Context(), operatorParam, bookingIdParam, BookingStatus(statusParam), messageParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}
// PostBookings - Create a punctual outward Booking request.
func (c *InteractAPIController) PostBookings(w http.ResponseWriter, r *http.Request) {
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
if !authenticated {
response := ImplResponse{
Code: 401,
Body: "Unauthorized request. Check your operator / API Key.",
}
EncodeJSONResponse(response.Body, &response.Code, w)
return
}
bookingRequestParam := BookingRequest{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&bookingRequestParam); err != nil && !errors.Is(err, io.EOF) {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertBookingRequestRequired(bookingRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
if err := AssertBookingRequestConstraints(bookingRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.PostBookings(r.Context(), bookingRequestParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}
// PostConnections - Send a message to the owner of a retrieved journey.
func (c *InteractAPIController) PostConnections(w http.ResponseWriter, r *http.Request) {
postConnectionsRequestParam := PostConnectionsRequest{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&postConnectionsRequestParam); err != nil && !errors.Is(err, io.EOF) {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertPostConnectionsRequestRequired(postConnectionsRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
if err := AssertPostConnectionsRequestConstraints(postConnectionsRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.PostConnections(r.Context(), postConnectionsRequestParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}

View File

@@ -0,0 +1,196 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"context"
"errors"
"fmt"
"github.com/spf13/viper"
"net/http"
"solidarity-service/handler"
"solidarity-service/internal"
"solidarity-service/storage"
"strings"
)
// InteractAPIService is a service that implements the logic for the InteractAPIServicer
// This service should implement the business logic for every endpoint for the InteractAPI API.
// Include any external packages or services that will be required by this service.
type InteractAPIService struct {
config *viper.Viper
handler *handler.SolidarityServiceHandler
storage storage.Storage
}
// NewInteractAPIService creates a default api service
func NewInteractAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) InteractAPIServicer {
return &InteractAPIService{
config: config,
handler: handler,
storage: storage,
}
}
// GetBookings - Retrieves an existing Booking request.
func (s *InteractAPIService) GetBookings(ctx context.Context, operator string, bookingId string) (ImplResponse, error) {
booking, err := s.storage.GetBooking(bookingId)
if err != nil {
if strings.Contains(err.Error(), " no rows in result set") {
return Response(http.StatusBadRequest, "ID not found in the database"), nil
} else {
return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
}
}
passenger, err := s.storage.GetPassenger(booking.Passenger.ID)
if err != nil {
return Response(http.StatusInternalServerError, nil), nil
}
driver, err := s.storage.GetDriver(booking.Driver.ID)
if err != nil {
return Response(http.StatusInternalServerError, nil), nil
}
duration, err := s.handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
if err != nil {
duration = 0
}
response := Booking{
Id: booking.ID,
Driver: User{
Id: driver.Driver.ID,
Operator: driver.Driver.Operator,
Alias: driver.Driver.Alias,
FirstName: driver.Driver.FirstName,
LastName: driver.Driver.LastName,
Grade: int32(driver.Driver.Grade),
Picture: driver.Driver.Picture,
Gender: driver.Driver.Gender,
VerifiedIdentity: driver.Driver.VerifiedIdentity,
},
Passenger: User{
Id: passenger.Passenger.ID,
Operator: passenger.Passenger.Operator,
Alias: passenger.Passenger.Alias,
FirstName: passenger.Passenger.FirstName,
LastName: passenger.Passenger.LastName,
Grade: int32(passenger.Passenger.Grade),
Picture: passenger.Passenger.Picture,
Gender: passenger.Passenger.Gender,
VerifiedIdentity: passenger.Passenger.VerifiedIdentity,
},
PassengerPickupDate: int32(passenger.Passenger_pickup_date),
PassengerPickupLat: passenger.Passenger_departure_address.Point().X(),
PassengerPickupLng: passenger.Passenger_departure_address.Point().Y(),
PassengerPickupAddress: passenger.Passenger_departure_address.Properties.MustString("name"),
PassengerDropLat: passenger.Passenger_destination_address.Point().X(),
PassengerDropLng: passenger.Passenger_destination_address.Point().Y(),
PassengerDropAddress: passenger.Passenger_destination_address.Properties.MustString("name"),
Status: BookingStatus(booking.Status),
Duration: int32(duration),
Distance: int32(s.handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)),
Car: Car{
Model: driver.Car.Model,
Brand: driver.Car.Brand,
},
Price: Price{
Type: "FREE",
},
}
fmt.Println(response)
return Response(200, response), nil
}
// PatchBookings - Updates status of an existing Booking request.
func (s *InteractAPIService) PatchBookings(ctx context.Context, operator string, bookingId string, status BookingStatus, message string) (ImplResponse, error) {
err := s.storage.UpdateBookingStatus(bookingId, internal.BookingStatus(status))
fmt.Println(err)
if err != nil {
if strings.Contains(err.Error(), " no rows in result set") {
return Response(http.StatusBadRequest, "ID not found in the database"), nil
}
return Response(http.StatusInternalServerError, nil), nil
}
return Response(200, "Successful operation"), nil
}
// PostBookings - Create a punctual outward Booking request.
func (s *InteractAPIService) PostBookings(ctx context.Context, bookingRequest BookingRequest) (ImplResponse, error) {
booking := internal.BookingRequest{}
booking.ID = bookingRequest.Id
booking.Status = internal.BookingStatus(bookingRequest.Status)
booking.Driver_id = bookingRequest.DriverId
booking.Passenger_id = bookingRequest.PassengerId
booking.Operator = bookingRequest.Operator
err := s.storage.CreateBooking(booking)
if err != nil {
return Response(http.StatusInternalServerError, nil), errors.New("PostBookings internal server error")
}
passenger, err := s.storage.GetPassenger(booking.Passenger_id)
if err != nil {
return Response(http.StatusInternalServerError, nil), errors.New("PostBookings internal server error")
}
driver, err := s.storage.GetDriver(booking.Driver_id)
if err != nil {
return Response(http.StatusInternalServerError, nil), errors.New("PostBookings internal server error")
}
duration, err := s.handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
if err != nil {
duration = 0
}
response := Booking{
Id: bookingRequest.Id,
Driver: User{
Id: driver.Driver.ID,
Operator: driver.Driver.Operator,
Alias: driver.Driver.Alias,
FirstName: driver.Driver.FirstName,
LastName: driver.Driver.LastName,
Grade: int32(driver.Driver.Grade),
Picture: driver.Driver.Picture,
Gender: driver.Driver.Gender,
VerifiedIdentity: driver.Driver.VerifiedIdentity,
},
Passenger: User{
Id: passenger.Passenger.ID,
Operator: passenger.Passenger.Operator,
Alias: passenger.Passenger.Alias,
FirstName: passenger.Passenger.FirstName,
LastName: passenger.Passenger.LastName,
Grade: int32(passenger.Passenger.Grade),
Picture: passenger.Passenger.Picture,
Gender: passenger.Passenger.Gender,
VerifiedIdentity: passenger.Passenger.VerifiedIdentity,
},
PassengerPickupDate: int32(passenger.Passenger_pickup_date),
PassengerPickupLat: passenger.Passenger_departure_address.Point().X(),
PassengerPickupLng: passenger.Passenger_departure_address.Point().Y(),
PassengerPickupAddress: passenger.Passenger_departure_address.Properties.MustString("name"),
PassengerDropLat: passenger.Passenger_destination_address.Point().X(),
PassengerDropLng: passenger.Passenger_destination_address.Point().Y(),
PassengerDropAddress: passenger.Passenger_destination_address.Properties.MustString("name"),
Status: bookingRequest.Status,
Duration: int32(duration),
Distance: int32(s.handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)),
Car: Car{
Model: driver.Car.Model,
Brand: driver.Car.Brand,
},
Price: Price{
Type: "FREE",
},
}
return Response(201, response), nil
}
// PostConnections - Send a message to the owner of a retrieved journey.
func (s *InteractAPIService) PostConnections(ctx context.Context, postConnectionsRequest PostConnectionsRequest) (ImplResponse, error) {
return Response(http.StatusNotImplemented, nil), errors.New("PostConnections method not implemented")
}

View File

@@ -0,0 +1,93 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"encoding/json"
"net/http"
"strings"
)
// PassengerTripRequestAPIController binds http requests to an api service and writes the service results to the http response
type PassengerTripRequestAPIController struct {
service PassengerTripRequestAPIServicer
errorHandler ErrorHandler
}
// PassengerTripRequestAPIOption for how the controller is set up.
type PassengerTripRequestAPIOption func(*PassengerTripRequestAPIController)
// WithPassengerTripRequestAPIErrorHandler inject ErrorHandler into controller
func WithPassengerTripRequestAPIErrorHandler(h ErrorHandler) PassengerTripRequestAPIOption {
return func(c *PassengerTripRequestAPIController) {
c.errorHandler = h
}
}
// NewPassengerTripRequestAPIController creates a default api controller
func NewPassengerTripRequestAPIController(s PassengerTripRequestAPIServicer, opts ...PassengerTripRequestAPIOption) Router {
controller := &PassengerTripRequestAPIController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all the api routes for the PassengerTripRequestAPIController
func (c *PassengerTripRequestAPIController) Routes() Routes {
return Routes{
"PassengerPost": Route{
strings.ToUpper("Post"),
"/passenger",
c.PassengerPost,
},
}
}
// PassengerPost - Create a Passenger Trip Request
func (c *PassengerTripRequestAPIController) PassengerPost(w http.ResponseWriter, r *http.Request) {
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
if !authenticated {
response := ImplResponse{
Code: 401,
Body: "Unauthorized request. Check your operator / API Key.",
}
EncodeJSONResponse(response.Body, &response.Code, w)
return
}
passengerTripRequestParam := PassengerTripRequest{}
d := json.NewDecoder(r.Body)
d.DisallowUnknownFields()
if err := d.Decode(&passengerTripRequestParam); err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
if err := AssertPassengerTripRequestRequired(passengerTripRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
if err := AssertPassengerTripRequestConstraints(passengerTripRequestParam); err != nil {
c.errorHandler(w, r, err, nil)
return
}
result, err := c.service.PassengerPost(r.Context(), passengerTripRequestParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}

View File

@@ -0,0 +1,80 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"context"
"errors"
"github.com/paulmach/orb"
"github.com/paulmach/orb/geojson"
"github.com/spf13/viper"
"net/http"
"solidarity-service/handler"
"solidarity-service/internal"
"solidarity-service/storage"
)
// PassengerTripRequestAPIService is a service that implements the logic for the PassengerTripRequestAPIServicer
// This service should implement the business logic for every endpoint for the PassengerTripRequestAPI API.
// Include any external packages or services that will be required by this service.
type PassengerTripRequestAPIService struct {
config *viper.Viper
handler *handler.SolidarityServiceHandler
storage storage.Storage
}
// NewPassengerTripRequestAPIService creates a default api service
func NewPassengerTripRequestAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) PassengerTripRequestAPIServicer {
return &PassengerTripRequestAPIService{
config: config,
handler: handler,
storage: storage,
}
}
// PassengerPost - Create a Passenger Trip Request
func (s *PassengerTripRequestAPIService) PassengerPost(ctx context.Context, passengerTripRequest PassengerTripRequest) (ImplResponse, error) {
passenger := internal.Passenger{}
passenger.Passenger_departure_address = &geojson.Feature{
Type: "Feature",
Geometry: orb.Geometry(orb.Point{passengerTripRequest.DepartureLatitude, passengerTripRequest.DepartureLongitude}),
Properties: geojson.Properties{
"name": passengerTripRequest.DepartureAddress,
},
}
passenger.Passenger_destination_address = &geojson.Feature{
Type: "Feature",
Geometry: orb.Geometry(orb.Point{passengerTripRequest.DestinationLatitude, passengerTripRequest.DestinationLongitude}),
Properties: geojson.Properties{
"name": passengerTripRequest.DestinationAddress,
},
}
passenger.Passenger_pickup_date = int64(passengerTripRequest.DepartureDate)
passenger.Passenger.ID = passengerTripRequest.User.Id
passenger.Passenger.Operator = passengerTripRequest.User.Operator
passenger.Passenger.Alias = passengerTripRequest.User.Alias
passenger.Passenger.FirstName = passengerTripRequest.User.FirstName
passenger.Passenger.LastName = passengerTripRequest.User.LastName
passenger.Passenger.Picture = passengerTripRequest.User.Picture
passenger.Passenger.Grade = int64(passengerTripRequest.User.Grade)
passenger.Passenger.Gender = passengerTripRequest.User.Gender
passenger.Passenger.VerifiedIdentity = passengerTripRequest.User.VerifiedIdentity
passenger.Preferences.Animals = passengerTripRequest.Preferences.Animals
passenger.Preferences.Luggage_size = int64(passengerTripRequest.Preferences.LuggageSize)
passenger.Preferences.Smoking = passengerTripRequest.Preferences.Smoking
passenger.Preferences.Is_talker = passengerTripRequest.Preferences.IsTalker
passenger.Preferences.Music = passengerTripRequest.Preferences.Music
err := s.storage.CreatePassenger(passenger)
if err != nil {
return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
} else {
return Response(201, "Trip request created"), nil
}
}

View File

@@ -0,0 +1,103 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"net/http"
"strings"
)
// SearchAPIController binds http requests to an api service and writes the service results to the http response
type SearchAPIController struct {
service SearchAPIServicer
errorHandler ErrorHandler
}
// SearchAPIOption for how the controller is set up.
type SearchAPIOption func(*SearchAPIController)
// WithSearchAPIErrorHandler inject ErrorHandler into controller
func WithSearchAPIErrorHandler(h ErrorHandler) SearchAPIOption {
return func(c *SearchAPIController) {
c.errorHandler = h
}
}
// NewSearchAPIController creates a default api controller
func NewSearchAPIController(s SearchAPIServicer, opts ...SearchAPIOption) Router {
controller := &SearchAPIController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all the api routes for the SearchAPIController
func (c *SearchAPIController) Routes() Routes {
return Routes{
"GetDriverJourneys": Route{
strings.ToUpper("Get"),
"/driver_journeys",
c.GetDriverJourneys,
},
}
}
// GetDriverJourneys - Search for matching punctual planned outward driver journeys.
func (c *SearchAPIController) GetDriverJourneys(w http.ResponseWriter, r *http.Request) {
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
if !authenticated {
response := ImplResponse{
Code: 401,
Body: "Unauthorized request. Check your operator / API Key.",
}
EncodeJSONResponse(response.Body, &response.Code, w)
return
}
query := r.URL.Query()
departureLatParam, err := parseNumericParameter[float32](
query.Get("departureLat"),
WithRequire[float32](parseFloat32),
)
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
departureLngParam, err := parseNumericParameter[float32](
query.Get("departureLng"),
WithRequire[float32](parseFloat32),
)
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
departureDateParam, err := parseNumericParameter[int32](
query.Get("departureDate"),
WithRequire[int32](parseInt32),
)
if err != nil {
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
operatorParam := query.Get("operator")
result, err := c.service.GetDriverJourneys(r.Context(), departureLatParam, departureLngParam, departureDateParam, operatorParam)
// If an error occurred, encode the error with the status code
if err != nil {
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
EncodeJSONResponse(result.Body, &result.Code, w)
}

View File

@@ -0,0 +1,105 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"context"
"github.com/paulmach/orb"
"github.com/paulmach/orb/geojson"
"github.com/spf13/viper"
"net/http"
"solidarity-service/handler"
"solidarity-service/internal"
"solidarity-service/storage"
"strings"
)
// SearchAPIService is a service that implements the logic for the SearchAPIServicer
// This service should implement the business logic for every endpoint for the SearchAPI API.
// Include any external packages or services that will be required by this service.
type SearchAPIService struct {
config *viper.Viper
handler *handler.SolidarityServiceHandler
storage storage.Storage
}
// NewSearchAPIService creates a default api service
func NewSearchAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) SearchAPIServicer {
return &SearchAPIService{
config: config,
handler: handler,
storage: storage,
}
}
// GetDriverJourneys - Search for matching punctual planned outward driver journeys.
func (s *SearchAPIService) GetDriverJourneys(ctx context.Context, departureLat float32, departureLng float32, departureDate int32, operator string) (ImplResponse, error) {
drivers, err := s.storage.DriverJourneys(&geojson.Feature{
Type: "Feature",
Geometry: orb.Geometry(orb.Point{float64(departureLat), float64(departureLng)}),
}, int64(departureDate))
if err != nil {
if strings.Contains(err.Error(), " no rows in result set") {
return Response(http.StatusBadRequest, "ID not found in the database"), nil
} else {
return Response(http.StatusInternalServerError, nil), nil
}
}
response := []DriverJourney{}
for _, v := range drivers {
temp := DriverJourney{}
if v.AvailabilitiesType == internal.Regular && v.RegularAvailabilities != nil {
for _, v := range v.RegularAvailabilities {
temp.RegularAvailabilitySlot = append(temp.RegularAvailabilitySlot, RegularAvailabilitySlot{
DayOfWeek: v.DayOfWeek,
StartTime: v.StartTime,
EndTime: v.EndTime,
})
}
} else if v.AvailabilitiesType == internal.Punctual && v.PunctualAvailabilities != nil {
for _, v := range v.PunctualAvailabilities {
temp.PunctualAvailabilitySlot = append(temp.PunctualAvailabilitySlot, PunctualAvailabilitySlot{
Date: int32(v.Date),
StartTime: v.StartTime,
EndTime: v.EndTime,
})
}
}
tamp := DriverJourney{
User: User{
Id: v.Driver.ID,
Operator: v.Driver.Operator,
Alias: v.Driver.Alias,
FirstName: v.Driver.FirstName,
LastName: v.Driver.LastName,
Grade: int32(v.Driver.Grade),
Picture: v.Driver.Picture,
Gender: v.Driver.Gender,
VerifiedIdentity: v.Driver.VerifiedIdentity,
},
Car: Car{
Model: v.Car.Model,
Brand: v.Car.Brand,
},
DriverDepartureDate: int64(departureDate),
Price: Price{
Type: "FREE",
},
DriverDepartureAddress: v.Driver_departure_address.Properties.MustString("name"),
}
temp.DriverDepartureAddress = tamp.DriverDepartureAddress
temp.Car = tamp.Car
temp.User = tamp.User
temp.DriverDepartureDate = tamp.DriverDepartureDate
temp.Price = tamp.Price
response = append(response, temp)
}
return Response(200, response), nil
}

View File

@@ -0,0 +1,62 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"errors"
"fmt"
"net/http"
)
var (
// ErrTypeAssertionError is thrown when type an interface does not match the asserted type
ErrTypeAssertionError = errors.New("unable to assert type")
)
// ParsingError indicates that an error has occurred when parsing request parameters
type ParsingError struct {
Err error
}
func (e *ParsingError) Unwrap() error {
return e.Err
}
func (e *ParsingError) Error() string {
return e.Err.Error()
}
// RequiredError indicates that an error has occurred when parsing request parameters
type RequiredError struct {
Field string
}
func (e *RequiredError) Error() string {
return fmt.Sprintf("required field '%s' is zero value.", e.Field)
}
// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if
// you would like errors to be handled differently from the DefaultErrorHandler
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse)
// DefaultErrorHandler defines the default logic on how to handle errors from the controller. Any errors from parsing
// request params will return a StatusBadRequest. Otherwise, the error code originating from the servicer will be used.
func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) {
if _, ok := err.(*ParsingError); ok {
// Handle parsing errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), w)
} else if _, ok := err.(*RequiredError); ok {
// Handle missing required errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusUnprocessableEntity), w)
} else {
// Handle all other errors
EncodeJSONResponse(err.Error(), &result.Code, w)
}
}

View File

@@ -0,0 +1,60 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"reflect"
)
// Response return a ImplResponse struct filled
func Response(code int, body interface{}) ImplResponse {
return ImplResponse {
Code: code,
Body: body,
}
}
// IsZeroValue checks if the val is the zero-ed value.
func IsZeroValue(val interface{}) bool {
return val == nil || reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface())
}
// AssertRecurseInterfaceRequired recursively checks each struct in a slice against the callback.
// This method traverse nested slices in a preorder fashion.
func AssertRecurseInterfaceRequired[T any](obj interface{}, callback func(T) error) error {
return AssertRecurseValueRequired(reflect.ValueOf(obj), callback)
}
// AssertRecurseValueRequired checks each struct in the nested slice against the callback.
// This method traverse nested slices in a preorder fashion. ErrTypeAssertionError is thrown if
// the underlying struct does not match type T.
func AssertRecurseValueRequired[T any](value reflect.Value, callback func(T) error) error {
switch value.Kind() {
// If it is a struct we check using callback
case reflect.Struct:
obj, ok := value.Interface().(T)
if !ok {
return ErrTypeAssertionError
}
if err := callback(obj); err != nil {
return err
}
// If it is a slice we continue recursion
case reflect.Slice:
for i := 0; i < value.Len(); i += 1 {
if err := AssertRecurseValueRequired(value.Index(i), callback); err != nil {
return err
}
}
}
return nil
}

View File

@@ -0,0 +1,16 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
// ImplResponse defines an implementation response with error code and the associated body
type ImplResponse struct {
Code int
Body interface{}
}

View File

@@ -0,0 +1,32 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"log"
"net/http"
"time"
)
func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.Printf(
"%s %s %s %s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
})
}

View File

@@ -0,0 +1,28 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type PassengerPost400Response struct {
Error string `json:"error,omitempty"`
}
// AssertPassengerPost400ResponseRequired checks if the required fields are not zero-ed
func AssertPassengerPost400ResponseRequired(obj PassengerPost400Response) error {
return nil
}
// AssertPassengerPost400ResponseConstraints checks if the values respects the defined constraints
func AssertPassengerPost400ResponseConstraints(obj PassengerPost400Response) error {
return nil
}

View File

@@ -0,0 +1,93 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type Booking struct {
// Booking id is common between both operators, and must be created as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4) generation algorithm is advised.
Id string `json:"id"`
Driver User `json:"driver"`
Passenger User `json:"passenger"`
// Passenger pickup datetime as a UNIX UTC timestamp in seconds.
PassengerPickupDate int32 `json:"passengerPickupDate"`
// Latitude of the passenger pick-up point.
PassengerPickupLat float64 `json:"passengerPickupLat"`
// Longitude of the passenger pick-up point.
PassengerPickupLng float64 `json:"passengerPickupLng"`
// Latitude of the passenger drop-off point.
PassengerDropLat float64 `json:"passengerDropLat"`
// Longitude of the passenger drop-off point.
PassengerDropLng float64 `json:"passengerDropLng"`
// String representing the pickup-up address.
PassengerPickupAddress string `json:"passengerPickupAddress,omitempty"`
// String representing the drop-off address.
PassengerDropAddress string `json:"passengerDropAddress,omitempty"`
Status BookingStatus `json:"status"`
// Carpooling duration in seconds.
Duration int32 `json:"duration,omitempty"`
// Carpooling distance in meters.
Distance int32 `json:"distance,omitempty"`
Price Price `json:"price"`
Car Car `json:"car,omitempty"`
}
// AssertBookingRequired checks if the required fields are not zero-ed
func AssertBookingRequired(obj Booking) error {
elements := map[string]interface{}{
"id": obj.Id,
"driver": obj.Driver,
"passenger": obj.Passenger,
"passengerPickupDate": obj.PassengerPickupDate,
"passengerPickupLat": obj.PassengerPickupLat,
"passengerPickupLng": obj.PassengerPickupLng,
"passengerDropLat": obj.PassengerDropLat,
"passengerDropLng": obj.PassengerDropLng,
"status": obj.Status,
"price": obj.Price,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if err := AssertUserRequired(obj.Driver); err != nil {
return err
}
if err := AssertUserRequired(obj.Passenger); err != nil {
return err
}
if err := AssertPriceRequired(obj.Price); err != nil {
return err
}
if err := AssertCarRequired(obj.Car); err != nil {
return err
}
return nil
}
// AssertBookingConstraints checks if the values respects the defined constraints
func AssertBookingConstraints(obj Booking) error {
return nil
}

View File

@@ -0,0 +1,50 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type BookingRequest struct {
// Booking id is common between both operators, and must be created as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4) generation algorithm is advised.
Id string `json:"id"`
PassengerId string `json:"passengerId"`
DriverId string `json:"driverId"`
Status BookingStatus `json:"status"`
Operator string `json:"operator"`
}
// AssertBookingRequestRequired checks if the required fields are not zero-ed
func AssertBookingRequestRequired(obj BookingRequest) error {
elements := map[string]interface{}{
"id": obj.Id,
"passengerId": obj.PassengerId,
"driverId": obj.DriverId,
"status": obj.Status,
"operator": obj.Operator,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
return nil
}
// AssertBookingRequestConstraints checks if the values respects the defined constraints
func AssertBookingRequestConstraints(obj BookingRequest) error {
return nil
}

View File

@@ -0,0 +1,35 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
// BookingStatus : Status of the booking.
type BookingStatus string
// List of BookingStatus
const (
WAITING_DRIVER_CONFIRMATION BookingStatus = "WAITING_DRIVER_CONFIRMATION"
WAITING_PASSENGER_CONFIRMATION BookingStatus = "WAITING_PASSENGER_CONFIRMATION"
CONFIRMED BookingStatus = "CONFIRMED"
CANCELLED BookingStatus = "CANCELLED"
COMPLETED_PENDING_VALIDATION BookingStatus = "COMPLETED_PENDING_VALIDATION"
VALIDATED BookingStatus = "VALIDATED"
)
// AssertBookingStatusRequired checks if the required fields are not zero-ed
func AssertBookingStatusRequired(obj BookingStatus) error {
return nil
}
// AssertBookingStatusConstraints checks if the values respects the defined constraints
func AssertBookingStatusConstraints(obj BookingStatus) error {
return nil
}

View File

@@ -0,0 +1,32 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type Car struct {
// Model of the car.
Model string `json:"model,omitempty"`
// Brand of the car.
Brand string `json:"brand,omitempty"`
}
// AssertCarRequired checks if the required fields are not zero-ed
func AssertCarRequired(obj Car) error {
return nil
}
// AssertCarConstraints checks if the values respects the defined constraints
func AssertCarConstraints(obj Car) error {
return nil
}

View File

@@ -0,0 +1,51 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type DriverJourney struct {
User User `json:"user"`
Car Car `json:"car,omitempty"`
RegularAvailabilitySlot []RegularAvailabilitySlot `json:"regular_availabilities,omitempty"`
PunctualAvailabilitySlot []PunctualAvailabilitySlot `json:"punctual_availabilities,omitempty"`
// Driver departure datetime as a UNIX UTC timestamp in seconds.
DriverDepartureDate int64 `json:"driver_departure_Date"`
DriverDepartureAddress string `json:"driver_departure_Address,omitempty"`
Price Price `json:"price,omitempty"`
}
// AssertDriverJourneyRequired checks if the required fields are not zero-ed
func AssertDriverJourneyRequired(obj DriverJourney) error {
elements := map[string]interface{}{
"user": obj.User,
"driverDepartureDate": obj.DriverDepartureDate,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if err := AssertUserRequired(obj.User); err != nil {
return err
}
if err := AssertCarRequired(obj.Car); err != nil {
return err
}
if err := AssertPriceRequired(obj.Price); err != nil {
return err
}
return nil
}
// AssertDriverJourneyConstraints checks if the values respects the defined constraints
func AssertDriverJourneyConstraints(obj DriverJourney) error {
return nil
}

View File

@@ -0,0 +1,74 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type DriverPunctualAvailabilitiesRequest struct {
// The address or location description.
Address string `json:"address"`
// The latitude coordinate of the location.
Latitude float64 `json:"latitude"`
// The longitude coordinate of the location.
Longitude float64 `json:"longitude"`
// The radius around the location.
Radius int32 `json:"radius"`
Availabilities []PunctualAvailabilitySlot `json:"availabilities"`
User User `json:"user"`
Preferences Preferences `json:"preferences,omitempty"`
Car Car `json:"car,omitempty"`
}
// AssertDriverPunctualAvailabilitiesRequestRequired checks if the required fields are not zero-ed
func AssertDriverPunctualAvailabilitiesRequestRequired(obj DriverPunctualAvailabilitiesRequest) error {
elements := map[string]interface{}{
"address": obj.Address,
"latitude": obj.Latitude,
"longitude": obj.Longitude,
"radius": obj.Radius,
"availabilities": obj.Availabilities,
"user": obj.User,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
for _, el := range obj.Availabilities {
if err := AssertPunctualAvailabilitySlotRequired(el); err != nil {
return err
}
}
if err := AssertUserRequired(obj.User); err != nil {
return err
}
if err := AssertPreferencesRequired(obj.Preferences); err != nil {
return err
}
if err := AssertCarRequired(obj.Car); err != nil {
return err
}
return nil
}
// AssertDriverPunctualAvailabilitiesRequestConstraints checks if the values respects the defined constraints
func AssertDriverPunctualAvailabilitiesRequestConstraints(obj DriverPunctualAvailabilitiesRequest) error {
return nil
}

View File

@@ -0,0 +1,74 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type DriverRegularAvailabilitiesRequest struct {
// The address or location description.
Address string `json:"address"`
// The latitude coordinate of the location.
Latitude float64 `json:"latitude"`
// The longitude coordinate of the location.
Longitude float64 `json:"longitude"`
// The radius around the location.
Radius int32 `json:"radius"`
Availabilities []RegularAvailabilitySlot `json:"availabilities"`
User User `json:"user"`
Preferences Preferences `json:"preferences,omitempty"`
Car Car `json:"car,omitempty"`
}
// AssertDriverRegularAvailabilitiesRequestRequired checks if the required fields are not zero-ed
func AssertDriverRegularAvailabilitiesRequestRequired(obj DriverRegularAvailabilitiesRequest) error {
elements := map[string]interface{}{
"address": obj.Address,
"latitude": obj.Latitude,
"longitude": obj.Longitude,
"radius": obj.Radius,
"availabilities": obj.Availabilities,
"user": obj.User,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
for _, el := range obj.Availabilities {
if err := AssertRegularAvailabilitySlotRequired(el); err != nil {
return err
}
}
if err := AssertUserRequired(obj.User); err != nil {
return err
}
if err := AssertPreferencesRequired(obj.Preferences); err != nil {
return err
}
if err := AssertCarRequired(obj.Car); err != nil {
return err
}
return nil
}
// AssertDriverRegularAvailabilitiesRequestConstraints checks if the values respects the defined constraints
func AssertDriverRegularAvailabilitiesRequestConstraints(obj DriverRegularAvailabilitiesRequest) error {
return nil
}

View File

@@ -0,0 +1,45 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type DriverTrip struct {
User User `json:"user"`
Car Car `json:"car,omitempty"`
}
// AssertDriverTripRequired checks if the required fields are not zero-ed
func AssertDriverTripRequired(obj DriverTrip) error {
elements := map[string]interface{}{
"user": obj.User,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if err := AssertUserRequired(obj.User); err != nil {
return err
}
if err := AssertCarRequired(obj.Car); err != nil {
return err
}
return nil
}
// AssertDriverTripConstraints checks if the values respects the defined constraints
func AssertDriverTripConstraints(obj DriverTrip) error {
return nil
}

View File

@@ -0,0 +1,29 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type GetBookings404Response struct {
// Explain why the request couldn't be processed.
Error string `json:"error,omitempty"`
}
// AssertGetBookings404ResponseRequired checks if the required fields are not zero-ed
func AssertGetBookings404ResponseRequired(obj GetBookings404Response) error {
return nil
}
// AssertGetBookings404ResponseConstraints checks if the values respects the defined constraints
func AssertGetBookings404ResponseConstraints(obj GetBookings404Response) error {
return nil
}

View File

@@ -0,0 +1,45 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type JourneySchedule struct {
// Passenger pickup datetime as a UNIX UTC timestamp in seconds.
PassengerPickupDate float32 `json:"passengerPickupDate"`
// Driver departure datetime as a UNIX UTC timestamp in seconds.
DriverDepartureDate float32 `json:"driverDepartureDate,omitempty"`
// Type of journey. A dynamic journey is happening in real time.
Type string `json:"type"`
}
// AssertJourneyScheduleRequired checks if the required fields are not zero-ed
func AssertJourneyScheduleRequired(obj JourneySchedule) error {
elements := map[string]interface{}{
"passengerPickupDate": obj.PassengerPickupDate,
"type": obj.Type,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
return nil
}
// AssertJourneyScheduleConstraints checks if the values respects the defined constraints
func AssertJourneyScheduleConstraints(obj JourneySchedule) error {
return nil
}

View File

@@ -0,0 +1,67 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type PassengerTripRequest struct {
User User `json:"user"`
DestinationAddress string `json:"destination_address"`
DestinationLatitude float64 `json:"destination_latitude"`
DestinationLongitude float64 `json:"destination_longitude"`
DepartureAddress string `json:"departure_address"`
DepartureLatitude float64 `json:"departure_latitude"`
DepartureLongitude float64 `json:"departure_longitude"`
// Departure datetime using a UNIX UTC timestamp in seconds.
DepartureDate int32 `json:"departure_date"`
Preferences Preferences `json:"preferences,omitempty"`
}
// AssertPassengerTripRequestRequired checks if the required fields are not zero-ed
func AssertPassengerTripRequestRequired(obj PassengerTripRequest) error {
elements := map[string]interface{}{
"user": obj.User,
"destination_address": obj.DestinationAddress,
"destination_latitude": obj.DestinationLatitude,
"destination_longitude": obj.DestinationLongitude,
"departure_address": obj.DepartureAddress,
"departure_latitude": obj.DepartureLatitude,
"departure_longitude": obj.DepartureLongitude,
"departure_date": obj.DepartureDate,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if err := AssertUserRequired(obj.User); err != nil {
return err
}
if err := AssertPreferencesRequired(obj.Preferences); err != nil {
return err
}
return nil
}
// AssertPassengerTripRequestConstraints checks if the values respects the defined constraints
func AssertPassengerTripRequestConstraints(obj PassengerTripRequest) error {
return nil
}

View File

@@ -0,0 +1,63 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type PostConnectionsRequest struct {
From User `json:"from"`
To User `json:"to"`
// Free text content of a message. The message can contain all the details (phone number, email, etc.) allowing the recipient to call back the sender in order to carpool with him/her.
Message string `json:"message"`
// Defines if the recipient of this message is either the driver or the passenger.
RecipientCarpoolerType string `json:"recipientCarpoolerType"`
// ID of the Driver's journey to which the message is related (if any). Unique given the `Driver`'s `operator` property.
DriverJourneyId string `json:"driverJourneyId,omitempty"`
// ID of the Passenger's journey to which the message is related (if any). Unique given the `Passenger`'s `operator` property.
PassengerJourneyId string `json:"passengerJourneyId,omitempty"`
// Booking id is common between both operators, and must be created as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4) generation algorithm is advised.
BookingId string `json:"bookingId,omitempty"`
}
// AssertPostConnectionsRequestRequired checks if the required fields are not zero-ed
func AssertPostConnectionsRequestRequired(obj PostConnectionsRequest) error {
elements := map[string]interface{}{
"from": obj.From,
"to": obj.To,
"message": obj.Message,
"recipientCarpoolerType": obj.RecipientCarpoolerType,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
if err := AssertUserRequired(obj.From); err != nil {
return err
}
if err := AssertUserRequired(obj.To); err != nil {
return err
}
return nil
}
// AssertPostConnectionsRequestConstraints checks if the values respects the defined constraints
func AssertPostConnectionsRequestConstraints(obj PostConnectionsRequest) error {
return nil
}

View File

@@ -0,0 +1,51 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"errors"
)
type Preferences struct {
// If driver journey, specifies if the driver allows smoking in the car.
Smoking bool `json:"smoking,omitempty"`
// If driver journey, specifies if the driver allows animals in the car.
Animals bool `json:"animals,omitempty"`
// If driver journey, specifies if the driver enjoys music in the car.
Music bool `json:"music,omitempty"`
// If driver journey, specifies if the driver enjoys talking with passengers.
IsTalker bool `json:"isTalker,omitempty"`
// If driver journey, specifies the size of allowed luggages. From very small (1) to very big (5).
LuggageSize int32 `json:"luggageSize,omitempty"`
}
// AssertPreferencesRequired checks if the required fields are not zero-ed
func AssertPreferencesRequired(obj Preferences) error {
return nil
}
// AssertPreferencesConstraints checks if the values respects the defined constraints
func AssertPreferencesConstraints(obj Preferences) error {
if obj.LuggageSize < 1 {
return &ParsingError{Err: errors.New(errMsgMinValueConstraint)}
}
if obj.LuggageSize > 5 {
return &ParsingError{Err: errors.New(errMsgMaxValueConstraint)}
}
return nil
}

View File

@@ -0,0 +1,35 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type Price struct {
// Either « FREE », « PAYING » or « UNKNOWN ». « UNKNOWN » is given when it should be « PAYING » but we cannot set the price yet.
Type string `json:"type,omitempty"`
// Carpooling passenger cost estimate. In the case of integrated booking by API, amount expected by the carpooling operator.
Amount float32 `json:"amount,omitempty"`
// ISO 4217 code representing the currency of the price.
Currency string `json:"currency,omitempty"`
}
// AssertPriceRequired checks if the required fields are not zero-ed
func AssertPriceRequired(obj Price) error {
return nil
}
// AssertPriceConstraints checks if the values respects the defined constraints
func AssertPriceConstraints(obj Price) error {
return nil
}

View File

@@ -0,0 +1,46 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type PunctualAvailabilitySlot struct {
// UNIX UTC timestamp in seconds.
Date int32 `json:"date"`
// Start time for punctual scheduling (RFC3339 partial-time).
StartTime string `json:"startTime"`
// End time for punctual scheduling (RFC3339 partial-time).
EndTime string `json:"endTime"`
}
// AssertPunctualAvailabilitySlotRequired checks if the required fields are not zero-ed
func AssertPunctualAvailabilitySlotRequired(obj PunctualAvailabilitySlot) error {
elements := map[string]interface{}{
"date": obj.Date,
"startTime": obj.StartTime,
"endTime": obj.EndTime,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
return nil
}
// AssertPunctualAvailabilitySlotConstraints checks if the values respects the defined constraints
func AssertPunctualAvailabilitySlotConstraints(obj PunctualAvailabilitySlot) error {
return nil
}

View File

@@ -0,0 +1,46 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
type RegularAvailabilitySlot struct {
// Day of the week for regular scheduling.
DayOfWeek string `json:"dayOfWeek"`
// Start time for regular scheduling (RFC3339 partial-time).
StartTime string `json:"startTime"`
// End time for regular scheduling (RFC3339 partial-time).
EndTime string `json:"endTime"`
}
// AssertRegularAvailabilitySlotRequired checks if the required fields are not zero-ed
func AssertRegularAvailabilitySlotRequired(obj RegularAvailabilitySlot) error {
elements := map[string]interface{}{
"dayOfWeek": obj.DayOfWeek,
"startTime": obj.StartTime,
"endTime": obj.EndTime,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
return nil
}
// AssertRegularAvailabilitySlotConstraints checks if the values respects the defined constraints
func AssertRegularAvailabilitySlotConstraints(obj RegularAvailabilitySlot) error {
return nil
}

View File

@@ -0,0 +1,74 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"errors"
)
type User struct {
// User's identifier. It MUST be unique for a given `operator`.
Id string `json:"id"`
// The operator identifier. MUST be a Fully Qualified Domain Name (example carpool.mycity.com) owned by the operator or a Partially Qualified Domain Name (example operator.org) owned and exclusively operated by the operator. Operators SHOULD always send the same value.
Operator string `json:"operator"`
// User's alias.
Alias string `json:"alias"`
// User's first name.
FirstName string `json:"firstName,omitempty"`
// User's last name.
LastName string `json:"lastName,omitempty"`
// User's grade from 1 to 5.
Grade int32 `json:"grade,omitempty"`
// User's profile picture absolute URL.
Picture string `json:"picture,omitempty"`
// User's gender. 'O' stands for 'Other'.
Gender string `json:"gender,omitempty"`
// true if the identity of this user has been verified by the operator or a third party; and the firstName, lastName, birthdate have been confirmed as identitical to an official identity proof document. Can be left empty if the information is not available.
VerifiedIdentity bool `json:"verifiedIdentity,omitempty"`
}
// AssertUserRequired checks if the required fields are not zero-ed
func AssertUserRequired(obj User) error {
elements := map[string]interface{}{
"id": obj.Id,
"operator": obj.Operator,
"alias": obj.Alias,
}
for name, el := range elements {
if isZero := IsZeroValue(el); isZero {
return &RequiredError{Field: name}
}
}
return nil
}
// AssertUserConstraints checks if the values respects the defined constraints
func AssertUserConstraints(obj User) error {
if obj.Grade < 1 {
return &ParsingError{Err: errors.New(errMsgMinValueConstraint)}
}
if obj.Grade > 5 {
return &ParsingError{Err: errors.New(errMsgMaxValueConstraint)}
}
return nil
}

View File

@@ -0,0 +1,68 @@
package openapi
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"strings"
)
func CheckOperatorAuthorization(r *http.Request, authorizedOperators map[string]string) bool {
authorizationHeader := r.Header.Get("Authorization")
if authorizationHeader == "" {
return false
}
parts := strings.Split(authorizationHeader, " ")
if len(parts) != 2 {
return false
}
if parts[0] != "Bearer" {
return false
}
apiKey := parts[1]
operatorName, authorized := authorizedOperators[apiKey]
var operator string
var found bool
if r.Body != nil {
body, err := ioutil.ReadAll(r.Body)
if err == nil {
var payload map[string]interface{}
if json.Unmarshal(body, &payload) == nil {
// Check for "operator" in the top-level body
if op, ok := payload["operator"].(string); ok {
operator = op
found = true
} else {
// Check for "user" struct in the body
if user, ok := payload["user"].(map[string]interface{}); ok {
if op, ok := user["operator"].(string); ok {
operator = op
found = true
}
}
}
}
}
r.Body = ioutil.NopCloser(bytes.NewReader(body))
}
// If operator is not found in the request body, check the request parameters.
if !found {
operatorFromParams := r.URL.Query().Get("operator")
if operatorFromParams != "" {
operator = operatorFromParams
found = true
}
}
if found && operator == operatorName && authorized {
return true
}
return false
}
var AuthorizedOperators = map[string]string{
"$2y$10$TJuDZDu.mqy5dDKGMSfxSO5f6pz/36XVrAyQ1CXJd63ccjRlX7lmK": "test.com",
}

View File

@@ -0,0 +1,297 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"encoding/json"
"errors"
"github.com/gorilla/mux"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"strconv"
"strings"
)
// A Route defines the parameters for an api endpoint
type Route struct {
Method string
Pattern string
HandlerFunc http.HandlerFunc
}
// Routes is a map of defined api endpoints
type Routes map[string]Route
// Router defines the required methods for retrieving api routes
type Router interface {
Routes() Routes
}
const errMsgRequiredMissing = "required parameter is missing"
const errMsgMinValueConstraint = "provided parameter is not respecting minimum value constraint"
const errMsgMaxValueConstraint = "provided parameter is not respecting maximum value constraint"
// NewRouter creates a new router for any number of api routers
func NewRouter(routers ...Router) *mux.Router {
router := mux.NewRouter().StrictSlash(true)
for _, api := range routers {
for name, route := range api.Routes() {
var handler http.Handler
handler = route.HandlerFunc
handler = Logger(handler, name)
router.
Methods(route.Method).
Path(route.Pattern).
Name(name).
Handler(handler)
}
}
return router
}
// EncodeJSONResponse uses the json encoder to write an interface to the http response with an optional status code
func EncodeJSONResponse(i interface{}, status *int, w http.ResponseWriter) error {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
if status != nil {
w.WriteHeader(*status)
} else {
w.WriteHeader(http.StatusOK)
}
if i != nil {
return json.NewEncoder(w).Encode(i)
}
return nil
}
// ReadFormFileToTempFile reads file data from a request form and writes it to a temporary file
func ReadFormFileToTempFile(r *http.Request, key string) (*os.File, error) {
_, fileHeader, err := r.FormFile(key)
if err != nil {
return nil, err
}
return readFileHeaderToTempFile(fileHeader)
}
// ReadFormFilesToTempFiles reads files array data from a request form and writes it to a temporary files
func ReadFormFilesToTempFiles(r *http.Request, key string) ([]*os.File, error) {
if err := r.ParseMultipartForm(32 << 20); err != nil {
return nil, err
}
files := make([]*os.File, 0, len(r.MultipartForm.File[key]))
for _, fileHeader := range r.MultipartForm.File[key] {
file, err := readFileHeaderToTempFile(fileHeader)
if err != nil {
return nil, err
}
files = append(files, file)
}
return files, nil
}
// readFileHeaderToTempFile reads multipart.FileHeader and writes it to a temporary file
func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error) {
formFile, err := fileHeader.Open()
if err != nil {
return nil, err
}
defer formFile.Close()
fileBytes, err := ioutil.ReadAll(formFile)
if err != nil {
return nil, err
}
file, err := ioutil.TempFile("", fileHeader.Filename)
if err != nil {
return nil, err
}
defer file.Close()
file.Write(fileBytes)
return file, nil
}
type Number interface {
~int32 | ~int64 | ~float32 | ~float64
}
type ParseString[T Number | string | bool] func(v string) (T, error)
// parseFloat64 parses a string parameter to an float64.
func parseFloat64(param string) (float64, error) {
if param == "" {
return 0, nil
}
return strconv.ParseFloat(param, 64)
}
// parseFloat32 parses a string parameter to an float32.
func parseFloat32(param string) (float32, error) {
if param == "" {
return 0, nil
}
v, err := strconv.ParseFloat(param, 32)
return float32(v), err
}
// parseInt64 parses a string parameter to an int64.
func parseInt64(param string) (int64, error) {
if param == "" {
return 0, nil
}
return strconv.ParseInt(param, 10, 64)
}
// parseInt32 parses a string parameter to an int32.
func parseInt32(param string) (int32, error) {
if param == "" {
return 0, nil
}
val, err := strconv.ParseInt(param, 10, 32)
return int32(val), err
}
// parseBool parses a string parameter to an bool.
func parseBool(param string) (bool, error) {
if param == "" {
return false, nil
}
return strconv.ParseBool(param)
}
type Operation[T Number | string | bool] func(actual string) (T, bool, error)
func WithRequire[T Number | string | bool](parse ParseString[T]) Operation[T] {
var empty T
return func(actual string) (T, bool, error) {
if actual == "" {
return empty, false, errors.New(errMsgRequiredMissing)
}
v, err := parse(actual)
return v, false, err
}
}
func WithDefaultOrParse[T Number | string | bool](def T, parse ParseString[T]) Operation[T] {
return func(actual string) (T, bool, error) {
if actual == "" {
return def, true, nil
}
v, err := parse(actual)
return v, false, err
}
}
func WithParse[T Number | string | bool](parse ParseString[T]) Operation[T] {
return func(actual string) (T, bool, error) {
v, err := parse(actual)
return v, false, err
}
}
type Constraint[T Number | string | bool] func(actual T) error
func WithMinimum[T Number](expected T) Constraint[T] {
return func(actual T) error {
if actual < expected {
return errors.New(errMsgMinValueConstraint)
}
return nil
}
}
func WithMaximum[T Number](expected T) Constraint[T] {
return func(actual T) error {
if actual > expected {
return errors.New(errMsgMaxValueConstraint)
}
return nil
}
}
// parseNumericParameter parses a numeric parameter to its respective type.
func parseNumericParameter[T Number](param string, fn Operation[T], checks ...Constraint[T]) (T, error) {
v, ok, err := fn(param)
if err != nil {
return 0, err
}
if !ok {
for _, check := range checks {
if err := check(v); err != nil {
return 0, err
}
}
}
return v, nil
}
// parseBoolParameter parses a string parameter to a bool
func parseBoolParameter(param string, fn Operation[bool]) (bool, error) {
v, _, err := fn(param)
return v, err
}
// parseNumericArrayParameter parses a string parameter containing array of values to its respective type.
func parseNumericArrayParameter[T Number](param, delim string, required bool, fn Operation[T], checks ...Constraint[T]) ([]T, error) {
if param == "" {
if required {
return nil, errors.New(errMsgRequiredMissing)
}
return nil, nil
}
str := strings.Split(param, delim)
values := make([]T, len(str))
for i, s := range str {
v, ok, err := fn(s)
if err != nil {
return nil, err
}
if !ok {
for _, check := range checks {
if err := check(v); err != nil {
return nil, err
}
}
}
values[i] = v
}
return values, nil
}

View File

@@ -0,0 +1,40 @@
/*
* Solidarity Mobility API
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package Solidarity_api
import (
"github.com/spf13/viper"
"log"
"net/http"
"solidarity-service/handler"
"solidarity-service/interoperability/solidarity-api/server/openapi"
"solidarity-service/storage"
)
func Run(cfg *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) {
BookingsFilterAPIService := openapi.NewBookingsFilterAPIService(cfg, handler, storage)
BookingsFilterAPIController := openapi.NewBookingsFilterAPIController(BookingsFilterAPIService)
DriverAvailabilityAndScheduleAPIService := openapi.NewDriverAvailabilityAndScheduleAPIService(cfg, handler, storage)
DriverAvailabilityAndScheduleAPIController := openapi.NewDriverAvailabilityAndScheduleAPIController(DriverAvailabilityAndScheduleAPIService)
InteractAPIService := openapi.NewInteractAPIService(cfg, handler, storage)
InteractAPIController := openapi.NewInteractAPIController(InteractAPIService)
PassengerTripRequestAPIService := openapi.NewPassengerTripRequestAPIService(cfg, handler, storage)
PassengerTripRequestAPIController := openapi.NewPassengerTripRequestAPIController(PassengerTripRequestAPIService)
SearchAPIService := openapi.NewSearchAPIService(cfg, handler, storage)
SearchAPIController := openapi.NewSearchAPIController(SearchAPIService)
router := openapi.NewRouter(BookingsFilterAPIController, DriverAvailabilityAndScheduleAPIController, InteractAPIController, PassengerTripRequestAPIController, SearchAPIController)
log.Fatal(http.ListenAndServe(":9999", router))
}