docs: library comments say what the scanner and resolver do, not how they came to be (#6277)
release / govulncheck (push) Successful in 20s
release / web (push) Successful in 1m20s
release / go (push) Successful in 1m37s
release / integration (push) Successful in 5m15s
release / android (push) Successful in 5m26s
release / Build signed APK (releases and dev) (push) Successful in 5m45s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 16s
release / Verify release artifacts (tag releases only) (push) Skipped
release / govulncheck (push) Successful in 20s
release / web (push) Successful in 1m20s
release / go (push) Successful in 1m37s
release / integration (push) Successful in 5m15s
release / android (push) Successful in 5m26s
release / Build signed APK (releases and dev) (push) Successful in 5m45s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 16s
release / Verify release artifacts (tag releases only) (push) Skipped
Rewrites the internal/library comment blocks to rule 32. Task, milestone, decision and rule ids are gone; the incidents behind them are restated as the constraint they left (why a file is deleted before its row, why the missing mark is a mark, why duplicates block on duration). Counts and album names from one library are dropped from production comments; test comments keep the names their fixtures use. The tagReadVersion log keeps each version's before and after, without the measurements. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,30 +13,29 @@ import (
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
||||
)
|
||||
|
||||
// Missing-pair folding (M485).
|
||||
// Missing-pair folding.
|
||||
//
|
||||
// A track marked missing whose replacement already sits on disk under another
|
||||
// row is folded into that replacement: its likes, plays, playlist entries and
|
||||
// tags move across and the missing row goes. On the operator's library this was
|
||||
// 355 of 451 missing tracks (#5274), nearly all quality upgrades — the mp3
|
||||
// removed, a flac imported at a new path.
|
||||
// tags move across and the missing row goes. The common case is a quality
|
||||
// upgrade — the mp3 removed, a flac imported at a new path.
|
||||
//
|
||||
// Move adoption (moved.go) can't catch these. It links a new file to a missing
|
||||
// row when the file is first inserted, matching on the recording MBID or the
|
||||
// audio hash. A re-encode never shares the hash, and the replacements arrived
|
||||
// untagged, so there was nothing to match; AcoustID filled many of the MBIDs
|
||||
// weeks later, by which time both rows existed. Adoption keeps the old row and
|
||||
// re-points its path, which only works while the new file has no row of its own.
|
||||
// Here both do, so this folds instead, with the duplicate merge's row half.
|
||||
// audio hash. A re-encode never shares the hash, and an untagged replacement
|
||||
// has nothing to match until AcoustID fills its MBID, by which time both rows
|
||||
// exist. Adoption keeps the old row and re-points its path, which only works
|
||||
// while the new file has no row of its own. Here both do, so this folds
|
||||
// instead, with the duplicate merge's row half.
|
||||
//
|
||||
// The rules are in ListMissingTrackPairs. Only a pair where each side has exactly
|
||||
// one candidate is folded: a wrong fold can't be undone, a skipped one is only a
|
||||
// row left in the missing list.
|
||||
// The rules are in ListMissingTrackPairs. Only a pair where each side has
|
||||
// exactly one candidate is folded: a wrong fold can't be undone, a skipped one
|
||||
// is only a row left in the missing list.
|
||||
//
|
||||
// Unlike the duplicate merge this runs without review (operator, 2026-10-07):
|
||||
// no file is touched, the missing row has nothing to play, and adoption, its
|
||||
// closest relative, is automatic too. Each fold is logged with both paths so a
|
||||
// wrong pair can be read back.
|
||||
// Unlike the duplicate merge this runs without review: no file is touched, the
|
||||
// missing row has nothing to play, and adoption, its closest relative, is
|
||||
// automatic too. Each fold is logged with both paths so a wrong pair can be
|
||||
// read back.
|
||||
|
||||
// PairResult tallies one pass.
|
||||
type PairResult struct {
|
||||
@@ -112,8 +111,8 @@ func PairMissingTracks(ctx context.Context, pool *pgxpool.Pool, logger *slog.Log
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// foldMissingPair folds one pair in its own transaction, after locking both rows
|
||||
// and checking the pair still holds.
|
||||
// foldMissingPair folds one pair in its own transaction, after locking both
|
||||
// rows and checking the pair still holds.
|
||||
func foldMissingPair(ctx context.Context, pool *pgxpool.Pool, missingID, presentID pgtype.UUID) (foldResult, error) {
|
||||
var f foldResult
|
||||
err := pgx.BeginFunc(ctx, pool, func(tx pgx.Tx) error {
|
||||
|
||||
Reference in New Issue
Block a user