Skip to main content

pinto/storage/
repository.rs

1//! Persistence traits shared by the file, Git, and SQLite backends.
2
3use crate::backlog::{BacklogItem, ItemId};
4use crate::error::Result;
5use crate::sprint::{Sprint, SprintId};
6use std::future::Future;
7use std::path::PathBuf;
8
9pub trait BacklogItemRepository {
10    /// Save a backlog item, replacing any existing item with the same ID.
11    fn save(&self, item: &BacklogItem) -> impl Future<Output = Result<()>>;
12
13    /// Load a backlog item by ID. Return [`crate::error::Error::NotFound`] when it does not exist.
14    fn load(&self, id: &ItemId) -> impl Future<Output = Result<BacklogItem>>;
15
16    /// Return all backlog items in lexicographic rank order, using the ID as a tie-breaker.
17    ///
18    /// Implementations may read files concurrently and parse them in parallel (see
19    /// `docs/DESIGN.md` ยง3.4).
20    fn list(&self) -> impl Future<Output = Result<Vec<BacklogItem>>>;
21
22    /// Delete a backlog item by ID. Return [`crate::error::Error::NotFound`] when it does not exist.
23    fn delete(&self, id: &ItemId) -> impl Future<Output = Result<()>>;
24
25    /// Move a backlog item by ID to `archive/` and return the destination path.
26    ///
27    /// This is the non-destructive alternative to [`Self::delete`]. Return
28    /// [`crate::error::Error::NotFound`] when the item does not exist.
29    fn archive(&self, id: &ItemId) -> impl Future<Output = Result<PathBuf>>;
30
31    /// Return the next never-issued ID for `prefix`: one greater than the maximum issued or
32    /// existing number, or `1` when no such ID exists.
33    fn next_id(&self, prefix: &str) -> impl Future<Output = Result<ItemId>>;
34}
35
36/// Persistence operations for sprints.
37///
38/// Implementations store sprints separately from backlog items. The method names overlap with
39/// [`BacklogItemRepository`], so callers can disambiguate them with a fully qualified call such as
40/// `SprintRepository::save(&repo, &sprint)`.
41pub trait SprintRepository {
42    /// Save a sprint, replacing any existing sprint with the same ID.
43    fn save(&self, sprint: &Sprint) -> impl Future<Output = Result<()>>;
44
45    /// Load a sprint by ID. Return [`crate::error::Error::SprintNotFound`] when it does not exist.
46    fn load(&self, id: &SprintId) -> impl Future<Output = Result<Sprint>>;
47
48    /// Return all sprints in ascending creation-time order, using the ID as a tie-breaker.
49    fn list(&self) -> impl Future<Output = Result<Vec<Sprint>>>;
50
51    /// Delete a sprint by ID. Return [`crate::error::Error::SprintNotFound`] when it does not exist.
52    ///
53    /// Backend migration ([`crate::service::migrate_storage`]) uses this operation to remove
54    /// destination sprints that are absent from the source.
55    fn delete(&self, id: &SprintId) -> impl Future<Output = Result<()>>;
56}