Skip to content

feat(groups): add active group foundation#148

Open
chiptus wants to merge 3 commits into
mainfrom
claude/issue-123-active-group-foundation
Open

feat(groups): add active group foundation#148
chiptus wants to merge 3 commits into
mainfrom
claude/issue-123-active-group-foundation

Conversation

@chiptus

@chiptus chiptus commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Adds a nullable active_group_id column on profiles (FK to groups, cleared automatically on group deletion) plus a resolveActiveGroupId helper and useActiveGroup hook that auto-activates a user's sole group when no explicit choice is persisted. The header's Groups button now shows the active group's name, or a create/join CTA when the user has no groups.

Closes #123

Verification

  • Sign in as a user in exactly one group; the header "Groups" button shows that group's name without any manual action.
  • Sign in as a user in zero groups; the header shows a "Create/Join a Group" CTA instead of a group name.
  • Leave your only group; the header CTA updates to the zero-group state without a page reload.
  • Join a group after having none; the header updates to show it as active without a page reload.
  • Reload the page (or sign in on another device) as a single-group user; the same group still shows as active, proving it's read from the database.
  • pnpm test passes, including new src/lib/activeGroup.test.ts cases for auto-activation, multi-group, stale/deleted active group, and zero-group scenarios.

Generated by Claude Code

Adds a nullable active_group_id column on profiles (FK to groups, cleared
on group deletion) and a resolveActiveGroupId helper that treats a user's
sole group as active when no explicit choice has been persisted yet. A
useActiveGroup hook exposes this derived state for future tickets, and the
header's Groups button now surfaces the active group name or a create/join
CTA when the user has no groups.

Closes #123

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CKMx3D6cDTnUEYacpy9Mn6
Copilot AI review requested due to automatic review settings July 10, 2026 15:46
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
upline Ready Ready Preview, Comment Jul 10, 2026 3:54pm

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deploy → stagingworkflow run
Last updated: 2026-07-10 15:54:47 UTC

  • DB migrations succeeded
  • ⏭️ Edge functions skipped (no changes)

…tyles

Remove the speculative active_group_id case from useUpdateProfile.ts
(no caller sets it yet; issue #124 will add explicit switching), and
extract the shared Groups button className in Navigation.tsx to avoid
duplication between the active-group and zero-group CTA branches.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CKMx3D6cDTnUEYacpy9Mn6

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR lays the groundwork for an “Active Group” concept by adding a persisted active_group_id on profiles, introducing a pure helper for determining the effective active group, and updating the header to display the active group name (or a create/join CTA when the user has no groups).

Changes:

  • Adds profiles.active_group_id as a nullable FK to groups(id) with ON DELETE SET NULL, plus an index.
  • Introduces resolveActiveGroupId (and unit tests) to select a persisted active group when valid or auto-activate a sole membership.
  • Adds useActiveGroup and updates the App Header “Groups” button to display the active group name or a create/join CTA.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
supabase/migrations/20260710154342_add_active_group_id_to_profiles.sql Adds the active_group_id column and index on profiles with FK behavior.
src/lib/activeGroup.ts Adds helper to resolve the effective active group from profile + memberships.
src/lib/activeGroup.test.ts Adds Vitest coverage for single/multi/zero-group and stale persisted ID scenarios.
src/integrations/supabase/types.ts Updates generated Supabase types to include active_group_id + FK relationship metadata.
src/hooks/useActiveGroup.ts Adds hook to expose active group state derived from profile + memberships.
src/components/layout/AppHeader/Navigation.tsx Updates header Groups button to show active group name or create/join CTA.
src/api/auth/useUpdateProfile.ts Extends profile update typing to allow active_group_id updates.

Comment on lines +19 to +22
const activeGroupId = resolveActiveGroupId({
profileActiveGroupId: profile?.active_group_id,
groupIds: groups.map((group) => group.id),
});
Comment thread src/components/layout/AppHeader/Navigation.tsx Outdated
Comment thread src/components/layout/AppHeader/Navigation.tsx Outdated
Addresses Copilot review comments on PR #148: the header briefly
showed the "Create/Join a Group" CTA for users who do have groups
while useUserGroupsQuery was still resolving.

chiptus commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Fixed the two loading-state comments in c847a00: Navigation.tsx now suppresses the zero-groups CTA while useUserGroupsQuery is still loading, so single/multi-group users no longer see a transient "Create/Join a Group" flash.

On the third comment (useActiveGroup never writing the resolved id back to profiles.active_group_id): this was a deliberate scope call for this foundation ticket, not an oversight — noted in the PR's self-review. resolveActiveGroupId re-derives the effective active group from live DB-backed group membership on every read (verified: it already falls through correctly on the leave-only-group → join-new-group sequence the comment describes, since a stale persisted id is simply ignored when it's no longer in groupIds). So the app never shows a stale group. The gap is narrower than the comment implies: the active_group_id column itself stays unwritten until something explicit sets it, which matters for direct DB reads/other consumers of that column (e.g. #124's switcher) — but adding a write-back mutation now risks fighting with #124's own persistence logic. Leaving this thread open for @chiptus to weigh in on whether to add the write-back here or defer it to #124.


Generated by Claude Code

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.

Active Group foundation: persisted active group + auto-activation

3 participants