package application import ( "context" "encoding/json" "errors" "fmt" // "io" "net/http" // "strconv" "strings" // "time" "git.coopgo.io/coopgo-apps/parcoursmob/services" "git.coopgo.io/coopgo-apps/parcoursmob/utils/identification" // filestorage "git.coopgo.io/coopgo-apps/parcoursmob/utils/storage" diags "git.coopgo.io/coopgo-platform/diags/grpcapi" diagsstorage "git.coopgo.io/coopgo-platform/diags/storage" // groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi" // "git.coopgo.io/coopgo-platform/groups-management/storage" // mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi" // "github.com/google/uuid" "github.com/gorilla/mux" "github.com/rs/zerolog/log" "google.golang.org/protobuf/types/known/structpb" // "google.golang.org/protobuf/types/known/timestamppb" ) type DiagsForm struct { Name string `json:"name" validate:"required"` Namespace string `json:"namespace" validate:"required"` JsonSchema string `json:"json_schema"` UiSchema string `json:"ui_schema"` Data map[string]any `json:"data"` Deleted bool `json:"deleted"` } func (h *ApplicationHandler) DiagsHome(w http.ResponseWriter, r *http.Request) { resp, err := h.services.GRPC.Diags.GetDiags(context.TODO(), &diags.GetDiagsRequest{ Namespaces: []string{"parcoursmob_beneficiaries", "parcoursmob_diagnostiques", "parcoursmob_vehicles", "parcoursmob_bookings"}, // Mindate: timestamppb.New(time.Now().Add(-24 * time.Hour)), }) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } responses := []diagsstorage.Diag{} for _, e := range resp.Diags { responses = append(responses, e.ToStorageType()) } h.Renderer.DiagsHome(w, r, responses) } func (h *ApplicationHandler) DiagsHistory(w http.ResponseWriter, r *http.Request) { resp, err := h.services.GRPC.Diags.GetDiags(context.TODO(), &diags.GetDiagsRequest{ Namespaces: []string{"parcoursmob_beneficiaries", "parcoursmob_diagnostiques", "parcoursmob_vehicles", "parcoursmob_bookings"}, //Maxdate: timestamppb.New(time.Now().Add(24 * time.Hour)), }) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } responses := []diagsstorage.Diag{} for _, e := range resp.Diags { responses = append(responses, e.ToStorageType()) } h.Renderer.DiagsHistory(w, r, responses) } func (h *ApplicationHandler) BeneficiariesCreateDiag(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) beneficiaryID := vars["beneficiaryid"] if h.services == nil || (h.services.GRPC == services.GRPCServices{}) || h.services.GRPC.Diags == nil { log.Error().Msg("Diags service is not initialized") http.Error(w, "Internal server error", http.StatusInternalServerError) return } if r.Method == http.MethodPost { g := r.Context().Value(identification.GroupKey) if g == nil { http.Error(w, "Missing group information", http.StatusBadRequest) return } diagForm, err := parseDiagsForm(r) if err != nil { log.Error().Err(err).Msg("Invalid form data") http.Error(w, err.Error(), http.StatusBadRequest) return } log.Debug().Interface("diagForm", diagForm).Msg("Form data parsed") data, err := structpb.NewStruct(map[string]any{ "beneficiary": beneficiaryID, }) if err != nil { log.Error().Err(err).Msg("Failed to create protobuf struct") w.WriteHeader(http.StatusInternalServerError) return } request := &diags.CreateDiagRequest{ Diag: &diags.Diag{ Name: diagForm.Name, Namespace: diagForm.Namespace, JsonSchema: diagForm.JsonSchema, UiSchema: diagForm.UiSchema, Data: data, Deleted: diagForm.Deleted, }, } resp, err := h.services.GRPC.Diags.CreateDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("Failed to create diagnostic") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/diags/%s", resp.Diag.Id), http.StatusFound) return } h.Renderer.BeneficiariesCreateDiag(w, r, beneficiaryID) } func (h *ApplicationHandler) VehiclesCreateDiag(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) vehicleID := vars["vehicleid"] if h.services == nil || (h.services.GRPC == services.GRPCServices{}) || h.services.GRPC.Diags == nil { log.Error().Msg("Diags service is not initialized") http.Error(w, "Internal server error", http.StatusInternalServerError) return } if r.Method == http.MethodPost { g := r.Context().Value(identification.GroupKey) if g == nil { http.Error(w, "Missing group information", http.StatusBadRequest) return } diagForm, err := parseDiagsForm(r) if err != nil { log.Error().Err(err).Msg("Invalid form data") http.Error(w, err.Error(), http.StatusBadRequest) return } log.Debug().Interface("diagForm", diagForm).Msg("Form data parsed") data, err := structpb.NewStruct(map[string]any{ "vehicle": vehicleID, }) if err != nil { log.Error().Err(err).Msg("Failed to create protobuf struct") w.WriteHeader(http.StatusInternalServerError) return } request := &diags.CreateDiagRequest{ Diag: &diags.Diag{ Name: diagForm.Name, Namespace: diagForm.Namespace, JsonSchema: diagForm.JsonSchema, UiSchema: diagForm.UiSchema, Data: data, Deleted: diagForm.Deleted, }, } resp, err := h.services.GRPC.Diags.CreateDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("Failed to create diagnostic") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/diags/%s", resp.Diag.Id), http.StatusFound) return } h.Renderer.VehiclesCreateDiag(w, r, vehicleID) } func (h *ApplicationHandler) BookingsCreateDiag(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bookingID := vars["bookingid"] if h.services == nil || (h.services.GRPC == services.GRPCServices{}) || h.services.GRPC.Diags == nil { log.Error().Msg("Diags service is not initialized") http.Error(w, "Internal server error", http.StatusInternalServerError) return } if r.Method == http.MethodPost { g := r.Context().Value(identification.GroupKey) if g == nil { http.Error(w, "Missing group information", http.StatusBadRequest) return } diagForm, err := parseDiagsForm(r) if err != nil { log.Error().Err(err).Msg("Invalid form data") http.Error(w, err.Error(), http.StatusBadRequest) return } log.Debug().Interface("diagForm", diagForm).Msg("Form data parsed") data, err := structpb.NewStruct(map[string]any{ "booking": bookingID, }) if err != nil { log.Error().Err(err).Msg("Failed to create protobuf struct") w.WriteHeader(http.StatusInternalServerError) return } request := &diags.CreateDiagRequest{ Diag: &diags.Diag{ Name: diagForm.Name, Namespace: diagForm.Namespace, JsonSchema: diagForm.JsonSchema, UiSchema: diagForm.UiSchema, Data: data, Deleted: diagForm.Deleted, }, } resp, err := h.services.GRPC.Diags.CreateDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("Failed to create diagnostic") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/diags/%s", resp.Diag.Id), http.StatusFound) return } h.Renderer.BookingsCreateDiag(w, r, bookingID) } func (h *ApplicationHandler) VehicleBookingsCreateDiag(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bookingID := vars["bookingid"] if h.services == nil || (h.services.GRPC == services.GRPCServices{}) || h.services.GRPC.Diags == nil { log.Error().Msg("Diags service is not initialized") http.Error(w, "Internal server error", http.StatusInternalServerError) return } if r.Method == http.MethodPost { g := r.Context().Value(identification.GroupKey) if g == nil { http.Error(w, "Missing group information", http.StatusBadRequest) return } diagForm, err := parseDiagsForm(r) if err != nil { log.Error().Err(err).Msg("Invalid form data") http.Error(w, err.Error(), http.StatusBadRequest) return } log.Debug().Interface("diagForm", diagForm).Msg("Form data parsed") data, err := structpb.NewStruct(map[string]any{ "booking": bookingID, }) if err != nil { log.Error().Err(err).Msg("Failed to create protobuf struct") w.WriteHeader(http.StatusInternalServerError) return } request := &diags.CreateDiagRequest{ Diag: &diags.Diag{ Name: diagForm.Name, Namespace: diagForm.Namespace, JsonSchema: diagForm.JsonSchema, UiSchema: diagForm.UiSchema, Data: data, Deleted: diagForm.Deleted, }, } resp, err := h.services.GRPC.Diags.CreateDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("Failed to create diagnostic") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/diags/%s", resp.Diag.Id), http.StatusFound) return } h.Renderer.VehicleBookingsCreateDiag(w, r, bookingID) } func (h *ApplicationHandler) DiagsDisplayDiag(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) diagid := vars["diagid"] request := &diags.GetDiagRequest{ Id: diagid, } resp, err := h.services.GRPC.Diags.GetDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } g := r.Context().Value(identification.GroupKey) if g == nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } h.Renderer.DiagsDisplayDiag(w, r, resp.Diag.ToStorageType()) } func parseDiagsForm(r *http.Request) (*DiagsForm, error) { if err := r.ParseForm(); err != nil { return nil, err } formData := &DiagsForm{ Name: r.PostFormValue("name"), Namespace: r.PostFormValue("namespace"), // Récupère le namespace JsonSchema: r.PostFormValue("json_schema"), UiSchema: r.PostFormValue("ui_schema"), Deleted: false, } if formData.Name == "" || formData.Namespace == "" { return nil, errors.New("missing required fields: 'name' or 'namespace'") } // Gestion de la valeur JSON dans `data` if rawData := r.PostFormValue("data"); rawData != "" { data := map[string]any{} if err := json.Unmarshal([]byte(rawData), &data); err != nil { return nil, errors.New("invalid 'data' field: must be a valid JSON object") } formData.Data = data } return formData, nil } func (h *ApplicationHandler) DiagUpdate(w http.ResponseWriter, r *http.Request) { adm := strings.Split(r.URL.Path, "/") diagID := adm[3] request := &diags.GetDiagRequest{ Id: diagID, } resp, err := h.services.GRPC.Diags.GetDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } if r.Method == "POST" { g := r.Context().Value(identification.GroupKey) if g == nil { w.WriteHeader(http.StatusBadRequest) return } diagForm, err := parseDiagsForm(r) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusBadRequest) return } data, _ := structpb.NewStruct(map[string]any{}) request := &diags.UpdateDiagRequest{ Diag: &diags.Diag{ Namespace: diagForm.Namespace, Id: diagID, Name: diagForm.Name, JsonSchema: diagForm.JsonSchema, UiSchema: diagForm.UiSchema, Data: data, }, } resp, err := h.services.GRPC.Diags.UpdateDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/diags/%s", resp.Diag.Id), http.StatusFound) return } h.Renderer.DiagUpdate(w, r, resp.Diag.ToStorageType()) } func (h *ApplicationHandler) DiagDelete(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) diagID := vars["diagid"] request := &diags.GetDiagRequest{ Id: diagID, } resp, err := h.services.GRPC.Diags.GetDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } if r.Method == "POST" { request := &diags.UpdateDiagRequest{ Diag: &diags.Diag{ Namespace: resp.Diag.Namespace, Id: resp.Diag.Id, Name: resp.Diag.Name, JsonSchema: resp.Diag.JsonSchema, UiSchema: resp.Diag.UiSchema, Data: resp.Diag.Data, Deleted: true, }, } _, err := h.services.GRPC.Diags.UpdateDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, "/app/diags/", http.StatusFound) return } h.Renderer.DiagDelete(w, r, resp.Diag.ToStorageType()) } func (h *ApplicationHandler) DiagsHistoryDiag(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) diagId := vars["diagid"] request := &diags.GetDiagRequest{ Id: diagId, } resp, err := h.services.GRPC.Diags.GetDiag(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } h.Renderer.DiagsHistoryDiag(w, r, resp.Diag.ToStorageType()) }