Skip to content

Conversation

@lfdebrux
Copy link
Member

@lfdebrux lfdebrux commented May 21, 2025

What problem does this pull request solve?

I wanted to add a new feature report, but I found the feature report code was very repetitive and I had to add a lot of files to do that, and I felt like this situation could be improved. So in this PR, I try to make the feature report code more DRY.

The aim was to get it to the point where (in the simplest case) adding a new feature report required only adding a new method to Reports::FeatureReportService, and all the related routes, controller actions, views should automatically be generated, including for the CSV downloads.

A big part of this is making the responsibilities for each class involved in making a feature report more clearly deliniated and less overlapping, with the controller creating the pipeline to get the final result. It is now expected that FormDocumentsService will be called first, and that passed to FeatureReportService with is responsible just for filtering form documents and optionally converting it into a list of questions. There are helpers that turn this array of form documents or question page documents into a GOV.UK styles table; if a CSV is wanted for the end result, CsvReportService generates the CSV for either an array of form documents or an array of question page documents.

There is a little bit of metaprogramming magic required for this, to make the FeatureReportService aware of what methods the other things should be generated for there is a new class method .define_report:

class Reports::FeatureReportService
  define_report forms_for_juggling_licences
    form_documents
      .select { |form| form["content"]["name"] == "Apply for a juggling licence }
  end
end

For a more realistic example, see #1971.

The changes in this PR also increase the reusability to the point where it's feasible for us to add feature reports for draft forms, see #1972 for this in action.

Things to consider when reviewing

  • Ensure that you consider the wider context.
  • Does it work when run on your machine?
  • Is it clear what the code is doing?
  • Do the commit messages explain why the changes were made?
  • Are there all the unit tests needed?
  • Do the end to end tests need updating before these changes will pass?
  • Has all relevant documentation been updated?

@lfdebrux lfdebrux force-pushed the ldeb-refactor-feature-reports branch from 664b564 to 33d7a62 Compare May 22, 2025 04:56
Copy link
Contributor

@stephencdaly stephencdaly left a comment

Choose a reason for hiding this comment

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

I was following this quite well until the point CsvReportService was added, and then it started getting a bit confusing.

Up to this point, I think all the changes made sense and there were some really nice improvements in here.

Could you potentially make the PR stop at that point and then raise another PR that combines all the routes into one so we can look at that in isolation? I'd fear that although you've made it potentially simpler to add a report, it might be a bit confusing to understand the magic behind it.

return NilCsvService if record_type.nil?

"Reports::#{record_type.capitalize}CsvReportService".constantize
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 fear this is might make it more difficult to understand than it makes it easier to maintain.

@lfdebrux lfdebrux changed the title Refactor feature report to make it easier to add new feature reports Refactor feature report to make it easier to add new feature reports (part 2) May 23, 2025
lfdebrux added 3 commits May 23, 2025 12:39
Instead of having a controller action for each feature report, use a
single action which gets the report to generate from a dynamic segment
in the path. This should mean that in future adding a new feature report
should require only adding a new method to FeatureReportService.
Rather than allowing any method on FeatureReportService to be called
(and potentially opening up a security hole), this commit adds some
metaprogramming machinery to manage a list of methods which are feature
reports and adds methods to allow that to be used safely, both to
constrain the parameters in the routes and to prevent arbitrary methods
from being called from the controller.
@lfdebrux lfdebrux force-pushed the ldeb-refactor-feature-reports branch from 33d7a62 to 1d6cda5 Compare May 23, 2025 09:39
@sonarqubecloud
Copy link

@github-actions
Copy link

🎉 A review copy of this PR has been deployed! You can reach it at: https://pr-1970.admin.review.forms.service.gov.uk/

It may take 5 minutes or so for the application to be fully deployed and working. If it still isn't ready
after 5 minutes, there may be something wrong with the ECS task. You will need to go to the integration AWS account
to debug, or otherwise ask an infrastructure person.

For the sign in details and more information, see the review apps wiki page.

@lfdebrux lfdebrux marked this pull request as draft June 11, 2025 07:46
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.

2 participants