fix(backend): resolve shift signup by looking up Member via ExternalUserId
All checks were successful
CI Pipeline / Backend Build & Test (pull_request) Successful in 52s
CI Pipeline / Frontend Lint, Test & Build (pull_request) Successful in 29s
CI Pipeline / Infrastructure Validation (pull_request) Successful in 5s

The signup/cancel endpoints were passing the Keycloak sub claim (external UUID)
directly as MemberId, but ShiftSignup.MemberId references the internal Member.Id.
Now ShiftService resolves ExternalUserId to the internal Member.Id before creating
the signup record. Integration tests updated to seed proper Member entities.
This commit is contained in:
WorkClub Automation
2026-03-09 13:24:50 +01:00
parent 1117cf2004
commit a8730245b2
3 changed files with 104 additions and 38 deletions

View File

@@ -118,17 +118,17 @@ public static class ShiftEndpoints
ShiftService shiftService,
HttpContext httpContext)
{
var userIdClaim = httpContext.User.FindFirst("sub")?.Value;
if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var memberId))
var externalUserId = httpContext.User.FindFirst("sub")?.Value;
if (string.IsNullOrEmpty(externalUserId))
{
return TypedResults.UnprocessableEntity("Invalid user ID");
}
var (success, error, isConflict) = await shiftService.SignUpForShiftAsync(id, memberId);
var (success, error, isConflict) = await shiftService.SignUpForShiftAsync(id, externalUserId);
if (!success)
{
if (error == "Shift not found")
if (error == "Shift not found" || error == "Member not found")
return TypedResults.NotFound();
if (error == "Cannot sign up for past shifts")
@@ -146,17 +146,17 @@ public static class ShiftEndpoints
ShiftService shiftService,
HttpContext httpContext)
{
var userIdClaim = httpContext.User.FindFirst("sub")?.Value;
if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var memberId))
var externalUserId = httpContext.User.FindFirst("sub")?.Value;
if (string.IsNullOrEmpty(externalUserId))
{
return TypedResults.UnprocessableEntity("Invalid user ID");
}
var (success, error) = await shiftService.CancelSignupAsync(id, memberId);
var (success, error) = await shiftService.CancelSignupAsync(id, externalUserId);
if (!success)
{
if (error == "Sign-up not found")
if (error == "Sign-up not found" || error == "Member not found")
return TypedResults.NotFound();
return TypedResults.UnprocessableEntity(error!);