From e70909af4776c0809c624811c06d68ca2e18a0b5 Mon Sep 17 00:00:00 2001 From: Austin Schaefer Date: Thu, 3 Sep 2026 21:23:34 +0200 Subject: [PATCH] Add and apply a models.rs convention for data-model structs Document in the DoD that data-model structs (domain models, query row types, DTOs/views) belong in a crate's models.rs rather than the file that produces/consumes them, once used outside that function - matching the existing crates/core/src/models.rs pattern. Component- local structs (Props, Styles, context) are exempt. Apply it to db: move RankedArticleRow out of articles.rs into a new crates/db/src/models.rs. --- DEFINITION_OF_DONE.md | 7 +++++++ crates/db/src/articles.rs | 12 +----------- crates/db/src/lib.rs | 3 +++ crates/db/src/models.rs | 10 ++++++++++ 4 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 crates/db/src/models.rs diff --git a/DEFINITION_OF_DONE.md b/DEFINITION_OF_DONE.md index c3113ad..db0fff4 100644 --- a/DEFINITION_OF_DONE.md +++ b/DEFINITION_OF_DONE.md @@ -14,6 +14,13 @@ A change is done when all of the following hold, not just when it compiles. - Within `db`, one file per domain concern (`feeds.rs`, `articles.rs`, `reading_events.rs`, `affinities.rs`) — a new table gets its own file, not a growing `queries.rs`. +- Data-model structs (domain models, query row types, DTOs/views) live in + a crate's `models.rs` rather than the file that produces or consumes + them, whenever a struct is used outside the function that builds it — + matching the existing `crates/core/src/models.rs` pattern. This doesn't + apply to structs that are inherently local to one file/component (e.g. + a Dioxus component's `Props`/`Styles`/context struct, or a helper + struct scoped to a single function's internals). ## DRY, but not premature diff --git a/crates/db/src/articles.rs b/crates/db/src/articles.rs index 1b39b6d..e91d143 100644 --- a/crates/db/src/articles.rs +++ b/crates/db/src/articles.rs @@ -1,3 +1,4 @@ +use crate::models::RankedArticleRow; use crate::schema; use crate::Db; use anyhow::Result; @@ -7,17 +8,6 @@ use diesel_async::RunQueryDsl; use feedsignal_core::Article; use uuid::Uuid; -/// One row of [`Db::list_ranked_articles`]. -pub struct RankedArticleRow { - pub id: String, - pub feed_id: String, - pub title: String, - pub url: String, - pub summary: String, - pub topics: Vec, - pub final_score: Option, -} - impl Db { pub async fn insert_article(&self, article: &Article) -> Result<()> { use schema::articles::dsl; diff --git a/crates/db/src/lib.rs b/crates/db/src/lib.rs index fc31f51..72f5d25 100644 --- a/crates/db/src/lib.rs +++ b/crates/db/src/lib.rs @@ -1,7 +1,10 @@ mod affinities; mod articles; mod feeds; +mod models; mod reading_events; + +pub use models::RankedArticleRow; pub(crate) mod schema; use anyhow::Result; diff --git a/crates/db/src/models.rs b/crates/db/src/models.rs new file mode 100644 index 0000000..ffda104 --- /dev/null +++ b/crates/db/src/models.rs @@ -0,0 +1,10 @@ +/// One row of [`crate::Db::list_ranked_articles`]. +pub struct RankedArticleRow { + pub id: String, + pub feed_id: String, + pub title: String, + pub url: String, + pub summary: String, + pub topics: Vec, + pub final_score: Option, +}