Skip to main content

koprogo_api/application/ports/
organization_repository.rs

1use crate::domain::entities::Organization;
2use async_trait::async_trait;
3use uuid::Uuid;
4
5#[async_trait]
6pub trait OrganizationRepository: Send + Sync {
7    async fn create(&self, org: &Organization) -> Result<Organization, String>;
8    async fn find_by_id(&self, id: Uuid) -> Result<Option<Organization>, String>;
9    async fn find_by_slug(&self, slug: &str) -> Result<Option<Organization>, String>;
10    async fn find_all(&self) -> Result<Vec<Organization>, String>;
11
12    /// Une PAGE d'organisations, filtrée par une recherche libre.
13    ///
14    /// `find_all` rendait la table entière — 2743 lignes sur la recette au
15    /// 2026-09-17, d'où 8,2 s d'écran blanc sur `/admin/acps` (#943). Il
16    /// reste pour les appelants internes qui ont réellement besoin de tout.
17    ///
18    /// `recherche` porte sur le nom, le slug ET le courriel de contact, sans
19    /// distinction de casse.
20    /// `None` ou une chaîne vide ne filtre rien.
21    async fn find_page(
22        &self,
23        recherche: Option<String>,
24        limit: i64,
25        offset: i64,
26    ) -> Result<Vec<Organization>, String>;
27
28    /// Le nombre total correspondant à la même recherche, pour que
29    /// l'appelant sache combien il en reste. Sans lui, une page est un
30    /// fragment dont on ignore la taille du tout.
31    async fn count_matching(&self, recherche: Option<String>) -> Result<i64, String>;
32    async fn update(&self, org: &Organization) -> Result<Organization, String>;
33    async fn delete(&self, id: Uuid) -> Result<bool, String>;
34    async fn count_buildings(&self, org_id: Uuid) -> Result<i64, String>;
35}