Skip to content

refactor(tracker-core): split persistence traits by context #1713

@josecelano

Description

@josecelano

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:

  1. 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.

  2. 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

  • Write ADR: docs/adrs/<timestamp>_keep_database_as_aggregate_supertrait.md
  • Introduce SchemaMigrator trait in databases/schema.rs
  • Introduce TorrentMetricsStore trait in databases/torrent_metrics.rs
  • Introduce WhitelistStore trait in databases/whitelist.rs
  • Introduce AuthKeyStore trait in databases/auth_keys.rs
  • Introduce Database aggregate supertrait + blanket impl in databases/database.rs
  • Update SQLite driver to implement the four narrow traits
  • Update MySQL driver to implement the four narrow traits
  • Update mod.rs to declare new submodules and re-export traits/mocks

Acceptance Criteria

  • ADR is written and added to docs/adrs/index.md.
  • Four narrow traits exist in separate files under databases/.
  • Database is an empty aggregate supertrait with a blanket impl.
  • Both drivers (Sqlite, Mysql) compile through the blanket impl with no manual impl Database for <Driver> block.
  • No existing consumer file (persisted.rs, downloads.rs, etc.) is changed.
  • #[automock] is on the four narrow traits; MockDatabase is removed.
  • No behavior change — existing tests pass without modification.
  • cargo test --workspace --all-targets passes.
  • linter all exits with code 0.

References

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions