Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 19 additions & 120 deletions client/web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"@vitejs/plugin-react": "^5.1.1",
"eslint": "^9.39.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-boundaries": "^5.4.0",
"eslint-plugin-boundaries": "^5.1.0",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"eslint-plugin-simple-import-sort": "^12.1.1",
Expand Down
3 changes: 3 additions & 0 deletions cmd/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ func (app *application) mount() http.Handler {
r.Get("/hackathon-date-range", app.getHackathonDateRange)
r.Post("/hackathon-date-range", app.setHackathonDateRange)
r.Put("/scan-types", app.updateScanTypesHandler)
r.Get("/meal-groups", app.getMealGroups)
r.Put("/meal-groups", app.updateMealGroups)
r.Get("/meal-groups/stats", app.getMealGroupStats)
})

r.Route("/applications", func(r chi.Router) {
Expand Down
54 changes: 52 additions & 2 deletions cmd/api/scans.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package main

import (
"context"
"errors"
"math/rand"
"net/http"

"github.com/go-chi/chi"
Expand Down Expand Up @@ -29,6 +31,11 @@ type UpdateScanTypesPayload struct {
ScanTypes []store.ScanType `json:"scan_types" validate:"required,dive"`
}

type CreateScanResponse struct {
*store.Scan
MealGroup *string `json:"meal_group"`
}

// getScanTypesHandler returns all configured scan types
//
// @Summary Get scan types (Admin)
Expand Down Expand Up @@ -61,7 +68,7 @@ func (app *application) getScanTypesHandler(w http.ResponseWriter, r *http.Reque
// @Accept json
// @Produce json
// @Param scan body CreateScanPayload true "Scan to create"
// @Success 201 {object} store.Scan
// @Success 201 {object} CreateScanResponse
// @Failure 400 {object} object{error=string}
// @Failure 401 {object} object{error=string}
// @Failure 403 {object} object{error=string}
Expand Down Expand Up @@ -148,7 +155,23 @@ func (app *application) createScanHandler(w http.ResponseWriter, r *http.Request
return
}

if err := app.jsonResponse(w, http.StatusCreated, scan); err != nil {
if found.Category == store.ScanCategoryCheckIn {
app.assignMealGroup(r.Context(), req.UserID)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in the future we should separate meal scans and check in scans to different functions, might be helpful for implementing other things based on whether a person is checked in or not.

}

// Fetch meal group for response (non-fatal)
mealGroup, err := app.store.Application.GetMealGroupByUserID(r.Context(), req.UserID)
if err != nil && !errors.Is(err, store.ErrNotFound) {
// We don't want to fail the scan if we can't get the meal group info
app.logger.Warnw("failed to fetch meal group for scan response", "user_id", req.UserID, "error", err)
}

response := CreateScanResponse{
Scan: scan,
MealGroup: mealGroup,
}

if err := app.jsonResponse(w, http.StatusCreated, response); err != nil {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like the frontend wasn't updated to take in this new response format?

app.internalServerError(w, r, err)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a return here

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually its technically not needed, but include it for clarity

}
}
Expand Down Expand Up @@ -185,6 +208,33 @@ func (app *application) getUserScansHandler(w http.ResponseWriter, r *http.Reque
}
}

func (app *application) assignMealGroup(ctx context.Context, userID string) {
groups, err := app.store.Settings.GetMealGroups(ctx)
if err != nil {
app.logger.Warnw("failed to fetch meal groups for assignment", "error", err)
return
}

if len(groups) == 0 {
return
}

hackerApp, err := app.store.Application.GetByUserID(ctx, userID)
if err != nil {
app.logger.Warnw("failed to fetch application for meal group assignment", "user_id", userID, "error", err)
return
}

if hackerApp.MealGroup != nil {
return // Already assigned
}

selectedGroup := groups[rand.Intn(len(groups))]
if err := app.store.Application.SetMealGroup(ctx, hackerApp.ID, selectedGroup); err != nil {
app.logger.Warnw("failed to set meal group on application", "app_id", hackerApp.ID, "error", err)
}
}

// getScanStatsHandler returns aggregate scan counts grouped by scan type
//
// @Summary Get scan statistics (Admin)
Expand Down
Loading
Loading