Goal
Decompose the monolithic Database trait into four focused context traits while keeping Database as the unified driver contract, and write an ADR to record the decision.
Background
packages/tracker-core/src/databases/mod.rs defines a single Database trait with 19 methods covering four unrelated concerns: schema management, torrent metrics, whitelist, and authentication keys. This makes the trait long and conflates distinct responsibilities in one place.
Two options were considered:
-
Replace Database with four independent traits — consumers hold Arc<dyn WhitelistStore> etc. directly. Clean interface segregation, but it loses the single place that tells a new driver implementor exactly what to build, and it changes every consumer at once.
-
Keep Database as an aggregate supertrait (chosen) — the four narrow traits exist independently; Database is defined as:
pub trait Database:
Sync + Send + SchemaMigrator + TorrentMetricsStore + WhitelistStore + AuthKeyStore {}
A blanket impl means any type that implements all four narrow traits automatically satisfies Database. Existing consumers (Arc<Box<dyn Database>>) are untouched.
Tasks
Acceptance Criteria
References
Goal
Decompose the monolithic
Databasetrait into four focused context traits while keepingDatabaseas the unified driver contract, and write an ADR to record the decision.Background
packages/tracker-core/src/databases/mod.rsdefines a singleDatabasetrait with 19 methods covering four unrelated concerns: schema management, torrent metrics, whitelist, and authentication keys. This makes the trait long and conflates distinct responsibilities in one place.Two options were considered:
Replace
Databasewith four independent traits — consumers holdArc<dyn WhitelistStore>etc. directly. Clean interface segregation, but it loses the single place that tells a new driver implementor exactly what to build, and it changes every consumer at once.Keep
Databaseas an aggregate supertrait (chosen) — the four narrow traits exist independently;Databaseis defined as:A blanket impl means any type that implements all four narrow traits automatically satisfies
Database. Existing consumers (Arc<Box<dyn Database>>) are untouched.Tasks
docs/adrs/<timestamp>_keep_database_as_aggregate_supertrait.mdSchemaMigratortrait indatabases/schema.rsTorrentMetricsStoretrait indatabases/torrent_metrics.rsWhitelistStoretrait indatabases/whitelist.rsAuthKeyStoretrait indatabases/auth_keys.rsDatabaseaggregate supertrait + blanket impl indatabases/database.rsmod.rsto declare new submodules and re-export traits/mocksAcceptance Criteria
docs/adrs/index.md.databases/.Databaseis an empty aggregate supertrait with a blanket impl.Sqlite,Mysql) compile through the blanket impl with no manualimpl Database for <Driver>block.persisted.rs,downloads.rs, etc.) is changed.#[automock]is on the four narrow traits;MockDatabaseis removed.cargo test --workspace --all-targetspasses.linter allexits with code0.References
docs/issues/1525-04-split-persistence-traits.mdjosecelano:pr-1684-reviewpackages/tracker-core/src/databases/mod.rs— current monolithicDatabasetrait