Skip to main content

nythos_core/ports/
role.rs

1use crate::{NythosResult, Role, RoleAssignment, RoleId, TenantId, UserId};
2
3/// Tenant-scoped role assignment command.
4///
5/// This keeps assignment/revocation inputs explicit and avoids ambiguous
6/// multi-argument method signatures in orchestration code. It is a domain-facing
7/// boundary payload, not a storage row or transport DTO.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct RoleAssignmentInput {
10    tenant_id: TenantId,
11    user_id: UserId,
12    role_id: RoleId,
13}
14
15impl RoleAssignmentInput {
16    pub const fn new(tenant_id: TenantId, user_id: UserId, role_id: RoleId) -> Self {
17        Self {
18            tenant_id,
19            user_id,
20            role_id,
21        }
22    }
23
24    pub const fn tenant_id(&self) -> TenantId {
25        self.tenant_id
26    }
27
28    pub const fn user_id(&self) -> UserId {
29        self.user_id
30    }
31
32    pub const fn role_id(&self) -> RoleId {
33        self.role_id
34    }
35
36    pub const fn into_assignment(self) -> RoleAssignment {
37        RoleAssignment::new(self.tenant_id, self.user_id, self.role_id)
38    }
39}
40
41/// Tenant-scoped role repository contract used by login and refresh flows.
42///
43/// Every method is explicitly tenant-bound. Implementations must not introduce
44/// global-role behavior or silently cross tenant boundaries.
45///
46/// This contract supports loading current RBAC state as well as assigning and
47/// revoking user-role membership inside a tenant.
48pub trait RoleRepository {
49    /// Assigns a role to a user within the provided tenant boundary.
50    async fn assign_role(&self, input: RoleAssignmentInput) -> NythosResult<()>;
51
52    /// Revokes a role from a user within the provided tenant boundary.
53    async fn revoke_role(&self, input: RoleAssignmentInput) -> NythosResult<()>;
54
55    /// Loads all roles currently assigned to a user within one tenant.
56    async fn get_roles_for_user(
57        &self,
58        tenant_id: TenantId,
59        user_id: UserId,
60    ) -> NythosResult<Vec<Role>>;
61}