- Create domain entities in WorkClub.Domain/Entities: Club, Member, WorkItem, Shift, ShiftSignup - Implement enums: SportType, ClubRole, WorkItemStatus - Add ITenantEntity interface for multi-tenancy support - Implement state machine validation on WorkItem with C# 14 switch expressions - Valid transitions: Open→Assigned→InProgress→Review→Done, Review→InProgress (rework) - All invalid transitions throw InvalidOperationException - TDD approach: Write tests first, 12/12 passing - Use required properties with explicit Guid/Guid? for foreign keys - DateTimeOffset for timestamps (timezone-aware, multi-tenant friendly) - RowVersion byte[] for optimistic concurrency control - No navigation properties yet (deferred to EF Core task) - No domain events or validation attributes (YAGNI for MVP)
44 lines
1.1 KiB
Plaintext
44 lines
1.1 KiB
Plaintext
Task 3 JWT Claims Structure
|
|
============================
|
|
|
|
Expected JWT structure for admin@test.com after authentication:
|
|
|
|
{
|
|
"exp": <timestamp>,
|
|
"iat": <timestamp>,
|
|
"auth_time": <timestamp>,
|
|
"jti": "<uuid>",
|
|
"iss": "http://localhost:8080/realms/workclub",
|
|
"aud": "workclub-app",
|
|
"sub": "<user-uuid>",
|
|
"typ": "Bearer",
|
|
"azp": "workclub-app",
|
|
"session_state": "<uuid>",
|
|
"acr": "1",
|
|
"scope": "openid profile email",
|
|
"sid": "<uuid>",
|
|
"email_verified": true,
|
|
"clubs": {
|
|
"club-1-uuid": "admin",
|
|
"club-2-uuid": "member"
|
|
},
|
|
"name": "Admin User",
|
|
"given_name": "Admin",
|
|
"family_name": "User",
|
|
"email": "admin@test.com"
|
|
}
|
|
|
|
CRITICAL VERIFICATION POINTS:
|
|
|
|
1. 'clubs' claim MUST be present
|
|
2. 'clubs' claim MUST be JSON object (not string)
|
|
3. Claim structure: {"<tenant-id>": "<role>"}
|
|
4. For admin@test.com:
|
|
- Should have 2 entries (club-1-uuid and club-2-uuid)
|
|
- club-1-uuid value should be "admin"
|
|
- club-2-uuid value should be "member"
|
|
|
|
To verify after Docker startup:
|
|
./infra/keycloak/test-auth.sh
|
|
cat .sisyphus/evidence/task-3-jwt-claims.txt
|