Skip to content

Conversation

@bokelley
Copy link
Contributor

@bokelley bokelley commented Jan 7, 2026

Summary

Fixes duplicate members appearing in chapter member lists and broken leader permissions when users have both Slack and web (WorkOS) accounts.

Root cause: Users who joined chapters via Slack had their Slack user ID stored (e.g., U1234567). When they later linked their WorkOS account via web login, they got a different ID (e.g., user_abc). The slack_user_mappings table linked these together, but the membership/leader records still had the old Slack IDs.

Changes

Write-time ID resolution

  • Added resolveToCanonicalUserId() helper that checks slack_user_mappings to resolve Slack IDs to WorkOS IDs
  • Applied resolution to all write paths:
    • addMembership()
    • addLeader()
    • setLeaders()
    • addMembershipWithInterest()

Read/check path resolution

  • Applied resolution to all lookup and removal functions:
    • isMember()
    • isLeader()
    • getMembership()
    • removeMembership()
    • removeLeader()
    • deleteMembership()
    • getCommitteesLedByUser()

Data migration

  • Migration 149 consolidates existing duplicate records by updating Slack IDs to their linked WorkOS IDs and removing duplicates

Frontend compatibility

  • Added canonical_user_id to WorkingGroupLeader type
  • Updated leader permission checks to use canonical_user_id

Test plan

  • All existing tests pass (187 tests)
  • Build succeeds
  • Type checking passes
  • Manual test on staging: verify David Porzelt appears only once on German chapter page
  • Manual test: verify leader actions (manage button, post visibility toggle) work for chapter leaders

🤖 Generated with Claude Code

bokelley and others added 3 commits January 7, 2026 07:24
Root cause: Users who joined chapters via Slack had their Slack user ID stored.
When they later linked their WorkOS account via web login, they got a different ID.
The slack_user_mappings table linked these, but membership/leader records still
had the old Slack IDs, causing duplicates and broken permissions.

Solution:
- Add resolveToCanonicalUserId() helper to resolve Slack IDs to WorkOS IDs
- Apply resolution in all write paths: addMembership, addLeader, setLeaders,
  addMembershipWithInterest
- Apply resolution in all read/check paths: isMember, isLeader, getMembership,
  removeMembership, removeLeader, deleteMembership, getCommitteesLedByUser
- Add migration 149 to consolidate existing duplicate records
- Add canonical_user_id to WorkingGroupLeader type for frontend compatibility
- Update frontend and backend leader checks to use canonical_user_id

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Migration 149: Use joined_at instead of UUID id for deduplication
  (UUIDs are not sequential, so id comparison doesn't determine age)
- Empty changeset since this doesn't impact the protocol

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migration 149 and 150 already exist on main branch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@bokelley bokelley merged commit 74210fc into main Jan 9, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants