Skip to content
CAI
Software that uses CAICheck a score

blackcandy-org/blackcandy

41.1

Weak · 26 September 2026

3.6k

lines of production code

Ruby

with JavaScript

5

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Black Candy is a self-hosted music streaming server that manages local audio libraries, handling media synchronization, transcoding, and playback. It provides a modern web interface and native app bridge for browsing albums, artists, and playlists, while supporting features like synchronized lyrics and cover art fetching. The system is built on a modernized Ruby and JavaScript stack, utilizing background jobs for library scanning and real-time updates for a responsive user experience.

How it got here

2018 — Rails 8.1 platform modernization

23 changes.

The project underwent a comprehensive platform upgrade to Rails 8.1, replacing legacy infrastructure with modern tools like esbuild, Solid Queue, and Thruster. This period focused on rewriting core application components, including controllers, authentication, and the frontend asset pipeline, to support a streamlined, secure, and performant architecture.

2019–2020 — UI redesign and test expansion

16 changes.

This period focused on overhauling the user interface for core entities like albums, artists, and playlists, introducing modern browsing, filtering, and drag-and-drop sorting capabilities. Concurrently, the team established a robust centralized linting infrastructure and significantly expanded test coverage across models, controllers, and helper methods to ensure stability for these new features.

2021–2023 — UI redesign and native app integration

18 changes.

This period focused on a comprehensive visual overhaul of the application, introducing a new design system with dark mode support and a modernized layout. Significant architectural changes were made to the frontend, including a refactored JavaScript structure using Stimulus and Turbo, alongside the implementation of a native bridge to support mobile clients. The work also expanded core features such as search, playlist management, and media synchronization, while substantially increasing test coverage across controllers and background jobs.

2024–2026 — Native app bridge and PWA support

7 changes.

This period focused on enabling native app integration through Hotwire Native bridge controllers and PWA capabilities, including manifest and service worker setup. It also introduced a Discogs integration for automatic cover image fetching and improved the playlist selection interface with creation and listing features.

Features

Add Puma plugin to monitor media listener

A new Puma plugin has been added to automatically manage the lifecycle of the MediaListener service. The plugin integrates with Puma's event hooks to start the listener after the server boots (if the media listener setting is enabled), and stops it before restarts or when the server stops, ensuring proper resource management.

lib/puma · high confidence

Add artist index and show pages with album listings

Users can now browse all artists via a new index page and view detailed artist profiles on a new show page. The artist index displays a grid of artist cards with cover images and names, supporting sorting and pagination. The artist show page features a large backdrop image, displays the artist's name along with counts for their albums and songs, and lists their albums in two sections: 'Albums' and 'Appears On'. The show page also includes an edit link for administrators. Both pages include JSON API responses for programmatic access.

app/views/artists · high confidence

Add library show page with native app search support

A new library show page has been added that displays a grouped list of library sections (albums, artists, songs, and playlists) with human-readable count badges. For native app users, the page includes a search input component at the top, while the standard web view presents the library contents as a navigable list.

app/views/libraries · high confidence

Added PWA manifest and service worker files

New files have been added to the app/views/pwa directory to support Progressive Web App capabilities. The manifest.json.erb file defines the app identity (BlackCandy), specifies logo icons for both standard and maskable usage, and configures the app to launch in standalone mode with a root scope. Additionally, a service-worker.js file has been introduced with commented-out handlers for Web Push notifications and notification click events, providing a foundation for future offline and push notification features.

app/views/pwa · high confidence

Introduce new data models and media synchronization logic

This change introduces the core domain models for the application, including Album, Artist, Song, Playlist, and User, along with supporting classes for media handling (Media, MediaFile, MediaListener) and streaming (Stream). It establishes the data structure for organizing music library content, managing user playlists, and handling media file metadata extraction and synchronization. The Media model now orchestrates the syncing process, including adding/removing files and fetching external metadata from Discogs, while the MediaListener monitors file system changes to trigger background sync jobs. Additionally, new models like CurrentPlaylist and FavoritePlaylist provide specialized playlist behaviors, and the User model now supports theme settings and session management.

app/models · high confidence

Native app bridge controllers for account, media, and UI

New JavaScript controllers have been added to the bridge directory to support the Hotwire Native bridge integration. These controllers handle specific native app interactions: account menu navigation, album and playlist playback (including play, playNow, playNext, playLast, and playBeginWith actions with numeric song IDs), song list actions, search input submission, flash message display, and theme initialization. Each controller extends BridgeComponent and sends events to the native layer.

app/javascript/controllers/bridge · high confidence

New Discogs integration service for automatic cover image fetching

A new integration service has been added to automatically fetch cover images for artists and albums from the Discogs API. This service handles API authentication, search queries for both artist and album metadata, and image downloading, enabling background jobs to sync media cover art without manual intervention.

app/models/integrations · high confidence

New Stimulus controller mixins for event delegation and playing song indicators

This change introduces two new JavaScript mixins in the application's controller layer to improve code reuse and UI state management. The \event\_handler\ mixin simplifies adding event delegation to Stimulus controllers by automatically managing listener registration and cleanup upon controller disconnection, supporting selective delegation via data attributes. The \playing\_song\_indicator\ mixin provides a standardized way to highlight the currently playing song in lists by listening to custom document events (\songs:showPlaying\, \songs:hidePlaying\, \songs:pausePlaying\) and toggling CSS classes (\is-active\, \is-paused\) on song elements. These mixins allow controllers to offload common event handling and UI update logic, reducing boilerplate and ensuring consistent behavior across different parts of the app.

app/javascript/controllers/mixins · high confidence

New album browsing and playback interface

The album section now features a redesigned user interface with a dedicated index page that includes genre and year filtering, a card-based grid layout for browsing, and a detailed show page that supports multi-disc albums. Users can now play an entire album or individual tracks directly from the UI, with playback actions wired to the native bridge for mobile apps. The update also introduces an edit page for album cover images and exposes album data via new JSON API endpoints.

app/views/albums · high confidence

New dedicated search result pages for albums, artists, playlists, and songs

The search interface now includes dedicated views for each content type (albums, artists, playlists, and songs) in addition to the main search index. Users can navigate to specific result lists via 'See all' links, where results are paginated using Turbo frames with lazy loading for a smoother experience. The main search page aggregates these categories, and JSON responses now include structured data for all four types to support client-side rendering.

app/views/search · high confidence

New helper modules and enhanced application helpers for UI and data formatting

This change introduces several new helper modules to support specific UI components and data presentation: AlbumHelper provides methods to display album metadata and track counts; DialogHelper implements a secure, Turbo-native dialog system using message verifiers for path parameters; SessionHelper formats session details for user management views; and SongHelper builds JSON responses for songs, including stream URLs, album art, and lyrics. Additionally, a new FilterSortPresenter centralizes logic for handling pagination, filtering, and sorting parameters. The ApplicationHelper has been significantly expanded to include avatar rendering via Gravatar, a generic SVG icon tag system, cover image handling with variant sizes and loading states, a loader component, empty state alerts, duration and number formatting, and page title management that adapts to native app and dialog contexts.

app/helpers · high confidence

New model concerns for filtering, sorting, search, settings, and image handling

This change introduces five new model concerns in app/models/concerns that provide reusable capabilities for models. Filterable adds dynamic scope generation for filtering by attributes and associations, with validation of allowed filters. Sortable enables sorting by attributes and associations, including default sort configuration. Searchable integrates Ransack for full-text search across attributes and associations. GlobalSetting and ScopedSetting provide a unified interface for managing application settings with type conversion and singleton/scoped storage patterns. Imageable adds support for attached cover images with size variants and content type validation.

app/models/concerns · high confidence

New session management interface and API endpoints

Users can now view a list of active sessions, see details such as the signing-in date and current status, and manually revoke access for non-current sessions via a dedicated index page. The login form has been rewritten to use Turbo for submission, providing a smoother user experience. Additionally, new JSON API endpoints expose session data, including the user's API token for authenticated requests.

app/views/sessions · high confidence

New settings pages for appearance, library, transcoding, and integrations

The settings interface now includes dedicated pages for managing appearance (theme selection), library configuration (media path, media listener, parallel sync), transcoding options (lossless allowance, bitrate), and integrations (Discogs token). These pages are accessible via a new main settings dashboard and a vertical navigation sidebar, with admin-only sections for library, integration, transcoding, users, and sessions.

app/views/settings · high confidence

Redesigned songs library with filtering, sorting, and lyrics support

The songs library view has been redesigned to include genre and year filtering, sorting options, and a new lyrics display. Users can now filter songs by genre or year using lazy-loaded Turbo frames, sort the list, and clear active filters. The song list is rendered in a table format with actions to play, play next, or play last, and supports native app interactions. Additionally, a new lyrics page allows users to view synchronized lyrics for songs, with click-to-seek functionality.

app/views/songs · high confidence

Behavioural changes

Add pagination support and update Rails configuration defaults

This change introduces pagination capabilities to the application by adding a new Pagy initializer (config/initializers/pagy.rb) which enables the headers and limit extras, allowing clients to control page size and receive pagination metadata. It also updates the Rails configuration by adding a new assets initializer, removing deprecated framework-defaults and silencer initializers that are no longer needed in modern Rails versions, and updating the Content Security Policy and filter parameter logging initializers to reflect current best practices and expanded sensitive parameter filtering. Additionally, it registers new MIME types for FLAC and WAV audio files and adds an inflection rule for 'media\_syncing'.

config/initializers · high confidence

Background media sync with parallel processing and automatic cover image attachment

Media synchronization has been moved to background jobs to prevent UI blocking and ensure consistent state. The new \MediaSyncJob\ and \MediaSyncAllJob\ support parallel processing of files (controlled by the \media\_sync.parallel\_processor\_count\ setting) to speed up large library scans, while limiting concurrency to one instance at a time to prevent data inconsistency. Additionally, a new \AttachCoverImageFromDiscogsJob\ automatically fetches and attaches cover art from Discogs in the background after syncing, retrying on rate limits. The system now broadcasts real-time sync status updates to the UI.

app/jobs · high confidence

Black Candy v3.2 release with configurable settings and versioning updates

This update introduces Black Candy v3.2, featuring a new configurable settings system that allows administrators to define and validate configuration options via environment variables or code blocks. The release also exposes minimum required versions for both the CLI (v0.1.0) and mobile apps (v2.0.0), ensuring client compatibility. Version reporting has been enhanced to display edge release commit hashes and provide direct links to GitHub releases or commits, improving transparency for users tracking their deployment version.

_lib/black\candy · high confidence

Complete UI redesign with new component library and dark mode support

The application's visual presentation has been completely overhauled with a new design system. This includes a new SVG logo, a comprehensive set of CSS components (such as player, lyrics, sidebar, and search), and a modernized layout using CSS layers and variables. The theme engine now supports both light and dark modes, allowing users to switch between them seamlessly.

app/assets · high confidence

Complete controller rewrite with modern authentication and streaming architecture

The application controllers have been completely rewritten to replace the legacy Authlogic authentication with a custom session-based system using signed cookies and tokens, enforced via a new Authentication concern. This change introduces a modernized streaming pipeline that distinguishes between direct file serving (via Thruster or Rack::Files) and on-the-fly transcoding (using ActionController::Live), with client detection logic handling format support for Safari, iOS, and Android. The new structure also unifies error handling through custom exception classes, implements Turbo Stream-based dialog rendering and flash messages, and reorganizes core resources like albums, artists, songs, and playlists into dedicated controllers with consistent pagination and filtering support.

app/controllers · high confidence

Database schema modernization and new features

This update introduces several database changes to support new capabilities and improve data integrity. Users can now view lyrics for songs, as a new \lyrics\ column has been added to the songs table. Album and artist records now include \year\ and \genre\ fields, and songs track \bit\_depth\ and \discnum\ to better represent multi-disc releases and high-resolution audio. To prevent data duplication, a unique index on song \md5\_hash\ is enforced, automatically removing duplicate entries. The system also migrates album and artist images to Active Storage, replacing the previous string-based image storage. Additionally, the database schema was updated to remove legacy authentication columns (Authlogic), drop unused Solid Cache and Solid Queue tables, and enforce non-null constraints on album and artist names.

db/migrate · high confidence

Database schema updated for Rails 7.2 and Solid components

The database schema has been upgraded to Rails 7.2, introducing dedicated schema files for Solid Cable, Solid Cache, and Solid Queue to support the new background job and caching infrastructure. The main application schema now includes tables for users, songs, albums, artists, and playlists, alongside Active Storage variant records. Additionally, a default admin user is now created during database seeding.

db · high confidence

Expose minimum CLI version in system status

The system status JSON response now includes a \min\_cli\_version\ field, allowing clients to determine the minimum required CLI version for compatibility. This change is implemented in the \app/views/systems/show.json.jbuilder\ view, which also continues to expose the current application version and the minimum application version.

app/views/systems · high confidence

Improved media syncing user interface with real-time status updates

The media syncing experience now features a dedicated button component that dynamically updates its state. When a sync is in progress, the button displays a 'Syncing' label and is disabled to prevent duplicate actions. Once the sync completes, the interface automatically refreshes via Turbo Streams to show the ready state again and displays a confirmation notice to the user. The button also provides a dropdown menu offering options for both quick and full synchronization.

_app/views/media\syncing · high confidence

Major platform upgrade to Ruby 4.0.2 and Node.js 20 with streamlined Docker build

The application runtime has been upgraded from Ruby 2.4.1 to 4.0.2 and Node.js to 20.11.0, enabling the use of modern language features and performance improvements. The Docker build process has been restructured to use a multi-stage build that compiles assets with esbuild (replacing previous tooling) and runs the server as a non-root user for improved security. Additionally, the build now integrates jemalloc to reduce memory usage and latency, and the default database has been switched to SQLite to simplify self-hosted installation.

(repo-wide) · high confidence

Modernized development environment and deployment tooling

The project has replaced legacy development and deployment scripts with modern alternatives. The \bin/spring\ binstub is removed, and \bin/dev\ now uses \foreman\ to manage the development server. Static file serving has switched from Nginx to Thruster via the new \bin/thrust\ script. Deployment tooling has moved from Webpacker to Kamal, evidenced by the \bin/kamal\ binstub and the removal of \bin/webpack\ and \bin/webpack-dev-server\. Additionally, background job processing is now handled by Solid Queue via \bin/jobs\, and the \bin/setup\ script has been updated to use \db:prepare\ and support a \--reset\ flag.

bin · high confidence

New JavaScript architecture for audio playback and navigation

The application introduces a new client-side JavaScript structure centered around a dedicated Player class (powered by Howler.js) and a Playlist manager, replacing previous inline or fragmented implementations. This change enables more robust audio state management, including proper unloading of HTML5 audio nodes when switching songs to prevent memory leaks. Additionally, the new application entry point integrates Turbo with Idiomorph to handle page rendering, specifically addressing a bug where returning to the previous page displayed the wrong content by morphing the app container instead of replacing it entirely. It also adds logic to disable form submissions in native app environments when specific data attributes are present.

app/javascript · high confidence

New centralized linting rake tasks

A new \lib/tasks/lint.rake\ file introduces a \lint\ namespace with tasks for JavaScript (\lint:js\), CSS (\lint:css\), ERB (\lint:erb\), and Ruby (\lint:rb\), allowing developers to run all checks via \lint:all\. The JavaScript task uses \npx standard\, CSS uses \npx stylelint\, ERB uses \erb\_lint\, and Ruby uses \rubocop\, providing a unified entry point for code quality checks across the application.

lib/tasks · high confidence

Playlist selection dialog with creation and listing

The playlist selection interface now allows users to create a new playlist directly from the dialog via a name input and submit button, in addition to selecting from existing playlists. The list of existing playlists is rendered as clickable buttons that add the current song to the chosen playlist, with pagination support for large libraries.

app/views/playlists/selections · high confidence

Preserve PID directory to prevent Puma startup errors

A \.keep\ file has been added to the \tmp/pids\ directory to ensure the folder persists in the repository. This change prevents Puma from encountering loading errors that occur when the PID directory is missing, ensuring smoother application startup.

tmp · high confidence

Rails 8.1 upgrade with multi-database separation and Solid Queue adoption

The application has been upgraded to Rails 8.1, introducing a multi-database architecture that separates the primary, cache, Action Cable, and Solid Queue databases into distinct connections (configurable via DB\_URL, CACHE\_DB\_URL, CABLE\_DB\_URL, and QUEUE\_DB\_URL). The default database adapter is now SQLite, with PostgreSQL support retained for production environments. Background job processing has migrated from Sidekiq to Solid Queue, configured via config/queue.yml and integrated into Puma. The asset pipeline has switched from Webpacker to Propshaft, and Action Cable now uses the solid\_cable adapter instead of Redis. Additionally, the configuration system now supports a customizable theme via rails-settings-cached 2.0, and deployment is managed via Kamal with Thruster replacing Nginx for static file serving.

config · high confidence

Redesign home page with native app support and album shelves

The home page view has been completely redesigned to replace the previous placeholder content with a functional layout that displays recently played and recently added albums in shelf-style grids. The update introduces conditional rendering for native app environments, adding an account menu header when accessed via the native app, and includes proper page title tagging for Turbo Native compatibility. Users will now see their music activity organized by recent playback and addition dates, with an empty state alert shown when no data is available.

app/views/home · high confidence

Redesigned UI with new shared components and native app bridge support

The application's user interface has been overhauled with a comprehensive set of new shared view components. This includes a new account menu, bottom and library navigation bars, a top bar, and a redesigned music player with mini-player support. Search functionality is now handled by a dedicated input component, and list management features new filter and sort dropdowns. The update also introduces Material Design icons, Turbo-powered pagination, and native app bridge integration for features like flash messages and account actions.

app/views/shared · high confidence

Redesigned application layout and custom error pages

The application now features a completely redesigned layout structure, replacing the previous single-page template with a modular system including a new base layout, a main application layout with a sidebar player and navigation, and specialized layouts for dialogs, lyrics, playlists, settings, and plain pages. This change introduces a responsive design with a sticky sidebar for desktop and a bottom navigation bar for mobile, while also adding custom, styled error pages for 403, 404, 422, 500, and unsupported browser states to improve user experience during errors.

app/views/layouts · high confidence

Redesigned current playlist with precise song insertion and drag-and-drop reordering

The current playlist view has been rebuilt to support adding songs to specific positions (next to the current track, at the top, or at the end) and reordering tracks via drag-and-drop. Users can now see a track count, clear the playlist, and interact with individual songs through a redesigned list item that includes play controls, artist links, and a dropdown menu for adding to other playlists or deleting. The interface uses HTML5 drag-and-drop for sorting and Turbo Streams for seamless, partial updates when songs are added or removed, replacing the previous implementation.

_app/views/current\playlist · high confidence

Redesigned favorite playlist songs view with native bridge integration

The favorite playlist songs index page has been redesigned to display playlist metadata (name, track count, and total duration) within a horizontal card layout. The view now integrates with the Hotwire Native bridge, allowing native clients to handle play actions directly via the \bridge--playlist\#play\ action, while retaining standard web interactions for clearing the playlist. The song list is rendered via a shared partial, ensuring consistent presentation across platforms.

_app/views/favorite\playlist · high confidence

Redesigned playlist management views with Turbo integration

The playlist interface has been rebuilt using modern view templates that integrate Turbo for navigation and form submissions. The new playlist index page displays a grid of playlist cards, each featuring a play button that triggers a Turbo frame update, alongside sorting and filtering controls. Users can now create and edit playlists through dedicated forms that support cover image uploads and are configured to handle native app interactions via specific Turbo actions. Additionally, JSON API responses for playlists have been standardized to include basic metadata and favorite status.

app/views/playlists · high confidence

Redesigned playlist songs page with native drag-and-drop sorting and Turbo streaming

The playlist songs view has been completely redesigned to support reordering songs via native HTML5 drag-and-drop (replacing the previous Shopify draggable library) and to use Turbo for seamless, partial-page updates. Users can now drag songs to rearrange the playlist order, play individual tracks, or queue songs to play next or last directly from the list. The interface also includes a dropdown menu for managing songs (play, delete, add to playlist) and displays updated track counts and durations in real-time as songs are added or removed.

app/views/playlists/songs · high confidence

Removal of default ActionCable and ActionMailer base classes

The default base classes for ActionCable channels and connections, as well as the default ActionMailer base class, have been removed from the application. This eliminates the standard scaffolding for real-time communication and email delivery, indicating a shift away from using these default implementations or a migration to a different architecture for these features.

app/channels · high confidence

Removal of default static error pages and robots.txt URL update

The default static error pages (404, 422, and 500) located in the public directory have been removed, indicating that the application now handles these errors through dynamic rendering or a different mechanism rather than serving static files. Additionally, the documentation link in robots.txt has been updated from the HTTP to the HTTPS protocol.

public · high confidence

Removal of legacy Webpacker and Stimulus application entry points

The legacy Webpacker pack file (application.js) and the default hello\_controller.js have been removed from the frontend packs directory. This eliminates the previous entry point that initialized Rails UJS, Turbolinks, ActiveStorage, and the Stimulus application via Webpack helpers, indicating a shift away from the Webpacker-based asset pipeline for this specific location.

app/frontend/packs · high confidence

Removed placeholder CSS rule

The application stylesheet no longer contains a rule that set the background color of all paragraph elements to red, cleaning up leftover development styles.

app/frontend/stylesheets · high confidence

Rewrite user management and profile editing with Turbo

The user management interface has been rewritten to use Turbo for a seamless, single-page experience. Users can now edit their own profile via a dedicated /my/profile endpoint and manage other users through a new index page that lists all users with inline actions to edit or delete them. All user creation, editing, and deletion operations are handled via Turbo Stream responses, replacing the previous page-reload behavior with instant UI updates.

app/views/users · high confidence

Stimulus-based UI and native bridge integration

The frontend JavaScript has been refactored to use Hotwired Stimulus controllers, replacing previous implementation patterns. This introduces a native bridge layer (account, album, playlist, search, songs, theme) for native app integration, adds lyrics synchronization with auto-scrolling, enables native media session controls (playback, seek, metadata), and implements native HTML5 drag-and-drop for playlist reordering. User-facing changes include improved cover image fallbacks, dialog handling via URL parameters, and refined player state management.

app/javascript/controllers · high confidence

Upgrade to Rails 8.1 and migrate to Solid Queue and Solid Cache

The application has been upgraded to Rails 8.1, introducing several configuration changes across development, test, and production environments. The legacy \cache\_classes\ setting is replaced by \enable\_reloading\, and the caching backend has switched from memory/null stores to \solid\_cache\_store\. Background job processing now uses \solid\_queue\ with a dedicated queue database, replacing previous adapters. Production logging is now directed to STDOUT with request ID tagging, and SSL enforcement is configurable via \BlackCandy.config.force\_ssl\. Additionally, strict security behaviors are enabled, such as raising errors for unpermitted parameters and missing callback actions, and the \Webpacker\ integrity check has been removed.

config/environments · high confidence

Test coverage

Added controller integration tests for core application features; Added integration tests for current playlist album and playlist replacement endpoints; Added integration tests for current playlist song management; Added integration tests for playlist song management and API interactions; Added integration tests for search API pagination; Added integration tests for song and album filtering and lyrics features; Added integration tests for the favorite playlist songs controller; Added integration tests for user settings controller; Added model tests for media, library, and session components; Added test fixtures for LRC lyrics files; Added test fixtures for case-insensitive file extensions; Added tests for Black Candy configuration, errors, and versioning; Added tests for Discogs integration service; Added tests for application helper methods; Added tests for lyrics parsing and upgraded test infrastructure; Added tests for media sync and cover image jobs; Added tests for the Searchable model concern.

Dependencies

Major dependency overhaul: Rails 8.1, Hotwire, and esbuild

The application has been upgraded to Rails 8.1, replacing the previous 5.2 stack. This change introduces a modern frontend toolchain by removing Webpacker and adopting Hotwire (Turbo 8 and Stimulus 3) alongside esbuild for JavaScript bundling. Backend infrastructure is updated to use Solid Cache, Solid Queue, and Solid Cable, while the default database shifts to SQLite 2.7. Development tooling is refreshed with rubocop-rails-omakase, ERB Lint, and the Cuprite browser driver for testing.

(dependencies) · high confidence

Housekeeping

Added storage directory placeholder

A .keep file was added to the storage directory to ensure the directory is tracked by version control.

storage · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 39 → 41 (+2.3)
  • Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 50 → 49 (-1.1)
  • Architecture 92 → 74 (-17.1)
  • Maturity 90 → 90 (+0.0)
  • Readiness 16 → 34 (+18.4)
  • Security 49 → 61 (+11.2)
  • Domain Modelling 56 (new)
  • Accessibility 35 (new)

Resolved (70)

  • Change coupling: index.js ↔ helper.js (app/javascript/controllers/index.js)
  • Change coupling: media_session_controller.js ↔ mini_player_controller.js (app/javascript/controllers/media_session_controller.js)
  • Change coupling: media_session_controller.js ↔ player_controller.js (app/javascript/controllers/media_session_controller.js)
  • Change coupling: media_session_controller.js ↔ playlist.js (app/javascript/controllers/media_session_controller.js)
  • Change coupling: media_session_controller.js ↔ playlist_sortable_controller.js (app/javascript/controllers/media_session_controller.js)
  • Change coupling: mini_player_controller.js ↔ player_controller.js (app/javascript/controllers/mini_player_controller.js)
  • Change coupling: mini_player_controller.js ↔ playlist.js (app/javascript/controllers/mini_player_controller.js)
  • Change coupling: mini_player_controller.js ↔ playlist_sortable_controller.js (app/javascript/controllers/mini_player_controller.js)
  • Change coupling: player.js ↔ playlist.js (app/javascript/player.js)
  • Change coupling: player_controller.js ↔ playlist_sortable_controller.js (app/javascript/controllers/player_controller.js)
  • Coverage not measured — test suite did not build
  • Critical CVE: [GHSA redacted] (Gemfile.lock)
  • Dimension evaluation failed
  • High CVE: [GHSA redacted] (Gemfile.lock)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (Gemfile.lock)
  • High CVE: [GHSA redacted] (package-lock.json)
  • …and 50 more

New (68)

  • Boundary-crossing change coupling: albums_controller.rb ↔ artist.rb (app/controllers/albums_controller.rb)
  • Boundary-crossing change coupling: artists_controller.rb ↔ album.rb (app/controllers/artists_controller.rb)
  • Change coupling: albums_controller.rb ↔ artists_controller.rb (app/controllers/albums_controller.rb)
  • Change coupling: artists_controller.rb ↔ playlists_controller.rb (app/controllers/artists_controller.rb)
  • Change coupling: player_controller.js ↔ player.js (app/javascript/controllers/player_controller.js)
  • Change coupling: production.rb ↔ test.rb (config/environments/production.rb)
  • Change coupling: settings_controller.rb ↔ users_controller.rb (app/controllers/settings_controller.rb)
  • Change-coupling hub: development.rb → application.rb, production.rb, test.rb (config/environments/development.rb)
  • ClientDetection.need_transcode? (cognitive 16) (app/controllers/concerns/client_detection.rb)
  • Critical CVE: [GHSA redacted] (Gemfile.lock)
  • Documentation: no licence statement (docs/demo_music_licenses.md)
  • Duplicated block (11 lines × 2) (app/controllers/current_playlist/songs/albums_controller.rb)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (Gemfile.lock)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (Gemfile.lock)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (Gemfile.lock)
  • …and 48 more

Changes since last survey

  • 6 commits — 4 feature/other, 2 fixes

By area

  • app/views — 2 commits
  • (root) — 1 commit
  • app/controllers — 1 commit
  • app/javascript — 1 commit
  • app/models — 1 commit

Notable commits

  • fix: fix: unload html5 audio nodes when switching songs (#502)
  • fix: fix: upgrade brakeman (#501)
  • change: feat: add lyrics support (#496)
  • change: feat: add playlist creation from add dialog (#486)
  • change: feat: sessions management (#505)
  • change: refactor: remove Concern suffix from model concerns (#503)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

blackcandy-org/blackcandy was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 26 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 2303154f7247a3714f1a26c2dd3c4213e36ee50a — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-7c1cb6328e11.