From 5691ab7c7248076f75d6e23b3c8dc71075b2de2c Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 15:01:11 -0700 Subject: [PATCH 01/23] wip --- internal/api/services/board.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/internal/api/services/board.go b/internal/api/services/board.go index d9bf2d07..eba1ce96 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -17,18 +17,18 @@ type BoardServicer interface { DeleteOfficer(ctx context.Context, id string) error // Tier methods - GetTier(ctx context.Context, tierName int64) (dbmodels.Tier, error) - ListTiers(ctx context.Context, filters ...any) ([]dbmodels.Tier, error) - CreateTier(ctx context.Context, params dbmodels.CreateTierParams) error - UpdateTier(ctx context.Context, params dbmodels.UpdateTierParams) error + GetTier(ctx context.Context, tierName int64) (domain.Tier, error) + ListTiers(ctx context.Context, filters ...any) ([]domain.Tier, error) + CreateTier(ctx context.Context, params domain.Tier) error + UpdateTier(ctx context.Context, params domain.UpdateTier) error DeleteTier(ctx context.Context, tierName int64) error // Position methods - GetPosition(ctx context.Context, oid string) (dbmodels.Position, error) - ListPositions(ctx context.Context, filters ...any) ([]dbmodels.Position, error) - CreatePosition(ctx context.Context, params dbmodels.CreatePositionParams) error - UpdatePosition(ctx context.Context, params dbmodels.UpdatePositionParams) error - DeletePosition(ctx context.Context, arg dbmodels.DeletePositionParams) error + GetPosition(ctx context.Context, oid string) (domain.Position, error) + ListPositions(ctx context.Context, filters ...any) ([]domain.Position, error) + CreatePosition(ctx context.Context, params domain.Position) error + UpdatePosition(ctx context.Context, params domain.UpdatePosition) error + DeletePosition(ctx context.Context, arg domain.DeletePosition) error } type BoardService struct { From 65ed2a8d9eb86f839e27adc8c4ff6cd19b92b4ff Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 15:01:24 -0700 Subject: [PATCH 02/23] oid -> officer_id --- internal/api/store/dbmodels/board.sql.go | 60 ++++++++++---------- internal/api/store/dbmodels/models.go | 12 ++-- internal/domain/position.go | 30 ++++++---- internal/dto/position.go | 60 ++++++++++---------- sql/migrations/000003_create_officers.up.sql | 6 +- sql/queries/board.sql | 12 ++-- 6 files changed, 93 insertions(+), 87 deletions(-) diff --git a/internal/api/store/dbmodels/board.sql.go b/internal/api/store/dbmodels/board.sql.go index a8b8ef80..46dc0e2a 100644 --- a/internal/api/store/dbmodels/board.sql.go +++ b/internal/api/store/dbmodels/board.sql.go @@ -54,7 +54,7 @@ func (q *Queries) CreateOfficer(ctx context.Context, arg CreateOfficerParams) (O const createPosition = `-- name: CreatePosition :one INSERT INTO position ( - oid, + officer_id, semester, tier, full_name, @@ -63,21 +63,21 @@ position ( ) VALUES (?, ?, ?, ?, ?, ?) -RETURNING oid, semester, tier, full_name, title, team +RETURNING officer_id, semester, tier, full_name, title, team ` type CreatePositionParams struct { - Oid string - Semester string - Tier int64 - FullName string - Title sql.NullString - Team sql.NullString + OfficerID string + Semester string + Tier int64 + FullName string + Title sql.NullString + Team sql.NullString } func (q *Queries) CreatePosition(ctx context.Context, arg CreatePositionParams) (Position, error) { row := q.db.QueryRowContext(ctx, createPosition, - arg.Oid, + arg.OfficerID, arg.Semester, arg.Tier, arg.FullName, @@ -86,7 +86,7 @@ func (q *Queries) CreatePosition(ctx context.Context, arg CreatePositionParams) ) var i Position err := row.Scan( - &i.Oid, + &i.OfficerID, &i.Semester, &i.Tier, &i.FullName, @@ -146,19 +146,19 @@ func (q *Queries) DeleteOfficer(ctx context.Context, uuid string) error { const deletePosition = `-- name: DeletePosition :exec DELETE FROM position WHERE - oid = ? + officer_id = ? AND semester = ? AND tier = ? ` type DeletePositionParams struct { - Oid string - Semester string - Tier int64 + OfficerID string + Semester string + Tier int64 } func (q *Queries) DeletePosition(ctx context.Context, arg DeletePositionParams) error { - _, err := q.db.ExecContext(ctx, deletePosition, arg.Oid, arg.Semester, arg.Tier) + _, err := q.db.ExecContext(ctx, deletePosition, arg.OfficerID, arg.Semester, arg.Tier) return err } @@ -245,7 +245,7 @@ func (q *Queries) GetOfficers(ctx context.Context) ([]Officer, error) { const getPosition = `-- name: GetPosition :one SELECT - oid, + officer_id, semester, tier, full_name, @@ -254,14 +254,14 @@ SELECT FROM position WHERE - oid = ? + officer_id = ? ` -func (q *Queries) GetPosition(ctx context.Context, oid string) (Position, error) { - row := q.db.QueryRowContext(ctx, getPosition, oid) +func (q *Queries) GetPosition(ctx context.Context, officerID string) (Position, error) { + row := q.db.QueryRowContext(ctx, getPosition, officerID) var i Position err := row.Scan( - &i.Oid, + &i.OfficerID, &i.Semester, &i.Tier, &i.FullName, @@ -273,7 +273,7 @@ func (q *Queries) GetPosition(ctx context.Context, oid string) (Position, error) const getPositions = `-- name: GetPositions :many SELECT - oid, + officer_id, semester, tier, full_name, @@ -293,7 +293,7 @@ func (q *Queries) GetPositions(ctx context.Context) ([]Position, error) { for rows.Next() { var i Position if err := rows.Scan( - &i.Oid, + &i.OfficerID, &i.Semester, &i.Tier, &i.FullName, @@ -416,18 +416,18 @@ SET title = COALESCE(?2, title), team = COALESCE(?3, team) WHERE - oid = ?4 + officer_id = ?4 AND semester = ?5 AND tier = ?6 ` type UpdatePositionParams struct { - FullName string - Title sql.NullString - Team sql.NullString - Oid string - Semester string - Tier int64 + FullName string + Title sql.NullString + Team sql.NullString + OfficerID string + Semester string + Tier int64 } func (q *Queries) UpdatePosition(ctx context.Context, arg UpdatePositionParams) error { @@ -435,7 +435,7 @@ func (q *Queries) UpdatePosition(ctx context.Context, arg UpdatePositionParams) arg.FullName, arg.Title, arg.Team, - arg.Oid, + arg.OfficerID, arg.Semester, arg.Tier, ) diff --git a/internal/api/store/dbmodels/models.go b/internal/api/store/dbmodels/models.go index a961babd..f0415f86 100644 --- a/internal/api/store/dbmodels/models.go +++ b/internal/api/store/dbmodels/models.go @@ -34,12 +34,12 @@ type Officer struct { } type Position struct { - Oid string - Semester string - Tier int64 - FullName string - Title sql.NullString - Team sql.NullString + OfficerID string + Semester string + Tier int64 + FullName string + Title sql.NullString + Team sql.NullString } type Tier struct { diff --git a/internal/domain/position.go b/internal/domain/position.go index 6b07cb3a..836b5fd9 100644 --- a/internal/domain/position.go +++ b/internal/domain/position.go @@ -1,19 +1,25 @@ package domain type Position struct { - Oid string - Semester string - Tier int - FullName string - Title *string - Team *string + OfficerID string + Semester string + Tier int + FullName string + Title *string + Team *string } type UpdatePosition struct { - Oid string - Semester string - Tier int - FullName string - Title *string - Team *string + OfficerID string + Semester string + Tier int + FullName string + Title *string + Team *string +} + +type DeletePosition struct { + OfficerID string + Semester string + Tier int64 } diff --git a/internal/dto/position.go b/internal/dto/position.go index f7a2ea84..17e05eaa 100644 --- a/internal/dto/position.go +++ b/internal/dto/position.go @@ -5,22 +5,22 @@ import ( ) type Position struct { - Oid string `json:"oid"` - Semester string `json:"semester"` - Tier int `json:"tier"` - FullName string `json:"full_name"` - Title *string `json:"title"` - Team *string `json:"team"` + OfficerID string `json:"officer_id"` + Semester string `json:"semester"` + Tier int `json:"tier"` + FullName string `json:"full_name"` + Title *string `json:"title"` + Team *string `json:"team"` } func PositionDomainToDto(p *domain.Position) Position { return Position{ - Oid: p.Oid, - Semester: p.Semester, - Tier: p.Tier, - FullName: p.FullName, - Title: p.Title, - Team: p.Team, + OfficerID: p.OfficerID, + Semester: p.Semester, + Tier: p.Tier, + FullName: p.FullName, + Title: p.Title, + Team: p.Team, } } @@ -30,22 +30,22 @@ func (p *Position) ToDomain() domain.Position { } return domain.Position{ - Oid: p.Oid, - Semester: p.Semester, - Tier: p.Tier, - FullName: p.FullName, - Title: p.Title, - Team: p.Team, + OfficerID: p.OfficerID, + Semester: p.Semester, + Tier: p.Tier, + FullName: p.FullName, + Title: p.Title, + Team: p.Team, } } type UpdatePosition struct { - Oid string `json:"oid"` - Semester string `json:"semester"` - Tier int `json:"tier"` - FullName string `json:"full_name"` - Title *string `json:"title"` - Team *string `json:"team"` + OfficerID string `json:"officer_id"` + Semester string `json:"semester"` + Tier int `json:"tier"` + FullName string `json:"full_name"` + Title *string `json:"title"` + Team *string `json:"team"` } func (p *UpdatePosition) ToDomain() domain.UpdatePosition { @@ -54,11 +54,11 @@ func (p *UpdatePosition) ToDomain() domain.UpdatePosition { } return domain.UpdatePosition{ - Oid: p.Oid, - Semester: p.Semester, - Tier: p.Tier, - FullName: p.FullName, - Title: p.Title, - Team: p.Team, + OfficerID: p.OfficerID, + Semester: p.Semester, + Tier: p.Tier, + FullName: p.FullName, + Title: p.Title, + Team: p.Team, } } diff --git a/sql/migrations/000003_create_officers.up.sql b/sql/migrations/000003_create_officers.up.sql index 55a46147..2b90fdb4 100644 --- a/sql/migrations/000003_create_officers.up.sql +++ b/sql/migrations/000003_create_officers.up.sql @@ -16,13 +16,13 @@ CREATE TABLE IF NOT EXISTS tier ( ); CREATE TABLE IF NOT EXISTS position ( - oid VARCHAR(4) NOT NULL, + officer_id VARCHAR(4) NOT NULL, semester VARCHAR(3) NOT NULL, tier INTEGER NOT NULL, full_name VARCHAR(30) NOT NULL, title VARCHAR(40), team VARCHAR(20), - PRIMARY KEY (oid, semester, tier), - CONSTRAINT fk_officer FOREIGN KEY (oid) REFERENCES officer (uuid), + PRIMARY KEY (officer_id, semester, tier), + CONSTRAINT fk_officer FOREIGN KEY (officer_id) REFERENCES officer (uuid), CONSTRAINT fk_tier FOREIGN KEY (tier) REFERENCES tier (tier) ); diff --git a/sql/queries/board.sql b/sql/queries/board.sql index 32b3a3dd..8f82bcc1 100644 --- a/sql/queries/board.sql +++ b/sql/queries/board.sql @@ -26,7 +26,7 @@ RETURNING *; -- name: CreatePosition :one INSERT INTO position ( - oid, + officer_id, semester, tier, full_name, @@ -61,7 +61,7 @@ WHERE -- name: GetPosition :one SELECT - oid, + officer_id, semester, tier, full_name, @@ -70,7 +70,7 @@ SELECT FROM position WHERE - oid = ?; + officer_id = ?; -- NOTE: Had to declare above table as :one, may need to change later to :many @@ -100,7 +100,7 @@ SET title = COALESCE(:title, title), team = COALESCE(:team, team) WHERE - oid = :oid + officer_id = :officer_id AND semester = :semester AND tier = :tier; @@ -115,7 +115,7 @@ WHERE tier = ?; -- name: DeletePosition :exec DELETE FROM position WHERE - oid = ? + officer_id = ? AND semester = ? AND tier = ?; @@ -142,7 +142,7 @@ ORDER BY -- name: GetPositions :many SELECT - oid, + officer_id, semester, tier, full_name, From d00239ae6e164e86033974ea8c67e23167941102 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 15:11:31 -0700 Subject: [PATCH 03/23] rm uuid field in UpdateOfficer --- internal/api/services/board.go | 10 ++++++---- internal/domain/officer.go | 1 - 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/api/services/board.go b/internal/api/services/board.go index eba1ce96..0cc91940 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -55,7 +55,8 @@ type PositionFilter interface { Apply(positions []dbmodels.Position) []dbmodels.Position } -// Officer Methods +// ==== Officer Methods ======================================================== + func (s *BoardService) GetOfficer(ctx context.Context, uuid string) (domain.Officer, error) { row, err := s.q.GetOfficer(ctx, uuid) if err != nil { @@ -96,7 +97,6 @@ func (s *BoardService) CreateOfficer(ctx context.Context, officer domain.Officer func (s *BoardService) UpdateOfficer(ctx context.Context, uuid string, updateOfficer domain.UpdateOfficer) error { - // NOTE: domain.UpdateOfficer has a uuid field, do we need the seperate function param here? dbParams := store.UpdateOfficerDomainToDB(updateOfficer) dbParams.Uuid = uuid return s.q.UpdateOfficer(ctx, dbParams) @@ -106,7 +106,8 @@ func (s *BoardService) DeleteOfficer(ctx context.Context, uuid string) error { return s.q.DeleteOfficer(ctx, uuid) } -// Tier Methods +// ==== Tier Methods =========================================================== + func (s *BoardService) GetTier(ctx context.Context, tierName int64) (dbmodels.Tier, error) { return s.q.GetTier(ctx, tierName) } @@ -140,7 +141,8 @@ func (s *BoardService) DeleteTier(ctx context.Context, tierName int64) error { return s.q.DeleteTier(ctx, tierName) } -// Position Methods +// ==== Position Methods ======================================================= + func (s *BoardService) GetPosition(ctx context.Context, oid string) (dbmodels.Position, error) { return s.q.GetPosition(ctx, oid) } diff --git a/internal/domain/officer.go b/internal/domain/officer.go index 6c8e7c88..8cddd7ed 100644 --- a/internal/domain/officer.go +++ b/internal/domain/officer.go @@ -9,7 +9,6 @@ type Officer struct { } type UpdateOfficer struct { - Uuid string FullName *string Picture *string Github *string From acd65f8f73753126ddf1c623f29a6834476457bf Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 15:23:54 -0700 Subject: [PATCH 04/23] api: get tier --- internal/api/handlers/board.go | 12 ++++++++---- internal/api/services/board.go | 13 +++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index bd0d43bf..d32b9fb4 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -194,7 +194,7 @@ func (h *BoardHandler) DeleteOfficer(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Success 200 {array} dbmodels.Tier "List of tiers" +// @Success 200 {array} dto.Tier "List of tiers" // @Failure 500 {object} map[string]string // @Router /v1/board/tiers [get] func (h *BoardHandler) GetTiers(c *gin.Context) { @@ -208,7 +208,11 @@ func (h *BoardHandler) GetTiers(c *gin.Context) { return } - c.JSON(http.StatusOK, tiers) + dtoTiers := make([]dto.Tier, len(tiers)) + for i, tier := range tiers { + dtoTiers[i] = dto.TierDomainToDto(&tier) + } + c.JSON(http.StatusOK, dtoTiers) } // GetTier godoc @@ -219,7 +223,7 @@ func (h *BoardHandler) GetTiers(c *gin.Context) { // @Accept json // @Produce json // @Param id path int true "Tier number" -// @Success 200 {object} dbmodels.Tier "Tier details" +// @Success 200 {object} dto.Tier "Tier details" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Failure 500 {object} map[string]string @@ -248,7 +252,7 @@ func (h *BoardHandler) GetTier(c *gin.Context) { return } - c.JSON(http.StatusOK, tier) + c.JSON(http.StatusOK, dto.TierDomainToDto(&tier)) } // CreateTier godoc diff --git a/internal/api/services/board.go b/internal/api/services/board.go index 0cc91940..2775eb6d 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -108,11 +108,12 @@ func (s *BoardService) DeleteOfficer(ctx context.Context, uuid string) error { // ==== Tier Methods =========================================================== -func (s *BoardService) GetTier(ctx context.Context, tierName int64) (dbmodels.Tier, error) { - return s.q.GetTier(ctx, tierName) +func (s *BoardService) GetTier(ctx context.Context, tierName int64) (domain.Tier, error) { + dbTier, err := s.q.GetTier(ctx, tierName) + return store.TierDBToDomain(dbTier), err } -func (s *BoardService) ListTiers(ctx context.Context, filters ...any) ([]dbmodels.Tier, error) { +func (s *BoardService) ListTiers(ctx context.Context, filters ...any) ([]domain.Tier, error) { tiers, err := s.q.GetTiers(ctx) if err != nil { return nil, err @@ -125,7 +126,11 @@ func (s *BoardService) ListTiers(ctx context.Context, filters ...any) ([]dbmodel } } - return result, nil + domainTiers := make([]domain.Tier, len(tiers)) + for i, tier := range result { + domainTiers[i] = store.TierDBToDomain(tier) + } + return domainTiers, nil } func (s *BoardService) CreateTier(ctx context.Context, params dbmodels.CreateTierParams) error { From 2f91d3d67f1c4fe7903bcc05b80542d8344661ec Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 16:10:19 -0700 Subject: [PATCH 05/23] create tier --- internal/api/handlers/board.go | 13 ++++++------- internal/api/services/board.go | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index d32b9fb4..600cdf28 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -145,7 +145,6 @@ func (h *BoardHandler) UpdateOfficer(c *gin.Context) { } domainModel := body.ToDomain() - domainModel.Uuid = id if err := h.boardService.UpdateOfficer(ctx, id, domainModel); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "Failed to update officer. " + err.Error(), @@ -262,23 +261,23 @@ func (h *BoardHandler) GetTier(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Param body body dbmodels.CreateTierParams true "Tier data" +// @Param body body dto.Tier true "Tier data" // @Success 200 {object} map[string]interface{} "Success message with tier number" // @Failure 400 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /v1/board/tiers [post] func (h *BoardHandler) CreateTier(c *gin.Context) { ctx := c.Request.Context() - var params dbmodels.CreateTierParams - - if err := c.ShouldBindJSON(¶ms); err != nil { + var body dto.Tier + if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid request body. " + err.Error(), }) return } - if err := h.boardService.CreateTier(ctx, params); err != nil { + tier, err := h.boardService.CreateTier(ctx, body.ToDomain()) + if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "Failed to create tier. " + err.Error(), }) @@ -287,7 +286,7 @@ func (h *BoardHandler) CreateTier(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "Tier created successfully", - "tier": params.Tier, + "tier": dto.TierDomainToDto(&tier), }) } diff --git a/internal/api/services/board.go b/internal/api/services/board.go index 2775eb6d..1cf1177d 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -19,7 +19,7 @@ type BoardServicer interface { // Tier methods GetTier(ctx context.Context, tierName int64) (domain.Tier, error) ListTiers(ctx context.Context, filters ...any) ([]domain.Tier, error) - CreateTier(ctx context.Context, params domain.Tier) error + CreateTier(ctx context.Context, params domain.Tier) (domain.Tier, error) UpdateTier(ctx context.Context, params domain.UpdateTier) error DeleteTier(ctx context.Context, tierName int64) error @@ -110,7 +110,10 @@ func (s *BoardService) DeleteOfficer(ctx context.Context, uuid string) error { func (s *BoardService) GetTier(ctx context.Context, tierName int64) (domain.Tier, error) { dbTier, err := s.q.GetTier(ctx, tierName) - return store.TierDBToDomain(dbTier), err + if err != nil { + return domain.Tier{}, err + } + return store.TierDBToDomain(dbTier), nil } func (s *BoardService) ListTiers(ctx context.Context, filters ...any) ([]domain.Tier, error) { @@ -133,13 +136,16 @@ func (s *BoardService) ListTiers(ctx context.Context, filters ...any) ([]domain. return domainTiers, nil } -func (s *BoardService) CreateTier(ctx context.Context, params dbmodels.CreateTierParams) error { - _, err := s.q.CreateTier(ctx, params) - return err +func (s *BoardService) CreateTier(ctx context.Context, params domain.Tier) (domain.Tier, error) { + dbTier, err := s.q.CreateTier(ctx, store.TierDomainToDB(params)) + if err != nil { + return domain.Tier{}, nil + } + return store.TierDBToDomain(dbTier), nil } -func (s *BoardService) UpdateTier(ctx context.Context, params dbmodels.UpdateTierParams) error { - return s.q.UpdateTier(ctx, params) +func (s *BoardService) UpdateTier(ctx context.Context, params domain.UpdateTier) error { + return s.q.UpdateTier(ctx, store.UpdateTierDomainToDB(params)) } func (s *BoardService) DeleteTier(ctx context.Context, tierName int64) error { From 7169370b6b8073a38e09bbe80bb0014f95590ed6 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 16:53:33 -0700 Subject: [PATCH 06/23] update tier --- internal/api/handlers/board.go | 24 +++++++++++------------- internal/api/services/board.go | 7 +++++-- internal/dto/tier.go | 2 -- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index 600cdf28..b6b7d6c7 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -221,15 +221,15 @@ func (h *BoardHandler) GetTiers(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Param id path int true "Tier number" +// @Param tier path int true "Tier number" // @Success 200 {object} dto.Tier "Tier details" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Failure 500 {object} map[string]string -// @Router /v1/board/tiers/{id} [get] +// @Router /v1/board/tiers/{tier} [get] func (h *BoardHandler) GetTier(c *gin.Context) { ctx := c.Request.Context() - id, err := strconv.Atoi(c.Param("id")) + tierName, err := strconv.ParseInt(c.Param("tierName"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid tier number", @@ -237,7 +237,7 @@ func (h *BoardHandler) GetTier(c *gin.Context) { return } - tier, err := h.boardService.GetTier(ctx, int64(id)) + tier, err := h.boardService.GetTier(ctx, tierName) if err != nil { if err.Error() == "sql: no rows in result set" { c.JSON(http.StatusNotFound, gin.H{ @@ -298,16 +298,16 @@ func (h *BoardHandler) CreateTier(c *gin.Context) { // @Accept json // @Produce json // @Param id path int true "Tier number" -// @Param body body dbmodels.UpdateTierParams true "Updated tier data" +// @Param body body dto.UpdateTier true "Updated tier data" // @Success 200 {object} map[string]string "Success message" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Failure 500 {object} map[string]string -// @Router /v1/board/tiers/{id} [put] +// @Router /v1/board/tiers/{tier} [put] func (h *BoardHandler) UpdateTier(c *gin.Context) { ctx := c.Request.Context() - var params dbmodels.UpdateTierParams - id, err := strconv.Atoi(c.Param("id")) + var body dto.UpdateTier + tierName, err := strconv.ParseInt(c.Param("tier"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid tier number", @@ -315,16 +315,14 @@ func (h *BoardHandler) UpdateTier(c *gin.Context) { return } - if err := c.ShouldBindJSON(¶ms); err != nil { + if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid request body. " + err.Error(), }) return } - params.Tier = int64(id) - - if err := h.boardService.UpdateTier(ctx, params); err != nil { + if err := h.boardService.UpdateTier(ctx, tierName, body.ToDomain()); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "Failed to update tier. " + err.Error(), }) @@ -333,7 +331,7 @@ func (h *BoardHandler) UpdateTier(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "Tier updated successfully", - "tier": params.Tier, + "tier": tierName, }) } diff --git a/internal/api/services/board.go b/internal/api/services/board.go index 1cf1177d..9d6c4dab 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -20,7 +20,7 @@ type BoardServicer interface { GetTier(ctx context.Context, tierName int64) (domain.Tier, error) ListTiers(ctx context.Context, filters ...any) ([]domain.Tier, error) CreateTier(ctx context.Context, params domain.Tier) (domain.Tier, error) - UpdateTier(ctx context.Context, params domain.UpdateTier) error + UpdateTier(ctx context.Context, tierName int64, params domain.UpdateTier) error DeleteTier(ctx context.Context, tierName int64) error // Position methods @@ -144,7 +144,10 @@ func (s *BoardService) CreateTier(ctx context.Context, params domain.Tier) (doma return store.TierDBToDomain(dbTier), nil } -func (s *BoardService) UpdateTier(ctx context.Context, params domain.UpdateTier) error { +func (s *BoardService) UpdateTier(ctx context.Context, tierName int64, + params domain.UpdateTier) error { + dbParams := store.UpdateTierDomainToDB(params) + dbParams.Tier = tierName return s.q.UpdateTier(ctx, store.UpdateTierDomainToDB(params)) } diff --git a/internal/dto/tier.go b/internal/dto/tier.go index 13647e7a..56343387 100644 --- a/internal/dto/tier.go +++ b/internal/dto/tier.go @@ -34,7 +34,6 @@ func TierDomainToDto(t *domain.Tier) Tier { } type UpdateTier struct { - Tier int `json:"tier"` Title *string `json:"title"` Tindex *int `json:"t_index"` Team *string `json:"team"` @@ -46,7 +45,6 @@ func (t *UpdateTier) ToDomain() domain.UpdateTier { } return domain.UpdateTier{ - Tier: t.Tier, Title: t.Title, Tindex: t.Tindex, Team: t.Team, From 5fa7f373beae5939ed348255228840a1fca920d9 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 16:56:22 -0700 Subject: [PATCH 07/23] delete tier --- internal/api/handlers/board.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index b6b7d6c7..925cd7be 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -342,15 +342,15 @@ func (h *BoardHandler) UpdateTier(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Param id path int true "Tier number" +// @Param tier path int true "Tier number" // @Success 200 {object} map[string]string "Success message" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Failure 500 {object} map[string]string -// @Router /v1/board/tiers/{id} [delete] +// @Router /v1/board/tiers/{tier} [delete] func (h *BoardHandler) DeleteTier(c *gin.Context) { ctx := c.Request.Context() - id, err := strconv.Atoi(c.Param("id")) + tierName, err := strconv.ParseInt(c.Param("tier"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid tier number", @@ -358,7 +358,7 @@ func (h *BoardHandler) DeleteTier(c *gin.Context) { return } - if err := h.boardService.DeleteTier(ctx, int64(id)); err != nil { + if err := h.boardService.DeleteTier(ctx, tierName); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "Failed to delete tier", }) From 34d4b4b4146d3a0fcb32404292b96b8645c2cfb0 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 17:02:24 -0700 Subject: [PATCH 08/23] get position --- internal/api/handlers/board.go | 8 ++++++-- internal/api/services/board.go | 18 +++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index 925cd7be..2f667417 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -377,7 +377,7 @@ func (h *BoardHandler) DeleteTier(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Success 200 {array} dbmodels.Position "List of positions" +// @Success 200 {array} dto.Position "List of positions" // @Failure 500 {object} map[string]string // @Router /v1/board/positions [get] func (h *BoardHandler) GetPositions(c *gin.Context) { @@ -391,6 +391,10 @@ func (h *BoardHandler) GetPositions(c *gin.Context) { return } + dtoPositions := make([]dto.Position, len(positions)) + for i, pos := range positions { + dtoPositions[i] = dto.PositionDomainToDto(&pos) + } c.JSON(http.StatusOK, positions) } @@ -402,7 +406,7 @@ func (h *BoardHandler) GetPositions(c *gin.Context) { // @Accept json // @Produce json // @Param id path string true "Officer full name" -// @Success 200 {object} dbmodels.Position "Position details" +// @Success 200 {object} dto.Position "Position details" // @Failure 404 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /v1/board/positions/{id} [get] diff --git a/internal/api/services/board.go b/internal/api/services/board.go index 9d6c4dab..28d30761 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -129,7 +129,7 @@ func (s *BoardService) ListTiers(ctx context.Context, filters ...any) ([]domain. } } - domainTiers := make([]domain.Tier, len(tiers)) + domainTiers := make([]domain.Tier, len(result)) for i, tier := range result { domainTiers[i] = store.TierDBToDomain(tier) } @@ -157,11 +157,15 @@ func (s *BoardService) DeleteTier(ctx context.Context, tierName int64) error { // ==== Position Methods ======================================================= -func (s *BoardService) GetPosition(ctx context.Context, oid string) (dbmodels.Position, error) { - return s.q.GetPosition(ctx, oid) +func (s *BoardService) GetPosition(ctx context.Context, oid string) (domain.Position, error) { + dbPosition, err := s.q.GetPosition(ctx, oid) + if err != nil { + return domain.Position{}, nil + } + return store.PositionDBToDomain(dbPosition), nil } -func (s *BoardService) ListPositions(ctx context.Context, filters ...any) ([]dbmodels.Position, error) { +func (s *BoardService) ListPositions(ctx context.Context, filters ...any) ([]domain.Position, error) { positions, err := s.q.GetPositions(ctx) if err != nil { return nil, err @@ -174,7 +178,11 @@ func (s *BoardService) ListPositions(ctx context.Context, filters ...any) ([]dbm } } - return result, nil + domainPositions := make([]domain.Position, len(result)) + for i, pos := range positions { + domainPositions[i] = store.PositionDBToDomain(pos) + } + return domainPositions, nil } func (s *BoardService) CreatePosition(ctx context.Context, params dbmodels.CreatePositionParams) error { From e6d520d04f2d56376007f9509bb8c03c2bf939a6 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 17:13:44 -0700 Subject: [PATCH 09/23] create position --- internal/api/handlers/board.go | 14 ++++++-------- internal/api/services/board.go | 12 ++++++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index 2f667417..de84ead4 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -439,23 +439,23 @@ func (h *BoardHandler) GetPosition(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Param body body dbmodels.CreatePositionParams true "Position data" +// @Param body body dto.Position true "Position data" // @Success 200 {object} map[string]interface{} "Success message" // @Failure 400 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /v1/board/positions [post] func (h *BoardHandler) CreatePosition(c *gin.Context) { ctx := c.Request.Context() - var params dbmodels.CreatePositionParams - - if err := c.ShouldBindJSON(¶ms); err != nil { + var body dto.Position + if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid request body. " + err.Error(), }) return } - if err := h.boardService.CreatePosition(ctx, params); err != nil { + position, err := h.boardService.CreatePosition(ctx, body.ToDomain()) + if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "Failed to create position. " + err.Error(), }) @@ -464,9 +464,7 @@ func (h *BoardHandler) CreatePosition(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "Position created successfully", - "oid": params.Oid, - "semester": params.Semester, - "tier": params.Tier, + "position": dto.PositionDomainToDto(&position), }) } diff --git a/internal/api/services/board.go b/internal/api/services/board.go index 28d30761..74754b16 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -26,7 +26,7 @@ type BoardServicer interface { // Position methods GetPosition(ctx context.Context, oid string) (domain.Position, error) ListPositions(ctx context.Context, filters ...any) ([]domain.Position, error) - CreatePosition(ctx context.Context, params domain.Position) error + CreatePosition(ctx context.Context, params domain.Position) (domain.Position, error) UpdatePosition(ctx context.Context, params domain.UpdatePosition) error DeletePosition(ctx context.Context, arg domain.DeletePosition) error } @@ -185,9 +185,13 @@ func (s *BoardService) ListPositions(ctx context.Context, filters ...any) ([]dom return domainPositions, nil } -func (s *BoardService) CreatePosition(ctx context.Context, params dbmodels.CreatePositionParams) error { - _, err := s.q.CreatePosition(ctx, params) - return err +func (s *BoardService) CreatePosition(ctx context.Context, + params domain.Position) (domain.Position, error) { + dbPosition, err := s.q.CreatePosition(ctx, store.PositionDomainToDB(params)) + if err != nil { + return domain.Position{}, err + } + return store.PositionDBToDomain(dbPosition), nil } func (s *BoardService) UpdatePosition(ctx context.Context, params dbmodels.UpdatePositionParams) error { From 8ea47df2583cb5a5a0361f893cbb9cf67213f3d9 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 18:25:38 -0700 Subject: [PATCH 10/23] delete position --- internal/api/handlers/board.go | 21 ++++++++------------- internal/api/services/board.go | 19 +++++++++++++++---- internal/domain/position.go | 4 ++-- internal/dto/position.go | 30 ++++++++++++++++++------------ 4 files changed, 43 insertions(+), 31 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index de84ead4..115792ec 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -475,7 +475,7 @@ func (h *BoardHandler) CreatePosition(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Param body body dbmodels.UpdatePositionParams true "Updated position data (must include oid, semester, tier)" +// @Param body body dto.UpdatePosition true "Updated position data (must include oid, semester, tier)" // @Success 200 {object} map[string]string "Success message" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string @@ -483,16 +483,15 @@ func (h *BoardHandler) CreatePosition(c *gin.Context) { // @Router /v1/board/positions [put] func (h *BoardHandler) UpdatePosition(c *gin.Context) { ctx := c.Request.Context() - var params dbmodels.UpdatePositionParams - - if err := c.ShouldBindJSON(¶ms); err != nil { + var body dto.UpdatePosition + if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid request body. " + err.Error(), }) return } - if err := h.boardService.UpdatePosition(ctx, params); err != nil { + if err := h.boardService.UpdatePosition(ctx, body.ToDomain()); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "Failed to update position. " + err.Error(), }) @@ -501,9 +500,6 @@ func (h *BoardHandler) UpdatePosition(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "Position updated successfully", - "oid": params.Oid, - "semester": params.Semester, - "tier": params.Tier, }) } @@ -514,7 +510,7 @@ func (h *BoardHandler) UpdatePosition(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Param body body dbmodels.DeletePositionParams true "Position identifier" +// @Param body body dto.Position true "Position identifier" // @Success 200 {object} map[string]string "Success message" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string @@ -522,16 +518,15 @@ func (h *BoardHandler) UpdatePosition(c *gin.Context) { // @Router /v1/board/positions [delete] func (h *BoardHandler) DeletePosition(c *gin.Context) { ctx := c.Request.Context() - var params dbmodels.DeletePositionParams - - if err := c.ShouldBindJSON(¶ms); err != nil { + var body dto.DeletePosition + if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid request body. " + err.Error(), }) return } - if err := h.boardService.DeletePosition(ctx, params); err != nil { + if err := h.boardService.DeletePosition(ctx, body.ToDomain()); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "Failed to delete position", }) diff --git a/internal/api/services/board.go b/internal/api/services/board.go index 74754b16..90798a62 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -194,10 +194,21 @@ func (s *BoardService) CreatePosition(ctx context.Context, return store.PositionDBToDomain(dbPosition), nil } -func (s *BoardService) UpdatePosition(ctx context.Context, params dbmodels.UpdatePositionParams) error { - return s.q.UpdatePosition(ctx, params) +func (s *BoardService) UpdatePosition(ctx context.Context, params domain.UpdatePosition) error { + return s.q.UpdatePosition(ctx, store.UpdatePositionDomainToDB(params)) } -func (s *BoardService) DeletePosition(ctx context.Context, arg dbmodels.DeletePositionParams) error { - return s.q.DeletePosition(ctx, arg) +/* + type DeletePositionParams struct { + OfficerID string + Semester string + Tier int64 + } +*/ +func (s *BoardService) DeletePosition(ctx context.Context, arg domain.Position) error { + return s.q.DeletePosition(ctx, dbmodels.DeletePositionParams{ + OfficerID: arg.OfficerID, + Semester: arg.Semester, + Tier: arg.Tier, + }) } diff --git a/internal/domain/position.go b/internal/domain/position.go index 836b5fd9..9954b0c6 100644 --- a/internal/domain/position.go +++ b/internal/domain/position.go @@ -3,7 +3,7 @@ package domain type Position struct { OfficerID string Semester string - Tier int + Tier int64 FullName string Title *string Team *string @@ -12,7 +12,7 @@ type Position struct { type UpdatePosition struct { OfficerID string Semester string - Tier int + Tier int64 FullName string Title *string Team *string diff --git a/internal/dto/position.go b/internal/dto/position.go index 17e05eaa..e64e7d10 100644 --- a/internal/dto/position.go +++ b/internal/dto/position.go @@ -7,7 +7,7 @@ import ( type Position struct { OfficerID string `json:"officer_id"` Semester string `json:"semester"` - Tier int `json:"tier"` + Tier int64 `json:"tier"` FullName string `json:"full_name"` Title *string `json:"title"` Team *string `json:"team"` @@ -24,11 +24,7 @@ func PositionDomainToDto(p *domain.Position) Position { } } -func (p *Position) ToDomain() domain.Position { - if p == nil { - return domain.Position{} - } - +func (p Position) ToDomain() domain.Position { return domain.Position{ OfficerID: p.OfficerID, Semester: p.Semester, @@ -42,17 +38,13 @@ func (p *Position) ToDomain() domain.Position { type UpdatePosition struct { OfficerID string `json:"officer_id"` Semester string `json:"semester"` - Tier int `json:"tier"` + Tier int64 `json:"tier"` FullName string `json:"full_name"` Title *string `json:"title"` Team *string `json:"team"` } -func (p *UpdatePosition) ToDomain() domain.UpdatePosition { - if p == nil { - return domain.UpdatePosition{} - } - +func (p UpdatePosition) ToDomain() domain.UpdatePosition { return domain.UpdatePosition{ OfficerID: p.OfficerID, Semester: p.Semester, @@ -62,3 +54,17 @@ func (p *UpdatePosition) ToDomain() domain.UpdatePosition { Team: p.Team, } } + +type DeletePosition struct { + OfficerID string `json:"officer_id"` + Semester string `json:"semester"` + Tier int64 `json:"tier"` +} + +func (p DeletePosition) ToDomain() domain.DeletePosition { + return domain.DeletePosition{ + OfficerID: p.OfficerID, + Semester: p.Semester, + Tier: p.Tier, + } +} From 1a3f33b3466c77fabf377fb7a40500ff2a5ce261 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 18:32:14 -0700 Subject: [PATCH 11/23] fix compile errors --- internal/api/handlers/board.go | 1 - internal/api/services/board.go | 11 ++------ internal/api/store/board_mapper.go | 43 +++++++++++++++--------------- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index 115792ec..150191b6 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -7,7 +7,6 @@ import ( "strconv" "github.com/acmcsufoss/api.acmcsuf.com/internal/api/services" - "github.com/acmcsufoss/api.acmcsuf.com/internal/api/store/dbmodels" "github.com/acmcsufoss/api.acmcsuf.com/internal/dto" "github.com/gin-gonic/gin" ) diff --git a/internal/api/services/board.go b/internal/api/services/board.go index 90798a62..3900f96f 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -148,7 +148,7 @@ func (s *BoardService) UpdateTier(ctx context.Context, tierName int64, params domain.UpdateTier) error { dbParams := store.UpdateTierDomainToDB(params) dbParams.Tier = tierName - return s.q.UpdateTier(ctx, store.UpdateTierDomainToDB(params)) + return s.q.UpdateTier(ctx, dbParams) } func (s *BoardService) DeleteTier(ctx context.Context, tierName int64) error { @@ -198,14 +198,7 @@ func (s *BoardService) UpdatePosition(ctx context.Context, params domain.UpdateP return s.q.UpdatePosition(ctx, store.UpdatePositionDomainToDB(params)) } -/* - type DeletePositionParams struct { - OfficerID string - Semester string - Tier int64 - } -*/ -func (s *BoardService) DeletePosition(ctx context.Context, arg domain.Position) error { +func (s *BoardService) DeletePosition(ctx context.Context, arg domain.DeletePosition) error { return s.q.DeletePosition(ctx, dbmodels.DeletePositionParams{ OfficerID: arg.OfficerID, Semester: arg.Semester, diff --git a/internal/api/store/board_mapper.go b/internal/api/store/board_mapper.go index 7a08b257..34b9fec2 100644 --- a/internal/api/store/board_mapper.go +++ b/internal/api/store/board_mapper.go @@ -15,7 +15,6 @@ func OfficerDomainToDB(officer domain.Officer) dbmodels.CreateOfficerParams { func UpdateOfficerDomainToDB(officer domain.UpdateOfficer) dbmodels.UpdateOfficerParams { return dbmodels.UpdateOfficerParams{ - Uuid: officer.Uuid, FullName: stringValue(officer.FullName), Picture: stringToNullString(officer.Picture), Github: stringToNullString(officer.Github), @@ -77,41 +76,41 @@ func TierDBToDomain(tier dbmodels.Tier) domain.Tier { func PositionDomainToDB(position domain.Position) dbmodels.CreatePositionParams { return dbmodels.CreatePositionParams{ - Oid: position.Oid, - Semester: position.Semester, - Tier: int64(position.Tier), - FullName: position.FullName, - Title: stringToNullString(position.Title), - Team: stringToNullString(position.Team), + OfficerID: position.OfficerID, + Semester: position.Semester, + Tier: int64(position.Tier), + FullName: position.FullName, + Title: stringToNullString(position.Title), + Team: stringToNullString(position.Team), } } func UpdatePositionDomainToDB(position domain.UpdatePosition) dbmodels.UpdatePositionParams { return dbmodels.UpdatePositionParams{ - Oid: position.Oid, - Semester: position.Semester, - Tier: int64(position.Tier), - FullName: position.FullName, - Title: stringToNullString(position.Title), - Team: stringToNullString(position.Team), + OfficerID: position.OfficerID, + Semester: position.Semester, + Tier: int64(position.Tier), + FullName: position.FullName, + Title: stringToNullString(position.Title), + Team: stringToNullString(position.Team), } } func DeletePositionDomainToDB(position domain.Position) dbmodels.DeletePositionParams { return dbmodels.DeletePositionParams{ - Oid: position.Oid, - Semester: position.Semester, - Tier: int64(position.Tier), + OfficerID: position.OfficerID, + Semester: position.Semester, + Tier: int64(position.Tier), } } func PositionDBToDomain(position dbmodels.Position) domain.Position { return domain.Position{ - Oid: position.Oid, - Semester: position.Semester, - Tier: int(position.Tier), - FullName: position.FullName, - Title: nullStringPtr(position.Title), - Team: nullStringPtr(position.Team), + OfficerID: position.OfficerID, + Semester: position.Semester, + Tier: position.Tier, + FullName: position.FullName, + Title: nullStringPtr(position.Title), + Team: nullStringPtr(position.Team), } } From c732c62da068c1aad175448c3ad798b9176b3cac Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 18:39:56 -0700 Subject: [PATCH 12/23] gen swag docs --- internal/api/docs/docs.go | 214 ++++++++++++--------------------- internal/api/docs/swagger.json | 214 ++++++++++++--------------------- internal/api/docs/swagger.yaml | 168 ++++++++++---------------- 3 files changed, 212 insertions(+), 384 deletions(-) diff --git a/internal/api/docs/docs.go b/internal/api/docs/docs.go index 20f97c5f..c9117ae3 100644 --- a/internal/api/docs/docs.go +++ b/internal/api/docs/docs.go @@ -513,7 +513,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/dbmodels.Position" + "$ref": "#/definitions/dto.Position" } } }, @@ -547,7 +547,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.UpdatePositionParams" + "$ref": "#/definitions/dto.UpdatePosition" } } ], @@ -609,7 +609,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.CreatePositionParams" + "$ref": "#/definitions/dto.Position" } } ], @@ -660,7 +660,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.DeletePositionParams" + "$ref": "#/definitions/dto.Position" } } ], @@ -730,7 +730,7 @@ const docTemplate = `{ "200": { "description": "Position details", "schema": { - "$ref": "#/definitions/dbmodels.Position" + "$ref": "#/definitions/dto.Position" } }, "404": { @@ -773,7 +773,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/dbmodels.Tier" + "$ref": "#/definitions/dto.Tier" } } }, @@ -807,7 +807,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.CreateTierParams" + "$ref": "#/definitions/dto.Tier" } } ], @@ -840,7 +840,7 @@ const docTemplate = `{ } } }, - "/v1/board/tiers/{id}": { + "/v1/board/tiers/{tier}": { "get": { "description": "Retrieves a single tier from the database.", "consumes": [ @@ -857,7 +857,7 @@ const docTemplate = `{ { "type": "integer", "description": "Tier number", - "name": "id", + "name": "tier", "in": "path", "required": true } @@ -866,7 +866,7 @@ const docTemplate = `{ "200": { "description": "Tier details", "schema": { - "$ref": "#/definitions/dbmodels.Tier" + "$ref": "#/definitions/dto.Tier" } }, "400": { @@ -924,7 +924,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.UpdateTierParams" + "$ref": "#/definitions/dto.UpdateTier" } } ], @@ -983,7 +983,7 @@ const docTemplate = `{ { "type": "integer", "description": "Tier number", - "name": "id", + "name": "tier", "in": "path", "required": true } @@ -1319,63 +1319,6 @@ const docTemplate = `{ } } }, - "dbmodels.CreatePositionParams": { - "type": "object", - "properties": { - "fullName": { - "type": "string" - }, - "oid": { - "type": "string" - }, - "semester": { - "type": "string" - }, - "team": { - "$ref": "#/definitions/sql.NullString" - }, - "tier": { - "type": "integer", - "format": "int64" - }, - "title": { - "$ref": "#/definitions/sql.NullString" - } - } - }, - "dbmodels.CreateTierParams": { - "type": "object", - "properties": { - "team": { - "$ref": "#/definitions/sql.NullString" - }, - "tier": { - "type": "integer", - "format": "int64" - }, - "tindex": { - "$ref": "#/definitions/sql.NullInt64" - }, - "title": { - "$ref": "#/definitions/sql.NullString" - } - } - }, - "dbmodels.DeletePositionParams": { - "type": "object", - "properties": { - "oid": { - "type": "string" - }, - "semester": { - "type": "string" - }, - "tier": { - "type": "integer", - "format": "int64" - } - } - }, "dbmodels.Event": { "type": "object", "properties": { @@ -1401,114 +1344,110 @@ const docTemplate = `{ } } }, - "dbmodels.Position": { + "dbmodels.UpdateEventParams": { "type": "object", "properties": { - "fullName": { - "type": "string" + "endAt": { + "$ref": "#/definitions/sql.NullInt64" }, - "oid": { - "type": "string" + "host": { + "$ref": "#/definitions/sql.NullString" }, - "semester": { - "type": "string" + "isAllDay": { + "$ref": "#/definitions/sql.NullBool" }, - "team": { + "location": { "$ref": "#/definitions/sql.NullString" }, - "tier": { - "type": "integer", - "format": "int64" + "startAt": { + "$ref": "#/definitions/sql.NullInt64" }, - "title": { - "$ref": "#/definitions/sql.NullString" + "uuid": { + "type": "string" } } }, - "dbmodels.Tier": { + "dto.Announcement": { "type": "object", "properties": { - "team": { - "$ref": "#/definitions/sql.NullString" + "announce_at": { + "type": "integer" }, - "tier": { - "type": "integer", - "format": "int64" + "discord_channel_id": { + "type": "string" }, - "tindex": { - "$ref": "#/definitions/sql.NullInt64" + "discord_message_id": { + "type": "string" }, - "title": { - "$ref": "#/definitions/sql.NullString" + "uuid": { + "type": "string" + }, + "visibility": { + "type": "string" } } }, - "dbmodels.UpdateEventParams": { + "dto.Officer": { "type": "object", "properties": { - "endAt": { - "$ref": "#/definitions/sql.NullInt64" - }, - "host": { - "$ref": "#/definitions/sql.NullString" + "discord": { + "type": "string" }, - "isAllDay": { - "$ref": "#/definitions/sql.NullBool" + "full_name": { + "type": "string" }, - "location": { - "$ref": "#/definitions/sql.NullString" + "github": { + "type": "string" }, - "startAt": { - "$ref": "#/definitions/sql.NullInt64" + "picture": { + "type": "string" }, "uuid": { "type": "string" } } }, - "dbmodels.UpdatePositionParams": { + "dto.Position": { "type": "object", "properties": { - "fullName": { + "full_name": { "type": "string" }, - "oid": { + "officer_id": { "type": "string" }, "semester": { "type": "string" }, "team": { - "$ref": "#/definitions/sql.NullString" + "type": "string" }, "tier": { - "type": "integer", - "format": "int64" + "type": "integer" }, "title": { - "$ref": "#/definitions/sql.NullString" + "type": "string" } } }, - "dbmodels.UpdateTierParams": { + "dto.Tier": { "type": "object", "properties": { + "t_index": { + "type": "integer" + }, "team": { - "$ref": "#/definitions/sql.NullString" + "type": "string" }, "tier": { - "type": "integer", - "format": "int64" - }, - "tindex": { - "$ref": "#/definitions/sql.NullInt64" + "type": "integer" }, "title": { - "$ref": "#/definitions/sql.NullString" + "type": "string" } } }, - "dto.Announcement": { + "dto.UpdateAnnouncement": { "type": "object", "properties": { "announce_at": { @@ -1528,7 +1467,7 @@ const docTemplate = `{ } } }, - "dto.Officer": { + "dto.UpdateOfficer": { "type": "object", "properties": { "discord": { @@ -1542,45 +1481,42 @@ const docTemplate = `{ }, "picture": { "type": "string" - }, - "uuid": { - "type": "string" } } }, - "dto.UpdateAnnouncement": { + "dto.UpdatePosition": { "type": "object", "properties": { - "announce_at": { - "type": "integer" + "full_name": { + "type": "string" }, - "discord_channel_id": { + "officer_id": { "type": "string" }, - "discord_message_id": { + "semester": { "type": "string" }, - "uuid": { + "team": { "type": "string" }, - "visibility": { + "tier": { + "type": "integer" + }, + "title": { "type": "string" } } }, - "dto.UpdateOfficer": { + "dto.UpdateTier": { "type": "object", "properties": { - "discord": { - "type": "string" - }, - "full_name": { - "type": "string" + "t_index": { + "type": "integer" }, - "github": { + "team": { "type": "string" }, - "picture": { + "title": { "type": "string" } } diff --git a/internal/api/docs/swagger.json b/internal/api/docs/swagger.json index 7063bc9b..cf8d06c9 100644 --- a/internal/api/docs/swagger.json +++ b/internal/api/docs/swagger.json @@ -502,7 +502,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/dbmodels.Position" + "$ref": "#/definitions/dto.Position" } } }, @@ -536,7 +536,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.UpdatePositionParams" + "$ref": "#/definitions/dto.UpdatePosition" } } ], @@ -598,7 +598,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.CreatePositionParams" + "$ref": "#/definitions/dto.Position" } } ], @@ -649,7 +649,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.DeletePositionParams" + "$ref": "#/definitions/dto.Position" } } ], @@ -719,7 +719,7 @@ "200": { "description": "Position details", "schema": { - "$ref": "#/definitions/dbmodels.Position" + "$ref": "#/definitions/dto.Position" } }, "404": { @@ -762,7 +762,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/dbmodels.Tier" + "$ref": "#/definitions/dto.Tier" } } }, @@ -796,7 +796,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.CreateTierParams" + "$ref": "#/definitions/dto.Tier" } } ], @@ -829,7 +829,7 @@ } } }, - "/v1/board/tiers/{id}": { + "/v1/board/tiers/{tier}": { "get": { "description": "Retrieves a single tier from the database.", "consumes": [ @@ -846,7 +846,7 @@ { "type": "integer", "description": "Tier number", - "name": "id", + "name": "tier", "in": "path", "required": true } @@ -855,7 +855,7 @@ "200": { "description": "Tier details", "schema": { - "$ref": "#/definitions/dbmodels.Tier" + "$ref": "#/definitions/dto.Tier" } }, "400": { @@ -913,7 +913,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dbmodels.UpdateTierParams" + "$ref": "#/definitions/dto.UpdateTier" } } ], @@ -972,7 +972,7 @@ { "type": "integer", "description": "Tier number", - "name": "id", + "name": "tier", "in": "path", "required": true } @@ -1308,63 +1308,6 @@ } } }, - "dbmodels.CreatePositionParams": { - "type": "object", - "properties": { - "fullName": { - "type": "string" - }, - "oid": { - "type": "string" - }, - "semester": { - "type": "string" - }, - "team": { - "$ref": "#/definitions/sql.NullString" - }, - "tier": { - "type": "integer", - "format": "int64" - }, - "title": { - "$ref": "#/definitions/sql.NullString" - } - } - }, - "dbmodels.CreateTierParams": { - "type": "object", - "properties": { - "team": { - "$ref": "#/definitions/sql.NullString" - }, - "tier": { - "type": "integer", - "format": "int64" - }, - "tindex": { - "$ref": "#/definitions/sql.NullInt64" - }, - "title": { - "$ref": "#/definitions/sql.NullString" - } - } - }, - "dbmodels.DeletePositionParams": { - "type": "object", - "properties": { - "oid": { - "type": "string" - }, - "semester": { - "type": "string" - }, - "tier": { - "type": "integer", - "format": "int64" - } - } - }, "dbmodels.Event": { "type": "object", "properties": { @@ -1390,114 +1333,110 @@ } } }, - "dbmodels.Position": { + "dbmodels.UpdateEventParams": { "type": "object", "properties": { - "fullName": { - "type": "string" + "endAt": { + "$ref": "#/definitions/sql.NullInt64" }, - "oid": { - "type": "string" + "host": { + "$ref": "#/definitions/sql.NullString" }, - "semester": { - "type": "string" + "isAllDay": { + "$ref": "#/definitions/sql.NullBool" }, - "team": { + "location": { "$ref": "#/definitions/sql.NullString" }, - "tier": { - "type": "integer", - "format": "int64" + "startAt": { + "$ref": "#/definitions/sql.NullInt64" }, - "title": { - "$ref": "#/definitions/sql.NullString" + "uuid": { + "type": "string" } } }, - "dbmodels.Tier": { + "dto.Announcement": { "type": "object", "properties": { - "team": { - "$ref": "#/definitions/sql.NullString" + "announce_at": { + "type": "integer" }, - "tier": { - "type": "integer", - "format": "int64" + "discord_channel_id": { + "type": "string" }, - "tindex": { - "$ref": "#/definitions/sql.NullInt64" + "discord_message_id": { + "type": "string" }, - "title": { - "$ref": "#/definitions/sql.NullString" + "uuid": { + "type": "string" + }, + "visibility": { + "type": "string" } } }, - "dbmodels.UpdateEventParams": { + "dto.Officer": { "type": "object", "properties": { - "endAt": { - "$ref": "#/definitions/sql.NullInt64" - }, - "host": { - "$ref": "#/definitions/sql.NullString" + "discord": { + "type": "string" }, - "isAllDay": { - "$ref": "#/definitions/sql.NullBool" + "full_name": { + "type": "string" }, - "location": { - "$ref": "#/definitions/sql.NullString" + "github": { + "type": "string" }, - "startAt": { - "$ref": "#/definitions/sql.NullInt64" + "picture": { + "type": "string" }, "uuid": { "type": "string" } } }, - "dbmodels.UpdatePositionParams": { + "dto.Position": { "type": "object", "properties": { - "fullName": { + "full_name": { "type": "string" }, - "oid": { + "officer_id": { "type": "string" }, "semester": { "type": "string" }, "team": { - "$ref": "#/definitions/sql.NullString" + "type": "string" }, "tier": { - "type": "integer", - "format": "int64" + "type": "integer" }, "title": { - "$ref": "#/definitions/sql.NullString" + "type": "string" } } }, - "dbmodels.UpdateTierParams": { + "dto.Tier": { "type": "object", "properties": { + "t_index": { + "type": "integer" + }, "team": { - "$ref": "#/definitions/sql.NullString" + "type": "string" }, "tier": { - "type": "integer", - "format": "int64" - }, - "tindex": { - "$ref": "#/definitions/sql.NullInt64" + "type": "integer" }, "title": { - "$ref": "#/definitions/sql.NullString" + "type": "string" } } }, - "dto.Announcement": { + "dto.UpdateAnnouncement": { "type": "object", "properties": { "announce_at": { @@ -1517,7 +1456,7 @@ } } }, - "dto.Officer": { + "dto.UpdateOfficer": { "type": "object", "properties": { "discord": { @@ -1531,45 +1470,42 @@ }, "picture": { "type": "string" - }, - "uuid": { - "type": "string" } } }, - "dto.UpdateAnnouncement": { + "dto.UpdatePosition": { "type": "object", "properties": { - "announce_at": { - "type": "integer" + "full_name": { + "type": "string" }, - "discord_channel_id": { + "officer_id": { "type": "string" }, - "discord_message_id": { + "semester": { "type": "string" }, - "uuid": { + "team": { "type": "string" }, - "visibility": { + "tier": { + "type": "integer" + }, + "title": { "type": "string" } } }, - "dto.UpdateOfficer": { + "dto.UpdateTier": { "type": "object", "properties": { - "discord": { - "type": "string" - }, - "full_name": { - "type": "string" + "t_index": { + "type": "integer" }, - "github": { + "team": { "type": "string" }, - "picture": { + "title": { "type": "string" } } diff --git a/internal/api/docs/swagger.yaml b/internal/api/docs/swagger.yaml index f8ab2102..62a63cf1 100644 --- a/internal/api/docs/swagger.yaml +++ b/internal/api/docs/swagger.yaml @@ -16,44 +16,6 @@ definitions: uuid: type: string type: object - dbmodels.CreatePositionParams: - properties: - fullName: - type: string - oid: - type: string - semester: - type: string - team: - $ref: '#/definitions/sql.NullString' - tier: - format: int64 - type: integer - title: - $ref: '#/definitions/sql.NullString' - type: object - dbmodels.CreateTierParams: - properties: - team: - $ref: '#/definitions/sql.NullString' - tier: - format: int64 - type: integer - tindex: - $ref: '#/definitions/sql.NullInt64' - title: - $ref: '#/definitions/sql.NullString' - type: object - dbmodels.DeletePositionParams: - properties: - oid: - type: string - semester: - type: string - tier: - format: int64 - type: integer - type: object dbmodels.Event: properties: endAt: @@ -71,34 +33,6 @@ definitions: uuid: type: string type: object - dbmodels.Position: - properties: - fullName: - type: string - oid: - type: string - semester: - type: string - team: - $ref: '#/definitions/sql.NullString' - tier: - format: int64 - type: integer - title: - $ref: '#/definitions/sql.NullString' - type: object - dbmodels.Tier: - properties: - team: - $ref: '#/definitions/sql.NullString' - tier: - format: int64 - type: integer - tindex: - $ref: '#/definitions/sql.NullInt64' - title: - $ref: '#/definitions/sql.NullString' - type: object dbmodels.UpdateEventParams: properties: endAt: @@ -114,34 +48,6 @@ definitions: uuid: type: string type: object - dbmodels.UpdatePositionParams: - properties: - fullName: - type: string - oid: - type: string - semester: - type: string - team: - $ref: '#/definitions/sql.NullString' - tier: - format: int64 - type: integer - title: - $ref: '#/definitions/sql.NullString' - type: object - dbmodels.UpdateTierParams: - properties: - team: - $ref: '#/definitions/sql.NullString' - tier: - format: int64 - type: integer - tindex: - $ref: '#/definitions/sql.NullInt64' - title: - $ref: '#/definitions/sql.NullString' - type: object dto.Announcement: properties: announce_at: @@ -168,6 +74,32 @@ definitions: uuid: type: string type: object + dto.Position: + properties: + full_name: + type: string + officer_id: + type: string + semester: + type: string + team: + type: string + tier: + type: integer + title: + type: string + type: object + dto.Tier: + properties: + t_index: + type: integer + team: + type: string + tier: + type: integer + title: + type: string + type: object dto.UpdateAnnouncement: properties: announce_at: @@ -192,6 +124,30 @@ definitions: picture: type: string type: object + dto.UpdatePosition: + properties: + full_name: + type: string + officer_id: + type: string + semester: + type: string + team: + type: string + tier: + type: integer + title: + type: string + type: object + dto.UpdateTier: + properties: + t_index: + type: integer + team: + type: string + title: + type: string + type: object sql.NullBool: properties: bool: @@ -550,7 +506,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/dbmodels.DeletePositionParams' + $ref: '#/definitions/dto.Position' produces: - application/json responses: @@ -592,7 +548,7 @@ paths: description: List of positions schema: items: - $ref: '#/definitions/dbmodels.Position' + $ref: '#/definitions/dto.Position' type: array "500": description: Internal Server Error @@ -613,7 +569,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/dbmodels.CreatePositionParams' + $ref: '#/definitions/dto.Position' produces: - application/json responses: @@ -647,7 +603,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/dbmodels.UpdatePositionParams' + $ref: '#/definitions/dto.UpdatePosition' produces: - application/json responses: @@ -695,7 +651,7 @@ paths: "200": description: Position details schema: - $ref: '#/definitions/dbmodels.Position' + $ref: '#/definitions/dto.Position' "404": description: Not Found schema: @@ -723,7 +679,7 @@ paths: description: List of tiers schema: items: - $ref: '#/definitions/dbmodels.Tier' + $ref: '#/definitions/dto.Tier' type: array "500": description: Internal Server Error @@ -744,7 +700,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/dbmodels.CreateTierParams' + $ref: '#/definitions/dto.Tier' produces: - application/json responses: @@ -768,7 +724,7 @@ paths: summary: Creates a new tier tags: - Board - /v1/board/tiers/{id}: + /v1/board/tiers/{tier}: delete: consumes: - application/json @@ -776,7 +732,7 @@ paths: parameters: - description: Tier number in: path - name: id + name: tier required: true type: integer produces: @@ -816,7 +772,7 @@ paths: parameters: - description: Tier number in: path - name: id + name: tier required: true type: integer produces: @@ -825,7 +781,7 @@ paths: "200": description: Tier details schema: - $ref: '#/definitions/dbmodels.Tier' + $ref: '#/definitions/dto.Tier' "400": description: Bad Request schema: @@ -862,7 +818,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/dbmodels.UpdateTierParams' + $ref: '#/definitions/dto.UpdateTier' produces: - application/json responses: From 844baae5578ace002c9a60ffd9c5b0800c3d786b Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 18:46:58 -0700 Subject: [PATCH 13/23] cleanup dtos --- fixtures/position_create.json | 2 +- fixtures/position_delete.json | 2 +- fixtures/position_update.json | 12 +++--------- fixtures/tier_create.json | 15 +++------------ fixtures/tier_create_dev_team.json | 15 +++------------ 5 files changed, 11 insertions(+), 35 deletions(-) diff --git a/fixtures/position_create.json b/fixtures/position_create.json index f3dce6a6..d95d0c1c 100644 --- a/fixtures/position_create.json +++ b/fixtures/position_create.json @@ -1,5 +1,5 @@ { - "oid": "alice-johnson-uuid", + "officer_id": "alice-johnson-uuid", "semester": "Spring 2024", "tier": 1 } diff --git a/fixtures/position_delete.json b/fixtures/position_delete.json index e6e7db92..1ef6fe68 100644 --- a/fixtures/position_delete.json +++ b/fixtures/position_delete.json @@ -1,5 +1,5 @@ { - "oid": "bob-smith-uuid", + "officer_id": "bob-smith-uuid", "semester": "Fall 2023", "tier": 2 } diff --git a/fixtures/position_update.json b/fixtures/position_update.json index 9193ad0c..bd57921a 100644 --- a/fixtures/position_update.json +++ b/fixtures/position_update.json @@ -1,14 +1,8 @@ { - "oid": "alice-johnson-uuid", + "officer_id": "alice-johnson-uuid", "semester": "Spring 2024", "tier": 1, "full_name": "Alice M. Johnson", - "title": { - "string": "President & Event Coordinator", - "valid": true - }, - "team": { - "string": "Leadership", - "valid": true - } + "title": "President & Event Coordinator", + "team": "Leadership" } diff --git a/fixtures/tier_create.json b/fixtures/tier_create.json index 91b0c0c9..ecc81cb5 100644 --- a/fixtures/tier_create.json +++ b/fixtures/tier_create.json @@ -1,15 +1,6 @@ { "tier": 1, - "title": { - "string": "President", - "valid": true - }, - "t_index": { - "int64": 100, - "valid": true - }, - "team": { - "string": "Executive", - "valid": true - } + "title": "President", + "t_index": 100, + "team": "Executive" } diff --git a/fixtures/tier_create_dev_team.json b/fixtures/tier_create_dev_team.json index f019a1fe..a3a377eb 100644 --- a/fixtures/tier_create_dev_team.json +++ b/fixtures/tier_create_dev_team.json @@ -1,15 +1,6 @@ { "tier": 3, - "title": { - "string": "Developer", - "valid": true - }, - "t_index": { - "int64": 300, - "valid": true - }, - "team": { - "string": "Dev Team", - "valid": true - } + "title": "Developer", + "t_index": 300, + "team": "Dev Team" } From 8d6e0b0fca636ffc8a5c46af33de0c8c0ce4c419 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 19:05:13 -0700 Subject: [PATCH 14/23] fix tier url param --- internal/api/handlers/board.go | 4 +++- internal/api/routes/v1.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index 150191b6..f95d3fff 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -5,6 +5,7 @@ package handlers import ( "net/http" "strconv" + "log" "github.com/acmcsufoss/api.acmcsuf.com/internal/api/services" "github.com/acmcsufoss/api.acmcsuf.com/internal/dto" @@ -228,11 +229,12 @@ func (h *BoardHandler) GetTiers(c *gin.Context) { // @Router /v1/board/tiers/{tier} [get] func (h *BoardHandler) GetTier(c *gin.Context) { ctx := c.Request.Context() - tierName, err := strconv.ParseInt(c.Param("tierName"), 10, 64) + tierName, err := strconv.ParseInt(c.Param("tier"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid tier number", }) + log.Println(err) return } diff --git a/internal/api/routes/v1.go b/internal/api/routes/v1.go index 48f13c6b..272c799d 100644 --- a/internal/api/routes/v1.go +++ b/internal/api/routes/v1.go @@ -55,7 +55,7 @@ func SetupV1(router *gin.Engine, eventService services.EventsServicer, board.GET("/officers/:id", bh.GetOfficer) board.GET("/tiers", bh.GetTiers) - board.GET("/tiers/:id", bh.GetTier) + board.GET("/tiers/:tier", bh.GetTier) board.GET("/positions", bh.GetPositions) board.GET("/positions/:id", bh.GetPosition) From c116044ffb43f00f30ccb3b44ea7d969028a0f46 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 19:09:50 -0700 Subject: [PATCH 15/23] tier update works --- fixtures/tier_update.json | 15 +++------------ internal/api/routes/v1.go | 4 ++-- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/fixtures/tier_update.json b/fixtures/tier_update.json index ddfe4a39..6a1acf02 100644 --- a/fixtures/tier_update.json +++ b/fixtures/tier_update.json @@ -1,15 +1,6 @@ { "tier": 1, - "title": { - "string": "Club President", - "valid": true - }, - "t_index": { - "int64": 50, - "valid": true - }, - "team": { - "string": "Leadership", - "valid": true - } + "title": "Treasurer", + "t_index": 50, + "team": "Leadership" } diff --git a/internal/api/routes/v1.go b/internal/api/routes/v1.go index 272c799d..beb7e3ff 100644 --- a/internal/api/routes/v1.go +++ b/internal/api/routes/v1.go @@ -83,8 +83,8 @@ func SetupV1(router *gin.Engine, eventService services.EventsServicer, // Tiers board.POST("/tiers", bh.CreateTier) - board.PUT("/tiers/:id", bh.UpdateTier) - board.DELETE("/tiers/:id", bh.DeleteTier) + board.PUT("/tiers/:tier", bh.UpdateTier) + board.DELETE("/tiers/:tier", bh.DeleteTier) // Positions board.POST("/positions", bh.CreatePosition) From 1769c87da9ff389bb8913dc03dec137f18ada9d9 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 19:30:11 -0700 Subject: [PATCH 16/23] change pos delete fixutre --- fixtures/position_delete.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fixtures/position_delete.json b/fixtures/position_delete.json index 1ef6fe68..d95d0c1c 100644 --- a/fixtures/position_delete.json +++ b/fixtures/position_delete.json @@ -1,5 +1,5 @@ { - "officer_id": "bob-smith-uuid", - "semester": "Fall 2023", - "tier": 2 + "officer_id": "alice-johnson-uuid", + "semester": "Spring 2024", + "tier": 1 } From 17b884589c4912c320fe6a935ad71ec0515aff67 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 19:38:47 -0700 Subject: [PATCH 17/23] fix swag docs for delete positions --- internal/api/docs/docs.go | 16 +++++++++++++++- internal/api/docs/swagger.json | 16 +++++++++++++++- internal/api/docs/swagger.yaml | 11 ++++++++++- internal/api/handlers/board.go | 2 +- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/internal/api/docs/docs.go b/internal/api/docs/docs.go index c9117ae3..6facf5c6 100644 --- a/internal/api/docs/docs.go +++ b/internal/api/docs/docs.go @@ -660,7 +660,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.Position" + "$ref": "#/definitions/dto.DeletePosition" } } ], @@ -1387,6 +1387,20 @@ const docTemplate = `{ } } }, + "dto.DeletePosition": { + "type": "object", + "properties": { + "officer_id": { + "type": "string" + }, + "semester": { + "type": "string" + }, + "tier": { + "type": "integer" + } + } + }, "dto.Officer": { "type": "object", "properties": { diff --git a/internal/api/docs/swagger.json b/internal/api/docs/swagger.json index cf8d06c9..03fa8a1b 100644 --- a/internal/api/docs/swagger.json +++ b/internal/api/docs/swagger.json @@ -649,7 +649,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.Position" + "$ref": "#/definitions/dto.DeletePosition" } } ], @@ -1376,6 +1376,20 @@ } } }, + "dto.DeletePosition": { + "type": "object", + "properties": { + "officer_id": { + "type": "string" + }, + "semester": { + "type": "string" + }, + "tier": { + "type": "integer" + } + } + }, "dto.Officer": { "type": "object", "properties": { diff --git a/internal/api/docs/swagger.yaml b/internal/api/docs/swagger.yaml index 62a63cf1..b755df48 100644 --- a/internal/api/docs/swagger.yaml +++ b/internal/api/docs/swagger.yaml @@ -61,6 +61,15 @@ definitions: visibility: type: string type: object + dto.DeletePosition: + properties: + officer_id: + type: string + semester: + type: string + tier: + type: integer + type: object dto.Officer: properties: discord: @@ -506,7 +515,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/dto.Position' + $ref: '#/definitions/dto.DeletePosition' produces: - application/json responses: diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index f95d3fff..2c758822 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -511,7 +511,7 @@ func (h *BoardHandler) UpdatePosition(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Param body body dto.Position true "Position identifier" +// @Param body body dto.DeletePosition true "Position identifier" // @Success 200 {object} map[string]string "Success message" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string From 915f858260aac3fbf30fc889e4b9f00197bd0aee Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 19:40:45 -0700 Subject: [PATCH 18/23] fix id->tier rename in swag docs --- internal/api/docs/docs.go | 2 +- internal/api/docs/swagger.json | 2 +- internal/api/docs/swagger.yaml | 2 +- internal/api/handlers/board.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/api/docs/docs.go b/internal/api/docs/docs.go index 6facf5c6..b7396e71 100644 --- a/internal/api/docs/docs.go +++ b/internal/api/docs/docs.go @@ -914,7 +914,7 @@ const docTemplate = `{ { "type": "integer", "description": "Tier number", - "name": "id", + "name": "tier", "in": "path", "required": true }, diff --git a/internal/api/docs/swagger.json b/internal/api/docs/swagger.json index 03fa8a1b..7d99281a 100644 --- a/internal/api/docs/swagger.json +++ b/internal/api/docs/swagger.json @@ -903,7 +903,7 @@ { "type": "integer", "description": "Tier number", - "name": "id", + "name": "tier", "in": "path", "required": true }, diff --git a/internal/api/docs/swagger.yaml b/internal/api/docs/swagger.yaml index b755df48..6c73f9cb 100644 --- a/internal/api/docs/swagger.yaml +++ b/internal/api/docs/swagger.yaml @@ -819,7 +819,7 @@ paths: parameters: - description: Tier number in: path - name: id + name: tier required: true type: integer - description: Updated tier data diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index 2c758822..d9193cf3 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -298,7 +298,7 @@ func (h *BoardHandler) CreateTier(c *gin.Context) { // @Tags Board // @Accept json // @Produce json -// @Param id path int true "Tier number" +// @Param tier path int true "Tier number" // @Param body body dto.UpdateTier true "Updated tier data" // @Success 200 {object} map[string]string "Success message" // @Failure 400 {object} map[string]string From ad5e03ee965fd00414153bee667b9d507d6f9469 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 19:41:34 -0700 Subject: [PATCH 19/23] respond with dtoPostions --- internal/api/handlers/board.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index d9193cf3..26238e92 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -396,7 +396,7 @@ func (h *BoardHandler) GetPositions(c *gin.Context) { for i, pos := range positions { dtoPositions[i] = dto.PositionDomainToDto(&pos) } - c.JSON(http.StatusOK, positions) + c.JSON(http.StatusOK, dtoPositions) } // GetPosition godoc From 2dda9342b74b5c027fa5d948fe0f9367c39a7a59 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 19:42:53 -0700 Subject: [PATCH 20/23] " --- internal/api/handlers/board.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index 26238e92..5658e6fe 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -430,7 +430,7 @@ func (h *BoardHandler) GetPosition(c *gin.Context) { return } - c.JSON(http.StatusOK, position) + c.JSON(http.StatusOK, dto.PositionDomainToDto(&position)) } // CreatePosition godoc From c2e4d45d5d3eb2acc619047858c95db54654142f Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 19:44:21 -0700 Subject: [PATCH 21/23] fix unreturned error --- internal/api/services/board.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/api/services/board.go b/internal/api/services/board.go index 3900f96f..232c66e2 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -139,7 +139,7 @@ func (s *BoardService) ListTiers(ctx context.Context, filters ...any) ([]domain. func (s *BoardService) CreateTier(ctx context.Context, params domain.Tier) (domain.Tier, error) { dbTier, err := s.q.CreateTier(ctx, store.TierDomainToDB(params)) if err != nil { - return domain.Tier{}, nil + return domain.Tier{}, err } return store.TierDBToDomain(dbTier), nil } From ea309e6cf2fc3afa3ea5166771aa1f6bdc94a8d0 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 19:47:16 -0700 Subject: [PATCH 22/23] fix more small bugs --- internal/api/services/board.go | 10 +++------- internal/api/store/board_mapper.go | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/internal/api/services/board.go b/internal/api/services/board.go index 232c66e2..2ccf9b94 100644 --- a/internal/api/services/board.go +++ b/internal/api/services/board.go @@ -160,7 +160,7 @@ func (s *BoardService) DeleteTier(ctx context.Context, tierName int64) error { func (s *BoardService) GetPosition(ctx context.Context, oid string) (domain.Position, error) { dbPosition, err := s.q.GetPosition(ctx, oid) if err != nil { - return domain.Position{}, nil + return domain.Position{}, err } return store.PositionDBToDomain(dbPosition), nil } @@ -179,7 +179,7 @@ func (s *BoardService) ListPositions(ctx context.Context, filters ...any) ([]dom } domainPositions := make([]domain.Position, len(result)) - for i, pos := range positions { + for i, pos := range result { domainPositions[i] = store.PositionDBToDomain(pos) } return domainPositions, nil @@ -199,9 +199,5 @@ func (s *BoardService) UpdatePosition(ctx context.Context, params domain.UpdateP } func (s *BoardService) DeletePosition(ctx context.Context, arg domain.DeletePosition) error { - return s.q.DeletePosition(ctx, dbmodels.DeletePositionParams{ - OfficerID: arg.OfficerID, - Semester: arg.Semester, - Tier: arg.Tier, - }) + return s.q.DeletePosition(ctx, store.DeletePositionDomainToDB(arg)) } diff --git a/internal/api/store/board_mapper.go b/internal/api/store/board_mapper.go index 34b9fec2..e8fa3bc3 100644 --- a/internal/api/store/board_mapper.go +++ b/internal/api/store/board_mapper.go @@ -96,11 +96,11 @@ func UpdatePositionDomainToDB(position domain.UpdatePosition) dbmodels.UpdatePos } } -func DeletePositionDomainToDB(position domain.Position) dbmodels.DeletePositionParams { +func DeletePositionDomainToDB(position domain.DeletePosition) dbmodels.DeletePositionParams { return dbmodels.DeletePositionParams{ OfficerID: position.OfficerID, Semester: position.Semester, - Tier: int64(position.Tier), + Tier: position.Tier, } } From c573e9a00e87e4a90753758afe7a3e409c00d18b Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 23 Apr 2026 20:09:02 -0700 Subject: [PATCH 23/23] formatting --- internal/api/handlers/board.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/api/handlers/board.go b/internal/api/handlers/board.go index 5658e6fe..0ef01920 100644 --- a/internal/api/handlers/board.go +++ b/internal/api/handlers/board.go @@ -3,9 +3,9 @@ package handlers import ( + "log" "net/http" "strconv" - "log" "github.com/acmcsufoss/api.acmcsuf.com/internal/api/services" "github.com/acmcsufoss/api.acmcsuf.com/internal/dto" @@ -500,7 +500,7 @@ func (h *BoardHandler) UpdatePosition(c *gin.Context) { } c.JSON(http.StatusOK, gin.H{ - "message": "Position updated successfully", + "message": "Position updated successfully", }) }