Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions CLAUDE.md

Large diffs are not rendered by default.

24 changes: 22 additions & 2 deletions chat/cache/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import (
// mutable — and can be mutated by other processes, which this cache can never
// observe — so group membership checks and member lists always defer to the
// backing store. The rest of the store is passed straight through, viewer
// state (restrictions included), activity reads, key envelopes and invites
// included: a user's state is theirs, or their group creator's, to change at any time, a group's recent senders change with every send, and
// state (restrictions included), activity reads, key envelopes, invites and
// pins included: a user's state is theirs, or their group creator's, to change at any time, a group's recent senders change with every send, and
// both reads are already one strongly consistent query, so nothing of either
// is held.
//
Expand Down Expand Up @@ -362,6 +362,26 @@ func (c *Cache) GetFeaturedGroups(ctx context.Context, userID *commonpb.UserId)
return c.db.GetFeaturedGroups(ctx, userID)
}

// The pin methods pass through: any member a chat permits may pin or unpin,
// from any process, and the reads are what the caller is told of the pins it
// just changed, so nothing of a chat's pins is held.

func (c *Cache) PinMessage(ctx context.Context, chatID *commonpb.ChatId, messageID *messagingpb.MessageId, pinnedBy *commonpb.UserId, pinnedAt time.Time, maxPins int) (chat.PinSummary, bool, error) {
return c.db.PinMessage(ctx, chatID, messageID, pinnedBy, pinnedAt, maxPins)
}

func (c *Cache) UnpinMessage(ctx context.Context, chatID *commonpb.ChatId, messageID *messagingpb.MessageId) (chat.PinSummary, bool, error) {
return c.db.UnpinMessage(ctx, chatID, messageID)
}

func (c *Cache) GetPinSummaries(ctx context.Context, chatIDs []*commonpb.ChatId) (map[string]chat.PinSummary, error) {
return c.db.GetPinSummaries(ctx, chatIDs)
}

func (c *Cache) GetPinsPage(ctx context.Context, chatID *commonpb.ChatId, after *chat.PinPosition, limit int) ([]chat.Pin, error) {
return c.db.GetPinsPage(ctx, chatID, after, limit)
}

// The invite methods pass through: an invite's use count and revoke change
// with every join and revoke, from any process, and its record is read once
// per create, preview, join or listing, so there is nothing worth holding.
Expand Down
8 changes: 8 additions & 0 deletions chat/cache/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/code-payments/flipcash2-server/chat"
"github.com/code-payments/flipcash2-server/chat/cache"
"github.com/code-payments/flipcash2-server/chat/memory"
"github.com/code-payments/flipcash2-server/chat/tests"
"github.com/code-payments/flipcash2-server/model"
)

Expand Down Expand Up @@ -628,3 +629,10 @@ func TestCache_Invites_PassThrough(t *testing.T) {
require.Len(t, page, 1)
require.Equal(t, chatpb.Invite_REVOKED, page[0].StatusAt(now))
}

// TestCache_Pins_PassThrough runs the shared pin tests through the cache: pins
// pass straight through, so the cache behaves as its backing store. Every test
// names chats of its own, so the store needs no reset between them.
func TestCache_Pins_PassThrough(t *testing.T) {
tests.RunPinStoreTests(t, cache.NewInCache(memory.NewInMemory(nil)), func() {})
}
4 changes: 2 additions & 2 deletions chat/dynamodb/activity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import (
// read and score as if their score were their last send.
func TestChat_ActivityScoreLegacyRecords(t *testing.T) {
ctx := context.Background()
require.NoError(t, CreateTables(ctx, testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable))
require.NoError(t, CreateTables(ctx, testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, pinsTable))

testStore := NewInDynamoDB(testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, nil)
testStore := NewInDynamoDB(testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, pinsTable, nil)
defer testStore.(*store).reset()

groupID := chat.MustGenerateGroupChatID()
Expand Down
12 changes: 6 additions & 6 deletions chat/dynamodb/invite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ import (
// up; and the table has TTL enabled on the attribute.
func TestChat_DynamoDBInviteItems(t *testing.T) {
ctx := context.Background()
require.NoError(t, CreateTables(ctx, testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable))
testStore := NewInDynamoDB(testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, nil)
require.NoError(t, CreateTables(ctx, testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, pinsTable))
testStore := NewInDynamoDB(testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, pinsTable, nil)
defer testStore.(*store).reset()

ttl, err := testEnv.Client.DescribeTimeToLive(ctx, &dynamodb.DescribeTimeToLiveInput{TableName: aws.String(invitesTable)})
Expand Down Expand Up @@ -168,8 +168,8 @@ func TestChat_DynamoDBInviteItems(t *testing.T) {
// attributes behind in chat_key_envelopes.
func TestChat_DynamoDBKeyEnvelopeCopyItem(t *testing.T) {
ctx := context.Background()
require.NoError(t, CreateTables(ctx, testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable))
testStore := NewInDynamoDB(testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, nil)
require.NoError(t, CreateTables(ctx, testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, pinsTable))
testStore := NewInDynamoDB(testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, pinsTable, nil)
defer testStore.(*store).reset()

groupID := chat.MustGenerateGroupChatID()
Expand Down Expand Up @@ -226,8 +226,8 @@ func TestChat_DynamoDBKeyEnvelopeCopyItem(t *testing.T) {
// the copy in the same write; and a member's join, the no-op, writes nothing.
func TestChat_DynamoDBInviteJoinItems(t *testing.T) {
ctx := context.Background()
require.NoError(t, CreateTables(ctx, testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable))
testStore := NewInDynamoDB(testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, nil)
require.NoError(t, CreateTables(ctx, testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, pinsTable))
testStore := NewInDynamoDB(testEnv.Client, chatsTable, dmInboxTable, groupMembersTable, userStateTable, activityTable, keyEnvelopesTable, lobbiesTable, featuredGroupsTable, holdingsTable, invitesTable, pinsTable, nil)
defer testStore.(*store).reset()

now := time.Now()
Expand Down
5 changes: 3 additions & 2 deletions chat/dynamodb/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ const (
serverFeaturedGroupsTable = "chat_featured_groups_server_test"
serverHoldingsTable = "chat_holdings_server_test"
serverInvitesTable = "chat_invites_server_test"
serverPinsTable = "chat_pins_server_test"
)

func TestChat_DynamoDBServer(t *testing.T) {
require.NoError(t, CreateTables(context.Background(), testEnv.Client, serverChatsTable, serverDmInboxTable, serverGroupMembersTable, serverUserStateTable, serverActivityTable, serverKeyEnvelopesTable, serverLobbiesTable, serverFeaturedGroupsTable, serverHoldingsTable, serverInvitesTable))
require.NoError(t, CreateTables(context.Background(), testEnv.Client, serverChatsTable, serverDmInboxTable, serverGroupMembersTable, serverUserStateTable, serverActivityTable, serverKeyEnvelopesTable, serverLobbiesTable, serverFeaturedGroupsTable, serverHoldingsTable, serverInvitesTable, serverPinsTable))

testStore := NewInDynamoDB(testEnv.Client, serverChatsTable, serverDmInboxTable, serverGroupMembersTable, serverUserStateTable, serverActivityTable, serverKeyEnvelopesTable, serverLobbiesTable, serverFeaturedGroupsTable, serverHoldingsTable, serverInvitesTable, nil)
testStore := NewInDynamoDB(testEnv.Client, serverChatsTable, serverDmInboxTable, serverGroupMembersTable, serverUserStateTable, serverActivityTable, serverKeyEnvelopesTable, serverLobbiesTable, serverFeaturedGroupsTable, serverHoldingsTable, serverInvitesTable, serverPinsTable, nil)
teardown := func() {
testStore.(*store).reset()
}
Expand Down
Loading
Loading