fix(keycloak): update user club attributes with real database UUIDs

- Replaced placeholder UUIDs (club-1-uuid, club-2-uuid) with real database UUIDs
- Updated all 5 test users via Keycloak database
- Restarted Keycloak to clear caches and apply changes

Impact:
- JWT tokens now contain real UUIDs in clubs claim
- API endpoints accept X-Tenant-Id with real UUIDs (returns 200 OK)
- Unblocks 46 remaining QA scenarios

Documentation:
- Created update-keycloak-club-uuids.py script for automation
- Added KEYCLOAK_UPDATE_GUIDE.md with step-by-step instructions
- Recorded learnings in notepad

Ref: .sisyphus/evidence/final-f3-manual-qa.md lines 465-512
This commit is contained in:
WorkClub Automation
2026-03-05 14:21:44 +01:00
parent b813043195
commit e8c8dac5d4
20 changed files with 1777 additions and 154 deletions

View File

@@ -2082,3 +2082,65 @@ bunx playwright test shifts.spec.ts --reporter=list
- Add notification test (verify member receives email/notification on sign-up confirmation)
---
## Keycloak Club UUID Update (2026-03-05)
### Learnings
1. **Keycloak Admin API Limitations**
- PUT /admin/realms/{realm}/users/{id} returns 204 No Content but may not persist attribute changes
- Direct database updates are more reliable for user attributes
- Always verify with database queries after API calls
2. **Keycloak User Attributes**
- Stored in PostgreSQL `user_attribute` table (key-value pairs)
- User list endpoint (/users) includes attributes in response
- Single user endpoint (/users/{id}) may not include attributes in some configurations
- Attributes are JSON strings stored in VARCHAR fields
3. **Token Attribute Mapping**
- oidc-usermodel-attribute-mapper reads user attributes and includes in JWT
- Configuration: `user.attribute: clubs` → `claim.name: clubs` → `jsonType.label: JSON`
- Keycloak caches user data in memory after startup
- Restart required after database updates for token changes to take effect
4. **UUID Update Strategy**
- Map placeholder UUIDs to real database UUIDs
- Execute updates at database level for reliability
- Restart Keycloak to clear caches
- Verify via JWT token decoding (base64 decode part 2 of token)
- Test with API endpoints to confirm end-to-end flow
5. **Best Practices**
- Always verify updates in database before restarting services
- Document user-to-UUID mappings for future reference
- Create automated scripts for reproducibility
- Test both JWT tokens and API endpoints after updates
### Commands Proven Effective
**Update Database:**
```bash
docker exec workclub_postgres psql -U postgres -d keycloak << 'SQL'
UPDATE user_attribute SET value = '{json}' WHERE user_id = 'uuid' AND name = 'clubs';
SQL
```
**Restart Keycloak:**
```bash
docker restart workclub_keycloak && sleep 10
```
**Verify JWT:**
```bash
TOKEN=$(curl -s -X POST http://localhost:8080/realms/workclub/protocol/openid-connect/token \
-d "client_id=workclub-app" -d "grant_type=password" -d "username=user" -d "password=pass" | jq -r '.access_token')
echo $TOKEN | cut -d'.' -f2 | base64 -d | jq '.clubs'
```
### Resolved Blocker
**Blocker #2 (Critical)**: JWT clubs claim uses placeholders instead of real UUIDs
- Status: ✅ RESOLVED
- Impact: Unblocks 46 remaining QA scenarios
- Date: 2026-03-05