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

fix: update autocomplete on applied controls creation from suggestions #1599

Conversation

nas-tabchiche
Copy link
Contributor

@nas-tabchiche nas-tabchiche commented Mar 3, 2025

Summary by CodeRabbit

  • New Features
    • Enhanced control creation now returns detailed information, giving users clear visibility into the new applied controls.
    • Improved error handling provides clear feedback when control creation encounters issues.
    • Updated interaction flow ensures that the interface refreshes and displays newly added controls—whether one or multiple—promptly and efficiently.

Copy link
Contributor

coderabbitai bot commented Mar 3, 2025

Walkthrough

This pull request updates both backend and frontend logic for creating and processing applied controls. In the backend, the methods in the assessment view sets now capture and serialize the results of control creation, returning detailed data instead of a simple success. On the frontend, the response of the POST handler is modified to return JSON data rather than an empty body. Additionally, the third-party assessment edit flow now includes improved error handling and updates the UI state to handle multiple new controls at once.

Changes

File(s) Change Summary
backend/core/views.py Modified create_suggested_applied_controls in both ComplianceAssessmentViewSet and RequirementAssessmentViewSet to collect and serialize applied controls using AppliedControlReadSerializer, returning an HTTP 200 with control details.
frontend/src/routes/(app)/(internal)/requirement-assessments/[id=uuid]/suggestions/applied-controls/+server.ts Updated POST response to include a JSON string representation of data obtained from the fetch operation instead of returning a null body.
frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.server.ts and .../+page.svelte Enhanced the createSuggestedControls action by adding error handling and processing of JSON response to extract multiple new control IDs; updated the UI with a new reactive statement that appends these controls to the applied controls store.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant V as ViewSet
    participant M as Control Creator
    participant S as Serializer

    C->>V: POST /create_suggested_applied_controls
    V->>M: create_applied_controls_from_suggestions()
    M-->>V: List of applied controls
    V->>S: Serialize applied controls
    S-->>V: JSON data payload
    V-->>C: HTTP 200 with applied controls JSON
Loading
sequenceDiagram
    participant U as User
    participant PS as +page.server.ts Handler
    participant F as +server.ts (Internal API)
    participant UI as +page.svelte (Frontend)

    U->>PS: Trigger createSuggestedControls action
    PS->>F: Fetch applied controls
    F-->>PS: JSON response (or error)
    PS->>U: Return { form, newControls } or fail response
    UI->>UI: Reactive statement processes form.newControls
    UI->>UI: Append new controls to $formStore.applied_controls
Loading

Possibly related PRs

Suggested reviewers

  • Mohamed-Hacene
  • ab-smith
  • eric-intuitem

Poem

I'm a rabbit, hopping with glee,
Through lines of code, light as can be.
Controls now dance in a neat array,
Backend sings and frontend plays.
With each new line, I leap and cheer,
Happy changes, fresh and clear!
🐰✨


📜 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 19a5716 and 316e8af.

📒 Files selected for processing (4)
  • backend/core/views.py (2 hunks)
  • frontend/src/routes/(app)/(internal)/requirement-assessments/[id=uuid]/suggestions/applied-controls/+server.ts (1 hunks)
  • frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.server.ts (1 hunks)
  • frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.svelte (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/src/routes/(app)/(internal)/requirement-assessments/[id=uuid]/suggestions/applied-controls/+server.ts
  • frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.server.ts
  • frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.svelte
🧰 Additional context used
🪛 Ruff (0.8.2)
backend/core/views.py

4073-4073: AppliedControlReadSerializer may be undefined, or defined from star imports

(F405)


4211-4211: AppliedControlReadSerializer may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: startup-functional-test (3.12)
  • GitHub Check: startup-docker-compose-test
  • GitHub Check: enterprise-functional-tests (3.12, chromium)
  • GitHub Check: enterprise-startup-functional-test (3.12)
  • GitHub Check: build (3.12)
  • GitHub Check: test (3.12)
  • GitHub Check: enterprise-startup-docker-compose-test
  • GitHub Check: functional-tests (3.12, chromium)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (2)
backend/core/views.py (2)

4067-4075: Applied controls now correctly returned in response enhancing frontend updates

The change is now properly capturing and returning the created applied controls in the HTTP response. By serializing the flattened list of created controls with AppliedControlReadSerializer, the frontend can now immediately update its state without making additional requests.

🧰 Tools
🪛 Ruff (0.8.2)

4073-4073: AppliedControlReadSerializer may be undefined, or defined from star imports

(F405)


4209-4213: Response improvement to return created controls data

This change enhances the API by returning the serialized controls data rather than just a success status. This approach allows the frontend to immediately update its state with the newly created controls.

Note: There's a warning about AppliedControlReadSerializer potentially being undefined from star imports. While explicit imports would be better for maintainability, this is consistent with the current codebase patterns and appears to work correctly.

🧰 Tools
🪛 Ruff (0.8.2)

4211-4211: AppliedControlReadSerializer may be undefined, or defined from star imports

(F405)

✨ Finishing Touches
  • 📝 Generate Docstrings

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 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
Contributor

@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

🧹 Nitpick comments (4)
frontend/src/routes/(app)/(internal)/requirement-assessments/[id=uuid]/suggestions/applied-controls/+server.ts (1)

23-23: Enhanced response structure with control data.

The change improves the API response by returning the parsed JSON data instead of an empty response. This allows clients to access details of the newly created applied controls, facilitating better UI updates and state management.

Consider adding error handling around the res.json() call in case the response isn't valid JSON:

-	return new Response(JSON.stringify(await res.json()), {
+	try {
+		const responseData = await res.json();
+		return new Response(JSON.stringify(responseData), {
+			headers: {
+				'Content-Type': 'application/json'
+			}
+		});
+	} catch (error) {
+		console.error('Error parsing response as JSON:', error);
+		return new Response(JSON.stringify({ error: 'Failed to parse response' }), {
+			status: 500,
+			headers: {
+				'Content-Type': 'application/json'
+			}
+		});
+	}
frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.server.ts (1)

305-306: Enhanced response handling for created controls.

The updated code now processes the JSON response to extract control IDs and returns them as newControls. This works with the new reactive block in the page component to update the UI with multiple new controls.

Consider adding error handling around the JSON parsing and data mapping:

-const newControls = await response.json().then((data) => data.map((e) => e.id));
-return { form, newControls };
+try {
+  const responseData = await response.json();
+  // Validate that responseData is an array
+  if (!Array.isArray(responseData)) {
+    console.error('Expected array response but got:', responseData);
+    return { form, newControls: [] };
+  }
+  const newControls = responseData.map((e) => e?.id).filter(Boolean);
+  return { form, newControls };
+} catch (error) {
+  console.error('Error processing response:', error);
+  return { form, newControls: [] };
+}

This provides better error resilience if the API response format changes unexpectedly.

backend/core/views.py (2)

4067-4075: Improved return value handling for multiple control creation.

The changes correctly enhance the endpoint to return the newly created applied controls rather than a simple success response. This allows the frontend to immediately access and display the created controls without requiring an additional API call.

A few observations:

  1. The code assumes create_applied_controls_from_suggestions() always returns a valid object that can be appended to a list.
  2. There's no error handling if the control creation fails.

Consider adding error handling to make the endpoint more robust:

def create_suggested_applied_controls(request, pk):
    compliance_assessment = ComplianceAssessment.objects.get(id=pk)
    if not RoleAssignment.is_access_allowed(
        user=request.user,
        perm=Permission.objects.get(codename="add_appliedcontrol"),
        folder=compliance_assessment.folder,
    ):
        return Response(status=status.HTTP_403_FORBIDDEN)
    requirement_assessments = compliance_assessment.requirement_assessments.all()
    controls = []
    for requirement_assessment in requirement_assessments:
-       controls.append(
-           requirement_assessment.create_applied_controls_from_suggestions()
-       )
+       try:
+           created_controls = requirement_assessment.create_applied_controls_from_suggestions()
+           if created_controls:
+               controls.append(created_controls)
+       except Exception as e:
+           logger.error(f"Error creating controls for requirement {requirement_assessment.id}: {str(e)}")
    return Response(
        AppliedControlReadSerializer(controls, many=True).data,
        status=status.HTTP_200_OK,
    )
🧰 Tools
🪛 Ruff (0.8.2)

4073-4073: AppliedControlReadSerializer may be undefined, or defined from star imports

(F405)


4209-4213: Improved return value handling for individual control creation.

This change correctly enhances the endpoint to return the newly created applied controls rather than a simple success response. This allows frontend code to immediately use the new control data without making additional API calls.

Consider adding error handling and validation of results:

def create_suggested_applied_controls(request, pk):
    requirement_assessment = RequirementAssessment.objects.get(id=pk)
    if not RoleAssignment.is_access_allowed(
        user=request.user,
        perm=Permission.objects.get(codename="add_appliedcontrol"),
        folder=requirement_assessment.folder,
    ):
        return Response(status=status.HTTP_403_FORBIDDEN)
-   controls = requirement_assessment.create_applied_controls_from_suggestions()
-   return Response(
-       AppliedControlReadSerializer(controls, many=True).data,
-       status=status.HTTP_200_OK,
-   )
+   try:
+       controls = requirement_assessment.create_applied_controls_from_suggestions()
+       return Response(
+           AppliedControlReadSerializer(controls, many=True).data,
+           status=status.HTTP_200_OK,
+       )
+   except Exception as e:
+       logger.error(f"Error creating controls: {str(e)}")
+       return Response(
+           {"error": "Failed to create suggested controls"},
+           status=status.HTTP_500_INTERNAL_SERVER_ERROR
+       )
🧰 Tools
🪛 Ruff (0.8.2)

4211-4211: AppliedControlReadSerializer may be undefined, or defined from star imports

(F405)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 964c264 and 19a5716.

📒 Files selected for processing (4)
  • backend/core/views.py (2 hunks)
  • frontend/src/routes/(app)/(internal)/requirement-assessments/[id=uuid]/suggestions/applied-controls/+server.ts (1 hunks)
  • frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.server.ts (1 hunks)
  • frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.svelte (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
backend/core/views.py

4073-4073: AppliedControlReadSerializer may be undefined, or defined from star imports

(F405)


4211-4211: AppliedControlReadSerializer may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms (11)
  • GitHub Check: startup-functional-test (3.12)
  • GitHub Check: startup-docker-compose-test
  • GitHub Check: functional-tests (3.12, chromium)
  • GitHub Check: enterprise-startup-functional-test (3.12)
  • GitHub Check: enterprise-startup-docker-compose-test
  • GitHub Check: ruff (3.12)
  • GitHub Check: test (3.12)
  • GitHub Check: enterprise-functional-tests (3.12, chromium)
  • GitHub Check: build (3.12)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (2)
frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.svelte (1)

209-214:

✅ Verification successful

Added support for handling multiple new controls.

Good enhancement that handles an array of control IDs returned from the createSuggestedControls action. This allows multiple controls to be added to the UI state at once when creating controls from suggestions.

Let's check if there are other instances in the codebase that might need similar handling of multiple items:


🏁 Script executed:

#!/bin/bash
# Search for patterns where a single item is added to an array in form stores
rg "formStore.*push\(.*\.new" --type svelte

Length of output: 76


I'll now re-run the search using an updated command to target Svelte files by their extension:

This command should help us verify if there are other locations in the codebase using a similar pattern for adding controls. Please run this script and share the output so we can confirm whether additional changes are necessary or if the current handling can be considered complete.


🏁 Script executed:

#!/bin/bash
# Search for instances where formStore.applied_controls is updated with "push" in Svelte files
rg "formStore\.applied_controls\.push\(" -g "*.svelte"

Length of output: 461


Enhancement Verified: Multiple Controls Handling Implemented Correctly

The update correctly iterates over form.newControls to add each control to $formStore.applied_controls. Our search shows that aside from the unchanged single control update (form.newControl), no other parts of the codebase require similar adjustments. This confirms that the implementation adequately supports adding multiple controls without unintended side effects.

frontend/src/routes/(app)/(third-party)/requirement-assessments/[id=uuid]/edit/+page.server.ts (1)

303-303: Added proper error handling for failed API requests.

Good improvement to return a proper fail response with the form data when the API request to create suggested controls fails. This ensures the UI can handle the error state correctly.

@nas-tabchiche nas-tabchiche force-pushed the CA-848-create-controls-from-suggestions-in-requirement-assessments-does-not-update-the-auto-complete branch from 19a5716 to 316e8af Compare March 3, 2025 14:13
Copy link
Collaborator

@Mohamed-Hacene Mohamed-Hacene left a comment

Choose a reason for hiding this comment

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

0k

@Mohamed-Hacene Mohamed-Hacene merged commit d9b9f9a into main Mar 5, 2025
21 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Mar 5, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants