Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.

fix(app): batch-2 — SSO roles, remove-member, notifications, idle session, admin seeder (+CI/lint)#85

Merged
Enes1998 merged 1 commit into
mainfrom
fix/prod-bugs-batch2
Jun 7, 2026
Merged

fix(app): batch-2 — SSO roles, remove-member, notifications, idle session, admin seeder (+CI/lint)#85
Enes1998 merged 1 commit into
mainfrom
fix/prod-bugs-batch2

Conversation

@Enes1998

@Enes1998 Enes1998 commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

Second batch of prod fixes. Root-caused + adversarially verified before implementing (the prior batch's attempts at #1/#2/#3 didn't hold).

Still-broken bugs (root causes were different than first thought)

# Issue Root cause Fix
1 Freelancer (GitHub SSO) standup → 403 GitHubSsoCommandHandler creates the DB user as Freelancer but never assigns the Keycloak realm role (only email/pwd signup did). JWT had no freelancer role. The PR#84 case-fix was irrelevant. Assign the realm role from the DB role on every SSO login (idempotent)
2 Enterprise "Remove member" button hidden lib/api/projects.ts read proj.ownerId/ownerName but the backend sends freelancerId/freelancerNameproject.freelancerId=""isOwner always false (also silently broke PR#84's invitations gating) Map from the correct keys
3 Bell badge persists after click Bell's useQuery re-hydrates the store with stale isRead=false on refetch, overwriting the mark-read Optimistic setQueriesData on the notifications cache + invalidate-on-error
4 Idle logout Keycloak ssoSessionIdleTimeout=1800 + no proactive refresh (idle = no requests = token expires = SSO idle elapses) Proactive keep-alive (useTokenRefresh, 4-min, visibility-gated) + idle timeout → 3600

Features

  • Admin bootstrapAdminSeeder (idempotent, config-driven) ensures a Keycloak admin user + DB Role=Admin at startup. Seed__AdminEmail in values.yaml; password via loopless-secrets (not committed). Unblocks the reconcile-roles/backfill-embeddings admin endpoints.
  • Swagger — already live at https://api.project-01.gjirafa.dev/swagger (no change needed; was hitting the web host).

Folded in (per request)

  • CI: retry the Trivy-job image builds on transient MCR 403 (the earlier stash).
  • Web: all 17 ESLint warnings fixed (zero-warning lint).

Verified locally

dotnet build ✓ · unit tests 22/22 ✓ · tsc ✓ · next lint 0 warnings ✓ · next build

Ship steps (after merge — auto-CD doesn't fire, dispatch manually)

  1. kubectl patch secret loopless-secrets -n project-01 -p '{"stringData":{"Seed__AdminPassword":"<pw>"}}'
  2. gh workflow run cd.yml --ref main -f image_sha=<merge-sha> (Helm deploy + migrate hook)
  3. Backend boots → AdminSeeder creates the admin. Existing SSO freelancer: re-login (role now assigned) — or POST /api/v1/admin/reconcile-roles as the new admin for an immediate fix.

🤖 Generated with Claude Code

…s, idle session, admin seeder + CI/lint

Bug fixes:
- Standup 403 (GitHub-SSO freelancer): GitHubSsoCommandHandler never assigned the
  Keycloak realm role (only email/pwd signup did) -> JWT lacked the role. Assign the
  realm role from the DB role on every SSO login (idempotent).
- Remove-member button hidden: lib/api/projects.ts mapped owner from the wrong JSON
  keys (proj.ownerId/ownerName) instead of freelancerId/freelancerName, so isOwner was
  always false for everyone (also silently broke the invitations-tab gating). Fixed.
- Notification bell badge persisted after click: the bell's useQuery re-hydrated the
  store with stale isRead=false on refetch. persistRead now optimistically updates the
  notifications query cache (+ invalidate-on-error) so reads stick.
- Idle logout: added a proactive token keep-alive (useTokenRefresh, 4-min interval,
  visibility-gated; getValidAccessToken(force)) mounted in RealtimeProvider, and raised
  Keycloak ssoSessionIdleTimeout 1800 -> 3600 in both realm exports.

Features:
- Admin bootstrap: AdminSeeder (idempotent, config-driven Seed:AdminEmail/AdminPassword)
  ensures a Keycloak admin user + DB Role=Admin at startup. Seed__AdminEmail set in
  values.yaml; password supplied via loopless-secrets (not committed). Unblocks the
  reconcile-roles/backfill-embeddings admin endpoints.
  (Swagger UI is already live at https://api.project-01.gjirafa.dev/swagger — no change.)

Also folded into this batch:
- CI: retry the Trivy-job image builds on transient MCR 403 (was stashed).
- Web: fix all 17 ESLint warnings (zero-warning lint; honor `_` prefix, memoize,
  justified disables, lazy-init purity, named default export).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Enes1998 Enes1998 merged commit 5de2cfb into main Jun 7, 2026
6 checks passed
@Enes1998 Enes1998 deleted the fix/prod-bugs-batch2 branch June 13, 2026 16:28
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant