-
Notifications
You must be signed in to change notification settings - Fork 61
Closed
Labels
Description
Problem
The Service struct currently has 18 generic parameters, making it extremely verbose and hard to maintain:
pub struct Service<R, C, U, CR, H, AS, RU, RO, KS, UR, URA, HC, W, RT, RC, SE, LC, LR>
where
R: RealmRepository,
C: ClientRepository,
U: UserRepository,
CR: CredentialRepository,
H: HasherRepository,
AS: AuthSessionRepository,
RU: RedirectUriRepository,
RO: RoleRepository,
KS: KeyStoreRepository,
UR: UserRoleRepository,
URA: UserRequiredActionRepository,
HC: HealthCheckRepository,
W: WebhookRepository,
RT: RefreshTokenRepository,
RC: RecoveryCodeRepository,
SE: SecurityEventRepository,
LC: LdapConnector,
LR: LdapRepository,This leads to:
- Extremely long generic constraints on every service implementation
- Poor readability and maintainability
- Difficulty adding new repositories
- Complex type signatures throughout the codebase
Solution
Group repositories by domain to reduce generic complexity while maintaining logical organization:
Create domain-specific repository containers
- Core repositories (authentication, users, client, etc.):
RealmRepository,ClientRepository
- Abyss domain (LDAP integration)
- Trident domain (MFA/Recovery code)
- Seawatch domain (Security events)
Proposed structure
// New domain repository containers
pub struct CoreRepositories<R, C, U, CR, H, AS, RU, RO, KS, UR, URA, HC, W, RT> { ... }
pub struct AbyssRepositories<LC, LR> { ... }
pub struct TridentRepositories<RC> { ... }
pub struct SeawatchRepositories<SE> { ...
pub struct Service<Core, Abyss, Trident, Seawatch>
where
Core: CoreRepositories,
Abyss: AbyssRepositories,
Trident: TridentRepositories,
Seawatch: SeawatchRepositories,
{
pub(crate) core: Core,
pub(crate) abyss: Abyss,
pub(crate) trident: Trident,
pub(crate) seawatch: Seawatch,
pub(crate) policy: FerriskeyPolicy<...>,
}
impl<Core, Abyss, Trident, Seawatch> Service<Core, Abyss, Trident, Seawatch>
where
Core: CoreRepositories,
Abyss: AbyssRepositories,
Trident: TridentRepositories,
Seawatch: SeawatchRepositories,
{
pub fn realm_repository(&self) -> &Arc<Core::RealmRepository> {
&self.core.realm_repository
}
pub fn client_repository(&self) -> &Arc<Core::ClientRepository> {
&self.core.client_repository
}
pub fn user_repository(&self) -> &Arc<Core::UserRepository> {
&self.core.user_repository
}
// ... other getters
pub fn ldap_connector(&self) -> &Arc<Abyss::LdapConnector> {
&self.abyss.ldap_connector
}
pub fn ldap_repository(&self) -> &Arc<Abyss::LdapRepository> {
&self.abyss.ldap_repository
}
pub fn recovery_code_repository(&self) -> &Arc<Trident::RecoveryCodeRepository> {
&self.trident.recovery_code_repository
}
pub fn security_event_repository(&self) -> &Arc<Seawatch::SecurityEventRepository> {
&self.seawatch.security_event_repository
}
}Benefits
- Reduced complexity: From 18 to 4 generic parameters
- Logical organization: Repositories grouped by business domain
- Backward compatibility: Maintain existing API through getters
- Easier maintenance: Adding new repositories is scoped to specific domains
- Better readability: Service implementations become much cleaner
Breaking changes
This should be a non-breaking change if implemented correctly with proper getter methods.
Priority
Medium - This is a significant architectural improvement that will make the codebase more maintainable long-term.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Done