Class: InlineForms::SchemaBatch
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- InlineForms::SchemaBatch
- Defined in:
- app/models/inline_forms/schema_batch.rb
Overview
A batch of proposed schema changes (SchemaIntentRecord rows), the unit the automated pipeline processes. Lifecycle:
draft — admin is still adding/removing intents (the "cart")
submitted — frozen; waiting for CI to pick it up
processing — CI is generating code / running the test gate
ready — code committed (git_sha set); waiting for the deploy window
applied — migrated + restarted
failed — any step failed; error holds the diagnostics
IMMUTABILITY: the moment a batch leaves draft, its intents are frozen (enforced in SchemaIntentRecord) and the batch itself only accepts status-flow updates (status, git_sha, error, applied_at). content_digest seals the intent list at submit time; export re-emits it and the import side re-verifies it, so a batch provably cannot change between "admin pressed submit" and "CI replayed it".
Constant Summary collapse
- STATUSES =
%w[draft submitted processing ready applied failed].freeze
- TRANSITIONS =
{ "draft" => %w[submitted], "submitted" => %w[processing failed], "processing" => %w[ready failed], "ready" => %w[applied failed], "failed" => %w[submitted], # resubmit after a fix "applied" => [] }.freeze
- STATUS_FLOW_COLUMNS =
Columns the pipeline may still write after the batch left draft.
%w[status git_sha error applied_at updated_at].freeze
Class Method Summary collapse
Instance Method Summary collapse
- #applied? ⇒ Boolean
- #draft? ⇒ Boolean
-
#due_for_apply? ⇒ Boolean
ready + the requested window (if any) has arrived.
- #failed? ⇒ Boolean
- #processing? ⇒ Boolean
- #ready? ⇒ Boolean
-
#submit!(requested_by: nil, window_at: nil) ⇒ Object
Freeze the batch: seal the digest, record who/when, optionally a window.
- #submitted? ⇒ Boolean
-
#transition!(to, git_sha: nil, error: nil) ⇒ Object
Status-flow update used by the pipeline (CI callback / apply task).
Class Method Details
.current_draft ⇒ Object
50 51 52 |
# File 'app/models/inline_forms/schema_batch.rb', line 50 def self.current_draft with_status(:draft).order(:id).first_or_create! end |
Instance Method Details
#applied? ⇒ Boolean
58 |
# File 'app/models/inline_forms/schema_batch.rb', line 58 def applied? = status == "applied" |
#draft? ⇒ Boolean
54 |
# File 'app/models/inline_forms/schema_batch.rb', line 54 def draft? = status == "draft" |
#due_for_apply? ⇒ Boolean
ready + the requested window (if any) has arrived.
62 63 64 |
# File 'app/models/inline_forms/schema_batch.rb', line 62 def due_for_apply? ready? && (window_at.nil? || window_at <= Time.current) end |
#failed? ⇒ Boolean
59 |
# File 'app/models/inline_forms/schema_batch.rb', line 59 def failed? = status == "failed" |
#processing? ⇒ Boolean
56 |
# File 'app/models/inline_forms/schema_batch.rb', line 56 def processing? = status == "processing" |
#ready? ⇒ Boolean
57 |
# File 'app/models/inline_forms/schema_batch.rb', line 57 def ready? = status == "ready" |
#submit!(requested_by: nil, window_at: nil) ⇒ Object
Freeze the batch: seal the digest, record who/when, optionally a window.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'app/models/inline_forms/schema_batch.rb', line 67 def submit!(requested_by: nil, window_at: nil) raise ArgumentError, "only a draft batch can be submitted" unless draft? raise ArgumentError, "cannot submit an empty batch" if intents.reload.empty? with_lock do self.status = "submitted" self.submitted_at = Time.current self.window_at = window_at self.requested_by = requested_by if requested_by self.content_digest = InlineFormsSchemaEdit::BatchExport.digest_for(self) save! end self end |
#submitted? ⇒ Boolean
55 |
# File 'app/models/inline_forms/schema_batch.rb', line 55 def submitted? = status == "submitted" |
#transition!(to, git_sha: nil, error: nil) ⇒ Object
Status-flow update used by the pipeline (CI callback / apply task).
83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'app/models/inline_forms/schema_batch.rb', line 83 def transition!(to, git_sha: nil, error: nil) to = to.to_s unless TRANSITIONS.fetch(status, []).include?(to) raise ArgumentError, "illegal transition #{status} -> #{to}" end self.status = to self.git_sha = git_sha if git_sha self.error = error if error self.applied_at = Time.current if to == "applied" save! self end |