Skip to content

Add Search#160

Merged
Mab879 merged 32 commits intomasterfrom
add_search
Jul 13, 2025
Merged

Add Search#160
Mab879 merged 32 commits intomasterfrom
add_search

Conversation

@Mab879
Copy link
Collaborator

@Mab879 Mab879 commented Mar 28, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a powerful, filterable search modal with Meilisearch integration, accessible via the navigation bar when enabled.
    • Added new UI components and theming, including enhanced buttons, modals, tags, filters, and dark mode support.
    • Search functionality can be toggled via a configuration option.
  • Enhancements

    • Improved build process with new Makefile targets for cleaning and static asset minification.
    • Added progress bars and structured logging for better feedback during site generation.
    • HTML output is now minified for faster load times.
    • JSON output is generated for controls to support search indexing.
    • Added Apple touch icon for improved device support.
  • Bug Fixes

    • Improved accessibility and keyboard navigation in the search modal.
    • Enhanced error handling and logging throughout the application.
  • Chores

    • Updated dependencies and configuration files for broader language support and improved project structure.
    • Added scripts for minifying assets and indexing search documents.
    • Refined editor and IDE configurations to support multiple file types and streamline development workflow.

@Mab879 Mab879 marked this pull request as ready for review June 19, 2025 18:19
@Mab879
Copy link
Collaborator Author

Mab879 commented Jun 20, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jun 20, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Jun 20, 2025

Walkthrough

This update introduces a client-side search modal with Meilisearch integration, new JSON output utilities, and extensive UI enhancements including dark mode and filterable search. The build process is improved with minification and progress bars, and logging is added throughout. Configuration and template files are updated to support the new features and improve maintainability.

Changes

File(s) Change Summary
.editorconfig Expanded indentation rules to CSS, JS, HTML; added global trailing whitespace rule, with exception for XML.
.gitignore Added rule to ignore *.tar.gz files.
.idea/misc.xml, .idea/stigaview-static.iml Updated IDE settings: changed Black formatter SDK, enabled auto-format, added/excluded directories.
Makefile Refactored to use variable for output directory, added .PHONY targets, new minify_static and clean targets.
public_html/static/css/style.css Major UI expansion: new button, modal, filter, tag styles, and dark mode support.
public_html/static/js/search.js New: Implements client-side search modal with Meilisearch integration, filter dropdowns, accessibility, and async data loading.
requirements.txt Added minify_html, tqdm, rjsmin, and csscompressor dependencies.
setup.cfg Renamed console script entry point from hello-world to stigaview.
stigaview.toml Added use_search boolean config option.
stigaview_static/html_output.py Added multiprocessing with progress bars, HTML minification, logging, and JSON output for controls.
stigaview_static/import_stig.py Refactored regex to use named groups for version/release extraction.
stigaview_static/json_output.py New: Functions to write product-STIG maps and control JSON files for search.
stigaview_static/main.py Added structured logging, progress bars, improved argument parsing, modularized config loading, and path handling.
stigaview_static/models.py Added search key and JSON export to Control, new config models, improved error handling with logging.
stigaview_static/utils.py New: get_config() function to load TOML config from environment or default.
templates/base.html Conditional search modal/button support, async script loading, added Apple touch icon.
templates/search.html New: Search modal template with filters, accessible structure, and results container.
templates/stig.html Added id attribute to "STIG ID" column header.
utils/add_to_search.py New: Script to batch upload JSON controls to Meilisearch.
utils/minify.py New: Script to minify CSS and JS files in output directory.

Sequence Diagram(s)

Search Modal Interaction with Meilisearch

sequenceDiagram
    participant User
    participant Browser
    participant SearchModal (JS)
    participant Meilisearch API

    User->>Browser: Clicks search button / types shortcut
    Browser->>SearchModal (JS): Opens modal, focuses input
    User->>SearchModal (JS): Types query, selects filters
    SearchModal (JS)->>Meilisearch API: Sends search request with query and filters
    Meilisearch API-->>SearchModal (JS): Returns search results
    SearchModal (JS)->>Browser: Renders results in modal
    User->>SearchModal (JS): Closes modal
    SearchModal (JS)->>Browser: Restores focus, hides modal
Loading

Build Process with Minification

sequenceDiagram
    participant Developer
    participant Makefile
    participant Python Scripts
    participant File System

    Developer->>Makefile: Run build
    Makefile->>Python Scripts: Generate HTML, JSON, assets
    Python Scripts->>File System: Write output files
    Makefile->>Python Scripts: Run minify_static
    Python Scripts->>File System: Minify CSS/JS in output directory
Loading

Poem

In the warren of code, a search modal appears,
With filters and tags, it dispels all our fears.
JSON hops out, controls leap into view,
Progress bars twinkle as the builds renew.
Dark mode at dusk, minified for speed—
A rabbit’s delight, in every new deed!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a1e8b6a and bacd26a.

📒 Files selected for processing (2)
  • requirements.txt (1 hunks)
  • utils/minify.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • requirements.txt
  • utils/minify.py
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: deploy
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (7)
.idea/misc.xml (1)

4-5: Reevaluate committing IDE-specific settings
Sharing .idea configuration can lead to merge conflicts and inconsistent setups. For project-wide Black formatting, prefer using pyproject.toml or .editorconfig. Otherwise, consider adding .idea/ to .gitignore and distributing shared settings in a more portable format.

.idea/stigaview-static.iml (1)

6-8: Validate IDE module exclusions
Excluding out and .venv/ folders from IDE indexing correctly mirrors the Makefile’s $(OUT) variable and virtual environment updates. Ensure these paths are also reflected in .gitignore/.editorconfig, or move exclusions to a shared configuration rather than committing IDE metadata.

stigaview_static/import_stig.py (1)

85-91: Avoid confusion in capture groups vs return order
The regex uses named groups version then release, but the function returns (release, version) to preserve legacy behavior. This mismatch can be confusing. Consider one of the following:

  • Swap capture group names to ?P<release> first, then ?P<version>.
  • Update the function signature or add a docstring/type hint to clarify the return order.
    Also, using re.fullmatch instead of re.match would be more explicit given the ^...$ anchors.
.editorconfig (1)

18-21: Standardize file pattern globbing
The header [{**.py, **.css, **.js, **.html}] may not be recognized by all EditorConfig implementations. Consider using a standard glob pattern:

[*.{py,css,js,html}]
indent_size = 4
indent_style = space

or separate sections [*.py], [*.css], etc., to ensure consistent styling.

utils/minify.py (1)

26-26: Fix typo in variable name.

The variable name minifed should be minified for clarity and correctness.

-        minifed = minify_html.minify(css_file.read_text(), minify_css=True)
-        css_file.write_text(minifed)
+        minified = minify_html.minify(css_file.read_text(), minify_css=True)
+        css_file.write_text(minified)
-        minifed = minify_html.minify(
+        minified = minify_html.minify(
             js_file.read_text(), minify_js=True, keep_comments=False
         )
-        js_file.write_text(minifed)
+        js_file.write_text(minified)

Also applies to: 32-32

utils/add_to_search.py (1)

60-60: Consider using list comprehension for better performance.

Following the Pylint suggestion, you can improve performance and readability.

-    docs = list()
-    for file in json_files:
-        docs.append(json.loads(file.read_text()))
+    docs = [json.loads(file.read_text()) for file in json_files]
stigaview_static/json_output.py (1)

10-22: Clean implementation of product mapping generation.

The function correctly generates JSON mappings for products and STIGs with appropriate data structures.

Consider applying this minor optimization suggested by pylint:

-    products_list: Dict[str, str] = dict()
+    products_list: Dict[str, str] = {}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66c7af0 and 4be3930.

📒 Files selected for processing (21)
  • .editorconfig (1 hunks)
  • .gitignore (1 hunks)
  • .idea/misc.xml (1 hunks)
  • .idea/stigaview-static.iml (1 hunks)
  • Makefile (1 hunks)
  • public_html/static/css/style.css (2 hunks)
  • public_html/static/js/search.js (1 hunks)
  • requirements.txt (1 hunks)
  • setup.cfg (1 hunks)
  • stigaview.toml (1 hunks)
  • stigaview_static/html_output.py (6 hunks)
  • stigaview_static/import_stig.py (1 hunks)
  • stigaview_static/json_output.py (1 hunks)
  • stigaview_static/main.py (3 hunks)
  • stigaview_static/models.py (4 hunks)
  • stigaview_static/utils.py (2 hunks)
  • templates/base.html (1 hunks)
  • templates/search.html (1 hunks)
  • templates/stig.html (1 hunks)
  • utils/add_to_search.py (1 hunks)
  • utils/minify.py (1 hunks)
🧰 Additional context used
🪛 checkmake (0.2.2)
Makefile

[warning] 16-16: Missing required phony target "all"

(minphony)


[warning] 16-16: Missing required phony target "test"

(minphony)


[warning] 18-18: Target "all" should be declared PHONY.

(phonydeclared)

🪛 HTMLHint (1.5.0)
templates/search.html

[error] 1-1: Doctype must be declared before any non-comment content.

(doctype-first)

🪛 Pylint (3.3.7)
stigaview_static/models.py

[refactor] 141-141: Too few public methods (0/2)

(R0903)


[refactor] 147-147: Too few public methods (0/2)

(R0903)

utils/add_to_search.py

[refactor] 60-60: Consider using [] instead of list()

(R1734)

stigaview_static/main.py

[refactor] 58-58: Consider using 'sys.exit' instead

(R1722)


[refactor] 98-98: Consider using '{}' instead of a call to 'dict'.

(R1735)


[refactor] 129-129: Consider using [] instead of list()

(R1734)


[refactor] 130-130: Consider using '{}' instead of a call to 'dict'.

(R1735)


[refactor] 139-139: Consider using 'sys.exit' instead

(R1722)

stigaview_static/json_output.py

[refactor] 12-12: Consider using '{}' instead of a call to 'dict'.

(R1735)

🪛 Gitleaks (8.26.0)
utils/add_to_search.py

11-11: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Ruff (0.11.9)
stigaview_static/main.py

28-28: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


142-142: Use key not in dict instead of key not in dict.keys()

Remove .keys()

(SIM118)

🔇 Additional comments (39)
requirements.txt (1)

7-8: Verify package versions for currency and security.

The addition of minify_html and tqdm dependencies supports the new HTML minification and progress bar features. However, ensure these specific versions are current and free from known vulnerabilities.

#!/bin/bash
# Description: Check for latest versions and security advisories for the new dependencies

echo "Checking minify_html version..."
curl -s https://pypi.org/pypi/minify-html/json | jq '.info.version'

echo "Checking tqdm version..."
curl -s https://pypi.org/pypi/tqdm/json | jq '.info.version'

echo "Checking for security advisories..."
gh api graphql -f query='
{
  securityVulnerabilities(first: 10, ecosystem: PIP, package: "minify-html") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

gh api graphql -f query='
{
  securityVulnerabilities(first: 10, ecosystem: PIP, package: "tqdm") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'
.gitignore (1)

195-196: LGTM! Proper exclusion of build artifacts.

Adding *.tar.gz to the gitignore under the "Output" section properly excludes generated archive files from version control, which is a best practice for build artifacts.

stigaview_static/utils.py (1)

1-4: Verify Python version compatibility for tomllib.

The tomllib module is only available in Python 3.11+. Ensure your project's minimum Python version supports this, or consider using tomli for backward compatibility.

#!/bin/bash
# Description: Check if project specifies Python version requirements

echo "Checking for Python version specifications..."
fd -t f "pyproject.toml|setup.py|setup.cfg|.python-version|requirements.txt" --exec cat {}
templates/stig.html (1)

11-11: LGTM! Good semantic HTML improvement.

Adding the id="stig_id_column" attribute enables targeted styling and scripting for the STIG ID column, which improves maintainability and supports the UI enhancements mentioned in the broader changes.

stigaview.toml (1)

4-4: LGTM! Good feature flag implementation.

The use_search = false configuration flag provides a clean way to control the new search functionality. Setting it to false by default is a conservative approach that prevents accidental activation during deployment.

setup.cfg (1)

15-15: Ensure CLI entry point update is reflected across the project
The new console script stigaview = stigaview_static:main:main aligns the CLI name with the application. Verify that documentation, CI/CD scripts, and any usage instructions have been updated accordingly.

templates/base.html (2)

21-30: Well-implemented accessible search button.

The conditional search button includes proper ARIA attributes (aria-haspopup="dialog", aria-controls="search-modal") and semantic HTML structure. The SVG icon is appropriately sized and uses currentColor for theme compatibility.


44-47: Good conditional loading pattern.

The search template and JavaScript are loaded only when the use_search flag is enabled, which prevents unnecessary resource loading when search is disabled. The async loading of the script is also a performance optimization.

Makefile (2)

16-16: Static analysis warnings are acceptable in this context.

The checkmake warnings about missing "all" and "test" phony targets are false positives for this specific build setup. The current .PHONY declaration appropriately covers the actual phony targets in use.


28-30: Good integration of minification step.

The new minify_static target properly integrates with the build process and uses the consistent $(OUT) variable pattern.

templates/search.html (1)

1-30: Excellent accessibility implementation for the search modal.

The modal structure includes proper ARIA roles, labels, and live regions for screen reader compatibility. The form elements are correctly labeled and the modal behavior attributes are properly set. The HTMLHint doctype warning is a false positive since this is a template fragment, not a standalone HTML document.

stigaview_static/html_output.py (7)

1-2: LGTM! Well-organized imports for new functionality.

The new imports properly support the enhanced features: logging for monitoring, multiprocessing for performance, minify_html for optimization, tqdm for progress tracking, and integration with the new JSON output module.

Also applies to: 6-6, 8-8, 11-12


19-25: Excellent enhancements to template rendering.

The configuration merging and HTML minification are well-implemented improvements that enhance both functionality and performance.


34-34: Good integration with JSON output generation.

The addition of render_json_control properly extends the rendering pipeline to generate search-compatible JSON data alongside HTML.


71-74: Clean multiprocessing helper function.

The process_product_args function properly adapts arguments for the multiprocessing pool.


82-93: Excellent multiprocessing implementation with progress tracking.

The combination of multiprocessing with tqdm provides both performance improvement and user feedback. Using cpu_count() cores is appropriate for this CPU-bound rendering task.


77-77: Good addition of logging for process visibility.

The logging statements provide helpful monitoring of the rendering pipeline stages.

Also applies to: 97-97, 110-110, 124-124


133-133: Consistent progress tracking for SRG details.

The tqdm progress bar aligns with the overall improvement in user feedback during rendering operations.

public_html/static/css/style.css (4)

64-94: Well-designed button styles with proper accessibility.

The button implementation includes appropriate hover states, focus indicators, and transitions. The focus ring using box-shadow provides good accessibility.


95-222: Comprehensive and accessible modal implementation.

The modal styles include:

  • Proper z-index layering
  • Overlay for backdrop interaction
  • Flexible layout with scrollable content
  • Accessible close button
  • Well-styled search input and results

The implementation follows modern CSS practices and accessibility guidelines.


223-323: Excellent responsive design and filter styling.

The tag system, filter components, and responsive breakpoints are well-implemented. The media queries provide appropriate adaptations for different screen sizes.


325-471: Thorough dark mode support.

The dark mode implementation comprehensively covers all UI components with appropriate color choices that maintain readability and accessibility.

stigaview_static/models.py (3)

4-4: Good improvement in error handling.

Replacing sys.stderr.write with logging.error provides better structured logging and integration with the application's logging system.

Also applies to: 106-108


47-66: Well-designed search integration methods.

The search_primary_key property and to_search_json method provide a clean interface for search functionality. The JSON structure includes all necessary fields for comprehensive search indexing.


141-151: Appropriate configuration models.

The Pydantic models for configuration provide type safety and validation. The pylint warnings about too few public methods can be safely ignored as these are data models, not behavior-focused classes.

stigaview_static/json_output.py (1)

24-29: Efficient JSON control output generation.

The function properly handles directory creation and file writing for individual control JSON files. The use of pathlib for path operations is a good practice.

public_html/static/js/search.js (6)

51-80: Excellent accessibility implementation with focus trapping.

The focus trap implementation properly handles keyboard navigation within the modal, ensuring good accessibility for screen reader and keyboard users.


82-93: Proper debounce implementation for search optimization.

The debounce function effectively reduces API calls during rapid user input, improving both performance and user experience.


112-149: Robust search implementation with good error handling.

The search function properly handles loading states, errors, and API communication. The filter integration and result limiting are well-implemented.


152-192: Well-structured result rendering with accessibility.

The result rendering creates properly structured HTML with focusable links and semantic markup. The metadata tags provide useful context for users.


194-215: Good modal state management with focus restoration.

The modal open/close logic properly manages focus, prevents body scrolling, and restores the previous focus state for accessibility.


284-322: Comprehensive dropdown initialization with proper error handling.

The async initialization properly loads and populates filter dropdowns with appropriate error handling and sorting.

stigaview_static/main.py (7)

3-3: LGTM: Good import additions for new functionality.

The new imports for logging, tqdm progress bars, and json_output align well with the enhanced functionality being added.

Also applies to: 9-9, 11-11


14-18: LGTM: Good modularization of model preparation.

The extraction of model preparation into a dedicated function with logging is a good improvement. The switch from update_forward_refs() to model_rebuild() suggests a Pydantic v2 migration, which is appropriate.


48-50: LGTM: Good addition of configurable log level.

The log level argument with custom validation enhances the CLI experience and allows users to control verbosity.


66-84: LGTM: Excellent improvements to main function.

The structured logging setup, runtime tracking, and addition of JSON output generation are all excellent improvements that enhance the CLI experience and functionality.


86-90: LGTM: Good extraction of product config loading.

Extracting the product configuration loading into a dedicated function improves code organization and reusability.


92-112: LGTM: Good improvements to process_product function.

The addition of progress bar integration and consistent use of pathlib.Path are excellent improvements that enhance user experience and code consistency.


115-123: LGTM: Good helper function for progress bar initialization.

The file counting logic is correct and necessary for proper progress bar initialization.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
stigaview_static/main.py (3)

20-28: Exception chaining has been properly addressed.

The exception handling in this function correctly uses from None to suppress the original exception context, which follows Python best practices for exception chaining.


133-140: Good improvements to path handling and error logging.

The use of pathlib.Path and structured logging for errors are good improvements. However, the exit(4) call should be sys.exit(4) as noted in previous reviews.


141-147: SRG merging logic improvements noted in previous reviews.

The progress bar integration here is good. However, the data structure initialization and dictionary key checking improvements were already identified in previous reviews.

🧹 Nitpick comments (5)
Makefile (1)

16-16: Add missing targets to .PHONY declaration.

The .PHONY declaration should include the all target to be complete and follow best practices.

-.PHONY: clean build copy_assets minify_static sitemap
+.PHONY: all clean build copy_assets minify_static sitemap
public_html/static/css/style.css (1)

83-93: Remove duplicate .btn:focus rule.

The .btn:focus rule is defined twice with identical properties. Remove the duplicate to avoid confusion and maintain clean code.

-.btn:focus {
-    outline: 2px solid transparent;
-    outline-offset: 2px;
-}
-
 .btn:focus {
     outline: 2px solid transparent;
     outline-offset: 2px;
     /* Add a focus ring using box-shadow for better visibility */
     box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
 }
utils/add_to_search.py (1)

60-60: Consider using list literal instead of list() constructor.

For better readability and slight performance improvement, use the list literal syntax.

-docs = list()
+docs = []
stigaview_static/json_output.py (1)

12-12: Use dict literal for better readability.

Consider using the dict literal syntax for improved readability.

-products_list: Dict[str, str] = dict()
+products_list: Dict[str, str] = {}
stigaview_static/main.py (1)

115-122: Consider handling missing product paths consistently.

The function only counts files for existing product paths, but process_products will error out when it encounters missing paths. This inconsistency could make the progress bar inaccurate.

Consider either counting all expected files (and handling missing paths gracefully) or failing early if required paths don't exist.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4be3930 and b1a7e99.

📒 Files selected for processing (19)
  • .editorconfig (1 hunks)
  • .gitignore (1 hunks)
  • .idea/misc.xml (1 hunks)
  • .idea/stigaview-static.iml (1 hunks)
  • Makefile (1 hunks)
  • public_html/static/css/style.css (2 hunks)
  • requirements.txt (1 hunks)
  • setup.cfg (1 hunks)
  • stigaview.toml (1 hunks)
  • stigaview_static/html_output.py (6 hunks)
  • stigaview_static/import_stig.py (1 hunks)
  • stigaview_static/json_output.py (1 hunks)
  • stigaview_static/main.py (3 hunks)
  • stigaview_static/models.py (4 hunks)
  • stigaview_static/utils.py (2 hunks)
  • templates/base.html (1 hunks)
  • templates/stig.html (1 hunks)
  • utils/add_to_search.py (1 hunks)
  • utils/minify.py (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • templates/stig.html
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (11)
  • requirements.txt
  • stigaview.toml
  • stigaview_static/import_stig.py
  • .idea/stigaview-static.iml
  • .idea/misc.xml
  • stigaview_static/utils.py
  • templates/base.html
  • setup.cfg
  • stigaview_static/html_output.py
  • .editorconfig
  • utils/minify.py
🧰 Additional context used
🧬 Code Graph Analysis (1)
stigaview_static/json_output.py (1)
stigaview_static/models.py (5)
  • Product (94-138)
  • short_version (77-78)
  • Control (22-66)
  • search_primary_key (48-49)
  • to_search_json (51-66)
🪛 checkmake (0.2.2)
Makefile

[warning] 16-16: Missing required phony target "all"

(minphony)


[warning] 16-16: Missing required phony target "test"

(minphony)


[warning] 18-18: Target "all" should be declared PHONY.

(phonydeclared)

🪛 Pylint (3.3.7)
stigaview_static/json_output.py

[refactor] 12-12: Consider using '{}' instead of a call to 'dict'.

(R1735)

stigaview_static/main.py

[refactor] 98-98: Consider using '{}' instead of a call to 'dict'.

(R1735)


[refactor] 129-129: Consider using [] instead of list()

(R1734)


[refactor] 130-130: Consider using '{}' instead of a call to 'dict'.

(R1735)


[refactor] 139-139: Consider using 'sys.exit' instead

(R1722)

stigaview_static/models.py

[refactor] 141-141: Too few public methods (0/2)

(R0903)


[refactor] 147-147: Too few public methods (0/2)

(R0903)

utils/add_to_search.py

[refactor] 60-60: Consider using [] instead of list()

(R1734)

🪛 Ruff (0.11.9)
stigaview_static/main.py

142-142: Use key not in dict instead of key not in dict.keys()

Remove .keys()

(SIM118)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: deploy
🔇 Additional comments (19)
Makefile (2)

28-30: LGTM! Good addition of the minify_static target.

The new minify_static target properly integrates with the build pipeline and uses the consistent $(OUT) variable.


36-37: LGTM! Clean target improves build hygiene.

The clean target is a useful addition that follows the standard pattern and uses the $(OUT) variable consistently.

public_html/static/css/style.css (2)

95-175: LGTM! Well-structured modal implementation.

The modal CSS implementation follows good practices with proper z-index layering, flexbox centering, and responsive design considerations.


325-471: Excellent dark mode implementation.

The dark mode styles are comprehensive and provide good contrast ratios for accessibility. The color choices maintain readability while providing a cohesive dark theme experience.

utils/add_to_search.py (1)

54-66: LGTM! Proper Meilisearch integration with error handling.

The implementation correctly:

  • Creates the index if it doesn't exist
  • Uses batch processing for efficient document addition
  • Waits for indexing tasks to complete
  • Provides appropriate error handling
stigaview_static/models.py (4)

47-49: LGTM! Well-designed search primary key.

The search_primary_key property creates a unique, descriptive identifier that combines product, STIG version, and control ID. This will work well for search indexing.


51-66: Excellent search JSON serialization method.

The to_search_json method provides comprehensive metadata for search functionality including all the key fields needed for effective searching and filtering. The structure is well-organized and includes proper date formatting.


141-151: LGTM! Appropriate configuration models.

The new ProductConfig and StigAViewConfig classes provide proper typing for configuration data and will improve type safety throughout the application.


106-107: Good improvement using structured logging.

Replacing direct stderr writes with logging.error is a best practice that provides better logging control and consistency.

stigaview_static/json_output.py (2)

10-21: LGTM! Well-structured product mapping generation.

The function correctly generates the JSON mappings needed for the search frontend:

  • Product to STIG version mapping for filters
  • Product short name to full name mapping for display
  • Proper sorting of STIGs for consistent output

24-29: LGTM! Efficient control JSON generation.

The function properly:

  • Creates the output directory structure as needed
  • Uses the control's search primary key for consistent file naming
  • Leverages the model's to_search_json() method for data serialization
stigaview_static/main.py (8)

3-3: LGTM! Imports support new functionality well.

The addition of logging, tqdm, and json_output imports properly support the structured logging, progress reporting, and JSON output functionality introduced in this refactor.

Also applies to: 9-9, 11-11


14-17: Excellent refactoring with proper logging.

The extraction of model preparation into a dedicated function with structured logging is a good improvement. Using model_rebuild() instead of update_forward_refs() suggests adoption of a newer API.


48-50: Good addition of configurable logging.

The log level argument with proper validation enhances usability by allowing users to control logging verbosity at runtime.


55-55: Excellent improvements with proper logging and error handling.

The structured logging, environment variable setting, and use of sys.exit() are all good improvements. The environment variable will help other parts of the system locate the config file.

Also applies to: 57-59, 63-63


66-73: Excellent modernization of the main function.

The structured logging setup, JSON output generation, and proper timing with logging instead of print statements are all significant improvements that enhance both functionality and maintainability.

Also applies to: 81-83


86-89: Good refactoring to extract configuration loading.

The extraction of product configuration loading into a dedicated function improves code organization and reusability.


93-93: Good improvements with progress tracking and cleaner code.

The progress bar integration, use of the extracted config function, and cleaner SRG merging with srgs.update() are all excellent improvements.

Also applies to: 96-96, 108-108, 110-111


131-132: Excellent progress bar integration.

The addition of total file counting and progress bar initialization significantly improves user experience by providing clear feedback during processing.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
utils/add_to_search.py (1)

31-33: Fix incorrect error message for SEARCH_HOST validation.

The error message mentions the wrong environment variable name. It should reference SEARCH_HOST since that's what's being checked.

 if not SEARCH_HOST:
-    print("Please set the environment variable SEARCH_MASTER_KEY", file=sys.stderr)
+    print("Please set the environment variable SEARCH_HOST", file=sys.stderr)
     sys.exit(1)
public_html/static/js/search.js (1)

1-6: Critical security issue: Hardcoded API key exposure.

The Meilisearch API key is still hardcoded in client-side JavaScript, making it publicly accessible and potentially exposing your search infrastructure to abuse.

🧹 Nitpick comments (10)
Makefile (1)

16-16: Add missing phony declarations.

The static analysis correctly identifies that all should be declared as a phony target for consistency with Make best practices.

-.PHONY: clean build copy_assets minify_static sitemap
+.PHONY: all clean build copy_assets minify_static sitemap
utils/add_to_search.py (1)

60-62: Consider using list comprehension for better performance.

The static analysis correctly suggests using [] instead of list() for better performance and readability.

-    docs = list()
+    docs = []
stigaview_static/json_output.py (2)

12-12: Use dictionary literal instead of dict() constructor.

Following Python best practices, use {} instead of dict() for better readability and slight performance improvement.

-    products_list: Dict[str, str] = dict()
+    products_list: Dict[str, str] = {}

19-21: Consider using proper JSON indentation for readability.

Using indent=0 produces compact but potentially hard-to-read JSON. Consider using indent=None for maximum compactness or indent=2 for better readability in development.

-        f.write(json.dumps(product_stig_map, indent=0))
+        f.write(json.dumps(product_stig_map))
-        f.write(json.dumps(products_list, indent=0))
+        f.write(json.dumps(products_list))
public_html/static/js/search.js (1)

287-292: Simplify Promise.all usage.

The variable assignment can be streamlined for better readability.

-        const productStigPromise =  loadProductStigMap();
-        const productPromise =  loadProductMap();
-
-        const [productMap, productStigMap] = await Promise.all(
-            [productPromise, productStigPromise]
-        )
+        const [productMap, productStigMap] = await Promise.all([
+            loadProductMap(),
+            loadProductStigMap()
+        ]);
stigaview_static/main.py (5)

98-98: Use dictionary literal instead of dict() constructor.

Following Python best practices for consistency with the codebase.

-    srgs: dict[str, list[models.Control]] = dict()
+    srgs: dict[str, list[models.Control]] = {}

129-130: Use modern literal syntax for better readability.

Replace constructor calls with literal syntax for improved readability and slight performance benefits.

-    result = list()
-    srgs_dict = dict()
+    result = []
+    srgs_dict = {}

139-139: Use sys.exit() instead of bare exit().

Following Python best practices for explicit imports and clearer intent.

-                exit(4)
+                sys.exit(4)

142-142: Simplify dictionary key existence check.

Remove unnecessary .keys() call for cleaner and more efficient code.

-                if srg not in srgs_dict.keys():
+                if srg not in srgs_dict:

131-147: Consider using collections.defaultdict for cleaner code.

The current manual key checking and list appending can be simplified using defaultdict(list).

+import collections
...
-    srgs_dict = {}
+    srgs_dict = collections.defaultdict(list)
    total_files = _get_total_files(input_path, products)
    with tqdm(total=total_files, desc="Processing all STIG files", unit="file") as pbar:
        for product in products:
            product_path = pathlib.Path(input_path) / product.short_name
            if not product_path.exists():
                logging.error(
                    f"Unable to find path for {product.short_name} at {product_path}"
                )
                sys.exit(4)
            product, srgs = process_product(product, product_path, pbar)
            for srg, controls in srgs.items():
-                if srg not in srgs_dict:
-                    srgs_dict[srg] = controls
-                else:
-                    for control in controls:
-                        srgs_dict[srg].append(control)
+                srgs_dict[srg].extend(controls)
            result.append(product)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b1a7e99 and 71a2f1c.

📒 Files selected for processing (21)
  • .editorconfig (1 hunks)
  • .gitignore (1 hunks)
  • .idea/misc.xml (1 hunks)
  • .idea/stigaview-static.iml (1 hunks)
  • Makefile (1 hunks)
  • public_html/static/css/style.css (2 hunks)
  • public_html/static/js/search.js (1 hunks)
  • requirements.txt (1 hunks)
  • setup.cfg (1 hunks)
  • stigaview.toml (1 hunks)
  • stigaview_static/html_output.py (6 hunks)
  • stigaview_static/import_stig.py (1 hunks)
  • stigaview_static/json_output.py (1 hunks)
  • stigaview_static/main.py (3 hunks)
  • stigaview_static/models.py (4 hunks)
  • stigaview_static/utils.py (2 hunks)
  • templates/base.html (1 hunks)
  • templates/search.html (1 hunks)
  • templates/stig.html (1 hunks)
  • utils/add_to_search.py (1 hunks)
  • utils/minify.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
  • stigaview.toml
  • templates/stig.html
  • .gitignore
  • .idea/misc.xml
  • setup.cfg
  • .idea/stigaview-static.iml
  • stigaview_static/import_stig.py
  • stigaview_static/utils.py
  • .editorconfig
  • requirements.txt
  • templates/base.html
  • utils/minify.py
  • public_html/static/css/style.css
🧰 Additional context used
🧬 Code Graph Analysis (1)
stigaview_static/json_output.py (1)
stigaview_static/models.py (5)
  • Product (94-138)
  • short_version (77-78)
  • Control (22-66)
  • search_primary_key (48-49)
  • to_search_json (51-66)
🪛 Gitleaks (8.26.0)
public_html/static/js/search.js

3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Pylint (3.3.7)
stigaview_static/main.py

[refactor] 98-98: Consider using '{}' instead of a call to 'dict'.

(R1735)


[refactor] 129-129: Consider using [] instead of list()

(R1734)


[refactor] 130-130: Consider using '{}' instead of a call to 'dict'.

(R1735)


[refactor] 139-139: Consider using 'sys.exit' instead

(R1722)

stigaview_static/json_output.py

[refactor] 12-12: Consider using '{}' instead of a call to 'dict'.

(R1735)

stigaview_static/models.py

[refactor] 141-141: Too few public methods (0/2)

(R0903)


[refactor] 147-147: Too few public methods (0/2)

(R0903)

utils/add_to_search.py

[refactor] 60-60: Consider using [] instead of list()

(R1734)

🪛 Ruff (0.11.9)
stigaview_static/main.py

142-142: Use key not in dict instead of key not in dict.keys()

Remove .keys()

(SIM118)

🪛 checkmake (0.2.2)
Makefile

[warning] 16-16: Missing required phony target "all"

(minphony)


[warning] 16-16: Missing required phony target "test"

(minphony)


[warning] 18-18: Target "all" should be declared PHONY.

(phonydeclared)

🪛 HTMLHint (1.5.0)
templates/search.html

[error] 1-1: Doctype must be declared before any non-comment content.

(doctype-first)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: deploy
🔇 Additional comments (21)
Makefile (2)

28-30: Good addition of minification target.

The new minify_static target integrates well with the build process and uses consistent variable naming.


36-37: Useful clean target addition.

The clean target provides a standard way to remove build artifacts and follows Make conventions.

templates/search.html (3)

1-9: Excellent accessibility implementation.

The modal structure includes proper ARIA attributes (role="dialog", aria-modal="true", aria-labelledby, aria-controls) and semantic HTML elements that ensure screen reader compatibility.


10-25: Well-structured filter interface.

The filter controls with progressive disclosure (STIG select disabled until product is chosen) provide a logical user experience. The "Clear Filters" button being initially hidden is a good UX pattern.


26-28: Proper live region for dynamic content.

Using aria-live="polite" on the search results container ensures that screen readers announce search results without being disruptive.

stigaview_static/html_output.py (6)

1-12: Good addition of imports for enhanced functionality.

The new imports support logging, multiprocessing, minification, progress tracking, and JSON output generation - all key improvements for the build process.


19-24: Excellent template context enhancement.

Merging global configuration into template context enables conditional features like search, and HTML minification reduces output size. This is a solid improvement to the rendering pipeline.


34-34: Good integration of JSON output generation.

Adding render_json_control call during product rendering ensures search index data is generated alongside HTML content.


71-73: Clean multiprocessing adapter function.

The process_product_args function properly unpacks arguments for the multiprocessing pool, following the standard pattern for pool.imap usage.


82-93: Excellent multiprocessing implementation.

The combination of multiprocessing pool with tqdm progress bar provides both performance improvement and user feedback. Using cpu_count() cores and imap with progress tracking is a best practice implementation.


133-133: Good addition of progress tracking.

Adding tqdm progress bar to SRG rendering provides consistent user feedback across all rendering operations.

utils/add_to_search.py (3)

10-11: Good security improvement using environment variables.

The implementation correctly retrieves sensitive credentials from environment variables rather than hardcoding them, addressing the security concerns from previous reviews.


25-27: Clean chunking implementation.

The generator function for chunking lists is well-implemented and will handle large document batches efficiently.


63-65: Robust batch processing with task waiting.

The implementation properly handles batch uploads and waits for all indexing tasks to complete, ensuring data consistency.

stigaview_static/models.py (4)

47-49: Well-designed search primary key generation.

The search_primary_key property creates a unique identifier combining product, STIG version, and control ID, ensuring proper indexing and retrieval.


51-66: Comprehensive search JSON representation.

The to_search_json method provides all necessary fields for search indexing including metadata, content, and relationships. The date formatting and structured output are well-implemented.


106-108: Good logging improvement.

Replacing direct stderr writing with structured logging is consistent with the broader codebase improvements and provides better error handling.


141-151: Well-structured configuration models.

The new Pydantic models ProductConfig and StigAViewConfig provide proper type safety and validation for configuration data. The static analysis warnings about too few public methods are false positives for Pydantic data models.

stigaview_static/json_output.py (1)

24-29: LGTM! Clean implementation of JSON control rendering.

The function correctly creates the directory structure and writes control JSON data using pathlib. The logic is sound and the error handling is implicit through pathlib operations.

public_html/static/js/search.js (2)

51-80: LGTM! Well-implemented focus trapping for accessibility.

The focus trap implementation correctly handles Tab and Shift+Tab navigation within the modal, ensuring good accessibility compliance. The logic for wrapping focus between first and last focusable elements is sound.


83-93: Clean debounce implementation.

The debounce function is correctly implemented with proper timeout handling and argument passing. This will help reduce API calls during rapid user input.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (2)
utils/add_to_search.py (1)

31-36: Fix swapped error messages in environment variable validation.

The error messages are incorrect for their respective validation checks.

Apply this diff to correct the error messages:

 if not SEARCH_HOST:
-    print("Please set the environment variable SEARCH_MASTER_KEY", file=sys.stderr)
+    print("Please set the environment variable SEARCH_HOST", file=sys.stderr)
     sys.exit(1)
 if not MASTER_KEY:
-    print("Please set the environment variable SEARCH_HOST", file=sys.stderr)
+    print("Please set the environment variable SEARCH_MASTER_KEY", file=sys.stderr)
     sys.exit(1)
public_html/static/js/search.js (1)

1-6: Critical security issue: Hardcoded API key exposure.

The Meilisearch API key is hardcoded in client-side JavaScript, making it visible to all users and potentially exposing your search infrastructure to abuse.

Move the API key to server-side configuration and implement a secure authentication mechanism or use read-only tenant tokens.

🧹 Nitpick comments (4)
Makefile (2)

28-30: minify_static target lacks explicit dependency on copy_assets

If somebody runs make minify_static directly (or adds minify_static elsewhere), the output directory may be empty because copy_assets hasn’t executed yet. To make the target self-contained:

-minify_static:
+minify_static: copy_assets

Alternatively, document in the README that minify_static assumes a populated $(OUT) directory.


16-16: Consider adding a test phony target

checkmake warns that the conventional test phony target is missing. Even if the project has no automated tests yet, stubbing the target avoids the warning and sets expectations for future contributors:

.PHONY: test
test:
	@echo "No tests defined yet"
utils/add_to_search.py (1)

60-60: Use list literal instead of constructor.

Apply this diff for more pythonic code:

-    docs = list()
+    docs = []
stigaview_static/json_output.py (1)

12-12: Use dict literal instead of constructor.

Apply this diff for more pythonic code:

-    products_list: Dict[str, str] = dict()
+    products_list: Dict[str, str] = {}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71a2f1c and ea47371.

📒 Files selected for processing (4)
  • Makefile (1 hunks)
  • public_html/static/js/search.js (1 hunks)
  • stigaview_static/json_output.py (1 hunks)
  • utils/add_to_search.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
stigaview_static/json_output.py (1)
stigaview_static/models.py (5)
  • Product (94-138)
  • short_version (77-78)
  • Control (22-66)
  • search_primary_key (48-49)
  • to_search_json (51-66)
🪛 checkmake (0.2.2)
Makefile

[warning] 16-16: Missing required phony target "test"

(minphony)

🪛 Gitleaks (8.26.0)
public_html/static/js/search.js

3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Pylint (3.3.7)
stigaview_static/json_output.py

[refactor] 12-12: Consider using '{}' instead of a call to 'dict'.

(R1735)

utils/add_to_search.py

[refactor] 60-60: Consider using [] instead of list()

(R1734)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: deploy
🔇 Additional comments (3)
utils/add_to_search.py (1)

14-70: LGTM! Well-structured script for search indexing.

The overall approach is solid - proper argument parsing, path validation, batch processing, and task waiting. The script correctly integrates with the JSON output from the main application.

stigaview_static/json_output.py (1)

10-29: LGTM! Clean JSON serialization implementation.

The functions properly serialize the model data to JSON format. The integration with the Product and Control models is correct, using appropriate properties like short_name, full_name, short_version, and to_search_json().

public_html/static/js/search.js (1)

44-356: LGTM! Comprehensive search modal implementation.

The search functionality is well-implemented with good UX practices:

  • Proper focus management and accessibility
  • Debounced search for performance
  • Clean modal state management
  • Filterable search with dynamic dropdowns

Comment on lines +54 to +59
client = meilisearch.Client(SEARCH_HOST, MASTER_KEY)
client.create_index("controls")
index = client.get_index("controls")
if not index:
print("No index found", file=sys.stderr)
sys.exit(1)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve index creation and retrieval error handling.

The current implementation has potential issues:

  1. create_index will fail if the index already exists
  2. The subsequent index existence check is redundant since get_index would raise an exception

Apply this diff to handle existing indexes gracefully:

-    client = meilisearch.Client(SEARCH_HOST, MASTER_KEY)
-    client.create_index("controls")
-    index = client.get_index("controls")
-    if not index:
-        print("No index found", file=sys.stderr)
-        sys.exit(1)
+    client = meilisearch.Client(SEARCH_HOST, MASTER_KEY)
+    try:
+        index = client.get_index("controls")
+    except Exception:
+        # Index doesn't exist, create it
+        client.create_index("controls")
+        index = client.get_index("controls")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
client = meilisearch.Client(SEARCH_HOST, MASTER_KEY)
client.create_index("controls")
index = client.get_index("controls")
if not index:
print("No index found", file=sys.stderr)
sys.exit(1)
client = meilisearch.Client(SEARCH_HOST, MASTER_KEY)
try:
index = client.get_index("controls")
except Exception:
# Index doesn't exist, create it
client.create_index("controls")
index = client.get_index("controls")
🤖 Prompt for AI Agents
In utils/add_to_search.py around lines 54 to 59, the code calls create_index
without handling the case where the index already exists, which causes an error,
and then redundantly checks for the index existence after get_index, which
raises an exception if the index does not exist. To fix this, wrap the
create_index call in a try-except block to catch the exception for an existing
index and ignore it, then directly call get_index without checking its return
value, handling any exceptions if the index retrieval fails.

Comment on lines +99 to +101
if (selectedProduct) {
filterParts.push(`product = "${selectedProduct}"`);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix missing product field in search implementation.

The code references a product field that doesn't exist in the JSON structure. Looking at Control.to_search_json() in models.py, there's no product field in the returned data.

You need to either:

  1. Add a product field to Control.to_search_json() method, or
  2. Extract the product name from the existing id field which contains {product}-{stig}-{control_id}

For option 1, update models.py:

def to_search_json(self) -> Dict[str, str | List[str]]:
    return {
        "id": self.search_primary_key,
+       "product": self.stig.product.short_name,
        "title": self.title,
        # ... rest of fields
    }

For option 2, extract from the ID in JavaScript:

-        const product = hit.product;
+        const product = hit.id.split('-')[0]; // Extract product from id

Also applies to: 167-169

🤖 Prompt for AI Agents
In public_html/static/js/search.js at lines 99-101 and also lines 167-169, the
code filters by a `product` field that does not exist in the JSON data returned
by Control.to_search_json(). To fix this, either update the
Control.to_search_json() method in models.py to include a `product` field, or
modify the JavaScript to extract the product name from the existing `id` field
by parsing the string before the first hyphen. Choose one approach and implement
it consistently in both places.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
utils/add_to_search.py (1)

54-59: Fix index creation and retrieval error handling.

The current implementation still has the issues identified in previous reviews:

  1. create_index will fail if the index already exists
  2. The subsequent index existence check is redundant since get_index would raise an exception

Apply this diff to handle existing indexes gracefully:

-    client = meilisearch.Client(SEARCH_HOST, MASTER_KEY)
-    client.create_index("controls")
-    index = client.get_index("controls")
-    if not index:
-        print("No index found", file=sys.stderr)
-        sys.exit(1)
+    client = meilisearch.Client(SEARCH_HOST, MASTER_KEY)
+    try:
+        index = client.get_index("controls")
+    except Exception:
+        # Index doesn't exist, create it
+        client.create_index("controls")
+        index = client.get_index("controls")
🧹 Nitpick comments (1)
utils/add_to_search.py (1)

60-60: Minor style improvement: use list literal.

Consider using the more Pythonic list literal syntax.

-    docs = list()
+    docs = []
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea47371 and a1e8b6a.

📒 Files selected for processing (3)
  • Makefile (1 hunks)
  • stigaview_static/models.py (4 hunks)
  • utils/add_to_search.py (1 hunks)
🧰 Additional context used
🪛 checkmake (0.2.2)
Makefile

[warning] 16-16: Missing required phony target "test"

(minphony)

🪛 Pylint (3.3.7)
stigaview_static/models.py

[refactor] 142-142: Too few public methods (0/2)

(R0903)


[refactor] 148-148: Too few public methods (0/2)

(R0903)

utils/add_to_search.py

[refactor] 60-60: Consider using [] instead of list()

(R1734)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: deploy
🔇 Additional comments (7)
Makefile (2)

16-18: LGTM! Previous issue has been resolved.

The minify_static target is now properly included in the all dependency chain and correctly declared in .PHONY. This addresses the previous concern about skipping minification in the default build process.


36-37: Good addition of clean target.

The new clean target provides a convenient way to remove the output directory, following standard Makefile conventions.

stigaview_static/models.py (4)

47-49: Well-designed search primary key.

The composite key format using product, STIG version, and DISA STIG ID ensures uniqueness across the search index while maintaining readability.


51-67: Comprehensive search JSON serialization.

The to_search_json method includes all relevant fields for search functionality with proper formatting, including date serialization and URL path generation.


107-107: Improved error handling with structured logging.

Replacing direct stderr output with proper logging is a good improvement that aligns with the application's logging strategy.


142-152: Appropriate Pydantic configuration models.

These models provide proper type validation for configuration data. The static analysis warnings about too few public methods are false positives - configuration models typically don't need many public methods.

utils/add_to_search.py (1)

30-36: Good environment variable validation.

The script properly validates required environment variables and provides clear error messages when they're missing.

@Mab879 Mab879 merged commit f7df12d into master Jul 13, 2025
6 checks passed
@Mab879 Mab879 deleted the add_search branch July 13, 2025 04:03
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.

1 participant