## Regression: Fix in v1.7.16 was insufficient — issue persists in production

### Updated Root Cause Analysis

Post-release investigation of live server debug logs on `sofarr.i3omb.com` confirms the blocklist feature is **still failing** after v1.7.16. The server logs still show:

```
[Blocklist] Download not found: { arrQueueId: 439913856, arrType: 'radarr' }
```

The v1.7.16 fix cast both sides of the comparison to `String`, which was the correct approach — but it was applied to the **wrong data source**.

The permission check at line 693 of `dashboard.js` calls:

```js
const allDownloads = await downloadClientRegistry.getAllDownloads();
const download = allDownloads.find(d => d.arrQueueId != null && String(d.arrQueueId) === String(arrQueueId) && d.arrType === arrType);
```

`downloadClientRegistry.getAllDownloads()` fetches **raw download client data** directly from qBittorrent, SABnzbd, etc. — these are unmatched objects with no Sonarr/Radarr queue metadata. The `arrQueueId` field is only populated during `DownloadMatcher.js` processing (which runs during the SSE/dashboard build from the *arr cache). Because qBittorrent's `normalizeDownload()` never sets `arrQueueId`, the lookup **always returns `undefined`** for any qBittorrent torrent, regardless of type casting.

### Correct Fix

The permission check should validate against the **Sonarr/Radarr queue cache records** directly (where `id` is the queue record ID), rather than against raw download client data. The fix will replace the `downloadClientRegistry.getAllDownloads()` lookup with a direct cache lookup of `poll:sonarr-queue` / `poll:radarr-queue` records, matching by `String(record.id) === String(arrQueueId)`.

This will be released in v1.7.17.
