Findings
correctness
crates/apotheke/src/repo/music.rs:436 — get_release_group_with_releases returns inconsistent (None, non-empty) tuple under concurrent delete (low)
crates/apotheke/src/repo/play_history/mod.rs:169 — parse_media_type silently maps all unrecognized strings to Music (low)
crates/apotheke/src/repo/play_history/mod.rs:399 — update_daily_stats carries a dead media_id parameter (info)
crates/apotheke/src/repo/play_history/mod.rs:462 — update_streak Some(_) arm breaks streak invariant between two non-transactional statements (low)
crates/apotheke/src/repo/user.rs:228 — Security-sensitive revoke operations ignore rows_affected — silent no-op on wrong ID (low)
resilience
crates/apotheke/src/repo/play_history/mod.rs:242 — get_active_sessions has no LIMIT; unbounded rows for users with unclosed sessions (low)
crates/apotheke/src/repo/play_history/mod.rs:376 — Wrap update_daily_stats two-statement sequence in a transaction (low)
crates/apotheke/src/repo/play_history/mod.rs:377 — update_daily_stats two-statement write is not transactional; unique_items permanently stale on partial failure (low)
crates/apotheke/src/repo/want.rs:112 — list_wants_by_type_and_status has no LIMIT clause and can return the entire wants table (low)
crates/apotheke/src/repo/zone.rs:122 — list_zones issues N+1 DB queries — one per zone for member lookup (low)
security
crates/apotheke/src/repo/play_history/mod.rs:415 — update_streak read-decide-write is not wrapped in a SAVEPOINT (low)
testing
crates/apotheke/src/repo/news.rs:230 — Add tests for article_guid_exists and episode_guid_exists deduplication guards (low)
crates/apotheke/src/repo/news.rs:278 — Add tests for delete_articles_exceeding_count retention logic (low)
crates/apotheke/src/repo/play_history/mod.rs:154 — Test bytes_to_media_id with malformed input to document silent-drop behavior (low)
crates/apotheke/src/repo/user.rs:227 — Test that revoke_refresh_token and revoke_api_key return an error (or detectable no-op) on nonexistent IDs (low)
Note
These are batched low/info findings; split any out if it gets prioritized.
Findings
correctness
crates/apotheke/src/repo/music.rs:436— get_release_group_with_releases returns inconsistent (None, non-empty) tuple under concurrent delete (low)crates/apotheke/src/repo/play_history/mod.rs:169— parse_media_type silently maps all unrecognized strings to Music (low)crates/apotheke/src/repo/play_history/mod.rs:399— update_daily_stats carries a dead media_id parameter (info)crates/apotheke/src/repo/play_history/mod.rs:462— update_streak Some(_) arm breaks streak invariant between two non-transactional statements (low)crates/apotheke/src/repo/user.rs:228— Security-sensitive revoke operations ignore rows_affected — silent no-op on wrong ID (low)resilience
crates/apotheke/src/repo/play_history/mod.rs:242— get_active_sessions has no LIMIT; unbounded rows for users with unclosed sessions (low)crates/apotheke/src/repo/play_history/mod.rs:376— Wrap update_daily_stats two-statement sequence in a transaction (low)crates/apotheke/src/repo/play_history/mod.rs:377— update_daily_stats two-statement write is not transactional; unique_items permanently stale on partial failure (low)crates/apotheke/src/repo/want.rs:112— list_wants_by_type_and_status has no LIMIT clause and can return the entire wants table (low)crates/apotheke/src/repo/zone.rs:122— list_zones issues N+1 DB queries — one per zone for member lookup (low)security
crates/apotheke/src/repo/play_history/mod.rs:415— update_streak read-decide-write is not wrapped in a SAVEPOINT (low)testing
crates/apotheke/src/repo/news.rs:230— Add tests for article_guid_exists and episode_guid_exists deduplication guards (low)crates/apotheke/src/repo/news.rs:278— Add tests for delete_articles_exceeding_count retention logic (low)crates/apotheke/src/repo/play_history/mod.rs:154— Test bytes_to_media_id with malformed input to document silent-drop behavior (low)crates/apotheke/src/repo/user.rs:227— Test that revoke_refresh_token and revoke_api_key return an error (or detectable no-op) on nonexistent IDs (low)Note
These are batched low/info findings; split any out if it gets prioritized.