Shopify/maintenance_tasks
64.7
Adequate · 20 September 2026
2.6k
lines of production code
Ruby
primary language
1
measurement over time
What this system is
This system is a Rails engine that provides a comprehensive framework for defining, executing, and monitoring background maintenance tasks. It offers a web-based interface for managing task lifecycles—including pausing, resuming, and canceling runs—alongside a command-line interface for direct execution. The engine supports processing large datasets via CSV batching, handles secure parameter input with sensitive data masking, and ensures data integrity through strict state transition validation.
How it got here
2020 — Maintenance Tasks UI and engine overhaul
36 changes.
This period focused on delivering a comprehensive web interface for the Maintenance Tasks engine, featuring a redesigned UI with dark mode, batch CSV processing, and full lifecycle management for task runs. The work included significant backend refactoring to support pluggable execution strategies, strict state validation, and enhanced configuration options, alongside extensive test coverage and generator tooling.
2021–2026 — architecture refactoring and Rails 8 support
6 changes.
This period focused on refactoring the core maintenance task execution logic by extracting shared behavior into reusable concerns, thereby centralizing lifecycle management and status handling. Concurrently, the project expanded its compatibility matrix to include testing against Rails 7.2, 8.0, 8.1, and the main branch, while also improving user experience with a custom 404 page for missing tasks.
Features
Added executable script for Maintenance Tasks CLI
A new executable file \exe/maintenance\_tasks\ has been added to the project. This script initializes the Rails application environment and invokes the \MaintenanceTasks::CLI\ to allow users to run maintenance tasks directly from the command line.
exe · high confidence
Introduce batch CSV processing and task data separation
Users can now process large CSV files in configurable batches via the new BatchCsvCollectionBuilder, which splits CSV content into chunks defined by a batch size. The task index page now uses a dedicated TaskDataIndex class to display task information, sorting tasks by the most recent run and separating active, completed, and new tasks for clearer status visibility.
_maintenance\tasks · high confidence
Introduce maintenance tasks UI with run lifecycle management and hardened security
This change introduces the core controllers for the maintenance tasks interface, allowing users to view available tasks, start new runs, and manage existing runs (pause, cancel, resume) directly from the UI. The RunsController handles the creation and state transitions of task runs, while the TasksController renders the task list and detail pages. To ensure security, the base ApplicationController now enforces a strict Content Security Policy using specific SHA-256 hashes for inline styles and scripts instead of nonces, and adds a handler to display a 404 page for missing tasks instead of raising raw errors.
app/controllers · high confidence
New generators for installing Maintenance Tasks and creating tasks
Maintenance Tasks now provides an InstallGenerator to automatically mount the engine in the host application's routes and install database migrations, and a TaskGenerator to scaffold new task files. The TaskGenerator supports creating CSV tasks via the --csv flag and collection-less tasks via the --no-collection flag, and it automatically generates corresponding test or spec files based on the application's configured testing framework.
_lib/generators/maintenance\tasks · high confidence
Architecture
Extract job execution logic into TaskJobConcern
The core logic for running maintenance tasks has been moved from the TaskJob class into a new TaskJobConcern module. This change centralizes the job lifecycle callbacks (start, shutdown, complete), error handling, cursor serialization, and enumerator building logic, ensuring that any custom job class overriding the default behavior can simply include this concern to maintain consistent task execution and status management.
app/jobs/concerns · high confidence
Behavioural changes
Add frozen\_string\_literal pragma to maintenance tasks rake file
The maintenance\_tasks\_tasks.rake file now includes the frozen\_string\_literal pragma, ensuring string literals in this file are immutable by default.
lib/tasks · high confidence
Custom 404 page for missing maintenance tasks
When a user attempts to access a maintenance task that does not exist or has been deleted, the application now displays a dedicated 'Task Not Found' page instead of raising a raw error. This new view provides a clear message and a link to return to the tasks list, improving the user experience for invalid task IDs.
_app/views/maintenance\tasks · high confidence
Detailed status information for maintenance task runs
The maintenance task run info view now displays specific status details for each lifecycle stage. Users can see how long a task has been running and when it ended for cancelled, errored, and succeeded runs. For running tasks, the estimated time to completion is shown if available. Paused runs display either the remaining time or the number of items processed. Interrupted and cancelling states show brief status messages, while enqueued runs indicate they are waiting to start. Error runs now display the error class, message, and backtrace (if present) in a structured card.
_app/views/maintenance\tasks/runs/info · high confidence
Enforce valid maintenance task run status transitions
A new RunStatusValidator has been introduced to strictly enforce allowed state changes for maintenance task runs. This prevents invalid status transitions (such as moving directly from 'paused' to 'cancelling' or 'interrupted' to 'succeeded') by validating the \status\_change\ attribute against a defined set of permitted transitions, ensuring data integrity for the task lifecycle.
app/validators · high confidence
Enhanced task parameter forms and improved time display
The maintenance tasks UI now renders specific input fields (number, datetime, date, time, checkbox, or text area) based on the attribute's data type, and automatically provides a dropdown selector for parameters with inclusion validators. Additionally, the time display now shows relative time with a UTC timestamp visible on hover, and helper text indicates the timezone for datetime-local fields.
app/helpers · high confidence
Extensive configuration options and deprecation of legacy error handling
The library now exposes a wide range of new configuration attributes via \MaintenanceTasks\, allowing users to customize task namespacing (\tasks\_module\), the background job class (\job\), progress ticker delay (\ticker\_delay\), Active Storage service for CSV uploads (\active\_storage\_service\), UI parent controller (\parent\_controller\), run metadata generation (\metadata\), stuck task detection threshold (\stuck\_task\_duration\), status reload frequency (\status\_reload\_frequency\), error reporting behavior (\report\_errors\_as\_handled\), cursor serialization format (\serialize\_cursors\_as\_json\), and task staleness detection (\task\_staleness\_threshold\). Additionally, the legacy \error\_handler\ configuration is now deprecated in favor of using the Rails error reporter, with a deprecation warning issued when the old setter or getter is accessed.
lib · high confidence
Extract run behavior to a concern
The behavior of the maintenance task run is now encapsulated in a new \RunConcern\ module, which is included in the \Run\ model. This change consolidates status definitions, validations, serialization logic, and core methods like \persist\_transition\, \persist\_progress\, and \persist\_error\ into a single reusable component, improving code organization without altering the external API of the \Run\ model.
app/models/concerns · high confidence
Generator templates updated to support collection-less tasks and CSV processing
The Maintenance Tasks generators now produce templates for collection-less tasks (using \no\_collection\ and a parameter-less \process\ method) and CSV-based tasks (using \csv\_collection\ and a \process(row)\ method). The standard task template has been updated to include an idempotency hint in the \process\ method comments, and the generated spec and test files now conditionally structure their examples based on whether the task is collection-less or not.
_lib/generators/maintenance\tasks/templates · high confidence
Maintenance Tasks CLI and engine initialization updates
The Maintenance Tasks engine now includes a new command-line interface (CLI) allowing users to list available tasks and run them directly via the \maintenance\_tasks\ executable, with support for passing CSV data (via file or stdin) and task parameters. Additionally, the engine enforces the use of the Zeitwerk autoloader by raising an error if classic autoloading is detected, and configures a default maximum job runtime of 5 minutes for \JobIteration\.
_lib/maintenance\tasks · high confidence
Migrate HTML linting to Herb and update development environment
The project has replaced the previous HTML linting tool with Herb, configured via a new .herb.yml file that enables security, nesting, and accessibility validators. The development environment is now set to Ruby 4.0.4 via a new .ruby-version file, and the Rakefile has been updated to include RuboCop in the default task, add system test support, and introduce a new integrity-hashes task for computing CSP hashes. Additionally, the repository is now licensed under MIT, and various configuration files (.gitignore, .yardopts) have been added or updated to reflect these changes.
(repo-wide) · high confidence
New maintenance tasks UI and API routes
The application now exposes a web interface for managing maintenance tasks. Users can view a list of available tasks and access individual task details via the new routes. The configuration adds RESTful routes for tasks and their associated runs, enabling users to enqueue runs, pause running tasks, cancel tasks, and resume paused tasks through specific POST endpoints. The root path now directs to the tasks index page.
config · high confidence
New production and setup scripts with streamlined bin/rails execution
This change introduces two new executable scripts: bin/production, which automates the production environment setup by generating a secret key, precompiling assets, setting up the database, and starting the server; and bin/setup, which simplifies initial project configuration by installing dependencies and setting up the database. Additionally, bin/rails has been updated to require only rails/engine/commands instead of the full rails/all, reducing startup overhead and ensuring consistent usage of the bin/rails wrapper across the application.
bin · high confidence
Redesigned UI with dark mode support and Bulma 1.0.4 integration
The maintenance tasks interface has been completely overhauled to use the Bulma 1.0.4 CSS framework (loaded via CDN with integrity checks) and includes native dark mode support that follows the system preference. The layout now features a dedicated navigation bar, structured sections for notifications, and custom styling for form elements and code syntax highlighting. Additionally, the page refresh mechanism has been updated to use JavaScript-based partial replacement instead of full page reloads, improving the user experience during task execution.
app/views/layouts · high confidence
Redesigned run detail view with anchor links, metadata, and masked arguments
The maintenance tasks run detail page has been restructured to improve usability and security. Each run is now wrapped in a collapsible section with a unique ID, enabling direct anchor links to specific runs. The view now displays run metadata and arguments, with sensitive arguments automatically masked for security. Additionally, a dedicated section allows users to download CSV files if available, and the UI provides clearer controls for resuming, pausing, or canceling runs based on their current status.
_app/views/maintenance\tasks/runs · high confidence
Refactored task execution and progress reporting with new strategy and runner classes
The maintenance task execution engine has been restructured to improve modularity and user experience. A new \Runner\ module centralizes task execution, supporting CSV file attachments via Active Storage and allowing custom arguments and metadata to be passed to runs. Task collection logic is now handled by pluggable strategies (\CsvCollectionBuilder\, \NoCollectionBuilder\, etc.), enabling tasks to process CSVs in batches or run as single iterations. Progress reporting is now managed by a dedicated \Progress\ class, providing more accurate row counts for CSV tasks and clearer text updates when the actual work exceeds the estimated total. Additionally, run history pagination has been optimized using a cursor-based \RunsPage\ model to reduce database query load.
_app/models/maintenance\tasks · high confidence
Removal of legacy asset pipeline stylesheets
The application no longer includes the legacy Maintenance Tasks stylesheets or the associated asset manifest. Users relying on the previous asset pipeline configuration for these styles will no longer have them automatically compiled or linked, indicating a shift away from the Sprockets-based asset management for this component.
app/assets · high confidence
Renamed base job class to TaskJob and included TaskJobConcern
The base job class in the MaintenanceTasks engine has been renamed from ApplicationJob to TaskJob to better reflect its role as the foundation for task execution. Additionally, the class now includes the TaskJobConcern, which centralizes shared behavior previously defined in the base class, ensuring that all task jobs inherit this common functionality.
_app/jobs/maintenance\tasks · high confidence
Revamped maintenance tasks UI with auto-refresh and staleness warnings
The maintenance tasks interface has been redesigned to improve usability and visibility. The index page now groups tasks into Active, New, and Completed sections and includes a toggle to enable or disable auto-refreshing of the task list. The task show page displays a staleness warning if a task has not run recently, based on the configured threshold, and provides a dedicated section to view source code. Additionally, the UI now supports custom run data via a new \\_custom.html.erb\ partial, allowing users to extend the display of run information.
_app/views/maintenance\tasks/tasks · high confidence
Schema evolution for maintenance task runs table
The \maintenance\_tasks\_runs\ database table has undergone several structural changes to support new capabilities and improve performance. A new \cursor\_is\_json\ boolean column was added to indicate when cursor data is stored as JSON, while a \metadata\ text column was introduced to store run context information. To support larger datasets, \tick\_count\ and \tick\_total\ columns were migrated from integers to bigints, and the \cursor\ column type was changed from bigint to string. Additionally, an \arguments\ text column was added to store task inputs, and a \lock\_version\ integer column was added to enable optimistic locking. Indexing was also refined: the single-column \task\_name\ index was removed, and the composite index on \task\_name\ and \created\_at\ was replaced with a new composite index on \task\_name\, \status\, and \created\_at\ (descending) to optimize queries filtering by task status.
db · high confidence
Stop spin from taking snapshots of the repo
The .spin configuration now includes a NOSNAPSHOTS file, which instructs the spin tool to skip creating snapshots of the repository. This change prevents unnecessary snapshot generation, likely to reduce storage usage or improve performance during local development workflows.
.spin · medium confidence
Updated Gemfile variants for Rails 7.2, 8.0, 8.1, and main
The project now includes specific Gemfile variants for testing against Rails 7.2, 8.0, 8.1, and the main development branch. The Rails 7.2 variant pins Minitest to version 5 (less than 6), while Rails 8.0, 8.1, and main do not impose this restriction, reflecting Minitest 6 support in newer Rails versions. The Rails main variant also explicitly sets a JSON gem requirement of version 0 or greater.
gemfiles · high confidence
Test coverage
Added model tests for Maintenance Tasks core components; Added sample CSV and TSV fixtures for import tests; Added system tests for task runs, task listing, and UI interactions; Added tests for Install and Task generators; Added tests for Maintenance Tasks CLI behavior; Added tests for TaskJob lifecycle and status transitions; Added tests for helper methods in maintenance tasks; Added tests for maintenance task run status transitions; Enhanced test infrastructure with stricter validation and system test migration; Expanded dummy application scaffolding for comprehensive task testing; Updated dummy Rails app environment configurations; Updated dummy app initializers for testing and security; Updated dummy app test fixtures for Rails 7 and Active Storage; Updated dummy application configuration for modern Rails and RuboCop standards; Updated test dummy database schema and seed data.
Dependencies
Maintenance Tasks 2.17.0: Rails 7.2+ support, Herb template engine, and Ruby 3.3 requirement
This release updates the gem to version 2.17.0, raising the minimum supported Rails version to 7.2 and the minimum Ruby version to 3.3. The template rendering engine has migrated from better\_html to herb, and the gemspec now explicitly declares dependencies on actionpack, activejob, activerecord, railties, csv, job-iteration, and zeitwerk. Development dependencies have been expanded to include debug, puma, rubocop, rubocop-shopify, and the full test suite (capybara, mocha, selenium-webdriver, minitest).
(dependencies) · 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
Baseline
- First survey — no prior run to compare against. CAI 65.
Lenses
- Code Health 98
- Architecture 97
- Maturity 56
- Readiness 61
- Security 88
- Domain Modelling 100
- Accessibility 68
Changes since last survey
- 300 commits — 293 feature/other, 7 fixes
By area
- (root) — 169 commits
- .github/workflows — 74 commits
- (repo) — 28 commits
- app/views — 10 commits
- app/models — 8 commits
- app/controllers — 2 commits
- test/models — 2 commits
- app/jobs — 1 commit
- db/migrate — 1 commit
- gemfiles/rails_8_0.gemfile — 1 commit
- test/dummy — 1 commit
- test/lib — 1 commit
- test/strict_locals_test.rb — 1 commit
- test/system — 1 commit
Notable commits
- fix: Fix HTML markup error in application layout found by Herb (#1305)
- fix: Fix cursor pagination ordering for task runs
- fix: Fix invalid README example (#1340)
- fix: Indentation fix within tasks/index.html.erb (#1405)
- fix: Merge pull request #1534 from salasebas/agent/fix-run-pagination-ordering
- fix: Revert "Avoid incrementing in-memory lock version on tick count updates" (#1326)
- fix: View fixes (#1407)
- change: (Not) handled exceptions (#1287)
- change: Add Rake task to compute CSP integrity hashes
- change: Add back error reporting code example to README (#1227)
- change: Add configurable status reload frequency (#1242)
- change: Add dark mode support following system preference
- change: Add refresh button to index page too
- change: Avoid incrementing lock version on tick count updates (#1241)
- change: Bump Bulma to 1.0.4
- change: Bump Bundler from 2.6.9 to 2.7.1 (#1259)
- change: Bump action_text-trix from 2.1.15 to 2.1.16 (#1364)
- change: Bump action_text-trix from 2.1.16 to 2.1.17 (#1413)
- change: Bump action_text-trix from 2.1.17 to 2.1.18 (#1431)
- change: Bump actionpack from 8.0.2.1 to 8.0.3 (#1294)
- …and 280 more
Architecture
- 0 containers · 1 bounded contexts · 0 dependency edges (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
Shopify/maintenance_tasks 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 20 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 9a81847d78fa60ed23d999e91175d1bed97f44a8 — 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-b51f968c9b10.