steid

@jamesgill /

steid/src/domain/repository/repo_repo.rs
1.8 KBCode·Blame·Raw
1use super::RepositoryResult;
2use crate::domain::{OrgId, RepoId, RepoName, Repository};
3
4/// Persistence for [`Repository`].
5pub trait RepoRepository: Send + Sync {
6 fn find_by_id(
7 &self,
8 id: &RepoId,
9 ) -> impl Future<Output = RepositoryResult<Option<Repository>>> + Send;
10
11 /// Looks a repository up by its owner and name — the `/{handle}/repos/{name}` pair.
12 fn find_by_org_and_name(
13 &self,
14 org_id: &OrgId,
15 name: &RepoName,
16 ) -> impl Future<Output = RepositoryResult<Option<Repository>>> + Send;
17
18 /// Every repository owned by an organisation, ordered by name.
19 ///
20 /// Returns them all regardless of visibility. Filtering is an authorization
21 /// decision and belongs to the use case, so that the page and `/api` cannot end up
22 /// applying different rules.
23 fn list_by_org(
24 &self,
25 org_id: &OrgId,
26 ) -> impl Future<Output = RepositoryResult<Vec<Repository>>> + Send;
27
28 /// Inserts or replaces a repository.
29 ///
30 /// The owning organisation must already exist; the foreign key runs that direction.
31 fn save(&self, repo: &Repository) -> impl Future<Output = RepositoryResult<()>> + Send;
32
33 /// Deletes a repository, succeeding if there was nothing to delete.
34 ///
35 /// A delete rather than a flag, for the same reason token revocation is: a row that
36 /// lingers is a repository that stops appearing only as long as every read remembers
37 /// to check. The bare repo on disk is a separate write and not this port's business.
38 ///
39 /// Succeeding on a missing row keeps the caller idempotent — two clicks on a delete
40 /// button must not turn the second one into an error.
41 fn delete(&self, id: &RepoId) -> impl Future<Output = RepositoryResult<()>> + Send;
42}