Add district resource and an API to RMO
We're going to need an API for the single-page frontend
This commit is contained in:
parent
4f9617aa2f
commit
bfecae7d61
9 changed files with 114 additions and 16 deletions
|
|
@ -110,9 +110,10 @@ func authenticatedHandlerJSON[T any](f handlerFunctionGet[T]) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
type handlerFunctionGetSlice[T any] func(context.Context, *http.Request, platform.User, resource.QueryParams) ([]*T, *nhttp.ErrorWithStatus)
|
||||
type handlerFunctionGetSlice[T any] func(context.Context, *http.Request, resource.QueryParams) ([]*T, *nhttp.ErrorWithStatus)
|
||||
type handlerFunctionGetSliceAuthenticated[T any] func(context.Context, *http.Request, platform.User, resource.QueryParams) ([]*T, *nhttp.ErrorWithStatus)
|
||||
|
||||
func authenticatedHandlerJSONSlice[T any](f handlerFunctionGetSlice[T]) http.Handler {
|
||||
func authenticatedHandlerJSONSlice[T any](f handlerFunctionGetSliceAuthenticated[T]) http.Handler {
|
||||
return auth.NewEnsureAuth(func(w http.ResponseWriter, r *http.Request, u platform.User) {
|
||||
ctx := r.Context()
|
||||
var body []byte
|
||||
|
|
@ -146,6 +147,40 @@ func authenticatedHandlerJSONSlice[T any](f handlerFunctionGetSlice[T]) http.Han
|
|||
w.Write(body)
|
||||
})
|
||||
}
|
||||
func handlerJSONSlice[T any](f handlerFunctionGetSlice[T]) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var body []byte
|
||||
var params resource.QueryParams
|
||||
err := decoder.Decode(¶ms, r.URL.Query())
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("decode query failure")
|
||||
http.Error(w, "failed to decode query", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
resp, e := f(ctx, r, params)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
//log.Info().Str("template", template).Err(e).Msg("handler done")
|
||||
if e != nil {
|
||||
log.Warn().Int("status", e.Status).Err(e).Str("user message", e.Message).Msg("Responding with an error from api")
|
||||
body, err = json.Marshal(ErrorAPI{Message: e.Error()})
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to marshal error")
|
||||
http.Error(w, "{\"message\": \"boom. I can't even tell you what went wrong\"}", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
http.Error(w, string(body), e.Status)
|
||||
return
|
||||
}
|
||||
body, err = json.Marshal(resp)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to marshal json")
|
||||
http.Error(w, "{\"message\": \"failed to marshal json\"}", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Write(body)
|
||||
}
|
||||
}
|
||||
|
||||
type handlerFunctionPost[ReqType any] func(context.Context, *http.Request, ReqType) (string, *nhttp.ErrorWithStatus)
|
||||
type handlerFunctionPostAuthenticated[RequestType any, ResponseType any] func(context.Context, *http.Request, platform.User, RequestType) (ResponseType, *nhttp.ErrorWithStatus)
|
||||
|
|
|
|||
|
|
@ -66,8 +66,10 @@ func AddRoutes(r *mux.Router) {
|
|||
r.Handle("/user/{id}", authenticatedHandlerJSONPut(user.ByIDPut)).Methods("PUT")
|
||||
|
||||
// Unauthenticated endpoints
|
||||
r.HandleFunc("/district", apiGetDistrict).Methods("GET")
|
||||
r.HandleFunc("/district/{slug}/logo", apiGetDistrictLogo).Methods("GET")
|
||||
district := resource.District(router)
|
||||
r.Handle("/district", handlerJSONSlice(district.List)).Methods("GET")
|
||||
//r.HandleFunc("/district", apiGetDistrict).Methods("GET")
|
||||
r.HandleFunc("/district/{slug}/logo", apiGetDistrictLogo).Methods("GET").Name("district.logo.BySlug")
|
||||
r.HandleFunc("/compliance-request/image/pool/{public_id}", getComplianceRequestImagePool).Methods("GET")
|
||||
r.HandleFunc("/twilio/call", twilioCallPost).Methods("POST")
|
||||
r.HandleFunc("/twilio/call/status", twilioCallStatusPost).Methods("POST")
|
||||
|
|
|
|||
6
main.go
6
main.go
|
|
@ -120,7 +120,13 @@ func main() {
|
|||
|
||||
// Set up routing by hostname
|
||||
nidussync.Router(sync_router)
|
||||
sync_api_router := sync_router.PathPrefix("/api").Subrouter()
|
||||
api.AddRoutes(sync_api_router)
|
||||
|
||||
rmo.Router(rmo_router)
|
||||
rmo_api_router := rmo_router.PathPrefix("/api").Subrouter()
|
||||
api.AddRoutes(rmo_api_router)
|
||||
|
||||
//hr.Map("", sr) // default
|
||||
//hr.Map("*", sr) // default
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ func (o Organization) ServiceRequestRecent(ctx context.Context) ([]*models.Field
|
|||
}
|
||||
return results, nil
|
||||
}
|
||||
func (o Organization) Slug() string {
|
||||
return o.model.Slug.GetOr("")
|
||||
}
|
||||
func OrganizationByID(ctx context.Context, id int) (*Organization, error) {
|
||||
org, err := models.FindOrganization(ctx, db.PGInstance.BobDB, int32(id))
|
||||
if err != nil {
|
||||
|
|
@ -94,10 +97,7 @@ func OrganizationByID(ctx context.Context, id int) (*Organization, error) {
|
|||
o := newOrganization(org)
|
||||
return &o, nil
|
||||
}
|
||||
func OrganizationList(ctx context.Context, user User) ([]*Organization, error) {
|
||||
if !user.HasRoot() {
|
||||
return []*Organization{&user.Organization}, nil
|
||||
}
|
||||
func OrganizationList(ctx context.Context) ([]*Organization, error) {
|
||||
rows, err := models.Organizations.Query().All(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("query orgs: %w", err)
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ func UserList(ctx context.Context, user User) ([]*User, error) {
|
|||
var orgByID map[int32]*Organization
|
||||
if user.HasRoot() {
|
||||
query = models.Users.Query()
|
||||
orgs, err := OrganizationList(ctx, user)
|
||||
orgs, err := OrganizationList(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("org list: %w", err)
|
||||
}
|
||||
|
|
|
|||
47
resource/district.go
Normal file
47
resource/district.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/platform"
|
||||
"net/http"
|
||||
//"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type districtR struct {
|
||||
router *router
|
||||
}
|
||||
|
||||
type district struct {
|
||||
Name string `json:"name"`
|
||||
URLLogo string `json:"url_logo"`
|
||||
}
|
||||
|
||||
func District(r *router) *districtR {
|
||||
return &districtR{
|
||||
router: r,
|
||||
}
|
||||
}
|
||||
|
||||
func (res *districtR) List(ctx context.Context, r *http.Request, query QueryParams) ([]*district, *nhttp.ErrorWithStatus) {
|
||||
organizations, err := platform.OrganizationList(ctx)
|
||||
if err != nil {
|
||||
return nil, nhttp.NewError("list orgs: %w", err)
|
||||
}
|
||||
districts := make([]*district, 0)
|
||||
for _, org := range organizations {
|
||||
slug := org.Slug()
|
||||
if slug == "" {
|
||||
continue
|
||||
}
|
||||
logo, err := res.router.SlugToURI("district.logo.BySlug", slug)
|
||||
if err != nil {
|
||||
return nil, nhttp.NewError("logo url: %w", err)
|
||||
}
|
||||
districts = append(districts, &district{
|
||||
Name: org.Name(),
|
||||
URLLogo: logo,
|
||||
})
|
||||
}
|
||||
return districts, nil
|
||||
}
|
||||
|
|
@ -59,6 +59,18 @@ func (r *router) IDToURI(route string, id int) (string, error) {
|
|||
uri.Scheme = "https"
|
||||
return uri.String(), nil
|
||||
}
|
||||
func (r *router) SlugToURI(route string, slug string) (string, error) {
|
||||
handler := r.router.Get(route)
|
||||
if handler == nil {
|
||||
return "", fmt.Errorf("nil handler '%s'", route)
|
||||
}
|
||||
uri, err := handler.URL("slug", slug)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("build uri: %w", err)
|
||||
}
|
||||
uri.Scheme = "https"
|
||||
return uri.String(), nil
|
||||
}
|
||||
|
||||
func (r *router) UUIDToURI(route string, u *uuid.UUID) (*string, error) {
|
||||
if u == nil {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package sync
|
||||
|
||||
import (
|
||||
"github.com/Gleipnir-Technology/nidus-sync/api"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/static"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
|
@ -36,9 +35,6 @@ func Router(r *mux.Router) {
|
|||
r.HandleFunc("/qr-code/mailer/{code}", getQRCodeMailer)
|
||||
r.HandleFunc("/template-test", getTemplateTest)
|
||||
|
||||
api_router := r.PathPrefix("/api").Subrouter()
|
||||
api.AddRoutes(api_router)
|
||||
|
||||
r.HandleFunc("/", getRoot)
|
||||
r.HandleFunc("/_/*", getRoot)
|
||||
|
||||
|
|
|
|||
|
|
@ -60,12 +60,12 @@ export default defineConfig({
|
|||
server: {
|
||||
allowedHosts: ["poweredge.local", "dev-report.mosquitoes.online"],
|
||||
port: 9001,
|
||||
/*proxy: {
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: "http://127.0.0.1:9002",
|
||||
target: "http://127.0.0.1:9003",
|
||||
changeOrigin: false,
|
||||
},
|
||||
},*/
|
||||
},
|
||||
strictPort: true,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue