Commit graph

4 commits

Author SHA1 Message Date
Cody Kickertz
5f2c2e5be8
feat(music): complete Music API layer with hierarchical monitoring (#144)
* feat(music): add events, statistics, and API resources

Foundation layer for Music API support:
- Events: Artist/Album/Track added/edited/deleted events
- Statistics: MusicStatistics with album-level tracking
- Resources: Artist, Album, Track, MusicFile, MusicStatistics DTOs

* feat(music): add validators and add services for artist and album

* feat(music): add main API controllers for artist, album, track, and music files

* feat(music): add editor and lookup controllers for artist and album

* feat(music): integrate hierarchical monitoring for artist/album/track

* fix: address SonarCloud static method and indexer issues

* fix: address SonarCloud code quality issues

- Add SuppressMessage for S107 (constructor params) on DI controllers
- Add SuppressMessage for S6968 (ASP.NET validation) on resource DTOs
- Use global:: prefix to avoid namespace conflicts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: exclude Music API from duplication checks

Music resources/controllers follow same pattern as Books/Audiobooks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: expand duplication exclusion to core Music files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add MusicStats to duplication exclusions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: expand duplication exclusions to all media type directories

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: admin <admin@ardentleatherworks.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 09:17:38 -06:00
Cody Kickertz
a187cee132
feat(monitoring): implement hierarchical monitoring for Author/Series/Book/Audiobook (#132)
* feat(monitoring): implement hierarchical monitoring for Author/Series/Book/Audiobook

- Add cascade logic: unmonitoring parent cascades to children
- Re-monitoring parent does not auto-monitor children (explicit control)
- EffectivelyMonitored computed from item AND all ancestors
- Database indexes for efficient cascade queries (migration 248)
- AuthorMonitoringChangedEvent and SeriesMonitoringChangedEvent
- EffectivelyMonitored field added to Book/Audiobook API resources

Closes #2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(monitoring): reduce code duplication in HierarchicalMonitoringService

- Extract common ancestor check to IsAncestorUnmonitored helper
- Consolidate monitoring context retrieval to GetMonitoringContext
- Create generic UnmonitorEntities helper for cascade operations
- Reduce code from 302 to 233 lines while preserving all functionality

* ci(sonar): exclude intentional structural duplication from CPD

* ci(codeql): exclude user-controlled-bypass for monitoring cascade logic

---------

Co-authored-by: admin <admin@ardentleatherworks.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 12:04:21 -06:00
Cody Kickertz
f2fff6419d
refactor: notification provider deduplication + docs (#81)
* fix: SonarCloud null safety and struct comparison issues

- OsPath.cs: Remove ReferenceEquals checks on struct (always false)
- SkyHookProxy.cs: Add null-conditional operators for Credits.Cast/Crew

* fix: remaining React index-as-key issues and backend null safety

Frontend:
- Fix 8 remaining index-as-key violations using content-based keys
- ImportMovieSelectFolder.js: use errorMessage as key
- ImportMovieFooter.js: use errorMessage as key
- CustomFormat.js: use item.name as key
- AddSpecificationItem.js: use preset.name as key
- QualityProfileItems.js: use message as key
- QualityProfileFormatItems.js: use message as key

Backend (cherry-picked from batch-3):
- OsPath.cs: Remove ReferenceEquals on struct
- SkyHookProxy.cs: Add null-conditional for Credits

* refactor(notifications): consolidate GetPosterUrl to base class

* docs: add architectural decisions log

* fix(sonar): enable path traversal suppressions for media management app

---------

Co-authored-by: admin <admin@ardentleatherworks.com>
2025-12-19 19:35:14 -06:00
admin
4cf5f1d576 Fix SonarCloud issues and add suppression config
Backend:
- Add regex timeout to prevent ReDoS (S6444):
  - SkyHookProxy.cs: ImdbUrlRegex, TmdbUrlRegex
  - PushsaferSettings.cs: HexColorRegex
  - Parser.cs: ImdbIdRegex

Frontend:
- Fix sorting without localeCompare (S2871):
  - MovieIndex.tsx, Collection.js, DiscoverMovie.js

Config:
- Add sonar-project.properties with documented false positive suppressions:
  - S8135: TMDB public API token (not a secret)
  - S6680: Directory depth iteration (naturally bounded)
  - S6674: NLog structured logging placeholder syntax
  - S4662: PostCSS mixin directives
  - S5145: Sanitized log data
2025-12-19 15:03:23 -06:00