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

WIP - Directors individual sanctions #2980

Merged
merged 10 commits into from
Jan 23, 2025
Merged

WIP - Directors individual sanctions #2980

merged 10 commits into from
Jan 23, 2025

Conversation

Omri-Levy
Copy link
Contributor

@Omri-Levy Omri-Levy commented Jan 21, 2025

Summary by CodeRabbit

  • New Features

    • Added a new DirectorBlock component for managing director information.
    • Introduced new hooks and utilities for handling director-related tasks.
    • Enhanced document and workflow management capabilities.
    • Added support for more granular director document updates.
    • New schema and function for fetching end-user data by ID.
    • New custom hook useEndUserByIdQuery for fetching end-user details.
    • Introduced endUsersQueryKeys for managing query keys related to end users.
  • Improvements

    • Improved type safety and null handling in various components.
    • Refined document and workflow decision-making processes.
    • Added optional parameters for more flexible director management.
  • Bug Fixes

    • Added null safety checks in document and workflow-related functions.
    • Improved error handling in various service methods.
  • Refactoring

    • Restructured director and document-related hooks and components.
    • Simplified data transformation and schema handling.

Copy link

changeset-bot bot commented Jan 21, 2025

⚠️ No Changeset found

Latest commit: 9fb23d0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Jan 21, 2025

Walkthrough

This pull request introduces a new DirectorBlock component and associated hooks in the backoffice application, enhancing the management of director information and documents. The DirectorBlock component accepts various props related to directors and integrates with existing workflows. Additionally, new utility functions and hooks are created to facilitate document handling and decision-making processes, including optional directorId parameters in mutation hooks to improve task management. Overall, the changes aim to create a more structured and modular approach to handling director-related data.

Changes

File Change Summary
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/... New DirectorBlock component and supporting hooks for rendering director blocks with enhanced document management. Functions added for creating director blocks and adapting document structures.
apps/backoffice-v2/src/domains/entities/hooks/mutations/... Updated mutation hooks to support optional directorId for more precise task management related to document decisions.
services/workflows-service/src/workflow/... Modified workflow service and controllers to handle director-specific document updates and incorporate the new directorId parameter in various functions.

Sequence Diagram

sequenceDiagram
    participant User
    participant DirectorBlock
    participant WorkflowService
    participant EndUserService
    
    User->>DirectorBlock: Interact with director documents
    DirectorBlock->>WorkflowService: Request document update
    WorkflowService->>EndUserService: Create/Update end user
    WorkflowService-->>DirectorBlock: Return update status
    DirectorBlock->>User: Render updated document status
Loading

Suggested reviewers

  • tomer-shvadron
  • alonp99

Poem

🐰 Hop, hop, through director's lane,
Blocks of data, no more pain!
Mutations dance with grace and might,
Workflows bloom in CodeRabbit's light 🌟
Documents now sing their song! 📄

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

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. (Beta)
  • @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: 7

🔭 Outside diff range comments (1)
apps/backoffice-v2/src/lib/blocks/hooks/useDocumentPageImages/useDocumentPageImages.ts (1)

Line range hint 14-21: Enhance null safety handling

While the optional chaining for documents?.reduce is good, there are additional null safety improvements needed:

  1. The function should return an empty array if documents is null
  2. The type casting to DocumentPageImagesResult may fail if the reduce operation returns undefined
  3. Unsafe array access with filesCopy?.shift()

Consider this safer implementation:

-    const result = documents?.reduce((list: DocumentPageImagesResult, document, documentIndex) => {
+    if (!documents?.length) return [] as DocumentPageImagesResult;
+    
+    const result = documents.reduce((list: DocumentPageImagesResult, document, documentIndex) => {
       (document?.pages as AnyObject[])?.forEach((_, pageIndex: number) => {
         if (!list[documentIndex]) {
           list[documentIndex] = [];
         }
-        list[documentIndex][pageIndex] = filesCopy?.shift()?.data as string;
+        const nextFile = filesCopy.shift();
+        list[documentIndex][pageIndex] = nextFile?.data as string ?? '';
       });

       return list;
-    }, []) as DocumentPageImagesResult;
+    }, [] as DocumentPageImagesResult);
🧹 Nitpick comments (13)
apps/backoffice-v2/src/lib/blocks/hooks/useDocumentBlocks/useDocumentBlocks.tsx (1)

Line range hint 1-372: Consider breaking down the large hook into smaller, focused hooks

The useDocumentBlocks hook is handling multiple concerns:

  • Document state management
  • UI rendering logic
  • Action handlers
  • Decision management

This makes it harder to maintain and test. Consider splitting it into smaller, focused hooks:

  • useDocumentActions - for handling approve/reject/revision actions
  • useDocumentDecisions - for decision-related logic
  • useDocumentRendering - for UI block creation

Would you like me to help create a detailed plan for breaking down this hook into smaller, more manageable pieces?

apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx (4)

127-127: Remove unnecessary React Fragment

At line 127, the <React.Fragment> is unnecessary since it wraps a single child. You can simplify the code by removing the fragment.

Apply this diff to remove the unnecessary fragment:

-value: <React.Fragment>Pending re-upload</React.Fragment>,
+value: 'Pending re-upload',
🧰 Tools
🪛 Biome (1.9.4)

[error] 127-127: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)


144-151: Simplify JSX by removing redundant Fragment

Within lines 144-151, the <React.Fragment> wraps multiple elements, but since they are within an array, you can remove the fragment for cleaner code.

Apply this diff to remove the unnecessary fragment:

-                value: (
-                  <React.Fragment>
-                    Re-upload needed
-                    <X
-                      className="h-4 w-4 cursor-pointer"
-                      onClick={() => onRemoveDecision(document.id)}
-                    />
-                  </React.Fragment>
-                ),
+                value: [
+                  'Re-upload needed',
+                  <X
+                    key="remove-decision-icon"
+                    className="h-4 w-4 cursor-pointer"
+                    onClick={() => onRemoveDecision(document.id)}
+                  />,
+                ],

311-313: Redundant nullish coalescing operator

The use of the ?? operator on an object literal is unnecessary since the object spread will always result in an object. This means the ?? {} will never return the right-hand side.

Apply this diff to remove the redundant operator:

             data: Object.entries(
               {
                 ...additionalProperties,
                 ...document.propertiesSchema?.properties,
-              } ?? {},
+              },
             )?.map(
🧰 Tools
🪛 GitHub Actions: CI

[warning] 311-313: The "??" operator here will always return the left operand


85-420: Consider refactoring for better readability and maintainability

The useMemo hook from lines 85-420 contains deeply nested code with complex logic. Refactoring into smaller, reusable components or functions would improve readability and maintainability.

🧰 Tools
🪛 Biome (1.9.4)

[error] 127-127: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

🪛 GitHub Actions: CI

[warning] 311-313: The "??" operator here will always return the left operand

apps/backoffice-v2/src/domains/individuals/queries/useEndUserById/useEndUserById.tsx (2)

10-12: Consider strengthening the AML hits schema validation.

The schema allows for optional AML hits and vendor, which could lead to undefined behavior if the API response structure changes.

Consider adding more specific validation:

-  amlHits: z.array(HitSchema.extend({ vendor: z.string().optional() })).optional(),
+  amlHits: z.array(HitSchema.extend({ 
+    vendor: z.string().optional().describe('AML vendor name'),
+    timestamp: z.string().datetime().optional(),
+  })).default([]),

14-23: Consider adding retry logic for network failures.

The API call could fail due to network issues, and the current implementation doesn't handle retries.

Consider adding retry logic for transient failures:

 export const getEndUserById = async ({ id }: { id: string }) => {
   const [endUser, error] = await apiClient({
     endpoint: `end-users/${id}`,
     method: Method.GET,
     schema: EndUserSchema,
     timeout: 30_000,
+    retry: {
+      attempts: 3,
+      backoff: 'exponential',
+    },
   });

   return handleZodError(error, endUser);
 };
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/create-directors-blocks.tsx (1)

23-25: Consider adding validation for malformed director data.

The early return for empty directors array is good, but consider adding validation for malformed director objects.

 if (!directors?.length) {
   return [];
 }
+
+// Filter out malformed director objects
+const validDirectors = directors.filter(director => 
+  director && director.id && (director.firstName || director.lastName)
+);
+
+if (!validDirectors.length) {
+  console.warn('No valid directors found in the input array');
+  return [];
+}
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/DirectorBlock.tsx (1)

45-49: Add prop types validation for BlocksComponent children.

The component should validate the structure of the cells prop.

+import PropTypes from 'prop-types';

 return (
   <BlocksComponent blocks={directorBlock} cells={cells}>
     {(Cell, cell) => <Cell {...cell} />}
   </BlocksComponent>
 );

+BlocksComponent.propTypes = {
+  cells: PropTypes.arrayOf(
+    PropTypes.shape({
+      type: PropTypes.string.isRequired,
+      value: PropTypes.node.isRequired,
+    })
+  ).isRequired,
+};
services/workflows-service/src/workflow/utils/entities-update.ts (1)

61-63: Add logging for skipped directors.

Consider adding logging when skipping director creation to aid in debugging and monitoring.

 if ('ballerineEntityId' in director && director.ballerineEntityId) {
+  console.log(`Skipping director creation - existing ballerineEntityId: ${director.ballerineEntityId}`);
   return;
 }
services/workflows-service/src/collection-flow/controllers/collection-flow.controller.ts (1)

164-182: Consider batch processing for better performance.

Creating directors one by one might not be optimal for large datasets. Consider implementing batch creation.

+    // Batch create directors
+    const directorRecords = event.context.entity.data.additionalInfo.directors?.map(director => ({
+      firstName: director.firstName,
+      lastName: director.lastName,
+      email: director.email,
+      projectId: tokenScope.projectId,
+    }));
+
+    const createdDirectors = await this.endUserService.createMany({
+      data: directorRecords,
+    });
packages/workflow-core/src/lib/plugins/external-plugin/individuals-sanctions-v2-plugin/individuals-sanctions-v2-plugin.ts (1)

242-242: Add type checking for additionalInfo destructuring.

The default empty object prevents runtime errors, but consider adding type checking.

-          const { dateOfBirth } = additionalInfo ?? {};
+          const { dateOfBirth } = (additionalInfo ?? {}) as { dateOfBirth?: string };
apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx (1)

219-235: Consider error handling for missing document schemas.

While the code handles the case where no document schema is found for a country code by logging a warning, it might be better to handle this more robustly.

Consider this improvement:

  const documentSchemas = useMemo(() => {
    const issuerCountryCode = extractCountryCodeFromWorkflow(workflow);
    const documentsSchemas = issuerCountryCode ? getDocumentsByCountry(issuerCountryCode) : [];

    if (!Array.isArray(documentsSchemas) || !documentsSchemas.length) {
-     console.warn(`No document schema found for issuer country code of "${issuerCountryCode}".`);
+     const warning = `No document schema found for issuer country code of "${issuerCountryCode}".`;
+     console.warn(warning);
+     toast.warning(warning);
    }

    return documentsSchemas;
  }, [workflow]);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5ce73dc and fe2a5bf.

📒 Files selected for processing (21)
  • apps/backoffice-v2/src/domains/individuals/queries/useEndUserById/useEndUserById.tsx (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/DirectorBlock.tsx (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/create-directors-blocks.tsx (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/helpers.ts (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/index.ts (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorsCallToAction/helpers.ts (2 hunks)
  • apps/backoffice-v2/src/lib/blocks/hooks/useCaseInfoBlock/useCaseInfoBlock.tsx (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/hooks/useDirectorsBlocks/helpers.ts (0 hunks)
  • apps/backoffice-v2/src/lib/blocks/hooks/useDirectorsBlocks/index.ts (0 hunks)
  • apps/backoffice-v2/src/lib/blocks/hooks/useDirectorsBlocks/useDirectorsBlocks.tsx (0 hunks)
  • apps/backoffice-v2/src/lib/blocks/hooks/useDocumentBlocks/useDocumentBlocks.tsx (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/hooks/useDocumentPageImages/useDocumentPageImages.ts (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (2 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx (3 hunks)
  • packages/common/src/schemas/documents/merchant-screening-plugin-schema.ts (1 hunks)
  • packages/workflow-core/src/lib/plugins/external-plugin/individuals-sanctions-v2-plugin/individuals-sanctions-v2-plugin.ts (4 hunks)
  • packages/workflow-core/src/lib/workflow-runner.ts (3 hunks)
  • services/workflows-service/prisma/data-migrations (1 hunks)
  • services/workflows-service/src/collection-flow/controllers/collection-flow.controller.ts (4 hunks)
  • services/workflows-service/src/workflow/utils/entities-update.ts (1 hunks)
💤 Files with no reviewable changes (3)
  • apps/backoffice-v2/src/lib/blocks/hooks/useDirectorsBlocks/helpers.ts
  • apps/backoffice-v2/src/lib/blocks/hooks/useDirectorsBlocks/index.ts
  • apps/backoffice-v2/src/lib/blocks/hooks/useDirectorsBlocks/useDirectorsBlocks.tsx
✅ Files skipped from review due to trivial changes (2)
  • services/workflows-service/prisma/data-migrations
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/index.ts
🧰 Additional context used
🪛 GitHub Actions: CI
apps/backoffice-v2/src/lib/blocks/hooks/useDocumentBlocks/useDocumentBlocks.tsx

[warning] 372-374: The "??" operator here will always return the left operand

apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx

[warning] 311-313: The "??" operator here will always return the left operand

🪛 Biome (1.9.4)
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx

[error] 127-127: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

🔇 Additional comments (13)
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx (1)

373-375: Ensure correct usage of directorAdapter

At lines 373-375, the directorAdapter is immediately invoked with directorsStorageFilesQueryResult inside the map function. Verify that directorAdapter returns a function when called with directorsStorageFilesQueryResult.

Run the following script to confirm that directorAdapter returns a function:

✅ Verification successful

Correct usage of directorAdapter confirmed

The directorAdapter is correctly implemented as a curried function and is being used appropriately in the code. The first call with directorsStorageFilesQueryResult returns a function that is then used to process individual director data within the map function.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if 'directorAdapter' is used correctly.

# Test: Search for the definition of 'directorAdapter' to ensure it returns a function.
ast-grep --pattern $'const directorAdapter = ($_$) => ($_$) => { $$$ }' --lang ts

# Expected Result: Matches the 'directorAdapter' definition that returns a function.

Length of output: 82


Script:

#!/bin/bash
# Search for any occurrence of directorAdapter
rg "directorAdapter" -A 5 -B 5

# Also look specifically in the file where it's being used
cat "apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx"

Length of output: 23606

apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (2)

373-375: Verify correct usage of directorAdapter

At lines 373-375, similar to the previous file, ensure that directorAdapter is being used correctly and returns a function when called.


332-334: ⚠️ Potential issue

Missing dependency in useCallback hook

In the onMutateApproveTaskByIdDirectors function at lines 332-334, workflow?.id is used but not included in the dependency array. This could lead to stale references if workflow?.id changes.

Apply this diff to include workflow?.id in the dependency array:

 const onMutateApproveTaskByIdDirectors = useCallback(
     (documentId: string) => () =>
       mutateApproveTaskById({ documentId, contextUpdateMethod: 'director' }),
-    [mutateApproveTaskById],
+    [mutateApproveTaskById, workflow?.id],
 );

Likely invalid or redundant comment.

apps/backoffice-v2/src/lib/blocks/components/DirectorsCallToAction/helpers.ts (1)

Line range hint 5-27: Ensure default revision reasons are provided

In the updated getRevisionReasonsForDocument function, if none of the specific conditions match, the function returns revisionReasons. Ensure that revisionReasons is not undefined to avoid potential runtime errors.

If revisionReasons can be undefined, consider providing a default value or handling the undefined case.

Apply this diff to provide a default value:

 return revisionReasons || [];
apps/backoffice-v2/src/domains/individuals/queries/useEndUserById/useEndUserById.tsx (1)

32-39: LGTM! Well-structured query hook with proper authentication check.

The hook correctly checks for both ID presence and authentication status before enabling the query.

apps/backoffice-v2/src/lib/blocks/hooks/useCaseInfoBlock/useCaseInfoBlock.tsx (1)

19-23: LGTM! Defensive programming improvement.

The addition of optional chaining operators makes the code more robust by safely handling potentially undefined properties in the workflow object hierarchy.

services/workflows-service/src/workflow/utils/entities-update.ts (1)

61-63: LGTM! Prevents duplicate EndUser creation.

The check for existing ballerineEntityId prevents redundant processing and maintains data integrity.

packages/workflow-core/src/lib/plugins/external-plugin/individuals-sanctions-v2-plugin/individuals-sanctions-v2-plugin.ts (1)

48-52: Add validation for context assignment.

When assigning the entire context, consider adding validation to prevent potential security issues.

✅ Verification successful

Context assignment is properly validated and secure

The context assignment is safe as it's part of a comprehensive validation system:

  • The entire payload is validated through strict Zod schemas
  • The context data undergoes multiple validation layers before being used
  • The transformed data is validated before making API requests
  • The plugin implements type-safe KYC information handling

The '*' path pattern is a deliberate design choice for passing the full context when needed, and the implementation includes proper safeguards.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for sensitive information patterns in context assignments
rg -g '*.{ts,tsx}' "context\s*=\s*\*" -A 5

Length of output: 44


Script:

#!/bin/bash
# Search for context assignments in plugin files
rg -g '*.ts' -A 5 'acc\[.*\]\s*=\s*context' 

# Look for similar property.type === 'path' patterns
ast-grep --pattern 'if ($_ === "path") { $$$ }'

# Search for validation patterns around context
rg -g '*.ts' -B 3 -A 3 'validateContext|sanitize.*context|context.*validation'

Length of output: 1767


Script:

#!/bin/bash
# Search for workflow context types and interfaces
rg -g '*.ts' -B 2 -A 5 'interface.*Context|type.*Context'

# Look for the plugin's class definition and imports
ast-grep --pattern 'class IndividualsSanctionsV2Plugin {
  $$$
}'

# Search for plugin validation patterns
rg -g '*.ts' -B 2 -A 5 'validate.*Plugin|plugin.*validation'

Length of output: 45448


Script:

#!/bin/bash
# Search for the plugin's validation and schema
rg -g '*.ts' -B 3 -A 5 'IndividualsSanctionsV2Plugin.*schema|IndividualsSanctionsV2Plugin.*validate'

# Look for the plugin's property handling
ast-grep --pattern 'if (property.type === "path") {
  $$$
}'

Length of output: 165


Script:

#!/bin/bash
# Get the complete plugin file content
cat packages/workflow-core/src/lib/plugins/external-plugin/individuals-sanctions-v2-plugin/individuals-sanctions-v2-plugin.ts

# Search for similar property path handling patterns in other plugins
rg -g '*.ts' -B 3 -A 5 'property\.type\s*===\s*.(path|PATH).'

Length of output: 12822

packages/common/src/schemas/documents/merchant-screening-plugin-schema.ts (1)

92-99: Verify the impact of making the Country field optional.

The change makes the Country field optional in the DriversLicenseSchema. While this provides more flexibility, it's important to ensure that:

  1. This change aligns with business requirements for driver's license validation.
  2. Any code that consumes this schema can handle cases where the country code is not provided.

Run the following script to check for direct usage of this field:

✅ Verification successful

Making the Country field optional is safe to proceed

The verification shows that the Country field in DriversLicenseSchema is not directly used in merchant screening validation logic. The merchant screening implementation sources country data from the entity's address information, making this change safe to implement.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for direct usage of the Country field from DriversLicenseSchema
# Test: Search for code that might be affected by this field becoming optional

# Look for direct property access
rg -A 5 "DriversLicense.*Country" 

# Look for potential validation logic
rg -A 5 "Country.*ISO.*3166"

# Look for schema validation code
ast-grep --pattern 'validate($_, { Country: $_ })'

Length of output: 119


Script:

#!/bin/bash
# Search for files importing or using the merchant screening plugin schema
rg -l "merchant-screening-plugin-schema"

# Look for merchant screening related files and validation logic
rg -l "merchantScreening|merchant.*screening"

# Search for country code validation patterns in TypeScript/JavaScript files
fd -e ts -e js --exec rg -l "countryCode|country.*code|ISO.*3166"

# Look for type definitions or interfaces using this schema
ast-grep --pattern 'import { $_ } from "./merchant-screening-plugin-schema"'
ast-grep --pattern 'type $_ = { Country?: string }'

Length of output: 3597


Script:

#!/bin/bash
# Check how the schema is used in default context
cat packages/common/src/schemas/documents/default-context-schema.ts

# Look for any direct Country field validation in merchant screening plugin
cat packages/workflow-core/src/lib/plugins/external-plugin/mastercard-merchant-screening-plugin.ts

Length of output: 7227

apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx (2)

171-217: LGTM! Well-structured mutation handlers for director actions.

The implementation follows a clean pattern of separating mutation handlers for different director-related actions (revision, approval, decision removal). Each handler correctly uses the 'director' context update method.


236-248: LGTM! Comprehensive director blocks configuration.

The createDirectorsBlocks call is well-structured with all necessary props for handling director-related functionality, including proper loading states and permissions.

packages/workflow-core/src/lib/workflow-runner.ts (2)

306-306: LGTM! Improved type safety.

The return type has been updated to explicitly omit 'actionPluginName' from IterativePluginParams, which better reflects the actual structure of the returned object.


321-325: LGTM! Added runtime validation for action plugin existence.

Good addition of an invariant check to ensure the action plugin exists before proceeding. This provides better error messages and fail-fast behavior when an action plugin is missing.

@Omri-Levy Omri-Levy changed the title Directors individual sanctions WIP - Directors individual sanctions Jan 21, 2025
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 (1)
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (1)

373-389: Consider extracting shared transformation logic.

The director data transformation and document schema retrieval logic is duplicated between useKybExampleBlocksLogic and useDefaultBlocksLogic. Consider extracting this into a shared utility function.

Create a new utility file getDirectorDocumentSchemas.ts:

import { TWorkflowById } from '@/domains/workflows/fetchers';
import { getDocumentsByCountry } from '@ballerine/common';
import { extractCountryCodeFromWorkflow } from '@/pages/Entity/hooks/useEntityLogic/utils';

export const getDirectorDocumentSchemas = (workflow: TWorkflowById | undefined) => {
  const issuerCountryCode = extractCountryCodeFromWorkflow(workflow);
  const documentsSchemas = issuerCountryCode ? getDocumentsByCountry(issuerCountryCode) : [];

  if (!Array.isArray(documentsSchemas) || !documentsSchemas.length) {
    console.warn(`No document schema found for issuer country code of "${issuerCountryCode}".`);
  }

  return documentsSchemas;
};
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fe2a5bf and d6c5257.

📒 Files selected for processing (2)
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (2 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: test_windows
  • GitHub Check: test_linux
  • GitHub Check: build (windows-latest)
  • GitHub Check: lint
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (6)
apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx (3)

17-17: LGTM! Well-organized imports.

The new imports are properly organized and necessary for the enhanced director-related functionality.

Also applies to: 31-35


219-235: LGTM! Clean data transformation with proper error handling.

The director data transformation and document schema retrieval are well-implemented with appropriate warning messages for edge cases.


236-248: Address the TODO comment about callToActionLegacy.

The code includes a TODO comment about removing callToActionLegacy. Please create a follow-up task to handle this technical debt.

Would you like me to create an issue to track the removal of callToActionLegacy?

apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (3)

60-65: LGTM! Consistent imports.

The imports are consistent with the changes in useKybExampleBlocksLogic.tsx.


332-371: LGTM! Well-structured task management callbacks.

The callbacks are focused and handle their specific tasks (revision, approval, decision removal) without side effects.


390-402: LGTM! Consistent director blocks configuration.

The configuration is consistent with the implementation in useKybExampleBlocksLogic.tsx.

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: 0

♻️ Duplicate comments (2)
services/workflows-service/src/collection-flow/controllers/collection-flow.controller.ts (2)

154-170: ⚠️ Potential issue

Add error handling for individual end user creation

The current implementation might fail silently if creation of a single director or UBO fails.

Also applies to: 174-190


154-170: 🛠️ Refactor suggestion

Add input validation for director and UBO data

The director and UBO object structures are assumed but not validated.

Also applies to: 174-190

🧹 Nitpick comments (4)
apps/backoffice-v2/src/pages/Entity/hooks/useEntityLogic/utils.ts (2)

69-72: Add documentation and improve error handling.

While the function logic is correct, consider these improvements for better maintainability and reliability:

  1. Add JSDoc documentation to clarify the function's purpose, parameters, and return value
  2. Add input validation for the documents array
  3. Consider handling the case when no document has an issuer country

Here's a suggested implementation:

+/**
+ * Extracts the country code from the first document that has an issuer country
+ * @param documents - Array of documents to search through
+ * @returns The country code if found, undefined otherwise
+ */
 export const extractCountryCodeFromDocuments = (documents: TDocument[]) => {
+  if (!Array.isArray(documents)) {
+    throw new Error('Expected documents to be an array');
+  }
+
   return documents?.find(document => {
     return !!document?.issuer?.country;
   })?.issuer?.country;
 };

69-72: Consider adding type safety for the return value.

The function could benefit from stronger typing and validation of the country value.

Consider using a type for valid country codes and adding validation:

type CountryCode = string; // Replace with your actual country code type

export const extractCountryCodeFromDocuments = (documents: TDocument[]): CountryCode | undefined => {
  const document = documents?.find(doc => !!doc?.issuer?.country);
  const country = document?.issuer?.country;
  
  // Add validation if you have a specific format for country codes
  return country;
};
services/workflows-service/src/collection-flow/controllers/collection-flow.controller.ts (2)

154-170: Extract shared logic for creating end users

The code for creating directors and UBOs contains duplicated logic. Consider extracting this into a shared helper method.

+  private async createEndUser(
+    data: { firstName: string; lastName: string; email: string },
+    projectId: string,
+  ) {
+    const { id } = await this.endUserService.create({
+      data: {
+        firstName: data.firstName,
+        lastName: data.lastName,
+        email: data.email,
+        projectId,
+      },
+    });
+
+    return {
+      ballerineEntityId: id,
+      ...data,
+    };
+  }

   async finalSubmission(@TokenScope() tokenScope: ITokenScope, @common.Body() body: FinishFlowDto) {
     // ...
     const directors = await Promise.all(
-      workflowRuntimeData.context.entity.data.additionalInfo.directors?.map(
-        async (director: { firstName: string; lastName: string; email: string }) => {
-          const { id } = await this.endUserService.create({
-            data: {
-              firstName: director.firstName,
-              lastName: director.lastName,
-              email: director.email,
-              projectId: tokenScope.projectId,
-            },
-          });
-
-          return {
-            ballerineEntityId: id,
-            ...director,
-          };
-        },
-      ),
+      workflowRuntimeData.context.entity.data.additionalInfo.directors?.map(director =>
+        this.createEndUser(director, tokenScope.projectId),
+      ),
     );

     const ubos = await Promise.all(
-      workflowRuntimeData.context.entity.data.additionalInfo.ubos?.map(
-        async (ubo: { firstName: string; lastName: string; email: string }) => {
-          const { id } = await this.endUserService.create({
-            data: {
-              firstName: ubo.firstName,
-              lastName: ubo.lastName,
-              email: ubo.email,
-              projectId: tokenScope.projectId,
-            },
-          });
-
-          return {
-            ballerineEntityId: id,
-            ...ubo,
-          };
-        },
-      ),
+      workflowRuntimeData.context.entity.data.additionalInfo.ubos?.map(ubo =>
+        this.createEndUser(ubo, tokenScope.projectId),
+      ),
     );

Also applies to: 174-190


154-155: Define proper interfaces for director and UBO types

Instead of using inline type annotations, define proper interfaces for better type safety and reusability.

interface EndUserData {
  firstName: string;
  lastName: string;
  email: string;
}

interface DirectorData extends EndUserData {
  // Add director-specific fields if any
}

interface UboData extends EndUserData {
  // Add UBO-specific fields if any
}

Also applies to: 174-175

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d6c5257 and 7007f16.

📒 Files selected for processing (9)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/create-directors-blocks.tsx (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/helpers.ts (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/hooks/useDocumentBlocks/useDocumentBlocks.tsx (2 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (2 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx (3 hunks)
  • apps/backoffice-v2/src/pages/Entity/hooks/useEntityLogic/utils.ts (1 hunks)
  • services/workflows-service/src/collection-flow/controllers/collection-flow.controller.ts (4 hunks)
  • services/workflows-service/src/workflow/utils/entities-update.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • services/workflows-service/src/workflow/utils/entities-update.ts
  • apps/backoffice-v2/src/lib/blocks/hooks/useDocumentBlocks/useDocumentBlocks.tsx
👮 Files not reviewed due to content moderation or server errors (5)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/helpers.ts
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/create-directors-blocks.tsx
  • apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx

[error] 130-130: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: test_linux
  • GitHub Check: test_windows
  • GitHub Check: build (windows-latest)
🔇 Additional comments (2)
services/workflows-service/src/collection-flow/controllers/collection-flow.controller.ts (2)

22-22: LGTM - Clean dependency injection

The EndUserService is properly imported and injected following NestJS dependency injection patterns.

Also applies to: 33-33


193-213: LGTM - Proper context update with array replacement

The workflow context update correctly uses the REPLACE array merge option to update the directors and UBOs data.

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: 2

🧹 Nitpick comments (9)
apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx (1)

221-228: Consider performance and type safety improvements.

  1. Memoize the directors transformation to prevent unnecessary recalculations on re-renders.
  2. Add type safety for the revision reasons extraction.

Apply this diff to implement the suggestions:

+ const directors = useMemo(
+   () =>
+     workflow?.context?.entity?.data?.additionalInfo?.directors?.map(
+       directorAdapter(directorsDocumentPagesResults),
+     ),
+   [workflow?.context?.entity?.data?.additionalInfo?.directors, directorsDocumentPagesResults],
+ );

+ type RevisionReason = {
+   enum?: string[];
+   [key: string]: unknown;
+ };

  const revisionReasons =
-   workflow?.workflowDefinition?.contextSchema?.schema?.properties?.documents?.items?.properties?.decision?.properties?.revisionReason?.anyOf?.find(
-     ({ enum: enum_ }) => !!enum_,
-   )?.enum ?? [];
+   workflow?.workflowDefinition?.contextSchema?.schema?.properties?.documents?.items?.properties?.decision?.properties?.revisionReason?.anyOf?.find(
+     ({ enum: enum_ }: RevisionReason) => !!enum_,
+   )?.enum ?? [];
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx (1)

139-139: Remove unnecessary React.Fragment

At line 139, the React.Fragment wraps only a single child, making it redundant. You can simplify the code by removing it.

Apply this diff to remove the unnecessary React.Fragment:

-                  value: <React.Fragment>Pending re-upload</React.Fragment>,
+                  value: 'Pending re-upload',
🧰 Tools
🪛 Biome (1.9.4)

[error] 139-139: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (1)

330-332: Add error handling for undefined workflow ID.

While the mutation hooks are correctly initialized, consider adding error handling for when workflow?.id is undefined. Also, consider tracking the loading state for mutateRemoveDecisionTaskById as you do with mutateApproveTaskById.

-  const { mutate: mutateRemoveDecisionTaskById } = useRemoveDecisionTaskByIdMutation(workflow?.id);
+  const { mutate: mutateRemoveDecisionTaskById, isLoading: isLoadingRemoveDecision } = 
+    useRemoveDecisionTaskByIdMutation(workflow?.id);
+  
+  if (!workflow?.id) {
+    throw new Error('Workflow ID is required for director task management');
+  }
apps/backoffice-v2/src/domains/entities/hooks/mutations/useRevisionTaskByIdMutation/useRevisionTaskByIdMutation.tsx (2)

18-18: Consider enhancing error handling

While directorId has been added consistently with other mutation hooks, consider including it in error messages to help with debugging director-specific issues.

  onError: (_error, variables, context) => {
    const workflowById = workflowsQueryKeys.byId({ workflowId: variables?.workflowId, filterId });

    toast.error(
      t(`toast:ask_revision_document.error`, {
        errorMessage: _error.message,
+       directorId: variables?.directorId,
      }),
    );

    queryClient.setQueryData(workflowById.queryKey, context.previousWorkflow);
  },

Also applies to: 24-24, 32-32


16-35: Consider implementing a shared type for mutation parameters

All three mutation hooks (useApproveTaskByIdMutation, useRemoveDecisionTaskByIdMutation, and useRevisionTaskByIdMutation) share similar parameter structures with directorId. Consider creating a shared type to maintain consistency and reduce duplication.

Create a new type in a shared location:

type DocumentDecisionMutationParams = {
  documentId: string;
  directorId?: string;
  contextUpdateMethod?: 'base' | 'director';
  // Add other common parameters
};

Then use it in all mutation hooks:

mutationFn: ({
  directorId,
  documentId,
  contextUpdateMethod,
  ...rest
}: DocumentDecisionMutationParams & {
  // Add hook-specific parameters
}) => {
  // Mutation logic
}
apps/backoffice-v2/src/domains/workflows/fetchers.ts (1)

303-303: LGTM! Consider using a type alias for the decision body.

The addition of the optional directorId parameter is well-placed. To improve type safety and reusability, consider extracting the decision body type into a separate type alias.

type WorkflowDecisionBody = {
  decision: string | null;
  directorId?: string;
  reason?: string;
  comment?: string;
};
services/workflows-service/src/workflow/workflow.controller.internal.ts (1)

294-294: Consider adding parameter validation.

While the directorId is properly passed to the service layer, consider adding validation to ensure it's a valid UUID or matches the expected format when present.

if (directorId && !isValidUUID(directorId)) {
  throw new BadRequestException('Invalid director ID format');
}
services/workflows-service/src/workflow/workflow.service.ts (2)

1125-1127: Enhance the error message for better debugging.

While the validation is good, the error message could be more specific by including the workflow ID and document ID in the message.

if (!directorId) {
  throw new BadRequestException(
    `Attempted to update director document without a director id. WorkflowId: ${workflowId}, DocumentId: ${documentId}`,
  );
}

1144-1156: Add type safety to director filtering.

The director filtering logic works correctly but could benefit from proper type definitions. Consider adding interfaces for the director structure.

interface Director {
  ballerineEntityId: string;
  additionalInfo?: {
    documents?: Array<{
      id: string;
      [key: string]: unknown;
    }>;
  };
}

private getDirectorsDocuments(
  context: WorkflowRuntimeData['context'],
  directorId?: string,
): Array<Director['additionalInfo']['documents'][number]> {
  return (
    this.getDirectors(context)
      .filter((director: Director) => {
        if (!directorId) return true;
        return director.ballerineEntityId === directorId;
      })
      .map(director => director.additionalInfo?.documents)
      .filter(Boolean)
      .flat() || []
  );
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7007f16 and 497154b.

📒 Files selected for processing (11)
  • apps/backoffice-v2/src/domains/entities/hooks/mutations/useApproveTaskByIdMutation/useApproveTaskByIdMutation.tsx (2 hunks)
  • apps/backoffice-v2/src/domains/entities/hooks/mutations/useRemoveDecisionTaskByIdMutation/useRemoveDecisionTaskByIdMutation.tsx (1 hunks)
  • apps/backoffice-v2/src/domains/entities/hooks/mutations/useRevisionTaskByIdMutation/useRevisionTaskByIdMutation.tsx (1 hunks)
  • apps/backoffice-v2/src/domains/workflows/fetchers.ts (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/helpers.ts (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (2 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx (3 hunks)
  • services/workflows-service/src/workflow/dtos/document-decision-update-input.ts (1 hunks)
  • services/workflows-service/src/workflow/workflow.controller.internal.ts (1 hunks)
  • services/workflows-service/src/workflow/workflow.service.ts (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/helpers.ts
🧰 Additional context used
🪛 Biome (1.9.4)
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx

[error] 139-139: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: test_windows
  • GitHub Check: test_linux
  • GitHub Check: build (windows-latest)
🔇 Additional comments (11)
apps/backoffice-v2/src/lib/blocks/variants/KybExampleBlocks/hooks/useKybExampleBlocksLogic/useKybExampleBlocksLogic.tsx (4)

17-17: LGTM! Well-organized imports.

The new imports are logically grouped and properly scoped to their respective functionalities.

Also applies to: 31-35


175-209: Add URL validation before window.open.

The onMutateRevisionTaskByIdDirectors callback opens a new window without validating the URL. This could lead to errors if collectionFlowUrl or token is undefined.


210-219: LGTM! Well-structured mutation callbacks.

The approve and remove decision callbacks are concise, properly typed, and correctly use the 'director' context update method.


229-241: LGTM! Well-structured director blocks creation.

The director blocks are created with comprehensive props, including all necessary callbacks, state flags, and configuration options.

apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/hooks/useDirectorBlock/useDirectorBlock.tsx (1)

1-460: Consider refactoring to improve maintainability

This file is quite long, which may affect readability and maintenance. Consider extracting reusable components or logic into separate files, such as the "Re-upload needed" badge component.

🧰 Tools
🪛 Biome (1.9.4)

[error] 139-139: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (2)

60-62: LGTM! Clean imports for director document management.

The new imports are well-organized and properly scoped to handle director-specific task management.


373-391: Track technical debt: Remove legacy code.

The code contains a TODO comment about removing callToActionLegacy. Consider creating a tracking issue to handle this technical debt.

Would you like me to create an issue to track the removal of the callToActionLegacy dependency?

Also, verify that all required properties are properly typed in the createDirectorsBlocks parameters.

✅ Verification successful

Technical debt is already being tracked across the codebase

The callToActionLegacy deprecation is already being tracked with consistent TODO comments across multiple files. The codebase shows evidence of an ongoing migration from callToActionLegacy to a new CallToAction component, with the legacy version marked for removal in:

  • DirectorBlock component
  • DefaultBlocks logic
  • KybExampleBlocks logic
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the type definition of createDirectorsBlocks
ast-grep --pattern 'interface $interface {
  $$$
  callToActionLegacy?: $type;
  $$$
}'

Length of output: 89


Script:

#!/bin/bash
# Search for callToActionLegacy usage and createDirectorsBlocks definition
rg "callToActionLegacy" -A 2 -B 2
ast-grep --pattern 'function createDirectorsBlocks($params) {
  $$$
}'

Length of output: 4558

apps/backoffice-v2/src/domains/entities/hooks/mutations/useRemoveDecisionTaskByIdMutation/useRemoveDecisionTaskByIdMutation.tsx (1)

16-16: Verify if directorId affects UI state

The directorId parameter has been added to the mutation, but the optimistic update in onMutate doesn't reflect any changes related to it. Please verify if directorId affects the UI state and whether it needs to be handled in the optimistic update.

Also applies to: 20-20, 27-27

✅ Verification successful

Optimistic update implementation is correct

The directorId is only used to track which director performed the action in the API context and doesn't affect the immediate UI state. The optimistic update correctly focuses on nullifying the decision status fields, which are the only UI-relevant changes when removing a decision task.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for UI components or state management code that might be affected by directorId
rg -g '*.tsx' -g '*.ts' -l 'directorId.*decision' apps/backoffice-v2/src/

Length of output: 75


Script:

#!/bin/bash
# Search for directorId usages in the codebase
echo "=== DirectorId usages ==="
rg -g '*.{tsx,ts}' 'directorId' apps/backoffice-v2/src/

echo -e "\n=== Decision task related files ==="
rg -g '*.{tsx,ts}' -l 'DecisionTask' apps/backoffice-v2/src/

echo -e "\n=== Mutation implementation ==="
cat apps/backoffice-v2/src/domains/entities/hooks/mutations/useRemoveDecisionTaskByIdMutation/useRemoveDecisionTaskByIdMutation.tsx

Length of output: 8217

apps/backoffice-v2/src/domains/entities/hooks/mutations/useApproveTaskByIdMutation/useApproveTaskByIdMutation.tsx (1)

16-16: Consider updating optimistic update logic

While directorId has been added to the mutation parameters and API call, the optimistic update in onMutate doesn't handle this new field. If directorId affects the UI state (e.g., showing which director approved), the optimistic update should be enhanced to maintain UI consistency.

Also applies to: 21-21, 30-30

services/workflows-service/src/workflow/workflow.service.ts (2)

823-830: LGTM! Parameter additions are consistent.

The directorId parameter is consistently added across the method signatures, maintaining proper type safety with the optional modifier.


908-908: LGTM! Proper parameter propagation.

The directorId is correctly passed through the document update chain, maintaining consistency in the workflow.

Also applies to: 930-930

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: 0

♻️ Duplicate comments (1)
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/DirectorBlock.tsx (1)

22-29: ⚠️ Potential issue

Add loading and error states for end user data fetching.

The component doesn't handle loading or error states from the useEndUserByIdQuery hook.

🧹 Nitpick comments (3)
apps/backoffice-v2/src/domains/individuals/queries/useEndUserByIdQuery/useEndUserByIdQuery.tsx (1)

8-11: Consider adding staleTime configuration for performance optimization.

While the implementation is correct, adding a staleTime configuration could optimize performance by reducing unnecessary refetches of relatively static end-user data.

 return useQuery({
   ...endUsersQueryKeys.byId({ id }),
   enabled: !!id && isAuthenticated,
+  staleTime: 5 * 60 * 1000, // 5 minutes
 });
apps/backoffice-v2/src/domains/individuals/fetchers.ts (1)

11-13: Strengthen the validation for amlHits array.

Consider adding more strict validation for the amlHits array to ensure data integrity and type safety.

 export const EndUserSchema = z.object({
-  amlHits: z.array(HitSchema.extend({ vendor: z.string().optional() })).optional(),
+  amlHits: z
+    .array(
+      HitSchema.extend({
+        vendor: z.string().min(1).optional(),
+      }),
+    )
+    .default([]),
 });
apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/DirectorBlock.tsx (1)

46-48: Consider memoizing the Cell render function.

The Cell render function could be memoized to prevent unnecessary re-renders.

+ const renderCell = React.useCallback((Cell, cell) => <Cell {...cell} />, []);
  return (
    <BlocksComponent blocks={directorBlock} cells={cells}>
-     {(Cell, cell) => <Cell {...cell} />}
+     {renderCell}
    </BlocksComponent>
  );
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 497154b and 7088d4f.

📒 Files selected for processing (4)
  • apps/backoffice-v2/src/domains/individuals/fetchers.ts (1 hunks)
  • apps/backoffice-v2/src/domains/individuals/queries/useEndUserByIdQuery/useEndUserByIdQuery.tsx (1 hunks)
  • apps/backoffice-v2/src/domains/individuals/query-keys.ts (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/DirectorBlock.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: build (windows-latest)
  • GitHub Check: test_windows
  • GitHub Check: test_linux
  • GitHub Check: Analyze (javascript)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: lint
🔇 Additional comments (2)
apps/backoffice-v2/src/domains/individuals/query-keys.ts (1)

4-9: LGTM! Well-structured query key factory implementation.

The query key structure follows React Query best practices, with proper separation of concerns between key generation and data fetching.

apps/backoffice-v2/src/lib/blocks/components/DirectorBlock/DirectorBlock.tsx (1)

23-29: 🛠️ Refactor suggestion

Make aml object construction more robust.

The current implementation could lead to undefined values being passed down. Consider providing default values and type safety.

 const directorWithAml = {
   ...director,
   aml: {
-    vendor: endUser?.amlHits?.find(({ vendor }) => !!vendor)?.vendor,
-    hits: endUser?.amlHits,
+    vendor: endUser?.amlHits?.find(({ vendor }) => !!vendor)?.vendor ?? null,
+    hits: endUser?.amlHits ?? [],
   },
 };

Likely invalid or redundant comment.

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: 0

♻️ Duplicate comments (1)
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (1)

360-369: ⚠️ Potential issue

Add error handling and loading state feedback.

The approval and removal callbacks need error handling and loading state feedback, as previously suggested.

Apply this diff to improve error handling:

  const onMutateApproveTaskByIdDirectors = useCallback(
-    ({ directorId, documentId }: { directorId: string; documentId: string }) =>
-      mutateApproveTaskById({ directorId, documentId, contextUpdateMethod: 'director' }),
+    ({ directorId, documentId }: { directorId: string; documentId: string }) => {
+      if (!directorId || !documentId) {
+        toast.error('Invalid director or document id');
+        return;
+      }
+      toast.loading('Approving document...');
+      mutateApproveTaskById({ 
+        directorId, 
+        documentId, 
+        contextUpdateMethod: 'director' 
+      }).catch(error => {
+        toast.error(`Failed to approve document: ${error.message}`);
+      });
+    },
    [mutateApproveTaskById],
  );

  const onMutateRemoveDecisionTaskByIdDirectors = useCallback(
-    ({ directorId, documentId }: { directorId: string; documentId: string }) =>
-      mutateRemoveDecisionTaskById({ directorId, documentId, contextUpdateMethod: 'director' }),
+    ({ directorId, documentId }: { directorId: string; documentId: string }) => {
+      if (!directorId || !documentId) {
+        toast.error('Invalid director or document id');
+        return;
+      }
+      toast.loading('Removing decision...');
+      mutateRemoveDecisionTaskById({ 
+        directorId, 
+        documentId, 
+        contextUpdateMethod: 'director' 
+      }).catch(error => {
+        toast.error(`Failed to remove decision: ${error.message}`);
+      });
+    },
    [mutateRemoveDecisionTaskById],
  );
🧹 Nitpick comments (3)
packages/workflow-core/src/lib/workflow-runner.ts (1)

321-322: Consider improving type safety.

The @ts-expect-error comment could be avoided by properly typing the params parameter.

-  // @ts-expect-error -- params is type unknown, changing it would mean updating multiple places
-  invariant(
+  invariant<{actionPluginName?: string}>(
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (2)

328-331: Consider adding loading state for removeDecision mutation.

While mutateApproveTaskById tracks its loading state, mutateRemoveDecisionTaskById doesn't. Consider adding loading state tracking for consistency and to prevent potential race conditions.

-  const { mutate: mutateRemoveDecisionTaskById } = useRemoveDecisionTaskByIdMutation(workflow?.id);
+  const { mutate: mutateRemoveDecisionTaskById, isLoading: isLoadingRemoveDecisionTaskById } = 
+    useRemoveDecisionTaskByIdMutation(workflow?.id);

374-377: Simplify revision reasons extraction.

The nested property access with optional chaining could be simplified using the nullish coalescing operator.

-  const revisionReasons =
-    workflow?.workflowDefinition?.contextSchema?.schema?.properties?.documents?.items?.properties?.decision?.properties?.revisionReason?.anyOf?.find(
-      ({ enum: enum_ }) => !!enum_,
-    )?.enum ?? [];
+  const revisionReasons = workflow?.workflowDefinition?.contextSchema?.schema?.properties?.documents
+    ?.items?.properties?.decision?.properties?.revisionReason?.anyOf
+    ?.find(({ enum: enum_ }) => !!enum_)
+    ?.enum ?? [];
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 99141fa and 6d031db.

📒 Files selected for processing (3)
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (2 hunks)
  • packages/workflow-core/src/lib/plugins/external-plugin/individuals-sanctions-v2-plugin/individuals-sanctions-v2-plugin.ts (3 hunks)
  • packages/workflow-core/src/lib/workflow-runner.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/workflow-core/src/lib/plugins/external-plugin/individuals-sanctions-v2-plugin/individuals-sanctions-v2-plugin.ts
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: test_windows
  • GitHub Check: test_linux
  • GitHub Check: Analyze (javascript)
  • GitHub Check: build (windows-latest)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: lint
  • GitHub Check: spell_check
🔇 Additional comments (4)
packages/workflow-core/src/lib/workflow-runner.ts (3)

69-69: LGTM! Good choice of assertion library.

The addition of invariant from 'outvariant' is appropriate for runtime assertions, being both lightweight and tree-shakeable.


306-306: LGTM! Improved type safety.

The return type modification correctly removes 'actionPluginName' from the return type as it's only used internally to find the action plugin.


321-325: LGTM! Good defensive programming.

The invariant check ensures early failure with a descriptive error message when an action plugin is not found, preventing potential runtime errors.

apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useDefaultBlocksLogic/useDefaultBlocksLogic.tsx (1)

60-63: LGTM! Well-organized imports.

The new imports for director-related functionality are properly structured and follow the project's conventions.

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: 2

🧹 Nitpick comments (1)
packages/workflow-core/src/lib/plugins/external-plugin/shared/get-payload-properties-value.ts (1)

Line range hint 11-14: Update Documentation to Include New Functionality

The JSDoc comment should be updated to document the new '*' special case and its implications.

 /**
  * Get the value of the properties in the payload depending on the type of the property i.e. 'literal' or 'path'
+ * @param properties - The properties object containing type information and values
+ * @param properties[key].__type - The type of the property
+ * @param properties[key].value - The value or path. Use '*' to get the entire context (use with caution)
  * @param context
+ * @returns A new object with resolved property values
+ * @example
+ * // Get specific property
+ * getPayloadPropertiesValue({
+ *   properties: { name: { __type: 'path', value: 'user.name' } },
+ *   context: { user: { name: 'John' } }
+ * }) // => { name: 'John' }
+ * 
+ * // Get entire context
+ * getPayloadPropertiesValue({
+ *   properties: { data: { __type: 'path', value: '*' } },
+ *   context: { user: { name: 'John' } }
+ * }) // => { data: { user: { name: 'John' } } }
  */
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6d031db and 4a7299e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (21)
  • apps/backoffice-v2/CHANGELOG.md (1 hunks)
  • apps/backoffice-v2/package.json (2 hunks)
  • apps/kyb-app/CHANGELOG.md (1 hunks)
  • apps/kyb-app/package.json (2 hunks)
  • examples/headless-example/CHANGELOG.md (1 hunks)
  • examples/headless-example/package.json (2 hunks)
  • packages/common/CHANGELOG.md (1 hunks)
  • packages/common/package.json (1 hunks)
  • packages/workflow-core/CHANGELOG.md (1 hunks)
  • packages/workflow-core/package.json (2 hunks)
  • packages/workflow-core/src/lib/plugins/external-plugin/shared/get-payload-properties-value.ts (1 hunks)
  • sdks/web-ui-sdk/CHANGELOG.md (1 hunks)
  • sdks/web-ui-sdk/package.json (2 hunks)
  • sdks/workflow-browser-sdk/CHANGELOG.md (1 hunks)
  • sdks/workflow-browser-sdk/package.json (2 hunks)
  • sdks/workflow-node-sdk/CHANGELOG.md (1 hunks)
  • sdks/workflow-node-sdk/package.json (2 hunks)
  • services/workflows-service/CHANGELOG.md (1 hunks)
  • services/workflows-service/package.json (2 hunks)
  • services/workflows-service/prisma/data-migrations (1 hunks)
  • websites/docs/package.json (1 hunks)
✅ Files skipped from review due to trivial changes (16)
  • websites/docs/package.json
  • packages/common/package.json
  • packages/common/CHANGELOG.md
  • packages/workflow-core/CHANGELOG.md
  • sdks/workflow-node-sdk/package.json
  • sdks/workflow-browser-sdk/CHANGELOG.md
  • sdks/web-ui-sdk/CHANGELOG.md
  • sdks/workflow-node-sdk/CHANGELOG.md
  • sdks/workflow-browser-sdk/package.json
  • services/workflows-service/package.json
  • apps/backoffice-v2/package.json
  • apps/kyb-app/CHANGELOG.md
  • examples/headless-example/CHANGELOG.md
  • examples/headless-example/package.json
  • apps/backoffice-v2/CHANGELOG.md
  • services/workflows-service/CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • services/workflows-service/prisma/data-migrations
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: test_windows
  • GitHub Check: test_linux
  • GitHub Check: build (windows-latest)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: lint
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: spell_check
🔇 Additional comments (3)
sdks/web-ui-sdk/package.json (2)

24-24: LGTM: Version bump follows semantic versioning.

The increment from 1.5.69 to 1.5.70 is appropriate for a patch release.


99-99: Verify compatibility with the updated common package.

The @ballerine/common dependency has been updated to version 0.9.69.

Let's verify the compatibility and changelog of the updated package:

apps/kyb-app/package.json (1)

4-4: Verify dependency updates and their implications.

The version updates look correct and follow semantic versioning:

  • Package version: 0.3.1140.3.115
  • Dependencies:
    • @ballerine/common: ^0.9.68^0.9.69
    • @ballerine/workflow-browser-sdk: 0.6.870.6.88

Let's verify the dependency updates and their implications:

Also applies to: 20-21

✅ Verification successful

Version updates are consistent and backward compatible

The dependency updates in kyb-app are properly synchronized:

  • All direct dependencies are on their latest versions
  • Version increments are patch-level updates, indicating backward compatibility
  • Caret versioning (^) ensures compatibility with future patch and minor updates
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for dependency version consistency and potential breaking changes

# Check workflow-browser-sdk versions
echo "workflow-browser-sdk versions:"
fd package.json | xargs jq -r 'select(.dependencies?."@ballerine/workflow-browser-sdk"?) | "\(.name): \(.dependencies."@ballerine/workflow-browser-sdk")"'

# Check if there are any breaking changes in the recent commits
echo -e "\nRecent commits in common package:"
git log --oneline -n 5 -- packages/common/

echo -e "\nRecent commits in workflow-browser-sdk:"
git log --oneline -n 5 -- sdks/workflow-browser-sdk/

Length of output: 501


Script:

#!/bin/bash
# Check common package versions and recent changes
echo "common package versions:"
fd package.json | xargs jq -r 'select(.dependencies?."@ballerine/common"?) | "\(.name): \(.dependencies."@ballerine/common")"'

echo -e "\nRecent changes mentioning version bumps:"
rg -i "bump.*(common|workflow.*sdk)" -g "!package-lock.json" -A 2

echo -e "\nChanges in workflow-browser-sdk package.json:"
rg "version" sdks/workflow-browser-sdk/package.json

echo -e "\nChanges in common package.json:"
rg "version" packages/common/package.json

Length of output: 1035

Comment on lines +26 to +30
if ('__type' in property && property.value === '*') {
acc[key] = context;

return acc;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security and Performance Concerns with Context Exposure

The new condition that assigns the entire context when value === '*' raises several concerns:

  1. Security: Exposing the entire context object could leak sensitive information
  2. Performance: Large context objects could impact memory usage
  3. Type Safety: No validation is performed on the context structure

Consider these alternatives:

  1. Whitelist specific context properties that can be exposed
  2. Add runtime type validation
  3. Document the security implications

Example implementation with whitelisting:

-    if ('__type' in property && property.value === '*') {
-      acc[key] = context;
-
-      return acc;
-    }
+    if ('__type' in property && property.value === '*') {
+      // Whitelist safe properties from context
+      const safeProps = ['id', 'name', 'status'];
+      acc[key] = Object.fromEntries(
+        Object.entries(context).filter(([key]) => safeProps.includes(key))
+      );
+
+      return acc;
+    }

Committable suggestion skipped: line range outside the PR's diff.

@@ -1,7 +1,7 @@
{
"name": "@ballerine/workflow-core",
"author": "Ballerine <[email protected]>",
"version": "0.6.87",
"version": "0.6.88",
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Update @ballerine/common dependency version in affected packages

The following packages are using an older version (^0.9.68) of @ballerine/common and should be updated to 0.9.69:

  • packages/workflows-dashboard
  • packages/blocks
  • packages/ui
🔗 Analysis chain

Verify version consistency across the monorepo.

The version updates look correct and follow semantic versioning:

  • Package version: 0.6.870.6.88
  • @ballerine/common dependency: 0.9.680.9.69

Let's verify version consistency across the monorepo:

Also applies to: 34-34

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for version consistency across the monorepo

# Find all package.json files and extract package versions
echo "Package versions:"
fd package.json | xargs jq -r 'select(.name? | contains("@ballerine")) | "\(.name): \(.version)"'

# Check @ballerine/common dependency versions
echo -e "\n@ballerine/common dependency versions:"
fd package.json | xargs jq -r 'select(.dependencies?."@ballerine/common"?) | "\(.name): \(.dependencies."@ballerine/common")"'

Length of output: 1391

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4a7299e and 9fb23d0.

📒 Files selected for processing (2)
  • packages/workflow-core/src/lib/workflow-runner.test.unit.ts (2 hunks)
  • services/workflows-service/prisma/data-migrations (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • services/workflows-service/prisma/data-migrations
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: build (windows-latest)
  • GitHub Check: test_windows
  • GitHub Check: test_linux
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: lint
🔇 Additional comments (1)
packages/workflow-core/src/lib/workflow-runner.test.unit.ts (1)

357-357: Verify the implementation of action plugin association.

The addition of actionPluginName suggests a new feature where common plugins can be associated with specific action plugins. Please ensure that this relationship is properly documented and tested.

Run the following script to verify the implementation:

✅ Verification successful

Action plugin association is properly implemented ✓

The feature is well-integrated with:

  • Type definitions in common plugin types
  • Runtime validation in workflow runner
  • Error handling for missing plugins
  • Usage in production workflow definitions
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for documentation and implementation details of the action plugin association feature

# Search for documentation about action plugin association
echo "Searching for documentation..."
rg -l "actionPluginName" --type md

# Search for implementation details
echo "Searching for implementation..."
rg "actionPluginName" --type ts -g "!*.test.ts"

Length of output: 1962

Comment on lines +377 to +387
const result = workflow.initiateCommonPlugins(commonPluginSchemas, [
{
name: 'actionPluginName1',
displayName: 'Action Plugin Name 1',
pluginKind: 'api',
stateNames: [],
successAction: 'SUCCESS',
errorAction: 'ERROR',
persistResponseDestination: 'pluginsOutput.actionPluginName1',
},
]);
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

🛠️ Refactor suggestion

Empty stateNames array will prevent plugin execution

The empty stateNames array is problematic as the workflow engine filters plugins based on stateNames.includes(currentState). This plugin won't be triggered in any state, making it effectively non-functional.

  • In packages/workflow-core/src/lib/workflow-runner.ts, plugins are explicitly filtered by their state names:
commonPlugins = commonPlugins?.filter(plugin =>
  plugin.stateNames.includes(this.#__currentState)
);

Even though this is a test file, it should model realistic scenarios to provide meaningful test coverage.

🔗 Analysis chain

Review empty stateNames array and verify persistence path format.

A few concerns about the action plugin configuration:

  1. The stateNames array is empty. This might prevent the action plugin from being triggered in any state.
  2. The persistResponseDestination follows a specific format. Ensure this format is documented and consistently used across the codebase.

Run the following script to verify the persistence path format:

Consider adding at least one state name to ensure the action plugin can be triggered:

-            stateNames: [],
+            stateNames: ['state1', 'state2'],
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistency in persistResponseDestination format

# Search for other persistResponseDestination usages
echo "Searching for persistResponseDestination patterns..."
rg "persistResponseDestination.*pluginsOutput\." --type ts

# Search for documentation about the format
echo "Searching for documentation about persistence path format..."
rg "pluginsOutput" --type md

Length of output: 1702


Script:

#!/bin/bash
# Check how stateNames are used and if empty arrays are valid
echo "Searching for stateNames usage in workflow implementation..."
ast-grep --pattern 'stateNames: $_'

echo -e "\nSearching for stateNames handling in workflow core..."
rg "stateNames" -B 2 -A 2 packages/workflow-core/src/lib/workflow-runner.ts

echo -e "\nSearching for empty stateNames arrays..."
rg "stateNames:\s*\[\s*\]" --type ts

Length of output: 6587


Script:

#!/bin/bash
# Check the test context around the empty stateNames
echo "Checking test context..."
rg -B 10 -A 10 "stateNames: \[\]" packages/workflow-core/src/lib/workflow-runner.test.unit.ts

Length of output: 813

@Omri-Levy Omri-Levy merged commit aa53dd4 into dev Jan 23, 2025
18 checks passed
@Omri-Levy Omri-Levy deleted the bal-3099 branch January 23, 2025 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants