From cbc13c4c5c1051dabfdf6f279673ff5f76fba96c Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Wed, 18 Sep 2024 16:33:36 +0200 Subject: [PATCH 1/9] feat(tasks): prefix tasks with timestamp --- config/initializers/maintenance_tasks.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 config/initializers/maintenance_tasks.rb diff --git a/config/initializers/maintenance_tasks.rb b/config/initializers/maintenance_tasks.rb new file mode 100644 index 000000000..1be27793e --- /dev/null +++ b/config/initializers/maintenance_tasks.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +Rails.application.config.after_initialize do + if defined?(Rails::Generators) + require "generators/maintenance_tasks/task_generator" + + class MaintenanceTasks::TaskGenerator + alias_method :original_assign_names!, :assign_names! + + private + + # Prefix the task name with a date so the tasks are better sorted. + def assign_names!(name) + timestamped_name = "T#{Date.current.strftime("%Y%m%d")}#{name}" + original_assign_names!(timestamped_name) + end + end + end +end From c0ae02f458fdf1780d7faea517aa9c5ae11f4ace Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Thu, 19 Sep 2024 13:25:21 +0200 Subject: [PATCH 2/9] feat(tasks): use our task template, with example doc --- config/initializers/maintenance_tasks.rb | 1 + lib/templates/maintenance_tasks/task.rb.tt | 25 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 lib/templates/maintenance_tasks/task.rb.tt diff --git a/config/initializers/maintenance_tasks.rb b/config/initializers/maintenance_tasks.rb index 1be27793e..90e1bed87 100644 --- a/config/initializers/maintenance_tasks.rb +++ b/config/initializers/maintenance_tasks.rb @@ -6,6 +6,7 @@ Rails.application.config.after_initialize do class MaintenanceTasks::TaskGenerator alias_method :original_assign_names!, :assign_names! + source_paths << Rails.root.join("lib/templates/maintenance_tasks") private diff --git a/lib/templates/maintenance_tasks/task.rb.tt b/lib/templates/maintenance_tasks/task.rb.tt new file mode 100644 index 000000000..ef2e399ca --- /dev/null +++ b/lib/templates/maintenance_tasks/task.rb.tt @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module <%= tasks_module %> +<% module_namespacing do -%> + class <%= class_name %>Task < MaintenanceTasks::Task + # Documentation: cette tâche modifie les données pour… + + def collection + # Collection to be iterated over + # Must be Active Record Relation or Array + end + + def process(element) + # The work to be done in a single iteration of the task. + # This should be idempotent, as the same element may be processed more + # than once if the task is interrupted and resumed. + end + + def count + # Optionally, define the number of rows that will be iterated over + # This is used to track the task's progress + end + end +<% end -%> +end From d0f77d0aab3ca8920d7195330ae27b922f7e05e8 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Thu, 19 Sep 2024 13:31:37 +0200 Subject: [PATCH 3/9] feat(task): with_statement_timeout helper for long running collection or process query --- .../concerns/statements_helpers_concern.rb | 25 +++++++++++++++ config/application.rb | 1 + config/brakeman.ignore | 23 ++++++++++++++ lib/templates/maintenance_tasks/task.rb.tt | 2 ++ .../statements_helpers_concern_spec.rb | 31 +++++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 app/tasks/maintenance/concerns/statements_helpers_concern.rb create mode 100644 spec/tasks/maintenance/concerns/statements_helpers_concern_spec.rb diff --git a/app/tasks/maintenance/concerns/statements_helpers_concern.rb b/app/tasks/maintenance/concerns/statements_helpers_concern.rb new file mode 100644 index 000000000..658c07b1b --- /dev/null +++ b/app/tasks/maintenance/concerns/statements_helpers_concern.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Maintenance + module StatementsHelpersConcern + extend ActiveSupport::Concern + + included do + # Execute block in transaction with a local statement timeout. + # A value of 0 disable the timeout. + # + # Example: + # def collection + # with_statement_timeout("5min") do + # Dossier.all + # end + # end + def with_statement_timeout(timeout) + ApplicationRecord.transaction do + ApplicationRecord.connection.execute("SET LOCAL statement_timeout = '#{timeout}'") + yield + end + end + end + end +end diff --git a/config/application.rb b/config/application.rb index b57986388..b45f7bd2f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -23,6 +23,7 @@ module TPS Rails.autoloaders.main.ignore(Rails.root.join('lib/cops')) Rails.autoloaders.main.ignore(Rails.root.join('lib/linters')) Rails.autoloaders.main.ignore(Rails.root.join('lib/tasks/task_helper.rb')) + Rails.autoloaders.main.collapse('app/tasks/maintenance/concerns') config.paths.add Rails.root.join('spec/mailers/previews').to_s, eager_load: true config.autoload_paths << "#{Rails.root}/app/jobs/concerns" diff --git a/config/brakeman.ignore b/config/brakeman.ignore index 9185336fb..4cb15c70d 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -113,6 +113,29 @@ ], "note": "" }, + { + "warning_type": "SQL Injection", + "warning_code": 0, + "fingerprint": "7dc4935d5b68365bedb8f6b953f01b396cff4daa533c98ee56a84249ca5a1f90", + "check_name": "SQL", + "message": "Possible SQL injection", + "file": "app/tasks/maintenance/concerns/statements_helpers_concern.rb", + "line": 19, + "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", + "code": "ApplicationRecord.connection.execute(\"SET LOCAL statement_timeout = '#{timeout}'\")", + "render_path": null, + "location": { + "type": "method", + "class": "Maintenance::StatementsHelpersConcern", + "method": "with_statement_timeout" + }, + "user_input": "timeout", + "confidence": "Medium", + "cwe_id": [ + 89 + ], + "note": "" + }, { "warning_type": "Cross-Site Scripting", "warning_code": 2, diff --git a/lib/templates/maintenance_tasks/task.rb.tt b/lib/templates/maintenance_tasks/task.rb.tt index ef2e399ca..2c0b98570 100644 --- a/lib/templates/maintenance_tasks/task.rb.tt +++ b/lib/templates/maintenance_tasks/task.rb.tt @@ -5,6 +5,8 @@ module <%= tasks_module %> class <%= class_name %>Task < MaintenanceTasks::Task # Documentation: cette tâche modifie les données pour… + include StatementsHelpersConcern + def collection # Collection to be iterated over # Must be Active Record Relation or Array diff --git a/spec/tasks/maintenance/concerns/statements_helpers_concern_spec.rb b/spec/tasks/maintenance/concerns/statements_helpers_concern_spec.rb new file mode 100644 index 000000000..970ca4898 --- /dev/null +++ b/spec/tasks/maintenance/concerns/statements_helpers_concern_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Maintenance::StatementsHelpersConcern do + let(:dummy_class) do + Class.new do + include Maintenance::StatementsHelpersConcern + end + end + + let(:instance) { dummy_class.new } + + describe '#with_statement_timeout' do + it 'applies the statement timeout and raises an error for long-running queries' do + expect { + instance.with_statement_timeout('1ms') do + # Cette requête devrait prendre plus de 1ms et donc déclencher un timeout + ActiveRecord::Base.connection.execute("SELECT pg_sleep(1)") + end + }.to raise_error(ActiveRecord::StatementInvalid, /canceling statement due to statement timeout/i) + end + + it 'allows queries to complete within the timeout and returns the result' do + result = instance.with_statement_timeout('1s') do + ActiveRecord::Base.connection.execute("SELECT 42 AS answer").first['answer'] + end + expect(result).to eq 42 + end + end +end From 2127f8cef19031083d2be420cc27947c7e19f2a3 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Mon, 23 Sep 2024 18:07:06 +0200 Subject: [PATCH 4/9] refactor: remove dead deploy code --- lib/tasks/deploy.rake | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/lib/tasks/deploy.rake b/lib/tasks/deploy.rake index f7edf1cc5..9ca276237 100644 --- a/lib/tasks/deploy.rake +++ b/lib/tasks/deploy.rake @@ -1,42 +1,4 @@ # frozen_string_literal: true -def domains_for_stage - if ENV['DOMAINS'].present? - ENV['DOMAINS'].split - else - raise "DOMAINS is empty. It must be something like DOMAINS='web1.dev web2.dev'" - end -end - -task :setup do - domains = domains_for_stage - - domains.each do |domain| - sh "mina setup domain=#{domain}" - end -end - -task :deploy do - domains = domains_for_stage - branch = ENV.fetch('BRANCH') - - domains.each do |domain| - sh "mina deploy domain=#{domain} branch=#{branch} force_asset_precompile=true" - end -end - -task :post_deploy do - domains = domains_for_stage - branch = ENV.fetch('BRANCH') - - sh "mina post_deploy domain=#{domains.first} branch=#{branch}" -end - -task :rollback do - domains = domains_for_stage - branch = ENV.fetch('BRANCH') - - domains.each do |domain| - sh "mina rollback service:restart_puma service:reload_nginx service:restart_delayed_job domain=#{domain} branch=#{branch}" end end From cae5d8afed9f9cd001f1a01a7c3f792383844b4c Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Mon, 23 Sep 2024 18:32:13 +0200 Subject: [PATCH 5/9] feat(task): task enqueueing a maintenance task runnable on deploy --- .../concerns/runnable_on_deploy_concern.rb | 24 +++++++++ lib/tasks/deploy.rake | 10 ++++ lib/templates/maintenance_tasks/task.rb.tt | 5 ++ .../runnable_on_deploy_concern_spec.rb | 53 +++++++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 app/tasks/maintenance/concerns/runnable_on_deploy_concern.rb create mode 100644 spec/tasks/maintenance/concerns/runnable_on_deploy_concern_spec.rb diff --git a/app/tasks/maintenance/concerns/runnable_on_deploy_concern.rb b/app/tasks/maintenance/concerns/runnable_on_deploy_concern.rb new file mode 100644 index 000000000..f324cef29 --- /dev/null +++ b/app/tasks/maintenance/concerns/runnable_on_deploy_concern.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Maintenance + module RunnableOnDeployConcern + extend ActiveSupport::Concern + + class_methods do + def run_on_first_deploy + @run_on_first_deploy = true + end + + def run_on_deploy? + return false unless @run_on_first_deploy + + task = MaintenanceTasks::TaskDataShow.new(name) + + return false if task.completed_runs.not_errored.any? + return false if task.active_runs.any? + + true + end + end + end +end diff --git a/lib/tasks/deploy.rake b/lib/tasks/deploy.rake index 9ca276237..22c95bc7c 100644 --- a/lib/tasks/deploy.rake +++ b/lib/tasks/deploy.rake @@ -1,4 +1,14 @@ # frozen_string_literal: true +namespace :deploy do + task maintenance_tasks: :environment do + tasks = MaintenanceTasks::Task + .load_all + .filter { _1.respond_to?(:run_on_deploy?) && _1.run_on_deploy? } + + tasks.each do |task| + Rails.logger.info { "MaintenanceTask run on deploy #{task.name}" } + MaintenanceTasks::Runner.run(name: task.name) + end end end diff --git a/lib/templates/maintenance_tasks/task.rb.tt b/lib/templates/maintenance_tasks/task.rb.tt index 2c0b98570..2affa82a5 100644 --- a/lib/templates/maintenance_tasks/task.rb.tt +++ b/lib/templates/maintenance_tasks/task.rb.tt @@ -5,8 +5,13 @@ module <%= tasks_module %> class <%= class_name %>Task < MaintenanceTasks::Task # Documentation: cette tâche modifie les données pour… + include RunnableOnDeployConcern include StatementsHelpersConcern + # Uncomment only if this task MUST run imperatively on its first deployment. + # If possible, leave commented for manual execution later. + # run_on_first_deploy + def collection # Collection to be iterated over # Must be Active Record Relation or Array diff --git a/spec/tasks/maintenance/concerns/runnable_on_deploy_concern_spec.rb b/spec/tasks/maintenance/concerns/runnable_on_deploy_concern_spec.rb new file mode 100644 index 000000000..7252b1c9a --- /dev/null +++ b/spec/tasks/maintenance/concerns/runnable_on_deploy_concern_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Maintenance::RunnableOnDeployConcern do + let(:test_class) do + Class.new do + include Maintenance::RunnableOnDeployConcern + end + end + + describe '.run_on_deploy?' do + context 'when run_on_first_deploy is not set' do + it 'returns false' do + expect(test_class.run_on_deploy?).to be false + end + end + + context 'when run_on_first_deploy is set' do + before do + test_class.run_on_first_deploy + allow(MaintenanceTasks::TaskDataShow).to receive(:new).and_return(task_data_show) + end + + let(:task_data_show) { instance_double(MaintenanceTasks::TaskDataShow, completed_runs: completed_runs, active_runs: active_runs) } + let(:completed_runs) { double(ActiveRecord::Relation, not_errored: not_errored_runs) } + let(:active_runs) { [] } + let(:not_errored_runs) { [] } + + context 'when there are no run yet' do + it 'returns true' do + expect(test_class.run_on_deploy?).to be true + end + end + + context 'when there are completed runs without errors' do + let(:not_errored_runs) { [instance_double(MaintenanceTasks::Run)] } + + it 'returns false' do + expect(test_class.run_on_deploy?).to be false + end + end + + context 'when there are active runs' do + let(:active_runs) { [instance_double(MaintenanceTasks::Run)] } + + it 'returns false' do + expect(test_class.run_on_deploy?).to be false + end + end + end + end +end From 0d5b0e81e7c753fb7f4ff5aa02763d58d540cfc8 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Tue, 24 Sep 2024 14:48:04 +0200 Subject: [PATCH 6/9] chore(dev): on update, run maintenance tasks configured on deploy --- bin/update | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/update b/bin/update index 82a89894f..ccb6fb6e3 100755 --- a/bin/update +++ b/bin/update @@ -37,6 +37,9 @@ FileUtils.chdir APP_ROOT do puts "\n== Running after_party tasks ==" system! 'bin/rails after_party:run' + puts "\n== Running on deploy maintenance tasks ==" + system! 'bin/rails deploy:maintenance_tasks' + puts "\n== Removing old logs ==" system! 'bin/rails log:clear' From 9eb9e8023263e18fe0dd5eae465d5e4372728c33 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Mon, 30 Sep 2024 09:26:46 +0200 Subject: [PATCH 7/9] chore(doc): more information about many maintenance tasks --- .../backfill_bulk_messages_with_procedure_id_task.rb | 3 +++ app/tasks/maintenance/backfill_city_name_task.rb | 3 +++ ...kfill_cloned_champs_private_piece_justificatives_task.rb | 3 +++ .../backfill_closing_reason_in_closed_procedures_task.rb | 3 +++ .../maintenance/backfill_commune_code_from_name_task.rb | 3 +++ app/tasks/maintenance/backfill_departement_services_task.rb | 3 +++ .../backfill_depose_at_on_deleted_dossiers_task.rb | 2 ++ .../maintenance/backfill_effectif_annuel_annee_task.rb | 2 ++ .../maintenance/backfill_invalid_dossiers_for_tiers_task.rb | 2 ++ .../create_previews_for_pj_of_latest_dossiers_task.rb | 3 +++ .../create_variants_for_pj_of_latest_dossiers_task.rb | 3 +++ .../delete_draft_revision_type_de_champs_task.rb | 6 +++--- .../maintenance/destroy_incomplete_bulk_messages_task.rb | 4 ++++ ...edure_without_administrateur_and_without_dossier_task.rb | 2 ++ .../maintenance/disable_remaining_invalid_mon_avis_task.rb | 2 ++ .../maintenance/fix_decimal_number_with_spaces_task.rb | 3 +++ ...conservation_greater_than_max_duree_conservation_task.rb | 4 ++++ .../fix_open_procedures_with_closing_reason_task.rb | 2 ++ app/tasks/maintenance/move_dol_to_cold_storage_task.rb | 4 ++++ app/tasks/maintenance/recompute_blob_checksum_task.rb | 5 +++++ app/tasks/maintenance/samsung_browser_is_supported_task.rb | 3 +++ app/tasks/maintenance/spread_dossier_deletion_task.rb | 2 ++ .../update_closing_reason_if_no_replaced_by_id_task.rb | 3 +++ ...update_conditions_based_on_commune_or_epci_champ_task.rb | 4 ++++ .../update_draft_revision_type_de_champs_task.rb | 2 ++ ...ate_routing_rules_based_on_commune_or_epci_champ_task.rb | 4 ++++ .../maintenance/update_service_etablissement_infos_task.rb | 3 +++ app/tasks/maintenance/update_zones_task.rb | 2 ++ 28 files changed, 82 insertions(+), 3 deletions(-) diff --git a/app/tasks/maintenance/backfill_bulk_messages_with_procedure_id_task.rb b/app/tasks/maintenance/backfill_bulk_messages_with_procedure_id_task.rb index 952c36b09..b7fb63d16 100644 --- a/app/tasks/maintenance/backfill_bulk_messages_with_procedure_id_task.rb +++ b/app/tasks/maintenance/backfill_bulk_messages_with_procedure_id_task.rb @@ -2,6 +2,9 @@ module Maintenance class BackfillBulkMessagesWithProcedureIdTask < MaintenanceTasks::Task + # Périmètre: envoi d’un email groupé aux usagers ayant dossiers en brouillon. + # Change la manière dont ces messages sont liés aux démarches. + # 2024-03-12-01 PR #10071 def collection BulkMessage .where(procedure: nil) diff --git a/app/tasks/maintenance/backfill_city_name_task.rb b/app/tasks/maintenance/backfill_city_name_task.rb index e22aa403e..636a65e76 100644 --- a/app/tasks/maintenance/backfill_city_name_task.rb +++ b/app/tasks/maintenance/backfill_city_name_task.rb @@ -2,6 +2,9 @@ module Maintenance class BackfillCityNameTask < MaintenanceTasks::Task + # corrige des données du champ adresse suite à un bug + # introduit pendant quelques jours début mars + # 2024-04-09-02 PR #10290 attribute :champ_ids, :string validates :champ_ids, presence: true diff --git a/app/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task.rb b/app/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task.rb index 23ad7af96..a042c8db9 100644 --- a/app/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task.rb +++ b/app/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task.rb @@ -2,6 +2,9 @@ module Maintenance class BackfillClonedChampsPrivatePieceJustificativesTask < MaintenanceTasks::Task + # Supprime les PJ d’annotations privées + # qui étaient conservées par erreur lorsqu’un dossier était cloné + # 2024-05-27-01 PR #10435 def collection Dossier.en_brouillon.where.not(parent_dossier_id: nil) end diff --git a/app/tasks/maintenance/backfill_closing_reason_in_closed_procedures_task.rb b/app/tasks/maintenance/backfill_closing_reason_in_closed_procedures_task.rb index 49981e6ed..88525d1f9 100644 --- a/app/tasks/maintenance/backfill_closing_reason_in_closed_procedures_task.rb +++ b/app/tasks/maintenance/backfill_closing_reason_in_closed_procedures_task.rb @@ -2,6 +2,9 @@ module Maintenance class BackfillClosingReasonInClosedProceduresTask < MaintenanceTasks::Task + # Remet les messages de cloture d'une démarche proprement (sinon affichage KO). + # Suite de UpdateClosingReasonIfNoReplacedByIdTask + # 2024-05-27-01 PR #9930 def collection Procedure .with_discarded diff --git a/app/tasks/maintenance/backfill_commune_code_from_name_task.rb b/app/tasks/maintenance/backfill_commune_code_from_name_task.rb index 922c3a377..b2285a602 100644 --- a/app/tasks/maintenance/backfill_commune_code_from_name_task.rb +++ b/app/tasks/maintenance/backfill_commune_code_from_name_task.rb @@ -2,6 +2,9 @@ module Maintenance class BackfillCommuneCodeFromNameTask < MaintenanceTasks::Task + # corrige structure champs commune pour une démarche donnée. Suite à un bug ? + # 2024-05-31-01 PR #10469 + attribute :procedure_id, :string validates :procedure_id, presence: true diff --git a/app/tasks/maintenance/backfill_departement_services_task.rb b/app/tasks/maintenance/backfill_departement_services_task.rb index cb75cee97..e2da6bc11 100644 --- a/app/tasks/maintenance/backfill_departement_services_task.rb +++ b/app/tasks/maintenance/backfill_departement_services_task.rb @@ -2,6 +2,9 @@ module Maintenance class BackfillDepartementServicesTask < MaintenanceTasks::Task + # Fait le lien service – département pour permettre + # le filtrage des démarches par département + # 2023-10-30-01 PR #9647 def collection Service.where.not(etablissement_infos: nil) end diff --git a/app/tasks/maintenance/backfill_depose_at_on_deleted_dossiers_task.rb b/app/tasks/maintenance/backfill_depose_at_on_deleted_dossiers_task.rb index 2f8eb6178..389eddef3 100644 --- a/app/tasks/maintenance/backfill_depose_at_on_deleted_dossiers_task.rb +++ b/app/tasks/maintenance/backfill_depose_at_on_deleted_dossiers_task.rb @@ -2,6 +2,8 @@ module Maintenance class BackfillDeposeAtOnDeletedDossiersTask < MaintenanceTasks::Task + # Améliore les stats à propos des dates de dépôts pour les dossiers supprimés + # 2024-04-05-01 PR #10259 def collection DeletedDossier.where(depose_at: nil) end diff --git a/app/tasks/maintenance/backfill_effectif_annuel_annee_task.rb b/app/tasks/maintenance/backfill_effectif_annuel_annee_task.rb index ce52d05f9..65d6d4a1e 100644 --- a/app/tasks/maintenance/backfill_effectif_annuel_annee_task.rb +++ b/app/tasks/maintenance/backfill_effectif_annuel_annee_task.rb @@ -2,6 +2,8 @@ module Maintenance class BackfillEffectifAnnuelAnneeTask < MaintenanceTasks::Task + # API entreprise: rattrape les informations d'effectif + # 2024-05-27-01 PR #10053 def collection Etablissement.where.not(entreprise_effectif_annuel: nil).where(entreprise_effectif_annuel_annee: nil) end diff --git a/app/tasks/maintenance/backfill_invalid_dossiers_for_tiers_task.rb b/app/tasks/maintenance/backfill_invalid_dossiers_for_tiers_task.rb index b7c1149ea..1af3f814a 100644 --- a/app/tasks/maintenance/backfill_invalid_dossiers_for_tiers_task.rb +++ b/app/tasks/maintenance/backfill_invalid_dossiers_for_tiers_task.rb @@ -2,6 +2,8 @@ module Maintenance class BackfillInvalidDossiersForTiersTask < MaintenanceTasks::Task + # Corrige les dossiers declarés pour un tiers mais sans avoir renseigné les infos du tiers + # 2024-05-22-01 def collection Dossier.where(for_tiers: true).where(mandataire_first_name: nil) end diff --git a/app/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task.rb b/app/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task.rb index 1c2378340..37e1d2b7b 100644 --- a/app/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task.rb +++ b/app/tasks/maintenance/create_previews_for_pj_of_latest_dossiers_task.rb @@ -2,6 +2,9 @@ module Maintenance class CreatePreviewsForPjOfLatestDossiersTask < MaintenanceTasks::Task + # Génère les vignettes de PJ existantes pour les dossiers déposés entre 2 dates (facultatif) + # Elles sont affichées dans le nouvel onglet "Pièces jointes" des instructeurs. + # 2024-07-11-01 attribute :start_text, :string validates :start_text, presence: true diff --git a/app/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task.rb b/app/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task.rb index 2b44d9ea6..2fa1bd2a4 100644 --- a/app/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task.rb +++ b/app/tasks/maintenance/create_variants_for_pj_of_latest_dossiers_task.rb @@ -2,6 +2,9 @@ module Maintenance class CreateVariantsForPjOfLatestDossiersTask < MaintenanceTasks::Task + # Génère les vignettes de fichiers PDF pour les dossiers déposés entre 2 dates (facultatif) + # Elles sont affichées dans le nouvel onglet "Pièces jointes" des instructeurs. + # 2024-07-11-01 attribute :start_text, :string validates :start_text, presence: true diff --git a/app/tasks/maintenance/delete_draft_revision_type_de_champs_task.rb b/app/tasks/maintenance/delete_draft_revision_type_de_champs_task.rb index 95f577403..cc08a519d 100644 --- a/app/tasks/maintenance/delete_draft_revision_type_de_champs_task.rb +++ b/app/tasks/maintenance/delete_draft_revision_type_de_champs_task.rb @@ -2,10 +2,10 @@ module Maintenance class DeleteDraftRevisionTypeDeChampsTask < MaintenanceTasks::Task - csv_collection - + # Modifie le form d’une démarche à partir d’un CSV (dev spécifique Fonds Verts). # See UpdateDraftRevisionTypeDeChampsTask for more information - # Just add delete_flag with "true" to effectively remove the type de champ from the draft. + # Just add delete_flag with "true" in CSV to effectively remove the type de champ from the draft. + csv_collection def process(row) return unless row["delete_flag"] == "true" diff --git a/app/tasks/maintenance/destroy_incomplete_bulk_messages_task.rb b/app/tasks/maintenance/destroy_incomplete_bulk_messages_task.rb index 32d1bef43..f0c96cbc8 100644 --- a/app/tasks/maintenance/destroy_incomplete_bulk_messages_task.rb +++ b/app/tasks/maintenance/destroy_incomplete_bulk_messages_task.rb @@ -2,6 +2,10 @@ module Maintenance class DestroyIncompleteBulkMessagesTask < MaintenanceTasks::Task + # Périmètre: envoi d’un email groupé aux usagers ayant dossiers en brouillon. + # Change la manière dont ces messages sont liés aux démarches. + # Suite de BackfillBulkMessagesWithProcedureIdTask + # 2024-03-12-01 PR #10071 def collection BulkMessage.where(procedure: nil).where.missing(:groupe_instructeurs) end diff --git a/app/tasks/maintenance/destroy_procedure_without_administrateur_and_without_dossier_task.rb b/app/tasks/maintenance/destroy_procedure_without_administrateur_and_without_dossier_task.rb index 70860af82..29768d104 100644 --- a/app/tasks/maintenance/destroy_procedure_without_administrateur_and_without_dossier_task.rb +++ b/app/tasks/maintenance/destroy_procedure_without_administrateur_and_without_dossier_task.rb @@ -2,6 +2,8 @@ module Maintenance class DestroyProcedureWithoutAdministrateurAndWithoutDossierTask < MaintenanceTasks::Task + # suppression de procédures closes sans admin et sans dossier + # 2024-03-18-01 PR #10125 def collection Procedure.with_discarded.where.missing(:administrateurs, :dossiers) end diff --git a/app/tasks/maintenance/disable_remaining_invalid_mon_avis_task.rb b/app/tasks/maintenance/disable_remaining_invalid_mon_avis_task.rb index 71a78696d..b0bef2c77 100644 --- a/app/tasks/maintenance/disable_remaining_invalid_mon_avis_task.rb +++ b/app/tasks/maintenance/disable_remaining_invalid_mon_avis_task.rb @@ -2,6 +2,8 @@ module Maintenance class DisableRemainingInvalidMonAvisTask < MaintenanceTasks::Task + # Supprime les codes d’intégration « mon avis » invalides + # 2024-03-18-01 PR #10120 def collection # rubocop:disable DS/Unscoped Procedure.unscoped.where.not(monavis_embed: nil) diff --git a/app/tasks/maintenance/fix_decimal_number_with_spaces_task.rb b/app/tasks/maintenance/fix_decimal_number_with_spaces_task.rb index 7e6fe41b8..499093a4b 100644 --- a/app/tasks/maintenance/fix_decimal_number_with_spaces_task.rb +++ b/app/tasks/maintenance/fix_decimal_number_with_spaces_task.rb @@ -2,6 +2,9 @@ module Maintenance class FixDecimalNumberWithSpacesTask < MaintenanceTasks::Task + # normalise les champs nombres en y supprimant les éventuels espaces + # 2024-07-01-01 PR #10554 + ANY_SPACES = /[[:space:]]/ def collection Champs::DecimalNumberChamp.where.not(value: nil) diff --git a/app/tasks/maintenance/fix_duree_conservation_greater_than_max_duree_conservation_task.rb b/app/tasks/maintenance/fix_duree_conservation_greater_than_max_duree_conservation_task.rb index 4d3618dbf..adcea8687 100644 --- a/app/tasks/maintenance/fix_duree_conservation_greater_than_max_duree_conservation_task.rb +++ b/app/tasks/maintenance/fix_duree_conservation_greater_than_max_duree_conservation_task.rb @@ -2,6 +2,10 @@ module Maintenance class FixDureeConservationGreaterThanMaxDureeConservationTask < MaintenanceTasks::Task + # Corrige la durée de conservation des dossiers : + # pour toutes les démarches dont la durée de conservation est supérieure + # à celle de l'instance, on prend la durée max de DS (12 mois) + # 2024-05-27-01 PR #10107 def collection Procedure.where('duree_conservation_dossiers_dans_ds > max_duree_conservation_dossiers_dans_ds') end diff --git a/app/tasks/maintenance/fix_open_procedures_with_closing_reason_task.rb b/app/tasks/maintenance/fix_open_procedures_with_closing_reason_task.rb index daf619542..711e454ff 100644 --- a/app/tasks/maintenance/fix_open_procedures_with_closing_reason_task.rb +++ b/app/tasks/maintenance/fix_open_procedures_with_closing_reason_task.rb @@ -2,6 +2,8 @@ module Maintenance class FixOpenProceduresWithClosingReasonTask < MaintenanceTasks::Task + # Corrige des démarches avec un motif de fermerture alors qu’elles ont été publiées + # 2024-05-27-01 PR #10181 def collection Procedure .with_discarded diff --git a/app/tasks/maintenance/move_dol_to_cold_storage_task.rb b/app/tasks/maintenance/move_dol_to_cold_storage_task.rb index 8f039d94c..f4ab280b3 100644 --- a/app/tasks/maintenance/move_dol_to_cold_storage_task.rb +++ b/app/tasks/maintenance/move_dol_to_cold_storage_task.rb @@ -2,6 +2,10 @@ module Maintenance class MoveDolToColdStorageTask < MaintenanceTasks::Task + # Opération de rattrapage suite à un cron qui ne fonctionnait plus. + # Permet de déplacer toutes les traces fonctionnelles (DossierOperationLog) + # vers le stockage object plutot que de les conserver en BDD + # 2024-04-15-01 attribute :start_text, :string validates :start_text, presence: true diff --git a/app/tasks/maintenance/recompute_blob_checksum_task.rb b/app/tasks/maintenance/recompute_blob_checksum_task.rb index 628ea9bd7..474c535b9 100644 --- a/app/tasks/maintenance/recompute_blob_checksum_task.rb +++ b/app/tasks/maintenance/recompute_blob_checksum_task.rb @@ -2,6 +2,11 @@ module Maintenance class RecomputeBlobChecksumTask < MaintenanceTasks::Task + # Avant février 2024, les filigranes ont corrompu les hash des fichiers. + # Régulièrement, des dossiers en brouillon étaient déposés avec ce problème + # (on retrouve les fichiers corrompu dans l'onglet retry de sidekiq). + # Cette tache recalcule les hashes. + # 2024-05-27-01 attribute :blob_ids, :string validates :blob_ids, presence: true diff --git a/app/tasks/maintenance/samsung_browser_is_supported_task.rb b/app/tasks/maintenance/samsung_browser_is_supported_task.rb index 988e3c010..d9ebfbb3d 100644 --- a/app/tasks/maintenance/samsung_browser_is_supported_task.rb +++ b/app/tasks/maintenance/samsung_browser_is_supported_task.rb @@ -2,6 +2,9 @@ module Maintenance class SamsungBrowserIsSupportedTask < MaintenanceTasks::Task + # Corrige une donnée si le navigateur utilisé + # dans l’historique des Traitements des dossiers + # 2024-02-21-01 def collection Traitement.where(browser_name: 'Samsung Browser', browser_version: 12..) end diff --git a/app/tasks/maintenance/spread_dossier_deletion_task.rb b/app/tasks/maintenance/spread_dossier_deletion_task.rb index 2e2f3c6a4..9c94bd6cf 100644 --- a/app/tasks/maintenance/spread_dossier_deletion_task.rb +++ b/app/tasks/maintenance/spread_dossier_deletion_task.rb @@ -2,6 +2,8 @@ module Maintenance class SpreadDossierDeletionTask < MaintenanceTasks::Task + # Contourne un égorgement de suppression de millions de dossiers qui aurait eu lieu le même jour + # 2024-05-27-01 PR #10062 ERROR_OCCURED_AT = Date.new(2024, 2, 14) ERROR_OCCURED_RANGE = ERROR_OCCURED_AT.at_midnight..(ERROR_OCCURED_AT + 1.day) SPREAD_DURATION_IN_DAYS = 150 diff --git a/app/tasks/maintenance/update_closing_reason_if_no_replaced_by_id_task.rb b/app/tasks/maintenance/update_closing_reason_if_no_replaced_by_id_task.rb index daf013ca0..99e715dd3 100644 --- a/app/tasks/maintenance/update_closing_reason_if_no_replaced_by_id_task.rb +++ b/app/tasks/maintenance/update_closing_reason_if_no_replaced_by_id_task.rb @@ -2,6 +2,9 @@ module Maintenance class UpdateClosingReasonIfNoReplacedByIdTask < MaintenanceTasks::Task + # Remet les messages de cloture d'une démarche proprement (sinon affichage KO). + # Avant BackfillClosingReasonInClosedProceduresTask + # 2024-03-21-01 PR #10158 def collection Procedure .with_discarded diff --git a/app/tasks/maintenance/update_conditions_based_on_commune_or_epci_champ_task.rb b/app/tasks/maintenance/update_conditions_based_on_commune_or_epci_champ_task.rb index c8f2afab5..bf67eb3b4 100644 --- a/app/tasks/maintenance/update_conditions_based_on_commune_or_epci_champ_task.rb +++ b/app/tasks/maintenance/update_conditions_based_on_commune_or_epci_champ_task.rb @@ -2,6 +2,10 @@ module Maintenance class UpdateConditionsBasedOnCommuneOrEpciChampTask < MaintenanceTasks::Task + # Met à jour les conditions et règles de routage + # pour les champs communes et ECPI suite à l'ajout de nouveaux opérateurs + # Voir aussi UpdateRoutingRulesBasedOnCommuneOrEpciChampTask + # 2023-12-20-01 PR #9850 include Logic def collection diff --git a/app/tasks/maintenance/update_draft_revision_type_de_champs_task.rb b/app/tasks/maintenance/update_draft_revision_type_de_champs_task.rb index af03e79ec..60b39e65b 100644 --- a/app/tasks/maintenance/update_draft_revision_type_de_champs_task.rb +++ b/app/tasks/maintenance/update_draft_revision_type_de_champs_task.rb @@ -2,6 +2,8 @@ module Maintenance class UpdateDraftRevisionTypeDeChampsTask < MaintenanceTasks::Task + # Modifie le form d’une démarche à partir d’un CSV (dev pour les Fonds Verts) + csv_collection # CSV structure: diff --git a/app/tasks/maintenance/update_routing_rules_based_on_commune_or_epci_champ_task.rb b/app/tasks/maintenance/update_routing_rules_based_on_commune_or_epci_champ_task.rb index afdda78e9..22f1ad2e4 100644 --- a/app/tasks/maintenance/update_routing_rules_based_on_commune_or_epci_champ_task.rb +++ b/app/tasks/maintenance/update_routing_rules_based_on_commune_or_epci_champ_task.rb @@ -2,6 +2,10 @@ module Maintenance class UpdateRoutingRulesBasedOnCommuneOrEpciChampTask < MaintenanceTasks::Task + # Ces 2 tâches mettent à jour les conditions et règles de routage + # pour les champs communes et ECPI suite à l'ajout de nouveaux opérateurs + # Voir aussi UpdateConditionsBasedOnCommuneOrEpciChampTask + # 2023-12-20-01 PR #9850 include Logic def collection diff --git a/app/tasks/maintenance/update_service_etablissement_infos_task.rb b/app/tasks/maintenance/update_service_etablissement_infos_task.rb index 8dcf511bd..a8fdfe15c 100644 --- a/app/tasks/maintenance/update_service_etablissement_infos_task.rb +++ b/app/tasks/maintenance/update_service_etablissement_infos_task.rb @@ -2,6 +2,9 @@ module Maintenance class UpdateServiceEtablissementInfosTask < MaintenanceTasks::Task + # Géocode les services à partir des établissements + # 2024-05-27-01 PR #10106 + # No more 20 geocoding by 10 seconds window THROTTLE_LIMIT = 20 THROTTLE_PERIOD = 10.seconds diff --git a/app/tasks/maintenance/update_zones_task.rb b/app/tasks/maintenance/update_zones_task.rb index c985f946a..203b00adf 100644 --- a/app/tasks/maintenance/update_zones_task.rb +++ b/app/tasks/maintenance/update_zones_task.rb @@ -2,6 +2,8 @@ module Maintenance class UpdateZonesTask < MaintenanceTasks::Task + # Synchronise les zones en base à partir du fichier de config zones.yml + # 2024-05-27-01 PR #10077 def collection config = Psych.safe_load(Rails.root.join("config", "zones.yml").read) config['ministeres'] From efa744c2276489d0cb7a39eddaa72af1aea407a3 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Wed, 9 Oct 2024 12:36:42 +0200 Subject: [PATCH 8/9] chore(task): deprecate after party tasks --- .../after_party/task/task_generator.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 lib/generators/after_party/task/task_generator.rb diff --git a/lib/generators/after_party/task/task_generator.rb b/lib/generators/after_party/task/task_generator.rb new file mode 100644 index 000000000..782bac34d --- /dev/null +++ b/lib/generators/after_party/task/task_generator.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails/generators' + +Rails.application.config.after_initialize do + module AfterParty + module Generators + class TaskGenerator + prepend Module.new { + def invoke_all + warn "[DEPRECATION] 'after_party:task' is deprecated. Use 'rails generate maintenance_tasks:task #{name}' instead." + end + } + end + end + end +end From da1bf573e381a6fdfde0ff1f8e311e1b7b1611f8 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Wed, 9 Oct 2024 12:41:49 +0200 Subject: [PATCH 9/9] chore(task): noop maintenance task verifying automatic run on deploy --- ...0241009_noop_attempt_run_on_deploy_task.rb | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 app/tasks/maintenance/t20241009_noop_attempt_run_on_deploy_task.rb diff --git a/app/tasks/maintenance/t20241009_noop_attempt_run_on_deploy_task.rb b/app/tasks/maintenance/t20241009_noop_attempt_run_on_deploy_task.rb new file mode 100644 index 000000000..36c5ae2e2 --- /dev/null +++ b/app/tasks/maintenance/t20241009_noop_attempt_run_on_deploy_task.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Maintenance + class T20241009NoopAttemptRunOnDeployTask < MaintenanceTasks::Task + # Documentation: cette tâche ne fait rien mais sert à vérifier + # qu'elle sera bien exécutée sur le déploiement suivant + # pour remplacer after party. + + include RunnableOnDeployConcern + include StatementsHelpersConcern + + # Uncomment only if this task MUST run imperatively on its first deployment. + # If possible, leave commented for manual execution later. + run_on_first_deploy + + def collection + 1.upto(10).to_a + end + + def process(element) + # NOOP + end + + def count + 10 + end + end +end