From 9d87bc4a892116856c1ca53c70cfdee248cc4e84 Mon Sep 17 00:00:00 2001 From: Raajheer1 Date: Sun, 13 Oct 2024 16:11:27 -0500 Subject: [PATCH] Event cleanup --- external/docs/docs.go | 115 ++++++++++++++++++++++---- external/docs/swagger.json | 115 ++++++++++++++++++++++---- external/docs/swagger.yaml | 84 +++++++++++++++---- external/v3/event/event.go | 55 +++++++++++- external/v3/event/struct.go | 10 +-- external/v3/router.go | 3 + pkg/database/models/event.go | 45 ++++------ pkg/database/models/event_template.go | 32 ++----- 8 files changed, 353 insertions(+), 106 deletions(-) diff --git a/external/docs/docs.go b/external/docs/docs.go index 71277cb..d8b55f5 100644 --- a/external/docs/docs.go +++ b/external/docs/docs.go @@ -24,6 +24,58 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/events": { + "get": { + "description": "Get All Events (Paginated, default 10, limit 25)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "event" + ], + "summary": "Get All Events", + "parameters": [ + { + "type": "integer", + "description": "Page", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "Limit", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/event.EventResponse" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/utils.ErrResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/utils.ErrResponse" + } + } + } + } + }, "/facility": { "get": { "description": "Get all facilities", @@ -392,6 +444,15 @@ const docTemplate = `{ "event" ], "summary": "Get Events", + "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + } + ], "responses": { "200": { "description": "OK", @@ -429,6 +490,13 @@ const docTemplate = `{ ], "summary": "Create an Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "description": "Event", "name": "event", @@ -475,6 +543,13 @@ const docTemplate = `{ ], "summary": "Get Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "type": "string", "description": "Event ID", @@ -523,6 +598,13 @@ const docTemplate = `{ ], "summary": "Update Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "type": "string", "description": "Event ID", @@ -580,6 +662,13 @@ const docTemplate = `{ ], "summary": "Delete Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "type": "string", "description": "Event ID", @@ -625,6 +714,13 @@ const docTemplate = `{ ], "summary": "Patch Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "type": "string", "description": "Event ID", @@ -5136,9 +5232,7 @@ const docTemplate = `{ "$ref": "#/definitions/constants.FacilityID" }, "example": [ - "[\"ZDV\"", - " \"ZAB\"", - " \"ZLC\"]" + "ZDV" ] }, "fields": { @@ -5147,9 +5241,7 @@ const docTemplate = `{ "type": "string" }, "example": [ - "[\"KDEN\"", - " \"KBJC\"", - " \"KAPA\"]" + "KDEN" ] }, "start_date": { @@ -5369,9 +5461,7 @@ const docTemplate = `{ "$ref": "#/definitions/constants.FacilityID" }, "example": [ - "[\"ZDV\"", - " \"ZAB\"", - " \"ZLC\"]" + "ZDV" ] }, "fields": { @@ -5380,9 +5470,7 @@ const docTemplate = `{ "type": "string" }, "example": [ - "[\"KDEN\"", - " \"KBJC\"", - " \"KAPA\"]" + "KDEN" ] }, "positions": { @@ -5391,8 +5479,7 @@ const docTemplate = `{ "type": "string" }, "example": [ - "[\"ZDV_APP\"", - " \"ZDV_TWR\"]" + "ZDV_APP" ] }, "shifts": { diff --git a/external/docs/swagger.json b/external/docs/swagger.json index 1e97120..6fc4e56 100644 --- a/external/docs/swagger.json +++ b/external/docs/swagger.json @@ -17,6 +17,58 @@ }, "basePath": "/v3", "paths": { + "/events": { + "get": { + "description": "Get All Events (Paginated, default 10, limit 25)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "event" + ], + "summary": "Get All Events", + "parameters": [ + { + "type": "integer", + "description": "Page", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "Limit", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/event.EventResponse" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/utils.ErrResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/utils.ErrResponse" + } + } + } + } + }, "/facility": { "get": { "description": "Get all facilities", @@ -385,6 +437,15 @@ "event" ], "summary": "Get Events", + "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + } + ], "responses": { "200": { "description": "OK", @@ -422,6 +483,13 @@ ], "summary": "Create an Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "description": "Event", "name": "event", @@ -468,6 +536,13 @@ ], "summary": "Get Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "type": "string", "description": "Event ID", @@ -516,6 +591,13 @@ ], "summary": "Update Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "type": "string", "description": "Event ID", @@ -573,6 +655,13 @@ ], "summary": "Delete Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "type": "string", "description": "Event ID", @@ -618,6 +707,13 @@ ], "summary": "Patch Event", "parameters": [ + { + "type": "string", + "description": "Facility ID", + "name": "FacilityID", + "in": "path", + "required": true + }, { "type": "string", "description": "Event ID", @@ -5129,9 +5225,7 @@ "$ref": "#/definitions/constants.FacilityID" }, "example": [ - "[\"ZDV\"", - " \"ZAB\"", - " \"ZLC\"]" + "ZDV" ] }, "fields": { @@ -5140,9 +5234,7 @@ "type": "string" }, "example": [ - "[\"KDEN\"", - " \"KBJC\"", - " \"KAPA\"]" + "KDEN" ] }, "start_date": { @@ -5362,9 +5454,7 @@ "$ref": "#/definitions/constants.FacilityID" }, "example": [ - "[\"ZDV\"", - " \"ZAB\"", - " \"ZLC\"]" + "ZDV" ] }, "fields": { @@ -5373,9 +5463,7 @@ "type": "string" }, "example": [ - "[\"KDEN\"", - " \"KBJC\"", - " \"KAPA\"]" + "KDEN" ] }, "positions": { @@ -5384,8 +5472,7 @@ "type": "string" }, "example": [ - "[\"ZDV_APP\"", - " \"ZDV_TWR\"]" + "ZDV_APP" ] }, "shifts": { diff --git a/external/docs/swagger.yaml b/external/docs/swagger.yaml index 449191a..f02482b 100644 --- a/external/docs/swagger.yaml +++ b/external/docs/swagger.yaml @@ -299,17 +299,13 @@ definitions: type: string facilities: example: - - '["ZDV"' - - ' "ZAB"' - - ' "ZLC"]' + - ZDV items: $ref: '#/definitions/constants.FacilityID' type: array fields: example: - - '["KDEN"' - - ' "KBJC"' - - ' "KAPA"]' + - KDEN items: type: string type: array @@ -471,24 +467,19 @@ definitions: properties: facilities: example: - - '["ZDV"' - - ' "ZAB"' - - ' "ZLC"]' + - ZDV items: $ref: '#/definitions/constants.FacilityID' type: array fields: example: - - '["KDEN"' - - ' "KBJC"' - - ' "KAPA"]' + - KDEN items: type: string type: array positions: example: - - '["ZDV_APP"' - - ' "ZDV_TWR"]' + - ZDV_APP items: type: string type: array @@ -1409,6 +1400,40 @@ info: title: VATUSA API version: "0.1" paths: + /events: + get: + consumes: + - application/json + description: Get All Events (Paginated, default 10, limit 25) + parameters: + - description: Page + in: query + name: page + type: integer + - description: Limit + in: query + name: limit + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/event.EventResponse' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/utils.ErrResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/utils.ErrResponse' + summary: Get All Events + tags: + - event /facility: get: consumes: @@ -1650,6 +1675,12 @@ paths: consumes: - application/json description: Get Events by Facility + parameters: + - description: Facility ID + in: path + name: FacilityID + required: true + type: string produces: - application/json responses: @@ -1675,6 +1706,11 @@ paths: - application/json description: Create an Event parameters: + - description: Facility ID + in: path + name: FacilityID + required: true + type: string - description: Event in: body name: event @@ -1705,6 +1741,11 @@ paths: - application/json description: Delete Event by ID parameters: + - description: Facility ID + in: path + name: FacilityID + required: true + type: string - description: Event ID in: path name: EventID @@ -1735,6 +1776,11 @@ paths: - application/json description: Get Event by ID parameters: + - description: Facility ID + in: path + name: FacilityID + required: true + type: string - description: Event ID in: path name: EventID @@ -1767,6 +1813,11 @@ paths: - application/json description: Patch Event by ID parameters: + - description: Facility ID + in: path + name: FacilityID + required: true + type: string - description: Event ID in: path name: EventID @@ -1805,6 +1856,11 @@ paths: - application/json description: Update Event by ID parameters: + - description: Facility ID + in: path + name: FacilityID + required: true + type: string - description: Event ID in: path name: EventID diff --git a/external/v3/event/event.go b/external/v3/event/event.go index d6267dd..c785593 100644 --- a/external/v3/event/event.go +++ b/external/v3/event/event.go @@ -7,6 +7,7 @@ import ( log "github.com/sirupsen/logrus" "net/http" "slices" + "strconv" "time" ) @@ -16,6 +17,7 @@ import ( // @Tags event // @Accept json // @Produce json +// @Param FacilityID path string true "Facility ID" // @Param event body EventRequest true "Event" // @Success 201 {object} EventResponse // @Failure 400 {object} utils.ErrResponse @@ -60,12 +62,59 @@ func CreateEvent(w http.ResponseWriter, r *http.Request) { utils.Render(w, r, NewEventResponse(ev)) } +// GetAllEvents godoc +// @Summary Get All Events +// @Description Get All Events (Paginated, default 10, limit 25) +// @Tags event +// @Accept json +// @Produce json +// @Param page query int false "Page" +// @Param limit query int false "Limit" +// @Success 200 {object} []EventResponse +// @Failure 400 {object} utils.ErrResponse +// @Failure 500 {object} utils.ErrResponse +// @Router /events [get] +func GetAllEvents(w http.ResponseWriter, r *http.Request) { + pageStr := r.URL.Query().Get("page") + limitStr := r.URL.Query().Get("limit") + + page, err := strconv.ParseInt(pageStr, 10, 64) + if err != nil { + page = 1 + } + + if page == 0 { + page = 1 + } + + limit, err := strconv.ParseInt(limitStr, 10, 64) + if err != nil { + limit = 10 + } + if limit < 1 || limit > 25 { + limit = 10 + } + + events, err := models.GetEventsFiltered(int(page), int(limit), "", time.Now()) + if err != nil { + log.WithError(err).Error("Error getting events") + utils.Render(w, r, utils.ErrInternalServer) + return + } + + if err := render.RenderList(w, r, NewEventListResponse(events)); err != nil { + utils.Render(w, r, utils.ErrRender(err)) + return + } +} + // GetEvents godoc // @Summary Get Events // @Description Get Events by Facility // @Tags event // @Accept json // @Produce json +// @Param FacilityID path string true "Facility ID" // @Success 200 {object} []EventResponse // @Failure 400 {object} utils.ErrResponse // @Failure 500 {object} utils.ErrResponse @@ -73,7 +122,7 @@ func CreateEvent(w http.ResponseWriter, r *http.Request) { func GetEvents(w http.ResponseWriter, r *http.Request) { fac := utils.GetFacilityCtx(r) - events, err := models.GetEventsFiltered(fac.ID, time.Now()) + events, err := models.GetEventsFiltered(0, 1000, fac.ID, time.Now()) if err != nil { log.WithError(err).Error("Error getting events") utils.Render(w, r, utils.ErrInternalServer) @@ -92,6 +141,7 @@ func GetEvents(w http.ResponseWriter, r *http.Request) { // @Tags event // @Accept json // @Produce json +// @Param FacilityID path string true "Facility ID" // @Param EventID path string true "Event ID" // @Success 200 {object} EventResponse // @Failure 400 {object} utils.ErrResponse @@ -109,6 +159,7 @@ func GetEvent(w http.ResponseWriter, r *http.Request) { // @Tags event // @Accept json // @Produce json +// @Param FacilityID path string true "Facility ID" // @Param EventID path string true "Event ID" // @Param event body EventRequest true "Event" // @Success 200 {object} EventResponse @@ -153,6 +204,7 @@ func UpdateEvent(w http.ResponseWriter, r *http.Request) { // @Tags event // @Accept json // @Produce json +// @Param FacilityID path string true "Facility ID" // @Param EventID path string true "Event ID" // @Param event body EventRequest true "Event" // @Success 200 {object} EventResponse @@ -211,6 +263,7 @@ func PatchEvent(w http.ResponseWriter, r *http.Request) { // @Tags event // @Accept json // @Produce json +// @Param FacilityID path string true "Facility ID" // @Param EventID path string true "Event ID" // @Success 204 // @Failure 400 {object} utils.ErrResponse diff --git a/external/v3/event/struct.go b/external/v3/event/struct.go index 152b497..01bebc5 100644 --- a/external/v3/event/struct.go +++ b/external/v3/event/struct.go @@ -10,9 +10,9 @@ import ( type EventTemplateRequest struct { Title string `json:"title" example:"KDEN FNO" validate:"required"` - Positions []string `json:"positions" example:"[\"ZDV_APP\", \"ZDV_TWR\"]" validate:"required"` - Facilities []constants.FacilityID `json:"facilities" example:"[\"ZDV\", \"ZAB\", \"ZLC\"]" validate:"required"` - Fields []string `json:"fields" example:"[\"KDEN\", \"KBJC\", \"KAPA\"]" validate:"required"` + Positions []string `json:"positions" example:"ZDV_APP" validate:"required"` + Facilities []constants.FacilityID `json:"facilities" example:"ZDV" validate:"required"` + Fields []string `json:"fields" example:"KDEN" validate:"required"` Shifts bool `json:"shifts" example:"true"` } @@ -53,8 +53,8 @@ type EventRequest struct { BannerURL string `json:"banner_url" example:"https://zdvartcc.org/banner.jpg"` StartDate time.Time `json:"start_date" example:"2021-01-01T00:00:00Z" validate:"required"` EndDate time.Time `json:"end_date" example:"2021-01-01T00:00:00Z" validate:"required"` - Fields []string `json:"fields" example:"[\"KDEN\", \"KBJC\", \"KAPA\"]" validate:"required"` - Facilities []constants.FacilityID `json:"facilities" example:"[\"ZDV\", \"ZAB\", \"ZLC\"]" validate:"required"` + Fields []string `json:"fields" example:"KDEN" validate:"required"` + Facilities []constants.FacilityID `json:"facilities" example:"ZDV" validate:"required"` } func (req *EventRequest) Validate() error { diff --git a/external/v3/router.go b/external/v3/router.go index ab5a2e4..297dbbc 100644 --- a/external/v3/router.go +++ b/external/v3/router.go @@ -1,6 +1,7 @@ package v3 import ( + "github.com/VATUSA/primary-api/external/v3/event" "github.com/VATUSA/primary-api/external/v3/facility" "github.com/VATUSA/primary-api/external/v3/user" "github.com/VATUSA/primary-api/pkg/config" @@ -16,5 +17,7 @@ func Router(r chi.Router, cfg *config.Config) { r.Route("/facility", func(r chi.Router) { facility.Router(r) }) + + r.Get("/events", event.GetAllEvents) }) } diff --git a/pkg/database/models/event.go b/pkg/database/models/event.go index 6943aa5..8b0959b 100644 --- a/pkg/database/models/event.go +++ b/pkg/database/models/event.go @@ -1,8 +1,6 @@ package models import ( - "database/sql/driver" - "encoding/json" "github.com/VATUSA/primary-api/pkg/constants" "github.com/VATUSA/primary-api/pkg/database" "time" @@ -11,13 +9,14 @@ import ( type Event struct { ID uint `json:"id" gorm:"primaryKey" example:"1"` - Title string `json:"title" gorm:"not null" example:"ZDV FNO"` - Description string `json:"description" gorm:"not null" example:"Join us for a fun night of flying in and out of Denver!"` - BannerURL string `json:"banner_url" example:"https://zdvartcc.org/banner.jpg"` - StartDate time.Time `json:"start_date" gorm:"not null" example:"2021-01-01T00:00:00Z"` - EndDate time.Time `json:"end_date" gorm:"not null" example:"2021-01-01T00:00:00Z"` - Fields Fields `json:"fields" gorm:"type:json" example:"[\"KDEN\", \"KBJC\", \"KAPA\"]"` - Facilities Facilities `json:"facilities" gorm:"type:json" example:"[\"ZDV\", \"ZAB\", \"ZLC\"]"` + Title string `json:"title" gorm:"not null" example:"ZDV FNO"` + Description string `json:"description" gorm:"not null" example:"Join us for a fun night of flying in and out of Denver!"` + BannerURL string `json:"banner_url" example:"https://zdvartcc.org/banner.jpg"` + StartDate time.Time `json:"start_date" gorm:"not null" example:"2021-01-01T00:00:00Z"` + EndDate time.Time `json:"end_date" gorm:"not null" example:"2021-01-01T00:00:00Z"` + + Fields []string `json:"fields" gorm:"serializer:json" example:"[\"KDEN\", \"KBJC\", \"KAPA\"]"` + Facilities []constants.FacilityID `json:"facilities" gorm:"serializer:json" example:"[\"ZDV\", \"ZAB\", \"ZLC\"]"` Positions []EventPosition `json:"positions" gorm:"foreignKey:EventID"` Routing []EventRouting `json:"routing" gorm:"foreignKey:EventID"` @@ -26,26 +25,6 @@ type Event struct { UpdatedAt time.Time `json:"updated_at" example:"2021-01-01T00:00:00Z"` } -type Fields []string - -func (f *Fields) Scan(value interface{}) error { - return json.Unmarshal(value.([]byte), f) -} - -func (f *Fields) Value() (driver.Value, error) { - return json.Marshal(f) -} - -type Facilities []constants.FacilityID - -func (f *Facilities) Scan(value interface{}) error { - return json.Unmarshal(value.([]byte), f) -} - -func (f *Facilities) Value() (driver.Value, error) { - return json.Marshal(f) -} - func (e *Event) Create() error { return database.DB.Create(e).Error } @@ -62,16 +41,20 @@ func (e *Event) Delete() error { return database.DB.Delete(e).Error } -func GetEventsFiltered(facilityID constants.FacilityID, afterDate time.Time) ([]Event, error) { +func GetEventsFiltered(page, pageSize int, facilityID constants.FacilityID, afterDate time.Time) ([]Event, error) { var events []Event + query := database.DB if !afterDate.IsZero() { - query = query.Where("start_date > ?", afterDate) + query = query.Where("end_date > ?", afterDate) } if facilityID != "" { // FIXME: idk if this query works query = query.Where("facilities @> ?", []constants.FacilityID{facilityID}) } + offset := (page - 1) * pageSize + query = query.Offset(offset).Limit(pageSize) + return events, query.Find(&events).Error } diff --git a/pkg/database/models/event_template.go b/pkg/database/models/event_template.go index 10e2642..276b8d3 100644 --- a/pkg/database/models/event_template.go +++ b/pkg/database/models/event_template.go @@ -1,8 +1,6 @@ package models import ( - "database/sql/driver" - "encoding/json" "github.com/VATUSA/primary-api/pkg/constants" "github.com/VATUSA/primary-api/pkg/database" "time" @@ -11,36 +9,16 @@ import ( type EventTemplate struct { ID uint `json:"id" gorm:"primaryKey" example:"1"` - Title string `json:"title" gorm:"not null" example:"KDEN FNO Template"` - Positions DefaultPositions `json:"positions" gorm:"type:json" example:"[\"ZDV_APP\", \"ZDV_TWR\"]"` - Facilities DefaultFacilities `json:"facilities" gorm:"type:json" example:"[\"ZDV\", \"ZAB\", \"ZLC\"]"` - Fields Fields `json:"fields" gorm:"type:json" example:"[\"KDEN\", \"KBJC\", \"KAPA\"]"` - Shifts bool `json:"shifts" gorm:"not null;default:false" example:"true"` + Title string `json:"title" gorm:"not null" example:"KDEN FNO Template"` + Positions []string `json:"positions" gorm:"serializer:json" example:"[\"ZDV_APP\", \"ZDV_TWR\"]"` + Facilities []constants.FacilityID `json:"facilities" gorm:"serializer:json" example:"[\"ZDV\", \"ZAB\", \"ZLC\"]"` + Fields []string `json:"fields" gorm:"serializer:json" example:"[\"KDEN\", \"KBJC\", \"KAPA\"]"` + Shifts bool `json:"shifts" gorm:"not null;default:false" example:"true"` CreatedAt time.Time `json:"created_at" example:"2021-01-01T00:00:00Z"` UpdatedAt time.Time `json:"updated_at" example:"2021-01-01T00:00:00Z"` } -type DefaultPositions []string - -func (f *DefaultPositions) Scan(value interface{}) error { - return json.Unmarshal(value.([]byte), f) -} - -func (f *DefaultPositions) Value() (driver.Value, error) { - return json.Marshal(f) -} - -type DefaultFacilities []constants.FacilityID - -func (f *DefaultFacilities) Scan(value interface{}) error { - return json.Unmarshal(value.([]byte), f) -} - -func (f *DefaultFacilities) Value() (driver.Value, error) { - return json.Marshal(f) -} - func (et *EventTemplate) Create() error { return database.DB.Create(et).Error }