poc(batch_operation): just the model and some specs and a poc for archive them without async

This commit is contained in:
Martin 2022-11-18 15:26:31 +01:00 committed by mfo
parent cc3c50fc14
commit 61f4cded75
15 changed files with 152 additions and 3 deletions

View file

@ -0,0 +1,31 @@
# == Schema Information
#
# Table name: batch_operations
#
# id :bigint not null, primary key
# failed_dossier_ids :bigint default([]), not null, is an Array
# finished_at :datetime
# operation :string not null
# payload :jsonb not null
# run_at :datetime
# success_dossier_ids :bigint default([]), not null, is an Array
# created_at :datetime not null
# updated_at :datetime not null
# instructeur_id :bigint not null
#
class BatchOperation < ApplicationRecord
enum operation: {
archiver: 'archiver'
}
has_many :dossiers, dependent: :nullify
belongs_to :instructeur
validates :operation, presence: true
def process
case operation
when BatchOperation.operations.fetch(:archiver)
dossiers.map { |dossier| dossier.archiver!(instructeur) }
end
end
end

View file

@ -35,6 +35,7 @@
# termine_close_to_expiration_notice_sent_at :datetime
# created_at :datetime
# updated_at :datetime
# batch_operation_id :bigint
# dossier_transfer_id :bigint
# groupe_instructeur_id :bigint
# parent_dossier_id :bigint
@ -134,7 +135,7 @@ class Dossier < ApplicationRecord
belongs_to :revision, class_name: 'ProcedureRevision', optional: false
belongs_to :user, optional: true
belongs_to :parent_dossier, class_name: 'Dossier', optional: true
belongs_to :batch_operation, optional: true
has_one :france_connect_information, through: :user
has_one :procedure, through: :revision

View file

@ -18,7 +18,7 @@ class Instructeur < ApplicationRecord
has_many :groupe_instructeurs, -> { order(:label) }, through: :assign_to
has_many :unordered_groupe_instructeurs, through: :assign_to, source: :groupe_instructeur
has_many :procedures, -> { distinct }, through: :unordered_groupe_instructeurs
has_many :batch_operations, dependent: :nullify
has_many :assign_to_with_email_notifications, -> { with_email_notifications }, class_name: 'AssignTo', inverse_of: :instructeur
has_many :groupe_instructeur_with_email_notifications, through: :assign_to_with_email_notifications, source: :groupe_instructeur

View file

@ -0,0 +1,14 @@
class CreateTableBatchOperation < ActiveRecord::Migration[6.1]
def change
create_table :batch_operations do |t|
t.bigint :instructeur_id, null: false
t.string :operation, null: false
t.jsonb :payload, default: {}, null: false
t.bigint :failed_dossier_ids, array: true, default: [], null: false
t.bigint :success_dossier_ids, array: true, default: [], null: false
t.datetime :run_at
t.datetime :finished_at
t.timestamps
end
end
end

View file

@ -0,0 +1,5 @@
class AddBatchOperationIdToDossiers < ActiveRecord::Migration[6.1]
def change
add_column :dossiers, :batch_operation_id, :bigint
end
end

View file

@ -0,0 +1,5 @@
class AddForeignKeyToBatchOperationId < ActiveRecord::Migration[6.1]
def change
add_foreign_key "dossiers", "batch_operations", validate: false
end
end

View file

@ -0,0 +1,5 @@
class ValidateForeighKeyToBatchOperationId < ActiveRecord::Migration[6.1]
def change
validate_foreign_key "dossiers", "batch_operations"
end
end

View file

@ -0,0 +1,5 @@
class AddForeignKeyToBatchOperationInstructeur < ActiveRecord::Migration[6.1]
def change
add_foreign_key "batch_operations", "instructeurs", validate: false
end
end

View file

@ -0,0 +1,5 @@
class AddValidateKeyToBatchBoperationInstructeur < ActiveRecord::Migration[6.1]
def change
validate_foreign_key "batch_operations", "instructeurs"
end
end

View file

@ -0,0 +1,7 @@
class AddIndexToDossiersBatchOperationId < ActiveRecord::Migration[6.1]
include Database::MigrationHelpers
disable_ddl_transaction!
def up
add_concurrent_index :dossiers, [:batch_operation_id]
end
end

View file

@ -11,7 +11,6 @@
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2022_11_30_113745) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
@ -158,6 +157,18 @@ ActiveRecord::Schema.define(version: 2022_11_30_113745) do
t.index ["experts_procedure_id"], name: "index_avis_on_experts_procedure_id"
end
create_table "batch_operations", force: :cascade do |t|
t.datetime "created_at", precision: 6, null: false
t.bigint "failed_dossier_ids", default: [], null: false, array: true
t.datetime "finished_at"
t.bigint "instructeur_id", null: false
t.string "operation", null: false
t.jsonb "payload", default: {}, null: false
t.datetime "run_at"
t.bigint "success_dossier_ids", default: [], null: false, array: true
t.datetime "updated_at", precision: 6, null: false
end
create_table "bill_signatures", force: :cascade do |t|
t.datetime "created_at", null: false
t.string "digest"
@ -307,6 +318,7 @@ ActiveRecord::Schema.define(version: 2022_11_30_113745) do
t.datetime "archived_at"
t.string "archived_by"
t.boolean "autorisation_donnees"
t.bigint "batch_operation_id"
t.datetime "brouillon_close_to_expiration_notice_sent_at"
t.interval "conservation_extension", default: "PT0S"
t.datetime "created_at"
@ -340,6 +352,7 @@ ActiveRecord::Schema.define(version: 2022_11_30_113745) do
t.datetime "updated_at"
t.integer "user_id"
t.index ["archived"], name: "index_dossiers_on_archived"
t.index ["batch_operation_id"], name: "index_dossiers_on_batch_operation_id"
t.index ["dossier_transfer_id"], name: "index_dossiers_on_dossier_transfer_id"
t.index ["groupe_instructeur_id"], name: "index_dossiers_on_groupe_instructeur_id"
t.index ["hidden_at"], name: "index_dossiers_on_hidden_at"
@ -913,6 +926,7 @@ ActiveRecord::Schema.define(version: 2022_11_30_113745) do
add_foreign_key "attestations", "dossiers"
add_foreign_key "avis", "dossiers"
add_foreign_key "avis", "experts_procedures"
add_foreign_key "batch_operations", "instructeurs"
add_foreign_key "bulk_messages_groupe_instructeurs", "bulk_messages"
add_foreign_key "bulk_messages_groupe_instructeurs", "groupe_instructeurs"
add_foreign_key "champs", "champs", column: "parent_id"
@ -925,6 +939,7 @@ ActiveRecord::Schema.define(version: 2022_11_30_113745) do
add_foreign_key "commentaires", "instructeurs"
add_foreign_key "dossier_operation_logs", "bill_signatures"
add_foreign_key "dossier_transfer_logs", "dossiers"
add_foreign_key "dossiers", "batch_operations"
add_foreign_key "dossiers", "dossier_transfers"
add_foreign_key "dossiers", "dossiers", column: "parent_dossier_id"
add_foreign_key "dossiers", "groupe_instructeurs"

View file

@ -0,0 +1,4 @@
FactoryBot.define do
factory :batch_operation do
end
end

View file

@ -0,0 +1,46 @@
describe BatchOperation, type: :model do
describe 'association' do
it { is_expected.to have_many(:dossiers) }
it { is_expected.to belong_to(:instructeur) }
end
describe 'attributes' do
subject { BatchOperation.new }
it { expect(subject.payload).to eq({}) }
it { expect(subject.failed_dossier_ids).to eq([]) }
it { expect(subject.success_dossier_ids).to eq([]) }
it { expect(subject.run_at).to eq(nil) }
it { expect(subject.finished_at).to eq(nil) }
it { expect(subject.operation).to eq(nil) }
end
describe 'validations' do
it { is_expected.to validate_presence_of(:operation) }
end
describe 'process' do
let(:procedure) { create(:procedure, :with_instructeur) }
subject do
create(:batch_operation, instructeur: procedure.instructeurs.first,
operation: operation,
dossiers: dossiers)
end
context 'archive' do
let(:operation) { BatchOperation.operations.fetch(:archiver) }
let(:dossier_accepte) { create(:dossier, :accepte, procedure: procedure) }
let(:dossier_refuse) { create(:dossier, :refuse, procedure: procedure) }
let(:dossier_classe_sans_suite) { create(:dossier, :sans_suite, procedure: procedure) }
let(:dossiers) { [dossier_accepte, dossier_refuse, dossier_classe_sans_suite] }
it 'works' do
expect { subject.process() }
.to change { dossiers.map(&:reload).map(&:archived) }
.from(dossiers.map { false })
.to(dossiers.map { true })
end
end
end
end

View file

@ -1855,6 +1855,11 @@ describe Dossier do
end
end
describe 'BatchOperation' do
subject { build(:dossier) }
it { is_expected.to belong_to(:batch_operation).optional }
end
private
def count_for_month(processed_by_month, month)

View file

@ -14,6 +14,7 @@ describe Instructeur, type: :model do
describe 'associations' do
it { is_expected.to have_and_belong_to_many(:administrateurs) }
it { is_expected.to have_many(:batch_operations) }
end
describe 'follow' do