From fe8c2287154a4d360f36b166b13f2762fcaa9a19 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 8 Jun 2026 18:27:58 +0530 Subject: [PATCH] fix: bump team cache when membership changes The cached team payload embeds a per-user is_member flag, but TeamMember create/destroy never bumped the team cache key, so warm IDB caches kept showing a stale membership flag after a user was added to or removed from a team. Bump the team cache key from the TeamMember lifecycle. --- app/models/team_member.rb | 6 ++++++ spec/models/team_member_spec.rb | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/app/models/team_member.rb b/app/models/team_member.rb index f99af264b..4caf05344 100644 --- a/app/models/team_member.rb +++ b/app/models/team_member.rb @@ -18,6 +18,12 @@ class TeamMember < ApplicationRecord belongs_to :user belongs_to :team validates :user_id, uniqueness: { scope: :team_id } + + # is_member is embedded into the cached team payload (per current user) via + # api/v1/models/_team.json.jbuilder, so membership changes must bump the team + # cache key. team is safe-navigated because destroying a team cascades here + # via destroy_async, by which point the team row is already gone. + after_commit -> { team&.account&.update_cache_key('team') }, on: [:create, :destroy] end TeamMember.include_mod_with('Audit::TeamMember') diff --git a/spec/models/team_member_spec.rb b/spec/models/team_member_spec.rb index f37f70425..a00b09aa8 100644 --- a/spec/models/team_member_spec.rb +++ b/spec/models/team_member_spec.rb @@ -5,4 +5,20 @@ RSpec.describe TeamMember do it { is_expected.to belong_to(:team) } it { is_expected.to belong_to(:user) } end + + describe 'team cache invalidation' do + let(:team) { create(:team) } + let(:user) { create(:user) } + + it 'bumps the team cache key after create' do + expect(team.account).to receive(:update_cache_key).with('team') + create(:team_member, team: team, user: user) + end + + it 'bumps the team cache key after destroy' do + team_member = create(:team_member, team: team, user: user) + expect(team.account).to receive(:update_cache_key).with('team') + team_member.destroy + end + end end