package client import ( "errors" "github.com/gofiber/fiber/v2" "github.com/jackc/pgx/v5" "github.com/techxcar/backend/internal/auth" "github.com/techxcar/backend/pkg/database" ) func RegisterRoutes(app *fiber.App, db *database.DB, secret string) { rw := []fiber.Handler{ auth.RequireAuth(secret), auth.RequireRole("tenant_admin", "manager", "technician"), auth.TenantMiddleware(db), } write := []fiber.Handler{ auth.RequireAuth(secret), auth.RequireRole("tenant_admin", "manager"), auth.TenantMiddleware(db), } app.Get("/api/v1/clients", append(rw, listClientsH())...) app.Post("/api/v1/clients", append(write, createClientH())...) app.Get("/api/v1/clients/:id", append(rw, getClientH())...) app.Put("/api/v1/clients/:id", append(write, updateClientH())...) app.Delete("/api/v1/clients/:id", append(write, deleteClientH())...) app.Get("/api/v1/clients/:id/vehicles", append(rw, listVehiclesH())...) app.Post("/api/v1/clients/:id/vehicles", append(write, createVehicleH())...) app.Put("/api/v1/vehicles/:id", append(write, updateVehicleH())...) } func listClientsH() fiber.Handler { return func(c *fiber.Ctx) error { conn := auth.GetConn(c) list, err := ListClients(c.Context(), conn) if err != nil { return fiber.NewError(500, "erro ao listar clientes") } if list == nil { list = []*Client{} } return c.JSON(fiber.Map{"data": list, "error": nil}) } } func getClientH() fiber.Handler { return func(c *fiber.Ctx) error { conn := auth.GetConn(c) cl, err := GetClient(c.Context(), conn, c.Params("id")) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return fiber.NewError(404, "cliente não encontrado") } return fiber.NewError(500, "erro ao obter cliente") } return c.JSON(fiber.Map{"data": cl, "error": nil}) } } type clientBody struct { Name string `json:"name"` NIF string `json:"nif"` Phone string `json:"phone"` Email string `json:"email"` Address string `json:"address"` Notes string `json:"notes"` } func createClientH() fiber.Handler { return func(c *fiber.Ctx) error { var b clientBody if err := c.BodyParser(&b); err != nil { return fiber.NewError(400, "corpo inválido") } if b.Name == "" { return fiber.NewError(400, "nome é obrigatório") } conn := auth.GetConn(c) cl, err := CreateClient(c.Context(), conn, b.Name, b.NIF, b.Phone, b.Email, b.Address, b.Notes) if err != nil { return fiber.NewError(500, "erro ao criar cliente") } return c.Status(201).JSON(fiber.Map{"data": cl, "error": nil}) } } func updateClientH() fiber.Handler { return func(c *fiber.Ctx) error { var b clientBody if err := c.BodyParser(&b); err != nil { return fiber.NewError(400, "corpo inválido") } if b.Name == "" { return fiber.NewError(400, "nome é obrigatório") } conn := auth.GetConn(c) cl, err := UpdateClient(c.Context(), conn, c.Params("id"), b.Name, b.NIF, b.Phone, b.Email, b.Address, b.Notes) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return fiber.NewError(404, "cliente não encontrado") } return fiber.NewError(500, "erro ao actualizar cliente") } return c.JSON(fiber.Map{"data": cl, "error": nil}) } } func deleteClientH() fiber.Handler { return func(c *fiber.Ctx) error { conn := auth.GetConn(c) if err := DeleteClient(c.Context(), conn, c.Params("id")); err != nil { return fiber.NewError(500, "erro ao eliminar cliente") } return c.SendStatus(204) } } func listVehiclesH() fiber.Handler { return func(c *fiber.Ctx) error { conn := auth.GetConn(c) list, err := ListVehiclesByClient(c.Context(), conn, c.Params("id")) if err != nil { return fiber.NewError(500, "erro ao listar veículos") } if list == nil { list = []*Vehicle{} } return c.JSON(fiber.Map{"data": list, "error": nil}) } } type vehicleBody struct { Plate string `json:"plate"` Brand string `json:"brand"` Model string `json:"model"` Year int `json:"year"` VIN string `json:"vin"` FuelType string `json:"fuel_type"` Mileage int `json:"mileage"` Notes string `json:"notes"` } func createVehicleH() fiber.Handler { return func(c *fiber.Ctx) error { var b vehicleBody if err := c.BodyParser(&b); err != nil { return fiber.NewError(400, "corpo inválido") } if b.Plate == "" { return fiber.NewError(400, "matrícula é obrigatória") } conn := auth.GetConn(c) v, err := CreateVehicle(c.Context(), conn, c.Params("id"), b.Plate, b.Brand, b.Model, b.Year, b.VIN, b.FuelType, b.Notes, b.Mileage) if err != nil { return fiber.NewError(500, "erro ao criar veículo") } return c.Status(201).JSON(fiber.Map{"data": v, "error": nil}) } } func updateVehicleH() fiber.Handler { return func(c *fiber.Ctx) error { var b vehicleBody if err := c.BodyParser(&b); err != nil { return fiber.NewError(400, "corpo inválido") } if b.Plate == "" { return fiber.NewError(400, "matrícula é obrigatória") } conn := auth.GetConn(c) v, err := UpdateVehicle(c.Context(), conn, c.Params("id"), b.Plate, b.Brand, b.Model, b.Year, b.VIN, b.FuelType, b.Notes, b.Mileage) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return fiber.NewError(404, "veículo não encontrado") } return fiber.NewError(500, "erro ao actualizar veículo") } return c.JSON(fiber.Map{"data": v, "error": nil}) } }