mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-13 00:36:02 +00:00
Membership management for workspaces: addMember, removeMember, getMembership, isMember, listMembers and listTeamsForUser. The permission scan is untouched -- readUserGroupPerms already joins jct_user_group and resolves group grants; this is the management side. Resolves the ticket's "do not leave two writers" by splitting domains and enforcing the split in SQL rather than by convention. Every existing caller of GroupStore targets a seeded system group -- ADMIN_GROUP_UID, default_user_group, default_temp_group -- never a team, so the two stores were already disjoint in practice. GroupStore.addUsers/removeUsers now carry `AND kind IS NULL`, making a team uid a no-op there, which costs no extra query because it folds into the existing subquery and matches how addUsers already treats an unknown username. TeamStore's writes select group_id from a kind-filtered subquery, so neither store can reach the other's rows. org_owned is written here but never accepted from a request; TeamService sets it at provisioning and workspace creation only. listMembers is keyset-paginated on id per doc/pagination.md, using the shared cursor and limit helpers and fetching one row past the limit to decide whether a cursor is warranted. Passes 1/0 for org_owned rather than db.booleanValue, which yields a real boolean on postgres and is rejected by the smallint column there -- sqlite accepted it silently.