feat(db): let a waiver name the rule it relaxed
`releases` forbade a rule name on anything but a rejection, so §9.3's deck showed a bare `waived` beside rejections that each named their own, and §5.7's "watchable but not what was asked" lost the half that says what was not asked for. Since #210 that is the ordinary outcome of waiving a size rejection, not a rare one. 0032 rebuilds the table with `CHECK (verdict != 'rejected' OR rejected_rule IS NOT NULL)`, and the daemon and arr-api's reclassification both store the waived rule. Existing rows keep NULL and read as they do today. `releases` is a parent — `grabs`, `movie_releases`, `episode_releases` and `season_releases` point at it, three ON DELETE CASCADE — so the rebuild runs `-- no-transaction` with foreign keys off around one explicit transaction, per SQLite's own procedure. Verified against a real database: the pre-0032 binary created and populated it, this build migrated a copy, and every release row, child row and created_at came through byte-identical with `PRAGMA foreign_key_check` clean. Refs #211
This commit is contained in:
@@ -1534,10 +1534,17 @@ fn search_query(movie: &PendingMovie) -> String {
|
||||
)
|
||||
}
|
||||
|
||||
/// The `verdict` and `rejected_rule` columns for a verdict.
|
||||
///
|
||||
/// A waiver names the rule it relaxed (#211). §5.7 calls a soft fail
|
||||
/// "watchable but not what was asked", and which rule was relaxed is the
|
||||
/// whole content of that sentence, so §9.3's deck can name it the way it
|
||||
/// names a rejection. Rows written before 0032 hold `NULL` there and stay
|
||||
/// readable.
|
||||
fn verdict_columns(verdict: &Verdict) -> (&'static str, Option<String>) {
|
||||
match verdict {
|
||||
Verdict::Eligible => ("eligible", None),
|
||||
Verdict::Waived(_) => ("waived", None),
|
||||
Verdict::Waived(rule) => ("waived", Some(rule.name())),
|
||||
Verdict::Rejected(rule) => ("rejected", Some(rule.name())),
|
||||
}
|
||||
}
|
||||
@@ -2029,6 +2036,22 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// #211: a waiver names the rule it relaxed, the same as a rejection, so
|
||||
/// §9.3's deck shows what was given up instead of a bare `waived`.
|
||||
/// Migration 0032 relaxed the constraint that forbade it.
|
||||
#[test]
|
||||
fn a_waiver_records_the_rule_it_relaxed() {
|
||||
assert_eq!(
|
||||
verdict_columns(&Verdict::Waived(arr_core::Rule::Size)),
|
||||
("waived", Some("size".to_owned()))
|
||||
);
|
||||
assert_eq!(verdict_columns(&Verdict::Eligible), ("eligible", None));
|
||||
assert_eq!(
|
||||
verdict_columns(&Verdict::Rejected(arr_core::Rule::RequiredAudio)),
|
||||
("rejected", Some("required_audio".to_owned()))
|
||||
);
|
||||
}
|
||||
|
||||
/// Every candidate is cached with its verdict, which is what the manual
|
||||
/// search view and the attention queues read (§9.3).
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user