Commit 1aa6cf1
Add per-link manual verification for Spotify duration mismatches
Some Spotify matches that read as duration mismatches are intentional —
the wrong-track-on-an-album case where the matcher's automation can't
help, and an admin has manually confirmed the link is correct. Without a
way to record that judgement, the same row reappears on
/admin/duration-mismatches forever and gets re-evaluated by the rematch
sweep on every cycle.
The matcher already honours match_method='manual' as a "do not touch"
flag in update_recording_release_track_id and clear_recording_release_track.
This commit adds the missing producer side: a way to flip the flag from
the admin UI, and the read-side filtering that makes verified rows
disappear from the mismatch reports.
Backend:
- New db helper integrations.spotify.db.set_track_link_manual_override(
conn, streaming_link_id, manual=True/False)
flips match_method to 'manual' (or back to 'fuzzy_search' on unverify).
No schema change — reuses the existing match_method column.
- New admin endpoint POST /admin/duration-mismatches/links/<id>/verify
with body {"manual": true|false}. 200 + JSON on success, 404 when
the link doesn't exist. Goes through the existing admin gate +
CSRF double-submit.
- get_songs_with_duration_mismatches and get_releases_with_duration_mismatches
in integrations/spotify/db.py now exclude rows where match_method = 'manual'.
This is the primary effect: the durable rematch sweep
(rematch_spotify_duration_mismatches.py) stops re-querying confirmed
matches.
- The /admin/duration-mismatches list page and /admin/duration-mismatches/<song>
detail page apply the same filter, with an ?include_verified=1 toggle
for when an admin needs to review or unverify previously-accepted
rows. The list page additionally shows a banner with the count of
manually-verified links currently excluded.
Admin UI:
- New "Status" column on the per-song mismatch table with a "Verify"
button per row. After click, the row reloads with a "Verified" badge
and an "Unverify" button next to it. Verified rows in include-verified
mode get a faded background so they visually recede.
- New "Include manually verified mismatches" checkbox above the table
on both the list page and the per-song page; preserved across
threshold changes via the URL query.
Tests: 9 new in test_admin_verify_match.py covering the db helper, the
mismatch-query exclusion (both songs and releases helpers), the admin
endpoint's success/unauth/404 paths, and the verify/unverify round trip.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent fa7ef9c commit 1aa6cf1
5 files changed
Lines changed: 528 additions & 7 deletions
File tree
- backend
- integrations/spotify
- routes
- templates/admin
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
261 | 261 | | |
262 | 262 | | |
263 | 263 | | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
264 | 268 | | |
265 | 269 | | |
266 | 270 | | |
| |||
305 | 309 | | |
306 | 310 | | |
307 | 311 | | |
| 312 | + | |
| 313 | + | |
308 | 314 | | |
309 | 315 | | |
310 | 316 | | |
| |||
624 | 630 | | |
625 | 631 | | |
626 | 632 | | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
627 | 671 | | |
628 | 672 | | |
629 | 673 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
28 | 31 | | |
29 | 32 | | |
30 | 33 | | |
| |||
2694 | 2697 | | |
2695 | 2698 | | |
2696 | 2699 | | |
| 2700 | + | |
| 2701 | + | |
| 2702 | + | |
| 2703 | + | |
2697 | 2704 | | |
2698 | 2705 | | |
2699 | 2706 | | |
| |||
2704 | 2711 | | |
2705 | 2712 | | |
2706 | 2713 | | |
| 2714 | + | |
| 2715 | + | |
| 2716 | + | |
| 2717 | + | |
| 2718 | + | |
2707 | 2719 | | |
2708 | 2720 | | |
2709 | 2721 | | |
| |||
2723 | 2735 | | |
2724 | 2736 | | |
2725 | 2737 | | |
| 2738 | + | |
2726 | 2739 | | |
2727 | 2740 | | |
2728 | 2741 | | |
| |||
2739 | 2752 | | |
2740 | 2753 | | |
2741 | 2754 | | |
| 2755 | + | |
| 2756 | + | |
| 2757 | + | |
| 2758 | + | |
| 2759 | + | |
| 2760 | + | |
| 2761 | + | |
2742 | 2762 | | |
2743 | 2763 | | |
2744 | 2764 | | |
2745 | 2765 | | |
2746 | 2766 | | |
2747 | 2767 | | |
| 2768 | + | |
| 2769 | + | |
2748 | 2770 | | |
2749 | 2771 | | |
2750 | 2772 | | |
| |||
2759 | 2781 | | |
2760 | 2782 | | |
2761 | 2783 | | |
| 2784 | + | |
2762 | 2785 | | |
2763 | 2786 | | |
| 2787 | + | |
| 2788 | + | |
| 2789 | + | |
| 2790 | + | |
| 2791 | + | |
2764 | 2792 | | |
2765 | 2793 | | |
2766 | 2794 | | |
| |||
2772 | 2800 | | |
2773 | 2801 | | |
2774 | 2802 | | |
2775 | | - | |
| 2803 | + | |
2776 | 2804 | | |
2777 | 2805 | | |
2778 | 2806 | | |
| |||
2805 | 2833 | | |
2806 | 2834 | | |
2807 | 2835 | | |
| 2836 | + | |
2808 | 2837 | | |
2809 | 2838 | | |
2810 | 2839 | | |
| |||
2838 | 2867 | | |
2839 | 2868 | | |
2840 | 2869 | | |
| 2870 | + | |
2841 | 2871 | | |
2842 | 2872 | | |
2843 | 2873 | | |
| |||
2851 | 2881 | | |
2852 | 2882 | | |
2853 | 2883 | | |
2854 | | - | |
| 2884 | + | |
| 2885 | + | |
2855 | 2886 | | |
2856 | 2887 | | |
2857 | 2888 | | |
| |||
2887 | 2918 | | |
2888 | 2919 | | |
2889 | 2920 | | |
| 2921 | + | |
| 2922 | + | |
| 2923 | + | |
| 2924 | + | |
| 2925 | + | |
| 2926 | + | |
| 2927 | + | |
| 2928 | + | |
| 2929 | + | |
| 2930 | + | |
| 2931 | + | |
| 2932 | + | |
| 2933 | + | |
| 2934 | + | |
| 2935 | + | |
| 2936 | + | |
| 2937 | + | |
| 2938 | + | |
| 2939 | + | |
| 2940 | + | |
| 2941 | + | |
| 2942 | + | |
| 2943 | + | |
| 2944 | + | |
| 2945 | + | |
| 2946 | + | |
| 2947 | + | |
| 2948 | + | |
| 2949 | + | |
| 2950 | + | |
| 2951 | + | |
| 2952 | + | |
| 2953 | + | |
| 2954 | + | |
| 2955 | + | |
| 2956 | + | |
2890 | 2957 | | |
2891 | 2958 | | |
2892 | 2959 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
231 | 231 | | |
232 | 232 | | |
233 | 233 | | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
234 | 242 | | |
235 | 243 | | |
236 | 244 | | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
237 | 253 | | |
238 | 254 | | |
239 | 255 | | |
| |||
249 | 265 | | |
250 | 266 | | |
251 | 267 | | |
252 | | - | |
| 268 | + | |
253 | 269 | | |
254 | 270 | | |
255 | 271 | | |
| |||
0 commit comments