fix(daemon): measure attention window from failure

Closes the gap #239 describes: §5.7's 30-day window was filtered on
grabbed_at, so a torrent stalling past the window before hard-failing
at import never surfaced in the needs-a-decision queue. grabs gains
failed_at (migration 0030, backfilled from grabbed_at for existing
failed rows), the import tick stamps it on hard fail, and every window
query in the daemon notifier and the attention endpoint reads it.
§5.7 now states the anchor explicitly. §6.2's pack backoff stays on
grabbed_at deliberately; noted on the issue.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Miguel Palhas
2026-08-25 11:05:59 +01:00
parent 0a0c6359a4
commit 528aadf59c
15 changed files with 147 additions and 77 deletions
@@ -0,0 +1,86 @@
{
"db_name": "SQLite",
"query": "\n SELECT s.id AS \"series_id!: i64\", s.tmdb_id AS \"tmdb_id!: i64\",\n s.title AS \"title!: String\", s.year,\n g.target_id AS \"season_id!: i64\", se.number AS \"season_number!: i64\"\n FROM grabs g\n JOIN seasons se ON g.target_kind = 'season' AND se.id = g.target_id\n JOIN series s ON s.id = se.series_id\n WHERE g.state = 'failed'\n AND g.failed_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', ?)\n AND EXISTS (\n SELECT 1 FROM episodes e\n WHERE e.season_id = se.id\n AND e.wanted = 1 AND e.state != 'available'\n )\n GROUP BY s.id, s.tmdb_id, s.title, s.year, se.id, se.number\n HAVING count(DISTINCT g.release_id) >= 2\n ",
"describe": {
"columns": [
{
"name": "series_id!: i64",
"ordinal": 0,
"type_info": "Integer",
"origin": {
"Table": {
"table": "series",
"name": "id"
}
}
},
{
"name": "tmdb_id!: i64",
"ordinal": 1,
"type_info": "Integer",
"origin": {
"Table": {
"table": "series",
"name": "tmdb_id"
}
}
},
{
"name": "title!: String",
"ordinal": 2,
"type_info": "Text",
"origin": {
"Table": {
"table": "series",
"name": "title"
}
}
},
{
"name": "year",
"ordinal": 3,
"type_info": "Integer",
"origin": {
"Table": {
"table": "series",
"name": "year"
}
}
},
{
"name": "season_id!: i64",
"ordinal": 4,
"type_info": "Integer",
"origin": {
"Table": {
"table": "grabs",
"name": "target_id"
}
}
},
{
"name": "season_number!: i64",
"ordinal": 5,
"type_info": "Integer",
"origin": {
"Table": {
"table": "seasons",
"name": "number"
}
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
true,
false,
false
]
},
"hash": "dba46c4901a633fc1bda1b2adf75eed66904f2847ee45a699c96fd53d5d9e777"
}