-
Notifications
You must be signed in to change notification settings - Fork 27
fix: Blueprinter adoption + query performance hardening #714
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
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
693671a
update to 2.3.3 (#712)
wdower fe94131
fix: eliminate N+1 SRG query in Rule#as_json
aaronlippold 1a89fd9
fix: exclude xml blobs from search_stigs and search_srgs
aaronlippold 9fa342a
fix: exclude xml from STIG/SRG show HTML to_json
aaronlippold 6b542b0
feat: add Blueprinter with leaf and supporting blueprints
aaronlippold 46226b8
feat: RuleBlueprint with navigator, viewer, editor views
aaronlippold b34bfc9
feat: StigBlueprint and SrgBlueprint with xml exclusion
aaronlippold 0af8f95
feat: ComponentBlueprint with index, show, editor views
aaronlippold 56f7863
feat: migrate controllers to use Blueprint.render
aaronlippold dbf737f
chore: migrate remaining controllers, deprecate as_json
aaronlippold b16289a
feat: complete Blueprinter migration, remove as_json
aaronlippold 843eb46
chore: fix Gemfile string quotes (rubocop)
aaronlippold 9d3e8e6
fix: show all password management options for admins
aaronlippold b24bb7c
fix: address Copilot review feedback
aaronlippold 431496b
fix: query performance hardening (H2, H3, M1-M4) + backtrace logging
aaronlippold 83ca80e
chore: bump v2.3.4, Ruby 3.4.9 docs, changelog
aaronlippold ccff67a
fix: resolve Copilot double-encoding review comments
aaronlippold 86bcaed
fix: avoid Project.pluck(:id) for admin access requests
aaronlippold 602d96f
chore: fix SonarCloud S1192 duplicated string literals in specs
aaronlippold 6a93d10
fix: resolve N+1, missing data, and silent query failures in Blueprin…
wdower File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| v2.3.1 | ||
| v2.3.4 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| # Serializes AdditionalAnswer for rule editor forms. | ||
| class AdditionalAnswerBlueprint < Blueprinter::Base | ||
| identifier :id | ||
|
|
||
| fields :additional_question_id, :answer | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| # Serializes Check records for rule detail views and editors. | ||
| class CheckBlueprint < Blueprinter::Base | ||
| identifier :id | ||
|
|
||
| fields :system, :content_ref_name, :content_ref_href, :content | ||
|
|
||
| # Rails accepts_nested_attributes_for expects _destroy key | ||
| field :_destroy do |_check, _options| | ||
| false | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| # Serializes Component records with context-specific views. | ||
| # | ||
| # Views: | ||
| # :index — listing page (minimal fields + severity_counts) | ||
| # :show — non-member read-only view (adds rules, reviews) | ||
| # :editor — full editing page (adds histories, memberships, metadata, etc.) | ||
| # | ||
| # Replaces Component#as_json override and the to_json(methods: [...]) pattern. | ||
| # The `admins` method is intentionally excluded — Vue analysis confirmed no | ||
| # component page consumer reads component.admins (it's only used on project pages). | ||
| class ComponentBlueprint < Blueprinter::Base | ||
| identifier :id | ||
|
|
||
| # === Default: fields shared by ALL views === | ||
| fields :name, :prefix, :version, :release | ||
|
|
||
| field :based_on_title do |component, _options| | ||
| component.based_on&.title | ||
| end | ||
|
|
||
| field :based_on_version do |component, _options| | ||
| component.based_on&.version | ||
| end | ||
|
|
||
| field :severity_counts do |component, _options| | ||
| component.severity_counts_hash | ||
| end | ||
|
|
||
| # === Index view: listing page === | ||
| view :index do | ||
| fields :updated_at, :released | ||
| end | ||
|
|
||
| # === Related view: related_rules parents (includes project for display name) === | ||
| view :related do | ||
| fields :updated_at, :released | ||
|
|
||
| field :project do |component, _options| | ||
| ProjectBlueprint.render_as_hash(component.project) | ||
| end | ||
| end | ||
|
|
||
| # === Show view: non-member read-only === | ||
| view :show do | ||
| fields :title, :description, :admin_name, :admin_email, :released, :updated_at | ||
|
|
||
| association :rules, blueprint: RuleBlueprint, view: :viewer do |component, _options| | ||
| component.rules | ||
| end | ||
|
|
||
| # Uses Component#reviews method (not ReviewBlueprint) because it returns | ||
| # pre-formatted hashes with `displayed_rule_name` that ReviewBlueprint lacks. | ||
| field :reviews do |component, _options| | ||
| component.reviews | ||
| end | ||
| end | ||
|
|
||
| # === Editor view: full editing page === | ||
| view :editor do | ||
| # All DB columns needed by Vue components | ||
| fields :title, :description, :admin_name, :admin_email, | ||
| :released, :advanced_fields, :project_id, :component_id, | ||
| :security_requirements_guide_id, :memberships_count, | ||
| :rules_count, :updated_at, :created_at | ||
|
|
||
| field :releasable do |component, _options| | ||
| component.releasable | ||
| end | ||
|
|
||
| field :status_counts do |component, _options| | ||
| component.status_counts | ||
| end | ||
|
|
||
| field :additional_questions do |component, _options| | ||
| component.additional_questions.as_json | ||
| end | ||
aaronlippold marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Rules via RuleBlueprint :editor view | ||
| association :rules, blueprint: RuleBlueprint, view: :editor do |component, _options| | ||
| component.rules | ||
| end | ||
|
|
||
| # Uses Component#reviews method (not ReviewBlueprint) because it returns | ||
| # pre-formatted hashes with `displayed_rule_name` that ReviewBlueprint lacks. | ||
| field :reviews do |component, _options| | ||
| component.reviews | ||
| end | ||
aaronlippold marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| field :histories do |component, _options| | ||
| component.histories | ||
| end | ||
|
|
||
| # Memberships via MembershipBlueprint (includes name, email from user) | ||
| association :memberships, blueprint: MembershipBlueprint do |component, _options| | ||
| component.memberships | ||
| end | ||
|
|
||
| field :metadata do |component, _options| | ||
| component.metadata | ||
| end | ||
|
|
||
| association :inherited_memberships, blueprint: MembershipBlueprint do |component, _options| | ||
| component.inherited_memberships | ||
| end | ||
|
|
||
| # Available members — uses SQL NOT IN (not Ruby subtraction) | ||
| association :available_members, blueprint: UserBlueprint do |component, _options| | ||
| component.available_members | ||
| end | ||
|
|
||
| # All users with access — compact (id, name, email only) | ||
| association :all_users, blueprint: UserBlueprint do |component, _options| | ||
| component.all_users | ||
| end | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| # Serializes DISA rule description fields for rule detail and editor views. | ||
| class DisaRuleDescriptionBlueprint < Blueprinter::Base | ||
| identifier :id | ||
|
|
||
| fields :vuln_discussion, :false_positives, :false_negatives, | ||
| :documentable, :mitigations, :severity_override_guidance, | ||
| :potential_impacts, :third_party_tools, :mitigation_control, | ||
| :responsibility, :ia_controls, :mitigations_available, | ||
| :poam_available, :poam | ||
|
|
||
| field :_destroy do |_drd, _options| | ||
| false | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| # Replaces Membership#as_json which added `methods: [:name, :email]`. | ||
| class MembershipBlueprint < Blueprinter::Base | ||
| identifier :id | ||
|
|
||
| fields :user_id, :role, :membership_type, :membership_id | ||
|
|
||
| # Delegated from user — avoids N+1 when user is eager-loaded via | ||
| # the has_many :memberships, -> { includes :user } scope | ||
| field :name do |membership, _options| | ||
| membership.user&.name | ||
| end | ||
|
|
||
| field :email do |membership, _options| | ||
| membership.user&.email | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| # Serializes Project records with context-specific views. | ||
| class ProjectBlueprint < Blueprinter::Base | ||
| identifier :id | ||
|
|
||
| fields :name, :description, :visibility, :memberships_count, | ||
| :admin_name, :admin_email, :created_at, :updated_at | ||
|
|
||
| view :index do | ||
| association :memberships, blueprint: MembershipBlueprint do |project, _options| | ||
| project.memberships | ||
| end | ||
| end | ||
|
|
||
| view :show do | ||
| field :details do |project, _options| | ||
| project.details | ||
| end | ||
|
|
||
| field :histories do |project, _options| | ||
| project.histories | ||
| end | ||
|
|
||
| field :metadata do |project, _options| | ||
| project.project_metadata&.data | ||
| end | ||
|
|
||
| association :memberships, blueprint: MembershipBlueprint do |project, _options| | ||
| project.memberships | ||
| end | ||
|
|
||
| association :components, blueprint: ComponentBlueprint, view: :index do |project, _options| | ||
| project.components | ||
| end | ||
|
|
||
| association :available_components, blueprint: ComponentBlueprint, view: :index do |project, _options| | ||
| project.available_components | ||
| end | ||
|
|
||
| association :available_members, blueprint: UserBlueprint do |project, _options| | ||
| project.available_members | ||
| end | ||
|
|
||
| association :users, blueprint: UserBlueprint do |project, _options| | ||
| project.users | ||
| end | ||
|
|
||
| field :access_requests do |project, _options| | ||
| project.access_requests.eager_load(:user, :project).map do |ar| | ||
| { id: ar.id, user: UserBlueprint.render_as_hash(ar.user), project_id: ar.project_id } | ||
| end | ||
| end | ||
| end | ||
| end |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.