func ModuleDELETE(w http.ResponseWriter, _ *http.Request, ps httprouter.Params) {
	id := ps.ByName("id")
	if err := module.Remove(id); err != nil {
		handleError(err, w)
		return
	}
	logger.Infof("Module %s removed", id)
	w.WriteHeader(http.StatusNoContent)
}
ModuleDELETE handles a DELETE request on a module entity endpoint
package controller
import (
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"github.com/tarkov-database/rest-api/model"
	"github.com/tarkov-database/rest-api/model/hideout/module"
	"github.com/tarkov-database/rest-api/model/hideout/production"
	"github.com/tarkov-database/rest-api/view"
	"github.com/google/logger"
	"github.com/julienschmidt/httprouter"
)
func ModuleGET(w http.ResponseWriter, _ *http.Request, ps httprouter.Params) {
	mod, err := module.GetByID(ps.ByName("id"))
	if err != nil {
		handleError(err, w)
		return
	}
	view.RenderJSON(mod, http.StatusOK, w)
}
func ModulesGET(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var result *model.Result
	var err error
	opts := &module.Options{Sort: getSort("-_modified", r)}
	opts.Limit, opts.Offset = getLimitOffset(r)
Loop:
	for p, v := range r.URL.Query() {
		switch p {
		case "id":
			q, err := url.QueryUnescape(v[0])
			if err != nil {
				StatusBadRequest(fmt.Sprintf("Query string error: %s", err)).Render(w)
				return
			}
			if len(q) < 24 {
				StatusBadRequest("ID is not valid").Render(w)
				return
			}
			ids := strings.Split(q, ",")
			if len(ids) > 100 {
				StatusBadRequest("ID limit exceeded").Render(w)
				return
			}
			result, err = module.GetByIDs(ids, opts)
			if err != nil {
				var res *Status
				switch err {
				case model.ErrInvalidInput:
					res = StatusUnprocessableEntity("Query contains an invalid ID")
				case model.ErrInternalError:
					res = StatusInternalServerError("Network or database error")
				default:
					res = StatusInternalServerError("Internal error")
				}
				res.Render(w)
				return
			}
			break Loop
		case "text":
			txt, err := url.QueryUnescape(v[0])
			if err != nil {
				StatusBadRequest(fmt.Sprintf("Query string error: %s", err)).Render(w)
				return
			}
			if l := len(txt); l < 3 || l > 32 {
				StatusBadRequest("Query string has an invalid length").Render(w)
				return
			}
			if !isAlnumBlankPunct(txt) {
				StatusBadRequest("Query string contains invalid characters").Render(w)
				return
			}
			result, err = module.GetByText(txt, opts)
			if err != nil {
				handleError(err, w)
				return
			}
			break Loop
		case "material":
			mat, err := url.QueryUnescape(v[0])
			if err != nil {
				StatusBadRequest(fmt.Sprintf("Query string error: %s", err)).Render(w)
				return
			}
			result, err = module.GetByMaterial(mat, opts)
			if err != nil {
				handleError(err, w)
				return
			}
			break Loop
		}
	}
	if result == nil {
		result, err = module.GetAll(opts)
		if err != nil {
			handleError(err, w)
			return
		}
	}
	view.RenderJSON(result, http.StatusOK, w)
}
func ModulePOST(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	if !isSupportedMediaType(r) {
		StatusUnsupportedMediaType("Wrong content type").Render(w)
		return
	}
	mod := &module.Module{}
	if err := parseJSONBody(r.Body, mod); err != nil {
		StatusBadRequest(fmt.Sprintf("JSON parsing error: %s", err)).Render(w)
		return
	}
	if err := mod.Validate(); err != nil {
		StatusUnprocessableEntity(fmt.Sprintf("Validation error: %s", err)).Render(w)
		return
	}
	if err := module.Create(mod); err != nil {
		handleError(err, w)
		return
	}
	logger.Infof("Module %s created", mod.ID.Hex())
	view.RenderJSON(mod, http.StatusCreated, w)
}
func ModulePUT(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	if !isSupportedMediaType(r) {
		StatusUnsupportedMediaType("Wrong content type").Render(w)
		return
	}
	mod := &module.Module{}
	if err := parseJSONBody(r.Body, mod); err != nil {
		StatusBadRequest(fmt.Sprintf("JSON parsing error: %s", err)).Render(w)
		return
	}
	if err := mod.Validate(); err != nil {
		StatusUnprocessableEntity(fmt.Sprintf("Validation error: %s", err)).Render(w)
		return
	}
	id := ps.ByName("id")
	if !mod.ID.IsZero() && mod.ID.Hex() != id {
		StatusUnprocessableEntity("ID mismatch").Render(w)
		return
	}
	if err := module.Replace(id, mod); err != nil {
		handleError(err, w)
		return
	}
	logger.Infof("Module %s updated", mod.ID.Hex())
	view.RenderJSON(mod, http.StatusOK, w)
}