Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CPDNPQ-2242] admin bulk reject applications #2088

Merged
merged 19 commits into from
Jan 14, 2025

Conversation

alkesh
Copy link
Contributor

@alkesh alkesh commented Dec 17, 2024

Context

Ticket: https://dfedigital.atlassian.net/browse/CPDNPQ-2242

Bulk operations:

  • reject applications
  • change applications to pending

Changes proposed in this pull request

production ready - when compared to the previous spike (#2046):

  • added bulk reject applications
  • improved UI
  • background jobs
  • specs

I tried the jobs locally, using a file that contained all the applications I had locally - which was 1459 applications - the background job took:

  • reject applications - 2 seconds
  • change to pending - 12 seconds

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to app/services/bulk_operation/bulk_change_applications_to_pending.rb

Copy link

Copy link
Contributor

@rwrrll rwrrll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be a big win when it goes live 👏 left a few comments, mostly just suggestions really!

app/models/bulk_operation.rb Show resolved Hide resolved
@@ -0,0 +1,2 @@
class NpqSeparation::Admin::BulkOperationsController < NpqSeparation::AdminController
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see anything else inheriting from this, is it just for namespacing? If so, does it need to inherit / should it be a module?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's definitely a required controller - used for the bulk operations index page, which just has the two links for "Revert applications to pending" and "Reject applications".
It needs to inherit from NpqSeparation::AdminController, just so that it's only accessible by admins.

db/migrate/20241204120620_create_bulk_operations.rb Outdated Show resolved Hide resolved
db/migrate/20241204120620_create_bulk_operations.rb Outdated Show resolved Hide resolved
result = {}
ActiveRecord::Base.transaction do
result = application_ecf_ids.each_with_object({}) do |application_ecf_id, hash|
application = Application.find_by(ecf_id: application_ecf_id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want a find_by! so that it blows up if the application doesn't exist, or is nil fine?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nil is fine here - the Applications::Reject has a presence validator for the application,
and the resulting outcome will be a "Not found" - so there is an entry in the result for every ID passed.

I did notice there's a spec missing for this though - will add.

Copy link
Contributor

@slawosz slawosz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, several comments regarding potential code cleanup.

@@ -0,0 +1,44 @@
module NpqSeparation::Admin::BulkOperations
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both controllers, RejectApplicationsController and RevertApplicationsToPendingController looks very similar. I wonder if it would be possible to extract a parent controller like

module NpqSeparation::Admin::BulkOperations
  class BaseController < NpqSeparation::AdminController
    before_action :set_bulk_operations, :set_bulk_operation, only: %i[index create]
    before_action :find_bulk_operation, only: %i[run show]

    def create
      if (file = params.dig(:bulk_operation_reject_applications, :file))
        bulk_operation_scope.not_started.destroy_all
        @bulk_operation.file.attach(file)
        if @bulk_operation.valid?
          @bulk_operation.save!
          @bulk_operation.update!(row_count: @bulk_operation.file.download.lines.count)
          return redirect_to redirect_to_path
        end
      end

      render :index, status: :unprocessable_entity
    end

    def run
      @bulk_operation.update!(started_at: Time.zone.now, ran_by_admin_id: current_admin.id)
      job_class.perform_later(bulk_operation_id: @bulk_operation.id)
      redirect_to redirect_to_path
    end

    def show
      # empty method, because rubocop will complain in the before_action otherwise
    end

  private

    def set_bulk_operations
      @bulk_operations = bulk_operation_scope.all.includes([file_attachment: :blob]).order(:created_at)
    end

    def set_bulk_operation
      @bulk_operation = bulk_operation_scope.new admin: current_admin
    end

    def find_bulk_operation
      @bulk_operation = bulk_operation_scope.find(params[:id])
    end
  end
end

and

module NpqSeparation::Admin::BulkOperations
  class RejectApplicationsController < BaseController
    private
    def redirect_to_path
      :npq_separation_admin_bulk_operations_reject_applications
    end

    def bulk_operation_scope
      BulkOperation::RejectApplications
    end

    def job_class
      BulkOperation::BulkRejectApplicationsJob
    end
  end
end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my view on this is that it is premature optimisation. I'm a fan of the rule of three.
If the next time we need a bulk operation, and that operation is as similar as the current 2 - then we extract a parent controller at that point.

@@ -0,0 +1,12 @@
# frozen_string_literal: true

class BulkOperation::BulkChangeApplicationsToPendingJob < ApplicationJob
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the controllers comment - both workers are very similar and maybe could be extracted to one?
I guess dry_run argument could be part of the interface.

@@ -0,0 +1,34 @@
# frozen_string_literal: true

class BulkOperation::BulkChangeApplicationsToPending
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, both services have very similar code. I wonder if it makes sense to extract them? One good argument for the extraction would be unification - if the future bulk service would not fit into intended structure, it could mean that it would be too complex and simplification would be recommended?

@@ -0,0 +1,59 @@
<%= govuk_back_link(href: npq_separation_admin_bulk_operations_path) %>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There would be possible to use template inheritance as well.

@alkesh alkesh force-pushed the CPDNPQ-2242-admin-bulk-reject-applications branch from 83c7047 to fbc55e8 Compare January 6, 2025 11:00
rwrrll added a commit that referenced this pull request Jan 13, 2025
rwrrll added a commit that referenced this pull request Jan 13, 2025
@alkesh alkesh force-pushed the CPDNPQ-2242-admin-bulk-reject-applications branch from dcbe020 to 2841887 Compare January 14, 2025 11:14
@alkesh alkesh added this pull request to the merge queue Jan 14, 2025
Merged via the queue into main with commit b9f2301 Jan 14, 2025
18 checks passed
@alkesh alkesh deleted the CPDNPQ-2242-admin-bulk-reject-applications branch January 14, 2025 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants