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
228 changes: 160 additions & 68 deletions client/web/package-lock.json

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions client/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,15 @@
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4",
"vite": "^7.2.4",
"vite-plugin-pwa": "^1.2.0"
"vite-plugin-pwa": "^0.19.8"
},
"overrides": {
"postcss": "^8.4.38",
"semver": "^7.5.2",
"minimatch": "^10.2.1"
"minimatch": "^10.2.1",
"serialize-javascript": "^7.0.5",
"vite-plugin-pwa": {
"vite": "$vite"
}
}
}
3 changes: 3 additions & 0 deletions cmd/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,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.Put("/applications-enabled", app.setApplicationsEnabled)
})

Expand Down
8 changes: 8 additions & 0 deletions cmd/api/applications.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (app *application) getOrCreateApplicationHandler(w http.ResponseWriter, r *

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -141,6 +142,7 @@ func (app *application) updateApplicationHandler(w http.ResponseWriter, r *http.

if err := app.jsonResponse(w, http.StatusOK, application); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -212,6 +214,7 @@ func (app *application) submitApplicationHandler(w http.ResponseWriter, r *http.

if err := app.jsonResponse(w, http.StatusOK, application); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -351,6 +354,7 @@ func (app *application) getApplicationStatsHandler(w http.ResponseWriter, r *htt

if err := app.jsonResponse(w, http.StatusOK, stats); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -456,6 +460,7 @@ func (app *application) listApplicationsHandler(w http.ResponseWriter, r *http.R

if err := app.jsonResponse(w, http.StatusOK, result); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -525,6 +530,7 @@ func (app *application) setApplicationStatus(w http.ResponseWriter, r *http.Requ

if err := app.jsonResponse(w, http.StatusOK, ApplicationResponse{Application: application}); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -573,6 +579,7 @@ func (app *application) getApplication(w http.ResponseWriter, r *http.Request) {

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -627,5 +634,6 @@ func (app *application) getApplicantEmailsByStatusHandler(w http.ResponseWriter,

if err = app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}
3 changes: 3 additions & 0 deletions cmd/api/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func (app *application) getCurrentUserHandler(w http.ResponseWriter, r *http.Req

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -79,6 +80,7 @@ func (app *application) checkEmailAuthMethodHandler(w http.ResponseWriter, r *ht
// Email not registered
if err := app.jsonResponse(w, http.StatusOK, CheckEmailResponse{Exists: false}); err != nil {
app.internalServerError(w, r, err)
return
}
return
}
Expand All @@ -92,5 +94,6 @@ func (app *application) checkEmailAuthMethodHandler(w http.ResponseWriter, r *ht
AuthMethod: &user.AuthMethod,
}); err != nil {
app.internalServerError(w, r, err)
return
}
}
1 change: 1 addition & 0 deletions cmd/api/reset_hackathon.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,6 @@ func (app *application) resetHackathonHandler(w http.ResponseWriter, r *http.Req

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}
3 changes: 3 additions & 0 deletions cmd/api/resume.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func (app *application) generateResumeUploadURLHandler(w http.ResponseWriter, r
ResumePath: objectPath,
}); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -142,6 +143,7 @@ func (app *application) deleteResumeHandler(w http.ResponseWriter, r *http.Reque

if err := app.jsonResponse(w, http.StatusOK, application); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -199,6 +201,7 @@ func (app *application) getResumeDownloadURLHandler(w http.ResponseWriter, r *ht
DownloadURL: downloadURL,
}); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down
7 changes: 7 additions & 0 deletions cmd/api/reviews.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func (app *application) getPendingReviews(w http.ResponseWriter, r *http.Request

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -94,6 +95,7 @@ func (app *application) getCompletedReviews(w http.ResponseWriter, r *http.Reque

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -130,6 +132,7 @@ func (app *application) getApplicationNotes(w http.ResponseWriter, r *http.Reque

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -160,6 +163,7 @@ func (app *application) batchAssignReviews(w http.ResponseWriter, r *http.Reques

if err := app.jsonResponse(w, http.StatusOK, result); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -202,6 +206,7 @@ func (app *application) getNextReview(w http.ResponseWriter, r *http.Request) {

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -259,6 +264,7 @@ func (app *application) submitVote(w http.ResponseWriter, r *http.Request) {

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -317,5 +323,6 @@ func (app *application) setAIPercent(w http.ResponseWriter, r *http.Request) {

if err := app.jsonResponse(w, http.StatusOK, response); err != nil {
app.internalServerError(w, r, err)
return
}
}
67 changes: 65 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,omitempty"`
}

// getScanTypesHandler returns all configured scan types
//
// @Summary Get scan types (Admin)
Expand All @@ -50,6 +57,7 @@ func (app *application) getScanTypesHandler(w http.ResponseWriter, r *http.Reque

if err := app.jsonResponse(w, http.StatusOK, ScanTypesResponse{ScanTypes: scanTypes}); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand All @@ -61,7 +69,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,8 +156,27 @@ func (app *application) createScanHandler(w http.ResponseWriter, r *http.Request
return
}

if err := app.jsonResponse(w, http.StatusCreated, scan); err != nil {
var mealGroup *string
if found.Category == store.ScanCategoryCheckIn {
mealGroup = app.assignMealGroup(r.Context(), req.UserID)
} else {
// Fetch meal group for response (non-fatal)
var err error
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 {
Comment thread
NoelVarghese2006 marked this conversation as resolved.
app.internalServerError(w, r, err)
Comment thread
NoelVarghese2006 marked this conversation as resolved.
return
}
}

Expand Down Expand Up @@ -182,9 +209,43 @@ func (app *application) getUserScansHandler(w http.ResponseWriter, r *http.Reque

if err := app.jsonResponse(w, http.StatusOK, ScansResponse{Scans: scans}); err != nil {
app.internalServerError(w, r, err)
return
}
}

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

if len(groups) == 0 {
return nil
}

hackerApp, err := app.store.Application.GetByUserID(ctx, userID)
if err != nil {
// If the user doesn't have an application, we can't assign a group.
if !errors.Is(err, store.ErrNotFound) {
app.logger.Warnw("failed to fetch application for meal group assignment", "user_id", userID, "error", err)
}
return nil
}

if hackerApp.MealGroup != nil {
return hackerApp.MealGroup // 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)
return nil
}

return &selectedGroup
}

// getScanStatsHandler returns aggregate scan counts grouped by scan type
//
// @Summary Get scan statistics (Admin)
Expand All @@ -206,6 +267,7 @@ func (app *application) getScanStatsHandler(w http.ResponseWriter, r *http.Reque

if err := app.jsonResponse(w, http.StatusOK, ScanStatsResponse{Stats: stats}); err != nil {
app.internalServerError(w, r, err)
return
}
}

Expand Down Expand Up @@ -265,5 +327,6 @@ func (app *application) updateScanTypesHandler(w http.ResponseWriter, r *http.Re

if err := app.jsonResponse(w, http.StatusOK, ScanTypesResponse(req)); err != nil {
app.internalServerError(w, r, err)
return
}
}
Loading
Loading