Skip to content

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

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

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions