feat: add Scripts — run arbitrary parameterized code from the UI - #27
Merged
Conversation
A second vertical alongside backfills: developers write a class in app/scripts subclassing DataDrip::Script, declaring typed inputs with the `input` DSL (type, default, required:) and implementing a single `call` method. The UI at /data_drip/script_runs lists available scripts, auto-generates a typed input form from the DSL (with server-side coercion and validation; required booleans accept false but not missing), and runs the script in a background job. Every run is recorded permanently in data_drip_script_runs: who ran it, inputs, log output, error message + backtrace, status and created/start/started/finished timestamps. Scripts emit output via a `log` API that persists timestamped lines immediately and streams them to the show page through a polling Stimulus controller. Shared machinery is extracted without changing Backfill's public API: - DataDrip::SchematizedOptions owns the typed-options DSL for both Backfill.attribute and Script.input, including required: support, :enum server-side validation, and the anonymous model name. - DataDrip::BackfillerContext shares controller backfiller/timezone resolution. - The option-form helper (typed_option_inputs) is parametrized by field prefix; backfill form output is unchanged. The Scripts UI matches the redesigned admin: it plugs into the shared header (Backfills/Scripts navigation, dark-mode aware), triggers new runs through the fuzzy, component-aware combobox class picker reused from backfills, and renders typed inputs via an AJAX options endpoint. Also: on_script_run_* lifecycle hooks with class-first/global-handler precedence, DataDrip.script_queue_name config, `rails g data_drip:script` and a `rails g data_drip:install_scripts` upgrade generator for existing installs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rogercampos
force-pushed
the
feature/scripts
branch
from
July 22, 2026 16:13
fcfc295 to
9b1c486
Compare
rogercampos
marked this pull request as ready for review
July 23, 2026 07:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A second vertical alongside backfills: Scripts — arbitrary one-shot parameterized code, written in the host app, triggered from the DataDrip UI.
How it works
input name, type, default:, required:— the form at/data_drip/script_runs/newis auto-generated from the declarations, values are coerced server-side via ActiveModel types, and required inputs are validated before the run is created (required booleans acceptfalsebut not missing — inclusion validation, not presence).data_drip_script_runstable — who ran it, inputs, full log output, error message + backtrace, status, and created/start/started/finished timestamps. Runs are only deletable while still enqueued.ScriptRunnerjob (configurableDataDrip.script_queue_name) runs#callonce. Scripts emit output through alogAPI that persists timestamped lines immediately (update_columnappends — no$stdoutredirection, which is unsafe in multithreaded workers) and streams them live to the show page via a polling Stimulus controller.on_script_run_*lifecycle callbacks with the same class-first / global-handler precedence as backfills.Shared machinery (Backfill behavior unchanged)
DataDrip::SchematizedOptions— extracted typed-options DSL now backing bothBackfill.attributeandScript.input, addingrequired:support.DataDrip::BackfillerContext— shared controller concern for backfiller/timezone resolution.One deliberate improvement over the backfill form: on validation errors the script form re-renders input fields server-side with submitted values kept sticky.
Generators / upgrade path
rails g data_drip:script MyScript(supports--sorbet)data_drip:installnow also createsapp/scripts+ the migrationrails g data_drip:install_scriptsTesting
bin/dev): script picker, generated form, live output streaming and failure display.Notes
base_job_classretries, a failed script re-runs from scratch — README documents scripts should be idempotent or hosts shoulddiscard_on.bin/dev+ bootable dummy app); that commit will drop out of the diff once main is pushed.🤖 Generated with Claude Code