Skip to content

fix(storage-metrics): deduplicate reclaimable bytes; add cleanup byte counters#2833

Merged
enoch85 merged 14 commits into
developmentfrom
fix/storage-metrics-dedup-2823
May 6, 2026
Merged

fix(storage-metrics): deduplicate reclaimable bytes; add cleanup byte counters#2833
enoch85 merged 14 commits into
developmentfrom
fix/storage-metrics-dedup-2823

Conversation

@enoch85

@enoch85 enoch85 commented May 3, 2026

Copy link
Copy Markdown
Collaborator

Closes #2823

Reclaimable from collections now counts each item once across multiple delete-rule collections, and excludes collections without deleteAfterDays > 0.

Cleanup totals gain a per-type bytes-reclaimed counter, incremented on delete-style actions only (unmonitor / quality-change leave files on disk and don't contribute).

@enoch85

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

@enoch85

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

SmolSoftBoi and others added 3 commits May 3, 2026 16:35
…r-item sizes are populated

The deduped reclaimable query reads CollectionMedia.sizeBytes, which is
NULL on freshly upgraded installs until the collection-handler cron runs
and calls updateCollectionTotalSize. That left users staring at "0 B"
between deploy and the next cron tick.

When the deduped query returns nothing, sum the eligible collections'
cached Collection.totalSizeBytes (un-deduped) and surface a
reclaimableUsingFallback flag so the UI can hint that the figure will
sharpen on the next collection run.
@enoch85

This comment was marked as outdated.

@github-actions

github-actions Bot commented May 3, 2026

Copy link
Copy Markdown
Contributor

Released to maintainerr/maintainerr:pr-2833 🚀

@enoch85 enoch85 added the enhancement New feature or request label May 3, 2026
@enoch85 enoch85 requested a review from SmolSoftBoi May 3, 2026 19:20
@enoch85 enoch85 enabled auto-merge (squash) May 6, 2026 16:02
@enoch85 enoch85 disabled auto-merge May 6, 2026 16:02
@enoch85 enoch85 merged commit 971f964 into development May 6, 2026
13 checks passed
@enoch85 enoch85 deleted the fix/storage-metrics-dedup-2823 branch May 6, 2026 16:08
maintainerr-automation Bot added a commit that referenced this pull request May 6, 2026
* fix(app): correct version comparison for multi-digit segments (#2838)

* fix(app): correct version comparison for multi-digit segments

Closes #2835

* refactor(app): drop regex prefix trim per AGENTS.md string-handling rule

* build(deps-dev): bump postcss from 8.5.10 to 8.5.11 (#2839)

Bumps [postcss](https://github.com/postcss/postcss) from 8.5.10 to 8.5.11.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.5.10...8.5.11)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.11
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump yaml from 2.8.3 to 2.8.4 (#2840)

Bumps [yaml](https://github.com/eemeli/yaml) from 2.8.3 to 2.8.4.
- [Release notes](https://github.com/eemeli/yaml/releases)
- [Commits](eemeli/yaml@v2.8.3...v2.8.4)

---
updated-dependencies:
- dependency-name: yaml
  dependency-version: 2.8.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump @typescript-eslint/eslint-plugin (#2843)

Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.59.0 to 8.59.2.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.59.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump react-hook-form from 7.74.0 to 7.75.0 (#2844)

Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.74.0 to 7.75.0.
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](react-hook-form/react-hook-form@v7.74.0...v7.75.0)

---
updated-dependencies:
- dependency-name: react-hook-form
  dependency-version: 7.75.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump @typescript-eslint/parser from 8.59.1 to 8.59.2 (#2845)

Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.59.1 to 8.59.2.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.59.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump axios from 1.15.2 to 1.16.0 (#2842)

Bumps [axios](https://github.com/axios/axios) from 1.15.2 to 1.16.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](axios/axios@v1.15.2...v1.16.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump postcss from 8.5.13 to 8.5.14 (#2849)

Bumps [postcss](https://github.com/postcss/postcss) from 8.5.13 to 8.5.14.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.5.13...8.5.14)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.14
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump react-router-dom from 7.14.2 to 7.15.0 (#2847)

Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 7.14.2 to 7.15.0.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@7.15.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-version: 7.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix(storage-metrics): deduplicate reclaimable bytes; add cleanup byte counters (#2833)

* fix(collections): suppress rule re-add of items the handler just processed (#2837)

* fix(collections): suppress rule re-add of items the handler just processed

Track the mediaServerIds CollectionHandler.handleMedia processes per
collection in a small in-memory service. RuleExecutorService.handleCollection
consults it before computing mediaToAdd so the comparator pass that runs
seconds after the handler doesn't re-add the same item — which produced a
confusing "Media Removed" + "Media Added" notification pair for any rule
keyed on conditions (watched / lastViewedAt) that don't change after the
arr action. State clears via the existing Collection_Deleted event.

* fix(collections): consume recently-handled marks each rule pass

The suppression set was only cleared on Collection_Deleted, so once an
item was handled it stayed suppressed for the lifetime of the process.
For unmonitor / quality-change actions where the file remains on disk,
that meant a legitimate later re-match would never re-add the item.

Clear the per-collection set right after the rule executor consults it
so the suppression blocks exactly the immediate echo. Update JSDoc and
inline comments to match. Add a regression test that runs two passes:
the first suppresses, the second re-adds.

---------

Co-authored-by: Kristian Matthews-Kennington <kristian@matthews-kennington.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: maintainerr-automation[bot] <261505141+maintainerr-automation[bot]@users.noreply.github.com>
Co-authored-by: enoch85 <mailto@danielhansson.nu>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Kristian Matthews-Kennington <kristian@matthews-kennington.com>
@maintainerr-automation

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.10.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@enoch85 enoch85 added this to the 3.10.2 milestone May 12, 2026
doonga pushed a commit to greyrock-labs/home-ops that referenced this pull request May 13, 2026
…11.1 ) (#29)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/maintainerr/maintainerr](https://github.com/Maintainerr/Maintainerr) | minor | `3.10.1` → `3.11.1` |

---

### Release Notes

<details>
<summary>Maintainerr/Maintainerr (ghcr.io/maintainerr/maintainerr)</summary>

### [`v3.11.1`](https://github.com/Maintainerr/Maintainerr/blob/HEAD/CHANGELOG.md#3111-2026-05-12)

[Compare Source](Maintainerr/Maintainerr@v3.11.0...v3.11.1)

#### Highlights

- Fixed an issue where Jellyfin libraries with "Group films into collections" enabled caused BoxSet members to incorrectly toggle in and out of rule results ([#&#8203;2870](Maintainerr/Maintainerr#2870)).
- Improved error message for invalid Plex library section IDs to better guide users in resolving configuration issues ([#&#8203;2883](Maintainerr/Maintainerr#2883)).
- Enhanced custom collection UX by renaming tags for clarity and adding tooltips to explain collection handling options ([#&#8203;2882](Maintainerr/Maintainerr#2882)).

#### Fixes

- Validated Jellyfin IDs before refresh to prevent errors ([#&#8203;2853](Maintainerr/Maintainerr#2853)).
- Improved error message when Plex library section ID is invalid ([#&#8203;2883](Maintainerr/Maintainerr#2883)).
- Resolved Jellyfin collection add/remove loop for BoxSet items ([#&#8203;2870](Maintainerr/Maintainerr#2870)).
- Clarified custom collection terminology and added warnings for disabling collection handling ([#&#8203;2882](Maintainerr/Maintainerr#2882)).
- Added explicit token permissions to the Fider move job to address CodeQL findings.
- Added environment gate to mitigate TOCTOU vulnerability in the release\_pr workflow ([#&#8203;2879](Maintainerr/Maintainerr#2879)).
- Addressed transitive dependency vulnerabilities by adding Yarn resolutions for specific packages ([#&#8203;2881](Maintainerr/Maintainerr#2881)).

#### Dependencies

- Updated 10 dependencies, including notable packages: vite, typeorm, and [@&#8203;typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/eslint-plugin).

#### New Contributors

- [@&#8203;blixten85](https://github.com/blixten85) made their first contribution in [#&#8203;2881](Maintainerr/Maintainerr#2881)

### [`v3.11.0`](https://github.com/Maintainerr/Maintainerr/blob/HEAD/CHANGELOG.md#3110-2026-05-11)

[Compare Source](Maintainerr/Maintainerr@v3.10.2...v3.11.0)

#### Highlights

- Added support for force-processing overlays and gated reset operations against concurrent processing runs ([#&#8203;2827](Maintainerr/Maintainerr#2827)).
- Improved collection sorting: collections now apply sort order on save and synchronize with the media server ([#&#8203;2860](Maintainerr/Maintainerr#2860)).
- Enhanced storage metrics: potential reclaimable storage is now split into movie, show, season, and episode panels ([#&#8203;2854](Maintainerr/Maintainerr#2854)).

#### Breaking Changes

- None.

#### Features

- Added force-processing support for overlay operations and gated reset operations against concurrent processing runs ([#&#8203;2827](Maintainerr/Maintainerr#2827)).
- Improved storage metrics by splitting potential reclaimable storage into movie, show, season, and episode panels ([#&#8203;2854](Maintainerr/Maintainerr#2854)).

#### Fixes

- Fixed collection sorting to apply on save and synchronize with the media server ([#&#8203;2860](Maintainerr/Maintainerr#2860)).
- Resolved issue where excluding a single episode incorrectly excluded all episodes of the same show ([#&#8203;2867](Maintainerr/Maintainerr#2867)).
- Fixed storage metrics to merge shared volumes across hosts when byte-exact ([#&#8203;2852](Maintainerr/Maintainerr#2852)).
- Fixed Jellyfin retry ID check to align with pre-filter logic ([#&#8203;2853](Maintainerr/Maintainerr#2853)).
- Addressed issue where reclaimed bytes were not credited when `sizeBytes` was not yet cached ([#&#8203;2855](Maintainerr/Maintainerr#2855)).

#### Performance

- None.

#### Database migrations

- Added a new `mediaServerSort` column to the `collection` table to support media server-specific sorting.

#### Internal

- Added typed TanStack Query test helpers and migrated UI spec mocks to use typed builders ([#&#8203;2863](Maintainerr/Maintainerr#2863)).
- Added an architecture overview document detailing the monorepo structure, runtime flow, and core components ([#&#8203;2817](Maintainerr/Maintainerr#2817)).

#### Dependencies

- Updated 5 dependencies, including notable updates to TypeScript and typescript-eslint.

### [`v3.10.2`](https://github.com/Maintainerr/Maintainerr/blob/HEAD/CHANGELOG.md#3102-2026-05-08)

[Compare Source](Maintainerr/Maintainerr@v3.10.1...v3.10.2)

#### Highlights

- Fixed incorrect version comparison logic that caused update notifications to fail for multi-digit version segments ([#&#8203;2838](Maintainerr/Maintainerr#2838)).
- Improved storage metrics by deduplicating reclaimable bytes and adding per-type cleanup byte counters ([#&#8203;2833](Maintainerr/Maintainerr#2833)).

</details>

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNjAuNyIsInVwZGF0ZWRJblZlciI6IjQzLjE2MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19-->

Reviewed-on: https://git.greyrock.io/greyrock-labs/home-ops/pulls/29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Storage Metric: Reclaimable from Collections - Not deduping

2 participants