Skip to content

chore: sync development to main#2964

Merged
maintainerr-automation[bot] merged 44 commits into
mainfrom
development
May 22, 2026
Merged

chore: sync development to main#2964
maintainerr-automation[bot] merged 44 commits into
mainfrom
development

Conversation

@maintainerr-automation

Copy link
Copy Markdown
Contributor

Summary

Promotes development to main for release. Squash-merge when approved; release automation continues on approval.

Changes

enoch85 and others added 30 commits May 20, 2026 21:25
…eps SWC-safe

ts-jest kept a full TypeScript program per worker, so workers were slow to
tear down under CI load and intermittently logged "A worker process has
failed to exit gracefully". @swc/jest is transpile-only: the server suite
drops from ~66s to ~13s and workers exit cleanly with no warning.

SWC's stricter CommonJS live-binding exports turn the codebase's existing
circular dependencies into TDZ ReferenceErrors at module load, so this makes
those cycles SWC-safe without changing runtime behaviour:

- Wrap singular concrete TypeORM relation property types in `Relation<>` so
  emitted `design:type` metadata no longer eagerly references the related
  entity class.
- Annotate forwardRef-injected constructor params with type-only import
  aliases so `design:paramtypes` doesn't eagerly reference the class; the
  value import stays for the forwardRef arrow. DI tokens are unchanged.
- Give the media-server factory's three adapter injections explicit
  `@Inject(forwardRef(...))` (matching the sibling params) so their types
  can be aliased as well.

Closes #2946
chore(server): switch jest transform to @swc/jest
…2950)

Bumps node from 26.1.0-alpine3.22 to 26.2.0-alpine3.22.

---
updated-dependencies:
- dependency-name: node
  dependency-version: 26.2.0-alpine3.22
  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>
Bumps the nestjs group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) | `11.1.21` | `11.1.22` |
| [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) | `11.1.21` | `11.1.22` |
| [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) | `11.1.21` | `11.1.22` |
| [@nestjs/swagger](https://github.com/nestjs/swagger) | `11.4.3` | `11.4.4` |
| [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) | `11.1.21` | `11.1.22` |


Updates `@nestjs/common` from 11.1.21 to 11.1.22
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.22/packages/common)

Updates `@nestjs/core` from 11.1.21 to 11.1.22
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.22/packages/core)

Updates `@nestjs/platform-express` from 11.1.21 to 11.1.22
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.22/packages/platform-express)

Updates `@nestjs/swagger` from 11.4.3 to 11.4.4
- [Release notes](https://github.com/nestjs/swagger/releases)
- [Commits](nestjs/swagger@11.4.3...11.4.4)

Updates `@nestjs/testing` from 11.1.21 to 11.1.22
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.22/packages/testing)

---
updated-dependencies:
- dependency-name: "@nestjs/common"
  dependency-version: 11.1.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/core"
  dependency-version: 11.1.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/platform-express"
  dependency-version: 11.1.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/swagger"
  dependency-version: 11.4.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/testing"
  dependency-version: 11.1.22
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: nestjs
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.13 to 8.0.14.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.14/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.14
  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>
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.19.17 to 22.19.19.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 22.19.19
  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>
Bumps [rolldown](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/rolldown/rolldown/releases)
- [Changelog](https://github.com/rolldown/rolldown/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rolldown/rolldown/commits/v1.0.2/packages/rolldown)

---
updated-dependencies:
- dependency-name: rolldown
  dependency-version: 1.0.2
  dependency-type: direct:production
  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>
…+ coordinator

Introduce SettingsStoreService as the sole owner of persisted settings state
(the hydrated fields, init(), reads, public masking, and low-level
persistence), depending only on the settings repositories. SettingsService
becomes a pure coordinator (test/save/reinit flows) with no settings state of
its own, and every read consumer injects the store.

Because the API services and media-server adapters/factory now read settings
from the store instead of SettingsService, the circular dependencies are gone:
constructor forwardRef injections drop from 28 to 2 and the @swc/jest type-only
import aliases from 28 to 2 -- the only remaining pair is the genuine, mutual
MediaServerFactory <-> MediaServerSwitchService cycle (factory checks
isSwitching(); switch calls uninitializeServer()).

No behaviour change: SettingsService keeps its public API by delegating reads to
the store; save flows persist via the store and re-hydrate. Public settings
masking, save/test/connection, and media-server switch flows are preserved.
…em) to reflect roles

SettingsStoreService -> SettingsDataService (owns/reads/persists settings data)
SettingsService      -> SettingsOperationsService (tests connections + applies changes)

Renames the classes, files, import paths, and the injected fields/mocks that hold
them so each field's name matches the service it holds. Also points AppModule at
SettingsDataService for init() (hydration is a data concern), and keeps the
deliberate names where they read better (`appSettings` in notification agents,
`settings` for plain data reads, the spec SUT `service`). No behaviour change.
…god-object

refactor(server): decouple SettingsService into data store + coordinator
…t warnings

- notifications: render media items by item type so Emby/Jellyfin movies
  (whose parentId points at the library folder) no longer render as
  "undefined - season undefined"
- emby: log the server response body when a collection image upload fails,
  so a 500 is diagnosable instead of a bare status
- rule builder: keep the Custom Value inputs controlled (coalesce undefined)
- router: add a HydrateFallback element to silence the initial-hydration warning
Add a server check-types script and make the turbo test task depend on it, so
SWC-transpiled tests (which skip type-checking) can no longer hide type errors.
Remove stale testConnections mocks this surfaced in the collection-worker spec.
…er-item abort

- Collapse to one bounded-parallel layer in the comparator and revert the
  Plex-getter internal episode batching, so total in-flight lookups never
  exceed the cap (was up to cap x cap when nested).
- Rename WATCH_HISTORY_CONCURRENCY -> RULE_EVALUATION_CONCURRENCY: the pool
  bounds per-item operand evaluation across all getters, not just Plex.
- Restore abort checks inside the batched tasks for prompt cancellation.
#2897 made getSeriesByTvdbId/getMovieByTmdbId uncached so the empty-show
cleanup reads post-deletion truth (#2757/#2891) — but that also de-cached
the rule-evaluation path, where the same series/movie resolves once per
item, so episode-level rules over large libraries regressed badly.

Add ArrLookupCache: a run-scoped memo created for the evaluation loop only
and never handed to the collection/action phase, so the cleanup still reads
fresh and 'delete then read stale cache' is structurally impossible. Only
the two uncached arr identity lookups use it; Tautulli/Seerr/Plex/Jellyfin/
Emby already cache at the API layer.
…a a memo

Guards the integration invariant behind the rule-evaluation ArrLookupCache:
the cleanup path resolves the series from the uncached Sonarr client on every
run. If a stale/memoized value ever leaked into this path, the second run
(files now gone) would skip deletion — this test would fail.
#2955 split the SettingsService god-object and made SettingsModule a @global
provider of SettingsDataService, but left the module-level forwardRef wiring in
place. With the settings cycles gone, those forwardRefs are now removable.

- Drop the vestigial `forwardRef(() => SettingsModule)` import from the Plex,
  TMDB, TVDB, Jellyfin and Emby modules: each only reads settings via the
  @global SettingsDataService, so it needs no import at all.
- Convert SettingsModule's nine `forwardRef(() => XApiModule)` imports to plain
  imports now that no API module imports SettingsModule back.
- Break the last MediaServerFactory <-> MediaServerSwitchService cycle (the pair
  #2955 called irreducible) by extracting the in-progress flag into a zero-
  dependency MediaServerSwitchState holder: the factory reads it, the switch
  service writes it, neither depends on the other. This removes the final two
  constructor forwardRefs and their two @swc/jest type-only aliases.
- Move the data-only testSetup() onto SettingsDataService (kept as a delegating
  wrapper on SettingsOperationsService) so MediaServerSetupGuard reads it from
  the @global service, letting MediaServerModule drop its SettingsModule import.

forwardRef constructor injections and type-only aliases both drop to 0. The
only remaining forwardRefs are the genuine, pre-existing CollectionsModule <->
RulesModule domain cycle, untouched here.

No behaviour change.
Project-scoped .mcp.json servers require per-project approval before Claude Code
loads them; without it the playwright server silently never attaches and its
browser tools are unavailable. Add enabledMcpjsonServers so both configured
servers auto-connect on session start.
enoch85 and others added 14 commits May 22, 2026 15:16
…ardrefs

refactor(server): remove module forwardRefs left by the settings split
…rvers

chore: pre-approve project MCP servers (github, playwright)
Bumps the nestjs group with 4 updates: [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common), [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core), [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) and [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing).


Updates `@nestjs/common` from 11.1.22 to 11.1.23
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.23/packages/common)

Updates `@nestjs/core` from 11.1.22 to 11.1.23
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.23/packages/core)

Updates `@nestjs/platform-express` from 11.1.22 to 11.1.23
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.23/packages/platform-express)

Updates `@nestjs/testing` from 11.1.22 to 11.1.23
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.23/packages/testing)

---
updated-dependencies:
- dependency-name: "@nestjs/common"
  dependency-version: 11.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/core"
  dependency-version: 11.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/platform-express"
  dependency-version: 11.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nestjs
- dependency-name: "@nestjs/testing"
  dependency-version: 11.1.23
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: nestjs
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.59.3 to 8.59.4.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.59.4
  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>
Bumps [@hookform/resolvers](https://github.com/react-hook-form/resolvers) from 5.2.2 to 5.4.0.
- [Release notes](https://github.com/react-hook-form/resolvers/releases)
- [Commits](react-hook-form/resolvers@v5.2.2...v5.4.0)

---
updated-dependencies:
- dependency-name: "@hookform/resolvers"
  dependency-version: 5.4.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>
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.14 to 8.5.15.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.5.14...8.5.15)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.15
  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>
16 over-drove co-located CPU-heavy backends (Tautulli history queries on an
all-in-one N100), pushing requests past the 10s timeout and triggering the
retry feedback loop. 8 keeps concurrent load in check while staying far
faster than the old sequential path.
…story

perf: parallelize per-item Plex watch-history reads during rule execution
…tracking

- collection-worker.server.spec: drop mock for non-existent
  SettingsDataService.testConnections (failed check-types CI)
- collection-worker: keep original mediaToHandle naming, apply the
  ruleEvaluationFailed filter inline (per review feedback)
- collections.service: make setCollectionMediaRuleEvaluationFailed
  best-effort so a failed flag write can't abort the rule run
Track rule execution failures for collection media evaluation
@maintainerr-automation maintainerr-automation Bot requested a review from enoch85 as a code owner May 22, 2026 18:22
@maintainerr-automation maintainerr-automation Bot added the release:docker-build Build release candidate Docker image label May 22, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved by release automation (CODEOWNER approval was verified by Release 2).

@maintainerr-automation maintainerr-automation Bot merged commit fa9a157 into main May 22, 2026
31 checks passed
@maintainerr-automation

Copy link
Copy Markdown
Contributor Author

📚 Docs drift report

Comparing origin/mainHEAD against Maintainerr_docs. Informational only — maintainers decide what needs doc updates before release.

Rule glossary parity

  • Code rule keys (rules.constants.ts): 160
  • Documented keys (docs/Glossary.md): 160

Glossary is in sync with the code.

New migrations on this branch

  • 1779215202958-AddCollectionMediaRuleEvaluationFailed.ts

Each migration typically introduces a setting or schema change. Confirm Configuration.md and Migration.md still reflect user-facing behaviour.

Rule constants

  • rules.constants.ts changed: +16 / -0 lines
  • Review rule tables in docs/Rules.mdx and entries in docs/Glossary.md.

Public contracts (@maintainerr/contracts)

No contract changes.

New HTTP controllers

No new controllers.

feat: commits on this branch

No feat: commits detected.

Behavioral fixes worth reviewing

  • bbe85c0 fix(collections): address review feedback on rule-evaluation failure tracking
    • touched: apps/server/src/modules/collections/collection-worker.server.spec.ts, apps/server/src/modules/collections/collection-worker.service.ts, apps/server/src/modules/collections/collections.service.ts
  • 6be7d75 fix: overlay notification titles for Emby/Jellyfin movies and UI input warnings
    • touched: apps/server/src/modules/api/media-server/emby/emby-adapter.service.ts, apps/server/src/modules/notifications/notifications.service.spec.ts, apps/server/src/modules/notifications/notifications.service.ts, apps/ui/src/components/Rules/Rule/RuleCreator/RuleInput/index.tsx, apps/ui/src/router.tsx
  • b35e636 fix(ui): provide production peer dependencies
    • touched: apps/ui/package.json
  • c07d522 fix(server): correct collection ruleGroup entity type
    • touched: apps/server/src/modules/collections/entities/collection.entities.ts

fix: commits that touched a doc-worthy surface — the UI, any server module except internal-only events/logging, any controller, or the README. Worth scanning to decide whether observable behavior changed enough to warrant a docs note.

Documentation-labeled issues & PRs

No open issues or in-range merged PRs carry the documentation label.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Release 2.5 - Execute Push PR To Main completed after approval.

  • PR squash-merged into main
  • Sync back: success
  • Build Main: success

@maintainerr-automation

Copy link
Copy Markdown
Contributor Author

🎉 This PR is included in version 3.12.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@enoch85 enoch85 added this to the 3.12.1 milestone May 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:docker-build Build release candidate Docker image released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants