pub struct GroupService {
backend: Arc<dyn GroupBackend>,
}Expand description
Service for group management operations.
Encapsulates business logic for groups, members, and invites.
Uses a GroupBackend for persistence.
Fields§
§backend: Arc<dyn GroupBackend>Implementations§
Source§impl GroupService
impl GroupService
Sourcepub fn new(backend: Arc<dyn GroupBackend>) -> Self
pub fn new(backend: Arc<dyn GroupBackend>) -> Self
Creates a new group service with the given backend.
Sourcepub fn try_default() -> Result<Self>
pub fn try_default() -> Result<Self>
Creates a new group service with a default SQLite backend.
Uses the user’s data directory for storage.
§Errors
Returns an error if the backend cannot be initialized.
Sourcepub fn create_group(
&self,
org_id: &str,
name: &str,
description: &str,
creator_email: &str,
) -> Result<Group>
pub fn create_group( &self, org_id: &str, name: &str, description: &str, creator_email: &str, ) -> Result<Group>
Creates a new group in the organization.
The creator is automatically added as an admin.
§Arguments
org_id- Organization identifiername- Group name (must be unique within org)description- Optional descriptioncreator_email- Email of the group creator
§Errors
Returns an error if:
- A group with the same name already exists
- Storage cannot be accessed
Sourcepub fn get_group_by_name(
&self,
org_id: &str,
name: &str,
) -> Result<Option<Group>>
pub fn get_group_by_name( &self, org_id: &str, name: &str, ) -> Result<Option<Group>>
Gets a group by name within an organization.
§Errors
Returns an error if storage cannot be accessed.
Sourcepub fn add_member(
&self,
group_id: &GroupId,
email: &str,
role: GroupRole,
requester_email: &str,
) -> Result<GroupMember>
pub fn add_member( &self, group_id: &GroupId, email: &str, role: GroupRole, requester_email: &str, ) -> Result<GroupMember>
Adds a member to a group.
If the member already exists, updates their role. Only admins can add members.
§Arguments
group_id- The group to add toemail- Email of the new memberrole- Role to assignrequester_email- Email of the user adding the member
§Errors
Returns an error if:
- The requester is not an admin
- The group doesn’t exist
- Storage cannot be accessed
Sourcepub fn get_member(
&self,
group_id: &GroupId,
email: &str,
) -> Result<Option<GroupMember>>
pub fn get_member( &self, group_id: &GroupId, email: &str, ) -> Result<Option<GroupMember>>
Sourcepub fn update_member_role(
&self,
group_id: &GroupId,
email: &str,
new_role: GroupRole,
requester_email: &str,
) -> Result<bool>
pub fn update_member_role( &self, group_id: &GroupId, email: &str, new_role: GroupRole, requester_email: &str, ) -> Result<bool>
Updates a member’s role in a group.
Only admins can update roles. Cannot demote the last admin.
§Arguments
group_id- The groupemail- The member’s emailnew_role- The new role to assignrequester_email- Email of the user updating the role
§Errors
Returns an error if:
- The requester is not an admin
- Demoting the last admin
- Storage cannot be accessed
Sourcepub fn remove_member(
&self,
group_id: &GroupId,
email: &str,
requester_email: &str,
) -> Result<bool>
pub fn remove_member( &self, group_id: &GroupId, email: &str, requester_email: &str, ) -> Result<bool>
Removes a member from a group.
Only admins can remove members. Cannot remove the last admin.
§Arguments
group_id- The groupemail- The member’s emailrequester_email- Email of the user removing the member
§Errors
Returns an error if:
- The requester is not an admin
- Removing the last admin
- Storage cannot be accessed
Sourcepub fn list_members(&self, group_id: &GroupId) -> Result<Vec<GroupMember>>
pub fn list_members(&self, group_id: &GroupId) -> Result<Vec<GroupMember>>
Sourcepub fn get_user_groups(
&self,
org_id: &str,
email: &str,
) -> Result<Vec<GroupMembership>>
pub fn get_user_groups( &self, org_id: &str, email: &str, ) -> Result<Vec<GroupMembership>>
Sourcepub fn create_invite(
&self,
group_id: &GroupId,
role: GroupRole,
creator_email: &str,
expires_in_secs: Option<u64>,
max_uses: Option<u32>,
) -> Result<(GroupInvite, String)>
pub fn create_invite( &self, group_id: &GroupId, role: GroupRole, creator_email: &str, expires_in_secs: Option<u64>, max_uses: Option<u32>, ) -> Result<(GroupInvite, String)>
Creates an invite for a group.
Only admins can create invites.
§Arguments
group_id- The group to invite torole- Role to assign when joinedcreator_email- Email of the admin creating the inviteexpires_in_secs- How long until expiration (default: 7 days)max_uses- Maximum number of uses (default: unlimited)
§Returns
A tuple of (invite, plaintext_token). The token should be shared
with invitees and never stored.
§Errors
Returns an error if:
- The creator is not an admin
- Storage cannot be accessed
Sourcepub fn join_via_invite(&self, token: &str, email: &str) -> Result<GroupMember>
pub fn join_via_invite(&self, token: &str, email: &str) -> Result<GroupMember>
Joins a group using an invite token.
Validates the token and adds the user as a member with the invite’s role.
§Arguments
token- The plaintext invite tokenemail- Email of the user joining
§Returns
The created member record.
§Errors
Returns an error if:
- The token is invalid or expired
- Storage cannot be accessed
Sourcepub fn list_invites(
&self,
group_id: &GroupId,
include_expired: bool,
) -> Result<Vec<GroupInvite>>
pub fn list_invites( &self, group_id: &GroupId, include_expired: bool, ) -> Result<Vec<GroupInvite>>
Sourcepub fn cleanup_expired_invites(&self) -> Result<u64>
pub fn cleanup_expired_invites(&self) -> Result<u64>
Sourcefn require_admin(&self, group_id: &GroupId, email: &str) -> Result<()>
fn require_admin(&self, group_id: &GroupId, email: &str) -> Result<()>
Checks if a user has admin role in a group.
Sourcepub fn require_role(
&self,
group_id: &GroupId,
email: &str,
min_role: GroupRole,
) -> Result<()>
pub fn require_role( &self, group_id: &GroupId, email: &str, min_role: GroupRole, ) -> Result<()>
Checks if a user has at least the specified role in a group.
Role hierarchy: Admin > Write > Read
§Errors
Returns an error if:
- The user is not a member of the group
- The user’s role is insufficient
Auto Trait Implementations§
impl Freeze for GroupService
impl !RefUnwindSafe for GroupService
impl Send for GroupService
impl Sync for GroupService
impl Unpin for GroupService
impl !UnwindSafe for GroupService
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].