location endpoints

This commit is contained in:
Hayden 2022-08-30 21:22:01 -08:00
parent 9583847f94
commit c7cfb4335b
10 changed files with 395 additions and 51 deletions

View file

@ -261,6 +261,78 @@ const docTemplate = `{
} }
} }
}, },
"/v1/locations": {
"get": {
"security": [
{
"Bearer": []
}
],
"produces": [
"application/json"
],
"tags": [
"Locations"
],
"summary": "Get All Locations",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/server.Results"
},
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/types.LocationOut"
}
}
}
}
]
}
}
}
},
"post": {
"security": [
{
"Bearer": []
}
],
"produces": [
"application/json"
],
"tags": [
"Locations"
],
"summary": "Create a new location",
"parameters": [
{
"description": "Location Data",
"name": "payload",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/types.LocationCreate"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/types.LocationOut"
}
}
}
}
},
"/v1/users/login": { "/v1/users/login": {
"post": { "post": {
"consumes": [ "consumes": [
@ -358,23 +430,8 @@ const docTemplate = `{
} }
], ],
"responses": { "responses": {
"200": { "204": {
"description": "OK", "description": ""
"schema": {
"allOf": [
{
"$ref": "#/definitions/server.Result"
},
{
"type": "object",
"properties": {
"item": {
"$ref": "#/definitions/ent.User"
}
}
}
]
}
} }
} }
} }
@ -908,6 +965,14 @@ const docTemplate = `{
} }
} }
}, },
"server.Results": {
"type": "object",
"properties": {
"items": {
"type": "any"
}
}
},
"types.ApiSummary": { "types.ApiSummary": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -928,6 +993,40 @@ const docTemplate = `{
} }
} }
}, },
"types.LocationCreate": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"types.LocationOut": {
"type": "object",
"properties": {
"createdAt": {
"type": "string"
},
"description": {
"type": "string"
},
"groupId": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"updatedAt": {
"type": "string"
}
}
},
"types.TokenResponse": { "types.TokenResponse": {
"type": "object", "type": "object",
"properties": { "properties": {

View file

@ -253,6 +253,78 @@
} }
} }
}, },
"/v1/locations": {
"get": {
"security": [
{
"Bearer": []
}
],
"produces": [
"application/json"
],
"tags": [
"Locations"
],
"summary": "Get All Locations",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/server.Results"
},
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/types.LocationOut"
}
}
}
}
]
}
}
}
},
"post": {
"security": [
{
"Bearer": []
}
],
"produces": [
"application/json"
],
"tags": [
"Locations"
],
"summary": "Create a new location",
"parameters": [
{
"description": "Location Data",
"name": "payload",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/types.LocationCreate"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/types.LocationOut"
}
}
}
}
},
"/v1/users/login": { "/v1/users/login": {
"post": { "post": {
"consumes": [ "consumes": [
@ -350,23 +422,8 @@
} }
], ],
"responses": { "responses": {
"200": { "204": {
"description": "OK", "description": ""
"schema": {
"allOf": [
{
"$ref": "#/definitions/server.Result"
},
{
"type": "object",
"properties": {
"item": {
"$ref": "#/definitions/ent.User"
}
}
}
]
}
} }
} }
} }
@ -900,6 +957,14 @@
} }
} }
}, },
"server.Results": {
"type": "object",
"properties": {
"items": {
"type": "any"
}
}
},
"types.ApiSummary": { "types.ApiSummary": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -920,6 +985,40 @@
} }
} }
}, },
"types.LocationCreate": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"types.LocationOut": {
"type": "object",
"properties": {
"createdAt": {
"type": "string"
},
"description": {
"type": "string"
},
"groupId": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"updatedAt": {
"type": "string"
}
}
},
"types.TokenResponse": { "types.TokenResponse": {
"type": "object", "type": "object",
"properties": { "properties": {

View file

@ -320,6 +320,11 @@ definitions:
message: message:
type: string type: string
type: object type: object
server.Results:
properties:
items:
type: any
type: object
types.ApiSummary: types.ApiSummary:
properties: properties:
health: health:
@ -333,6 +338,28 @@ definitions:
type: string type: string
type: array type: array
type: object type: object
types.LocationCreate:
properties:
description:
type: string
name:
type: string
type: object
types.LocationOut:
properties:
createdAt:
type: string
description:
type: string
groupId:
type: string
id:
type: string
name:
type: string
updatedAt:
type: string
type: object
types.TokenResponse: types.TokenResponse:
properties: properties:
expiresAt: expiresAt:
@ -522,6 +549,47 @@ paths:
summary: Update a User summary: Update a User
tags: tags:
- 'Admin: Users' - 'Admin: Users'
/v1/locations:
get:
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/server.Results'
- properties:
items:
items:
$ref: '#/definitions/types.LocationOut'
type: array
type: object
security:
- Bearer: []
summary: Get All Locations
tags:
- Locations
post:
parameters:
- description: Location Data
in: body
name: payload
required: true
schema:
$ref: '#/definitions/types.LocationCreate'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/types.LocationOut'
security:
- Bearer: []
summary: Create a new location
tags:
- Locations
/v1/users/login: /v1/users/login:
post: post:
consumes: consumes:
@ -583,15 +651,8 @@ paths:
produces: produces:
- application/json - application/json
responses: responses:
"200": "204":
description: OK description: ""
schema:
allOf:
- $ref: '#/definitions/server.Result'
- properties:
item:
$ref: '#/definitions/ent.User'
type: object
summary: Get the current user summary: Get the current user
tags: tags:
- User - User

View file

@ -49,6 +49,9 @@ func (a *app) newRouter(repos *repo.AllRepos) *chi.Mux {
r.Put(v1Base("/users/self/password"), v1Handlers.HandleUserUpdatePassword()) r.Put(v1Base("/users/self/password"), v1Handlers.HandleUserUpdatePassword())
r.Post(v1Base("/users/logout"), v1Handlers.HandleAuthLogout()) r.Post(v1Base("/users/logout"), v1Handlers.HandleAuthLogout())
r.Get(v1Base("/users/refresh"), v1Handlers.HandleAuthRefresh()) r.Get(v1Base("/users/refresh"), v1Handlers.HandleAuthRefresh())
r.Get(v1Base("/locations"), v1Handlers.HandleLocationGetAll())
r.Post(v1Base("/locations"), v1Handlers.HandleLocationCreate())
}) })
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {

View file

@ -0,0 +1,59 @@
package v1
import (
"net/http"
"github.com/hay-kot/content/backend/internal/services"
"github.com/hay-kot/content/backend/internal/types"
"github.com/hay-kot/content/backend/pkgs/server"
)
// HandleUserSelf godoc
// @Summary Get All Locations
// @Tags Locations
// @Produce json
// @Success 200 {object} server.Results{items=[]types.LocationOut}
// @Router /v1/locations [GET]
// @Security Bearer
func (ctrl *V1Controller) HandleLocationGetAll() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
user := services.UseUserCtx(r.Context())
locations, err := ctrl.svc.Location.GetAll(r.Context(), user.GroupID)
if err != nil {
ctrl.log.Error(err, nil)
server.RespondServerError(w)
return
}
server.Respond(w, http.StatusOK, server.Results{Items: locations})
}
}
// HandleUserSelf godoc
// @Summary Create a new location
// @Tags Locations
// @Produce json
// @Param payload body types.LocationCreate true "Location Data"
// @Success 200 {object} types.LocationOut
// @Router /v1/locations [POST]
// @Security Bearer
func (ctrl *V1Controller) HandleLocationCreate() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
createData := types.LocationCreate{}
if err := server.Decode(r, &createData); err != nil {
ctrl.log.Error(err, nil)
server.RespondError(w, http.StatusInternalServerError, err)
return
}
user := services.UseUserCtx(r.Context())
location, err := ctrl.svc.Location.Create(r.Context(), user.GroupID, createData)
if err != nil {
ctrl.log.Error(err, nil)
server.RespondServerError(w)
return
}
server.Respond(w, http.StatusCreated, location)
}
}

View file

@ -15,8 +15,8 @@ import (
// @Summary Get the current user // @Summary Get the current user
// @Tags User // @Tags User
// @Produce json // @Produce json
// @Param payload body types.UserRegistration true "User Data" // @Param payload body types.UserRegistration true "User Data"
// @Success 200 {object} server.Result{item=ent.User} // @Success 204
// @Router /v1/users/register [Post] // @Router /v1/users/register [Post]
func (ctrl *V1Controller) HandleUserRegistration() http.HandlerFunc { func (ctrl *V1Controller) HandleUserRegistration() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {

View file

@ -21,6 +21,7 @@ func (r *EntLocationRepository) Get(ctx context.Context, ID uuid.UUID) (*ent.Loc
func (r *EntLocationRepository) GetAll(ctx context.Context, groupId uuid.UUID) ([]*ent.Location, error) { func (r *EntLocationRepository) GetAll(ctx context.Context, groupId uuid.UUID) ([]*ent.Location, error) {
return r.db.Location.Query(). return r.db.Location.Query().
Where(location.HasGroupWith(group.ID(groupId))). Where(location.HasGroupWith(group.ID(groupId))).
WithGroup().
All(ctx) All(ctx)
} }

View file

@ -3,13 +3,15 @@ package services
import "github.com/hay-kot/content/backend/internal/repo" import "github.com/hay-kot/content/backend/internal/repo"
type AllServices struct { type AllServices struct {
User *UserService User *UserService
Admin *AdminService Admin *AdminService
Location *LocationService
} }
func NewServices(repos *repo.AllRepos) *AllServices { func NewServices(repos *repo.AllRepos) *AllServices {
return &AllServices{ return &AllServices{
User: &UserService{repos}, User: &UserService{repos},
Admin: &AdminService{repos}, Admin: &AdminService{repos},
Location: &LocationService{repos},
} }
} }

View file

@ -24,6 +24,22 @@ func ToLocationOut(location *ent.Location, err error) (*types.LocationOut, error
}, err }, err
} }
func (svc *LocationService) GetAll(ctx context.Context, groupId uuid.UUID) ([]*types.LocationOut, error) { func (svc *LocationService) Create(ctx context.Context, groupId uuid.UUID, data types.LocationCreate) (*types.LocationOut, error) {
panic("not implemented") location, err := svc.repos.Locations.Create(ctx, groupId, data)
return ToLocationOut(location, err)
}
func (svc *LocationService) GetAll(ctx context.Context, groupId uuid.UUID) ([]*types.LocationOut, error) {
locations, err := svc.repos.Locations.GetAll(ctx, groupId)
if err != nil {
return nil, err
}
locationsOut := make([]*types.LocationOut, len(locations))
for i, location := range locations {
locationOut, _ := ToLocationOut(location, nil)
locationsOut[i] = locationOut
}
return locationsOut, nil
} }

View file

@ -7,6 +7,10 @@ type Result struct {
Item interface{} `json:"item,omitempty"` Item interface{} `json:"item,omitempty"`
} }
type Results struct {
Items any `json:"items"`
}
// Wrap creates a Wrapper instance and adds the initial namespace and data to be returned. // Wrap creates a Wrapper instance and adds the initial namespace and data to be returned.
func Wrap(data interface{}) Result { func Wrap(data interface{}) Result {
return Result{ return Result{