Skip to content

feat(tracker-core): split Database trait into four narrow persistence traits#1714

Merged
josecelano merged 6 commits into
torrust:developfrom
josecelano:1713-1525-04-split-persistence-traits
Apr 29, 2026
Merged

feat(tracker-core): split Database trait into four narrow persistence traits#1714
josecelano merged 6 commits into
torrust:developfrom
josecelano:1713-1525-04-split-persistence-traits

Conversation

@josecelano
Copy link
Copy Markdown
Member

Summary

Implements GitHub issue #1713 — part of the persistence overhaul EPIC #1525.

Splits the monolithic Database trait in packages/tracker-core into four focused narrow traits, each covering a single concern:

Trait Concern
AuthKeyStore Authentication key persistence
SchemaMigrator Schema creation / teardown
TorrentMetricsStore Per-torrent and global download counters
WhitelistStore Info-hash whitelist management

The Database aggregate supertrait is kept as an internal-only compile-time guard via blanket impl — no consumer call sites change in this PR.

Changes

New: packages/tracker-core/src/databases/traits/

Four narrow trait files plus a mod.rs with re-exports:

  • auth_keys.rsAuthKeyStore (+ MockAuthKeyStore)
  • schema.rsSchemaMigrator (+ MockSchemaMigrator)
  • torrent_metrics.rsTorrentMetricsStore (+ MockTorrentMetricsStore)
  • whitelist.rsWhitelistStore (+ MockWhitelistStore)
  • database.rsDatabase blanket impl (internal guard only)

Updated: packages/tracker-core/src/databases/

  • mod.rs — routes through pub mod traits and re-exports all trait names at the databases level for backward compatibility
  • driver/sqlite.rs, driver/mysql.rs — implement four narrow traits via separate impl blocks; blanket impl satisfies Database automatically
  • authentication/handler.rs — tests now use MockAuthKeyStore instead of MockDatabase

Docs

  • ADR: docs/adrs/20260429000000_keep_database_as_aggregate_supertrait.md
  • Spec (updated): docs/issues/1713-1525-04-split-persistence-traits.md
  • Follow-up subissue spec (new): docs/issues/1525-04b-migrate-consumers-to-narrow-traits.md

Design Decision

The Database supertrait is kept (not removed) because consumer wiring (Arc<Box<dyn Database>> in TrackerCoreContainer) still references it. Consumer migration is deferred to subissue #1525-04b, where DatabaseStores (a plain struct with one Arc<dyn XxxStore> field per concern) will replace Arc<Box<dyn Database>> in the container.

See the ADR for full rationale.

Related

… traits

Introduce four focused traits in packages/tracker-core/src/databases/traits/:
- AuthKeyStore   — CRUD for authentication keys
- SchemaMigrator — database schema migration
- TorrentMetricsStore — torrent metrics queries and persistence
- WhitelistStore — whitelist CRUD

The monolithic Database trait is retained as an internal aggregate supertrait
satisfied automatically via a blanket impl over any type that implements all four
narrow traits. Drivers (SQLite, MySQL) now implement the four narrow traits
directly; the blanket impl compiles Database for free.

The authentication handler is updated to accept AuthKeyStore instead of the
full Database trait, narrowing its dependency surface.

Closes torrust#1713 (split-persistence-traits step)
Add ADR 20260429000000 explaining the decision to retain the Database aggregate
supertrait (satisfied via blanket impl) alongside the four new narrow traits
AuthKeyStore, SchemaMigrator, TorrentMetricsStore, and WhitelistStore.

Update docs/adrs/index.md to include the new entry.
…arrow traits

Add docs/issues/1525-04b-migrate-consumers-to-narrow-traits.md, the spec for
the next step: updating all call sites that currently depend on the full
Database aggregate trait to instead accept the appropriate narrow trait
(AuthKeyStore, SchemaMigrator, TorrentMetricsStore, or WhitelistStore).

Update docs/issues/1525-overhaul-persistence.md to reference the new subissue.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 29, 2026

Codecov Report

❌ Patch coverage is 27.58621% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.27%. Comparing base (899fc82) to head (bb98322).
⚠️ Report is 7 commits behind head on develop.

Files with missing lines Patch % Lines
...ackages/tracker-core/src/authentication/handler.rs 17.94% 64 Missing ⚠️
...ackages/tracker-core/src/databases/driver/mysql.rs 0.00% 16 Missing ⚠️
...ckages/tracker-core/src/databases/driver/sqlite.rs 78.94% 0 Missing and 4 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1714      +/-   ##
===========================================
- Coverage    81.47%   81.27%   -0.20%     
===========================================
  Files          340      340              
  Lines        24960    25034      +74     
  Branches     24960    25034      +74     
===========================================
+ Hits         20335    20346      +11     
- Misses        4364     4428      +64     
+ Partials       261      260       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements issue #1713 as part of EPIC #1525 by splitting the monolithic persistence Database trait in packages/tracker-core into four narrow, concern-focused traits while preserving Database as an aggregate supertrait via a blanket impl (so most consumer call sites remain unchanged for now).

Changes:

  • Added four narrow persistence traits (SchemaMigrator, TorrentMetricsStore, WhitelistStore, AuthKeyStore) under packages/tracker-core/src/databases/traits/, plus an aggregate Database supertrait with a blanket impl.
  • Updated SQLite/MySQL drivers to implement the four narrow traits in separate impl blocks (satisfying Database automatically).
  • Updated authentication handler tests to use MockAuthKeyStore (via a test double) after removing the monolithic MockDatabase, and added/updated ADR + issue specs to document the decision and follow-up plan.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/tracker-core/src/databases/mod.rs Switches persistence docs to the new trait split and re-exports narrow traits + mocks (and Database) for compatibility.
packages/tracker-core/src/databases/traits/mod.rs Declares the new traits submodules and re-exports trait and mock types.
packages/tracker-core/src/databases/traits/database.rs Defines the aggregate Database supertrait and blanket impl used as a completeness guard.
packages/tracker-core/src/databases/traits/schema.rs Introduces SchemaMigrator (+ mock) for schema lifecycle operations.
packages/tracker-core/src/databases/traits/torrent_metrics.rs Introduces TorrentMetricsStore (+ mock) for per-torrent/global download counters.
packages/tracker-core/src/databases/traits/whitelist.rs Introduces WhitelistStore (+ mock) and keeps a default helper method for whitelist checks.
packages/tracker-core/src/databases/traits/auth_keys.rs Introduces AuthKeyStore (+ mock) for authentication-key persistence.
packages/tracker-core/src/databases/driver/sqlite.rs Refactors the SQLite driver to implement the four narrow traits.
packages/tracker-core/src/databases/driver/mysql.rs Refactors the MySQL driver to implement the four narrow traits.
packages/tracker-core/src/authentication/handler.rs Updates tests to replace MockDatabase usage with auth-key-focused mocking.
docs/adrs/index.md Adds the new ADR entry to the index.
docs/adrs/20260429000000_keep_database_as_aggregate_supertrait.md Documents the decision to keep Database as an aggregate supertrait with blanket impl.
docs/issues/1713-1525-04-split-persistence-traits.md Updates the spec naming/branch and adds implementation notes + updated acceptance criteria.
docs/issues/1525-overhaul-persistence.md Updates the EPIC plan to point to the renamed spec and adds the new “04b” follow-up subissue.
docs/issues/1525-05-migrate-sqlite-and-mysql-to-sqlx.md Updates references to the renamed 1525-04 spec file.
docs/issues/1525-04b-migrate-consumers-to-narrow-traits.md Adds the follow-up spec for migrating consumers off Arc<Box<dyn Database>>.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/tracker-core/src/databases/driver/sqlite.rs Outdated
Comment thread packages/tracker-core/src/databases/driver/mysql.rs Outdated
Comment thread packages/tracker-core/src/databases/driver/sqlite.rs
Comment thread packages/tracker-core/src/databases/driver/mysql.rs Outdated
@josecelano
Copy link
Copy Markdown
Member Author

ACK bb98322

@josecelano josecelano merged commit ed0d168 into torrust:develop Apr 29, 2026
22 of 23 checks passed
josecelano added a commit that referenced this pull request Apr 29, 2026
Replace Arc<Box<dyn Database>> with the four narrow traits introduced in
#1714: AuthKeyStore, TorrentMetricsStore, WhitelistStore, SchemaMigrator.

- Introduce DatabaseStores bundle in databases::setup; initialize_database
  now returns DatabaseStores instead of Arc<Box<dyn Database>>
- TrackerCoreContainer wired through DatabaseStores fields
- DatabaseKeyRepository accepts Arc<dyn AuthKeyStore>
- DatabaseDownloadsMetricRepository accepts Arc<dyn TorrentMetricsStore>
- WhitelistRepository / setup accept Arc<dyn WhitelistStore>
- authentication::handler tests use MockAuthKeyStore directly
- REST API server force_database_error uses narrow trait mocks
- Benchmark binary operations use narrow traits
- Database re-export removed from databases::mod (now private to driver)
- Fix consumers in http-tracker-core, udp-tracker-server,
  axum-http-tracker-server that were missed by the Implementer agent

Closes #1715
josecelano added a commit that referenced this pull request Apr 29, 2026
…istence traits (#1715)

356699b fix(tracker-core): replace panicking unwrap/expect with error propagation (Jose Celano)
38a0574 docs(workflow): require ADR and code cross-linking (Jose Celano)
a2e0867 docs(packages): normalize markdown table formatting (Jose Celano)
d0d36eb docs(tracker-core): link persistence code to ADR rationale (Jose Celano)
b221dbb docs(adrs): clarify deferring torrent metric trait split (Jose Celano)
83fb636 refactor(tracker-core): split database drivers into folder modules (Jose Celano)
f628377 refactor(tracker-core): migrate consumers to narrow persistence traits (Jose Celano)
86fc930 docs(issues): rename spec and link to GitHub issue #1715 (Jose Celano)
2ff3b6b docs(github): add GitHub operator agent and subissue skill (Jose Celano)

Pull request description:

  ## Summary

  Closes #1715 (subissue of #1525 — Overhaul Persistence).

  Replaces all `Arc<Box<dyn Database>>` consumer wiring with the four narrow
  traits introduced in #1714: `AuthKeyStore`, `TorrentMetricsStore`,
  `WhitelistStore`, and `SchemaMigrator`.

  ## Changes

  ### New

  - `DatabaseStores` bundle in `databases::setup` — `initialize_database` now
    returns this struct instead of `Arc<Box<dyn Database>>`

  ### Updated consumers

  | Consumer | Narrow trait |
  |---|---|
  | `DatabaseKeyRepository` | `Arc<dyn AuthKeyStore>` |
  | `DatabaseDownloadsMetricRepository` | `Arc<dyn TorrentMetricsStore>` |
  | `WhitelistRepository` / `whitelist::setup` | `Arc<dyn WhitelistStore>` |
  | `TrackerCoreContainer` | `DatabaseStores` fields |
  | Benchmark binary operations | narrow traits per operation |
  | `authentication/handler.rs` tests | `MockAuthKeyStore` directly |
  | REST API server `force_database_error` tests | narrow trait mocks |

  ### Cleanup

  - `Database` removed from `databases::mod` public re-export (now private to
    the driver layer)
  - All callers in `http-tracker-core`, `udp-tracker-server`, and
    `axum-http-tracker-server` updated
  - Spec file renamed to `1715-1525-04b-migrate-consumers-to-narrow-traits.md`
    with cross-references updated in ADR and EPIC plan

  ## Testing

  - `cargo test --workspace --all-features` — all tests pass
  - `linter all` — exit code 0

ACKs for top commit:
  josecelano:
    ACK 356699b

Tree-SHA512: c4f81a909b5025c0df2aab204a6b3a664f8aa8712cbca24cbd136dfac88d5db7d914126f4c38f080300b0bef5a5d5c0292e6bab42b8899e980096d7d86e7181a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants