Skip to content

Conversation

chesterkmr
Copy link
Contributor

@chesterkmr chesterkmr commented Jun 30, 2025

Summary by CodeRabbit

  • New Features

    • Added the ability for users to approve or reject individual end users directly from the interface, with real-time feedback and status updates.
    • Introduced new approval states for individuals, now visible in relevant workflows and status badges.
  • Improvements

    • Enhanced status calculation for KYC checks, providing clearer and more accurate status indicators.
    • Streamlined approval workflows for individuals, improving consistency and reliability of approval actions.
  • Bug Fixes

    • Fixed issues with status display and approval actions to ensure correct handling of approval states.

Copy link

changeset-bot bot commented Jun 30, 2025

⚠️ No Changeset found

Latest commit: f1785eb

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 Jun 30, 2025

Walkthrough

This change set introduces a structured approval decision workflow for end users in a KYC context. It defines explicit approval states, adds API endpoints and DTOs for updating an individual's approval decision, updates related service and controller logic, centralizes status computation, and refactors React hooks and UI logic to use the new workflow and types.

Changes

File(s) / Area Change Summary
apps/backoffice-v2/src/domains/individuals/fetchers.ts Added approval state constants, types, extended schema, and updateIndividualApprovalDecision API function.
apps/backoffice-v2/src/domains/individuals/mutations/useMutateIndividualApprovalDecision/... Added useMutateIndividualApprovalDecision hook using the new API function and providing UI feedback.
apps/backoffice-v2/src/lib/blocks/components/KycBlock/hooks/useKycBlock/useKycBlock.tsx Refactored status handling to use new KYC check status enum and types.
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/compute-individual-kyc-check-status.ts Added computeIndividualKycCheckStatus utility, status enum, and type.
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/useTabsToBlocksMap.tsx Refactored tab-to-blocks mapping to use new approval mutation and status computation; removed old mutation logic.
services/workflows-service/prisma/data-migrations Updated subproject commit reference.
services/workflows-service/src/end-user/dtos/end-user-decision.ts Added EndUserDecisionDto class for API validation and documentation.
services/workflows-service/src/end-user/end-user.controller.internal.ts Added POST endpoint for updating approval decision, using new DTO and service method.
services/workflows-service/src/end-user/end-user.service.ts Added updateDecisionById method to handle approval state updates with validation.
services/workflows-service/src/workflow/workflow-runtime-data.repository.ts Included approvalState in individuals' data selection for enriched workflow data.
apps/backoffice-v2/public/locales/en/toast.json Added new toast messages for individual approval success and error notifications.

Sequence Diagram(s)

sequenceDiagram
    participant UI as React UI
    participant Hook as useMutateIndividualApprovalDecision
    participant API as updateIndividualApprovalDecision (fetcher)
    participant BE as EndUserControllerInternal (POST /:id/decision)
    participant Service as EndUserService
    participant Repo as EndUserRepository

    UI->>Hook: Call mutate({ endUserId, decision })
    Hook->>API: updateIndividualApprovalDecision({ endUserId, decision })
    API->>BE: POST /end-users/{id}/decision { decision }
    BE->>Service: updateDecisionById(id, decision, projectIds)
    Service->>Repo: findById(id, projectIds)
    Service->>Service: Validate current approval state
    Service->>Repo: update approvalState
    Repo-->>Service: Updated EndUser
    Service-->>BE: Updated EndUser
    BE-->>API: Updated EndUser
    API-->>Hook: Updated EndUser
    Hook-->>UI: Success/Error feedback
Loading

Suggested reviewers

  • Omri-Levy
  • tomer-shvadron

Poem

🐇
A hop, a skip, a brand new way,
To mark approvals in the fray.
With states and hooks and DTOs,
Decisions clear, the process flows.
No more guessing, just decide—
The KYC bunny beams with pride!
🌱✨


📜 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 ece1c7a and f1785eb.

📒 Files selected for processing (2)
  • apps/backoffice-v2/src/lib/blocks/components/KycBlock/hooks/useKycBlock/useKycBlock.tsx (5 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/compute-individual-kyc-check-status.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/compute-individual-kyc-check-status.ts
  • apps/backoffice-v2/src/lib/blocks/components/KycBlock/hooks/useKycBlock/useKycBlock.tsx
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: spell_check
  • GitHub Check: test_linux
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: lint
  • GitHub Check: format
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

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

Support

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

Copy link
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

🧹 Nitpick comments (4)
services/workflows-service/src/end-user/dtos/end-user-decision.ts (1)

5-12: Well-structured DTO with proper validation.

The implementation correctly uses validation decorators and Swagger documentation. The oneOf validator ensures only valid approval states are accepted.

Consider adding a more descriptive validation message:

- @oneOf([ApprovalState.APPROVED, ApprovalState.REJECTED])
+ @oneOf([ApprovalState.APPROVED, ApprovalState.REJECTED], {
+   message: 'Decision must be either APPROVED or REJECTED'
+ })
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/compute-individual-kyc-check-status.ts (1)

14-30: Consider adding a default return value for getStatusFromTags

The function can return undefined if none of the tag conditions match. Since this is called at line 47 as part of the status computation flow, consider either:

  1. Adding a default return of INDIVIDUAL_KYC_CHECK_STATUS_ENUM.pending
  2. Documenting that undefined is an expected return value
 const getStatusFromTags = (tags: string[]) => {
   if (tags?.includes(StateTag.REVISION)) {
     return INDIVIDUAL_KYC_CHECK_STATUS_ENUM.revision;
   }
 
   if (tags?.includes(StateTag.APPROVED)) {
     return INDIVIDUAL_KYC_CHECK_STATUS_ENUM.approved;
   }
 
   if (tags?.includes(StateTag.REJECTED)) {
     return INDIVIDUAL_KYC_CHECK_STATUS_ENUM.rejected;
   }
 
   if (tags?.includes(StateTag.PENDING_PROCESS)) {
     return INDIVIDUAL_KYC_CHECK_STATUS_ENUM.pending;
   }
+
+  return INDIVIDUAL_KYC_CHECK_STATUS_ENUM.pending;
 };
apps/backoffice-v2/src/domains/individuals/fetchers.ts (2)

19-31: Consider removing redundant EndUserApprovalStates array

The array duplicates the values from EndUserApprovalState. You can derive it dynamically to maintain a single source of truth.

 export const EndUserApprovalState = {
   NEW: 'NEW',
   PROCESSING: 'PROCESSING',
   APPROVED: 'APPROVED',
   REJECTED: 'REJECTED',
 } as const;
 
-export const EndUserApprovalStates = [
-  EndUserApprovalState.NEW,
-  EndUserApprovalState.PROCESSING,
-  EndUserApprovalState.APPROVED,
-  EndUserApprovalState.REJECTED,
-] as const;
+export const EndUserApprovalStates = Object.values(EndUserApprovalState) as [
+  (typeof EndUserApprovalState)[keyof typeof EndUserApprovalState],
+  ...(typeof EndUserApprovalState)[keyof typeof EndUserApprovalState][]
+];

95-97: Consider simplifying the TIndividualDecision type

While the template literal type works, it could be more explicit and easier to understand.

-export type TIndividualDecision =
-  | `${typeof EndUserApprovalState.APPROVED}`
-  | `${typeof EndUserApprovalState.REJECTED}`;
+export type TIndividualDecision = 'APPROVED' | 'REJECTED';

Or if you want to maintain the connection to the constants:

-export type TIndividualDecision =
-  | `${typeof EndUserApprovalState.APPROVED}`
-  | `${typeof EndUserApprovalState.REJECTED}`;
+export type TIndividualDecision = 
+  | typeof EndUserApprovalState.APPROVED
+  | typeof EndUserApprovalState.REJECTED;
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4b8d1a2 and d8e2264.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • apps/backoffice-v2/src/domains/individuals/fetchers.ts (4 hunks)
  • apps/backoffice-v2/src/domains/individuals/mutations/useMutateIndividualApprovalDecision/useMutateIndividualApprovalDecision.ts (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/components/KycBlock/hooks/useKycBlock/useKycBlock.tsx (5 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/compute-individual-kyc-check-status.ts (1 hunks)
  • apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/useTabsToBlocksMap.tsx (12 hunks)
  • services/workflows-service/prisma/data-migrations (1 hunks)
  • services/workflows-service/src/end-user/dtos/end-user-decision.ts (1 hunks)
  • services/workflows-service/src/end-user/end-user.controller.internal.ts (2 hunks)
  • services/workflows-service/src/end-user/end-user.service.ts (2 hunks)
  • services/workflows-service/src/workflow/workflow-runtime-data.repository.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/data-migrations.mdc:0-0
Timestamp: 2025-06-24T09:35:54.963Z
Learning: Use consistent naming conventions for related components (workflows, UI definitions, filters) in Ballerine migrations to improve maintainability and clarity.
services/workflows-service/prisma/data-migrations (2)

undefined

<retrieved_learning>
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/data-migrations.mdc:0-0
Timestamp: 2025-06-24T09:35:54.963Z
Learning: In Ballerine's workflow migration scripts (TypeScript), always establish the relationship between workflow definitions and UI definitions solely through the 'workflowDefinitionId' field in the UiDefinition model; do not create a separate junction table or relation.
</retrieved_learning>

<retrieved_learning>
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/data-migrations.mdc:0-0
Timestamp: 2025-06-24T09:35:54.963Z
Learning: Use consistent naming conventions for related components (workflows, UI definitions, filters) in Ballerine migrations to improve maintainability and clarity.
</retrieved_learning>

services/workflows-service/src/workflow/workflow-runtime-data.repository.ts (1)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/data-migrations.mdc:0-0
Timestamp: 2025-06-24T09:35:54.963Z
Learning: In Ballerine's workflow migration scripts (TypeScript), always establish the relationship between workflow definitions and UI definitions solely through the 'workflowDefinitionId' field in the UiDefinition model; do not create a separate junction table or relation.
services/workflows-service/src/end-user/dtos/end-user-decision.ts (2)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Use discriminated unions in TypeScript for managing complex state, enabling exhaustive type checking.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: Use discriminated unions for managing complex state shapes, and leverage TypeScript's type inference to reduce redundancy.
apps/backoffice-v2/src/domains/individuals/mutations/useMutateIndividualApprovalDecision/useMutateIndividualApprovalDecision.ts (8)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: Extract business logic into custom React hooks, placing them in dedicated hooks directories and using the 'use' prefix for naming, to promote reusability and separation of concerns.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Always use the 'use' prefix for custom React hooks to ensure they are recognized by React's rules of hooks.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-dashboard.mdc:0-0
Timestamp: 2025-06-24T09:37:03.204Z
Learning: Custom hooks in React should be single-purpose, follow the 'use' prefix naming convention, and be placed within feature directories for better organization and reusability.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: In the apps/backoffice-v2 React TypeScript codebase, always use functional components and TypeScript for all UI components to ensure consistency and type safety.
Learnt from: chesterkmr
PR: ballerine-io/ballerine#3265
File: apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringReportStatus/MerchantMonitoringReportStatus.tsx:121-124
Timestamp: 2025-04-29T09:05:55.562Z
Learning: When using React Query's `mutateAsync`, if the mutation fails, it throws an exception and halts execution of the surrounding function, preventing subsequent code from running. This provides automatic protection against partial operations when multiple related mutations need to happen atomically.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Use React Query for managing server state and data fetching, and React Context for global UI state, to separate concerns effectively.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: Use React Query for all server state management and API calls, leveraging its caching, loading, and error handling features.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-dashboard.mdc:0-0
Timestamp: 2025-06-24T09:37:03.204Z
Learning: React Query is the preferred solution for managing API state and data fetching in modern React applications, providing built-in caching, loading, and error handling.
apps/backoffice-v2/src/lib/blocks/components/KycBlock/hooks/useKycBlock/useKycBlock.tsx (1)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: In the apps/backoffice-v2 React TypeScript codebase, always use functional components and TypeScript for all UI components to ensure consistency and type safety.
services/workflows-service/src/end-user/end-user.service.ts (2)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-service.mdc:0-0
Timestamp: 2025-06-24T09:37:14.531Z
Learning: Use custom exception classes extending from base NestJS exceptions for consistent and meaningful error handling.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-service.mdc:0-0
Timestamp: 2025-06-24T09:37:14.531Z
Learning: Services must use the @Injectable() decorator and have names ending with the 'Service' suffix to align with NestJS conventions.
apps/backoffice-v2/src/domains/individuals/fetchers.ts (4)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Use discriminated unions in TypeScript for managing complex state, enabling exhaustive type checking.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: Use discriminated unions for managing complex state shapes, and leverage TypeScript's type inference to reduce redundancy.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-service.mdc:0-0
Timestamp: 2025-06-24T09:37:14.531Z
Learning: Use TypeScript 'as const' for fixed sets of values to ensure literal type inference.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: Use React Hook Form for form state management and Zod for schema validation, providing clear validation feedback and handling form submission states.
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/useTabsToBlocksMap.tsx (8)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: In the apps/backoffice-v2 React TypeScript codebase, always use functional components and TypeScript for all UI components to ensure consistency and type safety.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: Extract business logic into custom React hooks, placing them in dedicated hooks directories and using the 'use' prefix for naming, to promote reusability and separation of concerns.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Always use the 'use' prefix for custom React hooks to ensure they are recognized by React's rules of hooks.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-dashboard.mdc:0-0
Timestamp: 2025-06-24T09:37:03.204Z
Learning: Custom hooks in React should be single-purpose, follow the 'use' prefix naming convention, and be placed within feature directories for better organization and reusability.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Use React Query for managing server state and data fetching, and React Context for global UI state, to separate concerns effectively.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: Use React Query for all server state management and API calls, leveraging its caching, loading, and error handling features.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: Use React Context for shared state that needs to be accessed by multiple components, and implement state machines for managing complex flows.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/data-migrations.mdc:0-0
Timestamp: 2025-06-24T09:35:54.963Z
Learning: In Ballerine's workflow migration scripts (TypeScript), always establish the relationship between workflow definitions and UI definitions solely through the 'workflowDefinitionId' field in the UiDefinition model; do not create a separate junction table or relation.
🧬 Code Graph Analysis (6)
services/workflows-service/src/end-user/dtos/end-user-decision.ts (1)
services/workflows-service/src/common/decorators/one-of.decorator.ts (1)
  • oneOf (3-19)
apps/backoffice-v2/src/lib/blocks/components/KycBlock/hooks/useKycBlock/useKycBlock.tsx (1)
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/compute-individual-kyc-check-status.ts (2)
  • TIndividualKycCheckStatus (12-12)
  • INDIVIDUAL_KYC_CHECK_STATUS_ENUM (5-10)
services/workflows-service/src/end-user/end-user.controller.internal.ts (3)
services/workflows-service/src/common/decorators/project-ids.decorator.ts (1)
  • ProjectIds (6-32)
services/workflows-service/src/types.ts (1)
  • TProjectIds (16-16)
services/workflows-service/src/end-user/dtos/end-user-decision.ts (1)
  • EndUserDecisionDto (5-12)
services/workflows-service/src/end-user/end-user.service.ts (2)
services/workflows-service/src/alert/alert.controller.external.ts (1)
  • decision (290-314)
services/workflows-service/src/types.ts (1)
  • TProjectIds (16-16)
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/compute-individual-kyc-check-status.ts (3)
packages/common/src/consts/index.ts (1)
  • StateTag (3-16)
apps/backoffice-v2/src/domains/individuals/fetchers.ts (2)
  • TEndUser (68-68)
  • EndUserApprovalState (19-24)
apps/backoffice-v2/src/domains/workflows/fetchers.ts (1)
  • TWorkflowById (211-211)
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/useTabsToBlocksMap.tsx (3)
apps/backoffice-v2/src/domains/individuals/mutations/useMutateIndividualApprovalDecision/useMutateIndividualApprovalDecision.ts (1)
  • useMutateIndividualApprovalDecision (8-31)
apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/compute-individual-kyc-check-status.ts (1)
  • computeIndividualKycCheckStatus (32-57)
apps/backoffice-v2/src/domains/individuals/fetchers.ts (1)
  • EndUserApprovalState (19-24)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: lint
  • GitHub Check: spell_check
  • GitHub Check: test_linux
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: format
🔇 Additional comments (12)
services/workflows-service/prisma/data-migrations (1)

1-1: Confirm the new submodule SHA includes the intended DB migration only

Only the gitlink SHA changed; please double-check that commit 493a222 contains exclusively the KYC-approval migrations (e.g., approvalState column addition) and no unintended schema or data changes.
Make sure the migration can be applied/rolled back cleanly in all environments and that dependent services are using the same revision.

services/workflows-service/src/workflow/workflow-runtime-data.repository.ts (1)

311-312: LGTM: Essential data enrichment for approval workflow.

The addition of approvalState to the individuals CTE properly supports the new approval decision functionality throughout the system.

services/workflows-service/src/end-user/end-user.service.ts (1)

120-138: Excellent business logic implementation.

The method properly validates that approval decisions cannot be changed once they're finalized (APPROVED or REJECTED). The error handling with BadRequestException provides clear feedback to API consumers.

services/workflows-service/src/end-user/end-user.controller.internal.ts (1)

64-74: Well-implemented REST endpoint with proper documentation.

The controller method correctly uses NestJS decorators for parameter extraction and validation. The Swagger documentation appropriately describes the possible responses.

apps/backoffice-v2/src/lib/blocks/components/KycBlock/hooks/useKycBlock/useKycBlock.tsx (1)

31-34: Excellent type safety improvement.

The migration from string literals to the centralized INDIVIDUAL_KYC_CHECK_STATUS_ENUM enhances type safety and maintainability. The typed function signature ensures compile-time validation of status values.

Also applies to: 306-307, 322-322, 337-337, 352-352

apps/backoffice-v2/src/domains/individuals/mutations/useMutateIndividualApprovalDecision/useMutateIndividualApprovalDecision.ts (1)

1-31: Well-implemented custom hook following best practices!

The hook correctly uses React Query's useMutation, follows the 'use' prefix naming convention, and properly handles success/error states with toast notifications. The use of void operator for the promise is appropriate here.

apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/compute-individual-kyc-check-status.ts (1)

32-57: Status computation logic is well-structured

The function properly prioritizes verification check status, then approval state, and falls back to tag-based status. The explicit handling of each approval state ensures clear status mapping.

apps/backoffice-v2/src/domains/individuals/fetchers.ts (1)

99-117: API function implementation follows established patterns

The updateIndividualApprovalDecision function correctly uses the existing apiClient pattern and error handling approach consistent with other functions in this file.

apps/backoffice-v2/src/lib/blocks/variants/DefaultBlocks/hooks/useCaseBlocksLogic/utils/useTabsToBlocksMap.tsx (4)

27-29: Proper integration of the new individual approval decision mutation

The hook correctly replaces the generic approval mutation with the specific individual approval decision mutation, following the new structured workflow.

Also applies to: 138-141


177-200: Efficient refactoring of status computation logic

Good optimization by finding the endUser once and reusing it for both property extraction and status computation. The centralized status computation using computeIndividualKycCheckStatus improves maintainability.


261-267: Clear and explicit approval decision parameters

The onApprove handler now clearly specifies the endUserId and uses the typed EndUserApprovalState.APPROVED constant, making the intent explicit and type-safe.


422-427: Consistent implementation across all individual adapters

The same pattern of finding the endUser once and computing status is consistently applied to directors and people of interest adapters, maintaining code consistency.

Also applies to: 450-460

Comment on lines +45 to +46
[EndUserApprovalState.NEW, EndUserApprovalState.PROCESSING].includes(endUser?.approvalState)
) {
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. Thinking that new and processing should lead to pending (if somehow we can sync the end-user state with the check that would be great) 2. Tags should be the last control flow, having no approvalState would not guarantee there are tags 3. Between the check status and end-user state the tags might be an impossible state

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reworked.

Copy link
Contributor

Choose a reason for hiding this comment

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

Remove !endUser?.approvalState.

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