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

MM UI-UX Hackathon #2957

Merged
merged 20 commits into from
Jan 14, 2025
Merged

MM UI-UX Hackathon #2957

merged 20 commits into from
Jan 14, 2025

Conversation

tomer-shvadron
Copy link
Collaborator

@tomer-shvadron tomer-shvadron commented Jan 14, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added merchant monitoring status toggle functionality.
    • Introduced content tooltips for enhanced user guidance.
    • Added new metrics for merchant monitoring, including total active merchants and merchant count changes.
    • Added new alert filtering options in business reports.
  • Improvements

    • Enhanced business reports query with optional alert filtering.
    • Updated statistics page with month picker and portfolio analytics.
    • Refined UI components with more informative tooltips.
    • Streamlined date handling across components.
  • Bug Fixes

    • Resolved issues with date range handling in various components.
    • Improved error handling for monitoring state changes.
  • Documentation

    • Updated localization files for toast messages.
    • Added descriptions for various analysis sections.

shanegrouber and others added 18 commits January 6, 2025 17:50
* feat(ui): improve UI messages for no indications detected

- Provide more detailed messages for indications of website reputation
- Specify lack of issues in pricing and structural evaluation

(Your code comments speak less clearly than a cryptic crossword in a dark room)

* chore(deps): update @ballerine/ui to version 0.5.60

- Bump version of @ballerine/ui to 0.5.60 across multiple packages
- Update package.json and changelog for @ballerine/react-pdf-toolkit and kyb-app

(the dependencies are getting updated faster than my social life)

---------

Co-authored-by: Omri Levy <[email protected]>
- Update logic to return null for ad and social media violations
* feat(merchant-monitoring): display total items in results badge

- Add a badge to show total number of results
- Improve layout by adjusting heading structure

(Your layout is so crowded, it could use a personal space policy)

* fix(merchantMonitoring): format totalItems for improved readability

- Update totalItems to format with Intl.NumberFormat
- Enhance the display of item counts for user experience

(your number formatting was so plain, it looked like a binary tree without leaves)

---------

Co-authored-by: Omri Levy <[email protected]>
…ed data (BAL-3302, BAL-3303) (#2940)

* feat: monthly filter on statistics page and additional merchant related data

* fix: revert conditional statement

* fix: rewrite month picker to dayjs

* fix: CodeRabbit comments

* fix: minor code style correction
- Make the 'from' field optional in the statistics search schema
- Clean up date transformation for better readability

(your code's so tangled, it could be the plot of a soap opera)
* feat(monitoring): implement business monitoring feature

- Add success and error messages for turning monitoring on/off
- Update API endpoints to manage ongoing monitoring status
- Integrate tooltip UI for monitoring status display

(Your code is so reactive that I'm surprised it doesn't require a safe word)

* chore(business-report): remove unused import for BusinessReportMetricsDto

- Eliminate unnecessary import to clean up the code
- Reduces clutter and potential confusion in the module

(your code is so tidy now, it could be a minimalist's dream home)

* fix(report): optimize business report fetching logic

- Simplify monitoring mutation definitions
- Consolidate business fetching to reduce database calls

(Your database queries are so chatty, they could use a good night's sleep)
- Implement ContentTooltip component across multiple report templates
- Update Providers to include TooltipProvider from Ballerine UI
- Refactor headings with tooltips for additional information

(your tooltips are so informative, they should come with a user manual)
* refactor(backoffice-v2): changed home statistics

* feat(backoffice-v3): added filter for isAlert

* refactor(backoffice-v2): updated alert filter copy
- Consolidate tooltip component imports from '@ballerine/ui'
- Change section titles from "Ads and Social Media" to "Social Media"

(With these changes, we're one step closer to rebranding you as a minimalism guru)
Bal 3322 - Implement content tooltips in the backoffice
* refactor(backoffice-v2): changed home statistics

* feat(backoffice-v3): added filter for isAlert

* refactor(backoffice-v2): updated alert filter copy

* feat(backoffice-v2): added alerts graph to home page

* refactor(backoffice-v2): now using dayjs for last 30 days date

* refactor(backoffice-v2): added from and to to alerts count
- Add ChartContainer component for chart rendering
- Implement ChartTooltip and ChartTooltipContent components
- Enhance the WebsiteCredibility component to use the new Chart components

(your JSX structure is more nested than a Russian doll collection)
- Refactor conditional return for better clarity
- Enhance code structure for maintainability

(your code's readability is like a secret menu, good luck figuring it out)
Bal 3307 - Improve Monthly Visitors Chart
* feat(backoffice-v2): added default filter for merchant reports view

* fix(backoffice-v2): now clear all clears isAlert filter
- Remove registrationDate from AuthenticatedUserSchema
- Update isAlert field in BusinessReportSchema to be optional
- Add BusinessReportsCountSchema for report counting functionality

(Your schema changes are so dramatic, they should come with a Netflix subscription)
Copy link

changeset-bot bot commented Jan 14, 2025

⚠️ No Changeset found

Latest commit: 9b1491b

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 14, 2025

Walkthrough

The pull request introduces several enhancements across multiple components of the Ballerine platform, focusing on merchant monitoring, reporting, and user interface improvements. Key changes include adding monitoring status functionality, updating business report schemas, introducing new components like ContentTooltip, and refactoring various hooks and pages to support more flexible data handling and filtering. The modifications span frontend applications, services, and SDK packages, with a consistent approach to versioning and dependency updates.

Changes

File/Group Change Summary
apps/backoffice-v2/public/locales/en/toast.json Added new entries for business monitoring toast messages
apps/backoffice-v2/src/common/components/templates/Providers/Providers.tsx Integrated TooltipProvider from @ballerine/ui
apps/backoffice-v2/src/common/hooks/useHomeLogic/useHomeLogic.ts Removed onDateRangeChange, from, and to from the hook
apps/backoffice-v2/src/domains/auth/validation-schemas.ts Added lastActiveAt property to AuthenticatedUserSchema
apps/backoffice-v2/src/domains/business-reports/fetchers.ts Enhanced schemas, added new query parameters, introduced monitoring status handling
apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportMetricsQuery/useBusinessReportMetricsQuery.ts Expanded MetricsResponseSchema and updated method signatures for date handling
apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx Added alert filtering, new tooltips, and monitoring status controls
apps/backoffice-v2/src/pages/Statistics/Statistics.page.tsx Introduced new components like MonthPicker, PortfolioAnalytics, and enhanced metrics display
apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/MerchantMonitoringBusinessReport.page.tsx Added dropdown for managing ongoing monitoring status
apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/fetchers.ts Introduced turnOngoingMonitoring function for monitoring state updates
apps/backoffice-v2/src/pages/MerchantMonitoringCreateCheck/hooks/useMerchantMonitoringCreateBusinessReportPageLogic/useMerchantMonitoringCreateBusinessReportPageLogic.tsx Updated label for checks configuration section
apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/hooks/useMerchantMonitoringBusinessReportLogic/useMerchantMonitoringBusinessReportLogic.tsx Enhanced hook for managing monitoring state
apps/backoffice-v2/src/pages/Statistics/hooks/useStatisticsLogic.tsx Introduced StatisticsSearchSchema for managing search parameters
apps/backoffice-v2/CHANGELOG.md Updated changelog with new version 0.7.93 and dependency updates
apps/backoffice-v2/package.json Updated version to 0.7.93 and dependencies
apps/kyb-app/CHANGELOG.md Added new version 0.3.109 with dependency updates
apps/kyb-app/package.json Updated version to 0.3.109 and dependencies
packages/react-pdf-toolkit/CHANGELOG.md Added new version 1.2.62 with dependency updates
packages/react-pdf-toolkit/package.json Updated version to 1.2.62 and dependencies
packages/ui/CHANGELOG.md Added new version 0.5.62 with dependency updates
packages/ui/package.json Updated version to 0.5.62 and dependencies
packages/ui/src/components/molecules/ContentTooltip/ContentTooltip.tsx Introduced ContentTooltip component for enhanced UI
services/workflows-service/CHANGELOG.md Added new version 0.7.89 with dependency updates
services/workflows-service/package.json Updated version to 0.7.89 and dependencies

Suggested Labels

enhancement, Review effort [1-5]: 3

Poem

🐰 A Rabbit's Ode to Monitoring Magic 🔍

In backoffice halls of data's delight,
Merchants dance in monitoring's soft light
Tooltips whisper, metrics gleam so bright
Filtering alerts with algorithmic might
CodeRabbit's touch makes complexity take flight!

hop hop 🚀


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

🧹 Nitpick comments (40)
apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/PortfolioRiskStatistics.tsx (1)

155-180: Add aria-label to the "View" link for better accessibility.

The new monitoring alerts section is well-implemented, but the "View" link could benefit from an aria-label to provide more context for screen readers.

  <Link
    to={`/${locale}/merchant-monitoring?from=${from}&to=${to}&isAlert=Alerted`}
+   aria-label="View unresolved monitoring alerts"
    className={ctw(
      buttonVariants({
        variant: 'link',
      }),
      'h-[unset] cursor-pointer !p-0 !text-blue-500',
    )}
  >
    View
  </Link>
services/workflows-service/src/workflow/cron/ongoing-monitoring.cron.ts (2)

76-82: Consider enhancing the log message clarity.

The log message could be more specific about whether the monitoring is disabled at the business-level configuration.

-                  `Ongoing monitoring is not enabled for business ${business.companyName} (id: ${business.id})`,
+                  `Ongoing monitoring is disabled in business-level configuration for ${business.companyName} (id: ${business.id})`,

83-85: Consider restructuring the fallback condition for clarity.

The fallback logic when business-level config is undefined could be more explicit.

-              if (
-                isOngoingEnabledForBusiness === undefined &&
-                !featureConfig?.options.runByDefault
-              ) {
+              // Fallback to customer-level default when business-level config is not set
+              if (isOngoingEnabledForBusiness === undefined) {
+                if (!featureConfig?.options.runByDefault) {
apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringTable/columns.tsx (3)

78-91: Simplify the riskScore null-check logic for better readability

The current conditional rendering for riskScore involves checking !riskScore && riskScore !== 0 and (riskScore || riskScore === 0). This can be simplified by using a nullish coalescing operator or more explicit null/undefined checks to improve readability.

Apply this diff to simplify the conditionals:

-          {!riskScore && riskScore !== 0 && <TextWithNAFallback className={'py-0.5'} />}
-          {(riskScore || riskScore === 0) && (
+          {riskScore == null ? (
+            <TextWithNAFallback className={'py-0.5'} />
+          ) : (
             <Badge
               className={ctw(
                 severityToClassName[
                   (severity?.toUpperCase() as keyof typeof severityToClassName) ?? 'DEFAULT'
                 ],
                 'w-20 py-0.5 font-bold',
               )}
             >
               {titleCase(severity ?? '')}
             </Badge>
           )}

180-199: Consider removing commented-out code to improve maintainability

The code block for the merchantId column is commented out. Keeping large blocks of commented-out code can clutter the codebase and reduce readability. If this code is no longer needed, consider removing it. If it's intended for future use, consider adding a comment explaining why it's retained.


96-137: Ensure consistent usage of icons and tooltips for accessibility

In the monitoringStatus column, icons are used to represent the monitoring state with accompanying tooltips. To enhance accessibility and provide a better user experience, ensure that the icons have appropriate aria-labels or role attributes.

Apply this diff to add aria-label to the TooltipTrigger components:

           <TooltipTrigger>
+            <span aria-label={getValue() ? 'Monitored' : 'Not Monitored'}>
              {getValue() ? (
                <CheckCircle
                  size={18}
                  className={`stroke-background`}
                  containerProps={{
                    className: 'me-3 bg-success mt-px',
                  }}
                />
              ) : (
                <IndicatorCircle
                  size={18}
                  className={`stroke-transparent`}
                  containerProps={{
                    className: 'bg-slate-500/20',
                  }}
                />
              )}
+            </span>
           </TooltipTrigger>
services/workflows-service/src/business-report/business-report.controller.external.ts (2)

97-99: Update method documentation to include the new isAlert parameter

The listBusinessReports method now accepts an isAlert parameter. Ensure that any API documentation or Swagger annotations are updated to reflect this new parameter for accurate API representation.


100-145: Optimize database queries by reducing nested awaits

The current implementation involves nested await calls inside Promise.all, which can be inefficient. Consider refactoring to batch database calls where possible to improve performance.

As an example, you might retrieve the businesses and their metadata in the same query or use include statements to fetch related data in a single call.

packages/ui/src/components/atoms/Chart/Chart.tsx (1)

24-32: Ensure useChart hook is used within ChartContainer

The useChart hook throws an error if it's used outside of a ChartContainer. To improve developer experience, consider providing a more informative error message or handling this scenario more gracefully.

services/workflows-service/src/business-report/dtos/business-report-metrics.dto.ts (1)

17-20: Add date range validation to Zod schema.

The Zod schema should validate that the 'to' date is not before the 'from' date when both are provided.

Consider enhancing the schema:

 export const BusinessReportsMetricsQuerySchema = z.object({
-  from: z.string().optional(),
-  to: z.string().optional(),
+  from: z.string().datetime().optional(),
+  to: z.string().datetime().optional(),
+}).refine(
+  (data) => {
+    if (data.from && data.to) {
+      return new Date(data.to) >= new Date(data.from);
+    }
+    return true;
+  },
+  {
+    message: "'to' date must not be before 'from' date",
+    path: ['to'],
 });
apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/fetchers.ts (1)

11-13: Enhance type safety for the state parameter.

Consider using an enum or const object for better type safety and maintainability.

+export const MonitoringState = {
+  ON: 'on',
+  OFF: 'off',
+} as const;
+
+type MonitoringState = typeof MonitoringState[keyof typeof MonitoringState];
+
 type Props = {
   merchantId: string;
-  state: 'on' | 'off';
+  state: MonitoringState;
 };
packages/ui/src/components/molecules/ContentTooltip/ContentTooltip.stories.tsx (1)

1-36: LGTM! Consider adding more stories for different configurations.

The story is well-structured and demonstrates the component's usage effectively. To enhance documentation, consider adding stories for:

  • Different tooltip alignments
  • Various content types
  • Error states
  • Loading states
apps/backoffice-v2/src/pages/Statistics/hooks/useStatisticsLogic.tsx (1)

6-16: Consider adding date range validation.

While the schema correctly handles date transformation, it might benefit from additional validation to prevent selecting dates too far in the past or future.

 export const StatisticsSearchSchema = z.object({
   from: z
     .string()
     .date()
     .optional()
+    .refine(
+      date => !date || dayjs(date).isAfter(dayjs().subtract(1, 'year')),
+      'Date cannot be more than 1 year ago'
+    )
     .transform(value =>
       value
         ? dayjs(value).startOf('month').format('YYYY-MM-DD')
         : dayjs().startOf('month').format('YYYY-MM-DD'),
     ),
 });
apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/mutations/useTurnMonitoringOnMutation/useTurnMonitoringOnMutation.tsx (2)

24-24: Consider more specific query invalidation.

Instead of invalidating all queries, consider invalidating only the relevant query keys to improve performance and prevent unnecessary refetches.

-      void queryClient.invalidateQueries();
+      void queryClient.invalidateQueries({ queryKey: ['merchantMonitoring', merchantId] });

30-42: Enhance error type safety.

The error handling could benefit from more specific error typing and structured error responses.

-    onError: (error: unknown) => {
+    onError: (error: HttpError | Error | unknown) => {
       if (error instanceof HttpError && error.code === 400) {
         toast.error(error.message);
         return;
       }
+      if (error instanceof Error) {
+        toast.error(error.message);
+        return;
+      }
apps/backoffice-v2/src/pages/Statistics/Statistics.page.tsx (2)

11-13: Consider implementing an error boundary or error component.

Instead of throwing the error directly, consider handling it gracefully with a dedicated error component.

-  if (error) {
-    throw error;
-  }
+  if (error) {
+    return <ErrorDisplay error={error} />;
+  }

16-18: Enhance loading state presentation.

The current loading indicator could be improved with a skeleton loader for better UX.

-    return <Loader2 className="w-4 animate-spin" />;
+    return (
+      <div className="space-y-8">
+        <div className="flex items-center justify-between">
+          <div className="h-8 w-32 animate-pulse bg-gray-200 rounded" />
+          <div className="h-8 w-48 animate-pulse bg-gray-200 rounded" />
+        </div>
+        <div className="h-64 animate-pulse bg-gray-200 rounded" />
+      </div>
+    );
apps/backoffice-v2/src/common/hooks/useHomeLogic/useHomeLogic.ts (2)

Line range hint 21-31: Simplify navigation logic.

The navigation logic could be simplified and made more maintainable.

+  const HOME_ROUTES = {
+    ROOT: `/${locale}`,
+    HOME: `/${locale}/home`,
+    STATISTICS: `/${locale}/home/statistics`,
+  };
+
   useEffect(() => {
-    if (pathname !== `/${locale}` && pathname !== `/${locale}/home`) {
+    if (![HOME_ROUTES.ROOT, HOME_ROUTES.HOME].includes(pathname)) {
       return;
     }
 
-    navigate(`/${locale}/home/statistics`);
+    navigate(HOME_ROUTES.STATISTICS);
   }, [pathname, locale, navigate]);

Line range hint 33-44: Add TypeScript types for return values.

Consider adding explicit return type for better type safety and documentation.

+interface HomeLogicReturn {
+  firstName: string | undefined;
+  fullName: string | undefined;
+  avatarUrl: string | undefined;
+  statisticsLink: string;
+  workflowsLink: string;
+  defaultTabValue: string;
+  isLoadingCustomer: boolean;
+  isExample: boolean | undefined;
+  isDemo: boolean | undefined;
+}
+
-  return {
+  return {
     firstName,
     fullName,
     avatarUrl,
@@ -44,7 +44,7 @@
     isLoadingCustomer,
     isExample,
     isDemo,
-  };
+  } as HomeLogicReturn;
packages/ui/src/components/templates/report/components/Ecosystem/Ecosystem.tsx (1)

23-39: LGTM! Consider adding ARIA attributes for better accessibility.

The tooltip implementation looks clean and provides valuable context about the ecosystem analysis. However, consider enhancing accessibility by adding appropriate ARIA attributes.

 <ContentTooltip
   description={
     <p>
       Explores the merchant&apos;s broader activity, including related websites and
       affiliations, for a comprehensive risk assessment.
     </p>
   }
   props={{
     tooltipContent: {
       align: 'center',
+      'aria-label': 'About Ecosystem Analysis',
     },
   }}
 >
-  <h3 className={'col-span-full text-lg font-bold'}>Ecosystem Analysis</h3>
+  <h3 className={'col-span-full text-lg font-bold'} aria-describedby="ecosystem-tooltip">Ecosystem Analysis</h3>
 </ContentTooltip>
packages/ui/src/components/molecules/ContentTooltip/ContentTooltip.tsx (2)

8-16: Add type safety for tooltip positioning props.

Consider using TypeScript enums or union types for the align and side properties to prevent invalid values.

+type TooltipAlign = 'start' | 'center' | 'end';
+type TooltipSide = 'top' | 'right' | 'bottom' | 'left';

 export const ContentTooltip: FunctionComponentWithChildren<{
   description: ReactNode | ReactNode[];
   props?: {
     tooltip?: ComponentProps<typeof Tooltip>;
     tooltipTrigger?: ComponentProps<typeof TooltipTrigger>;
-    tooltipContent?: ComponentProps<typeof TooltipContent>;
+    tooltipContent?: Omit<ComponentProps<typeof TooltipContent>, 'align' | 'side'> & {
+      align?: TooltipAlign;
+      side?: TooltipSide;
+    };
     tooltipIcon?: ComponentProps<typeof HelpCircle>;
   };
 }> = ({ description, props, children }) => {

29-33: Consider moving styles to a theme configuration.

The hard-coded styles could be moved to a theme configuration for better maintainability and consistency.

-          'max-w-[400px] whitespace-normal border p-4 font-normal',
-          'rounded-[6px] bg-[#3D465A] shadow-[0px_4px_4px_rgba(0,0,0,0.05)]',
+          'max-w-[400px] whitespace-normal border p-4 font-normal rounded-md',
+          'bg-tooltip shadow-tooltip',
           props?.tooltipContent?.className,
apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportMetricsQuery/useBusinessReportMetricsQuery.ts (1)

37-45: Add date parameter validation.

Consider adding validation for the date parameters to ensure they are in the correct format.

+const isValidDateString = (date?: string) => {
+  if (!date) return true;
+  return !isNaN(Date.parse(date));
+};
+
 export const useBusinessReportMetricsQuery = ({ from, to }: { from?: string; to?: string }) => {
   const isAuthenticated = useIsAuthenticated();
+  
+  if (from && !isValidDateString(from)) {
+    throw new Error('Invalid from date format');
+  }
+  
+  if (to && !isValidDateString(to)) {
+    throw new Error('Invalid to date format');
+  }

   return useQuery({
     queryKey: ['business-report-metrics', from, to],
     queryFn: () => fetchBusinessReportMetrics({ from, to }),
     enabled: isAuthenticated,
     keepPreviousData: true,
   });
 };
services/workflows-service/src/business-report/dtos/business-report.dto.ts (1)

65-67: Enhance field documentation and add validation.

Consider adding more descriptive API documentation and class validator decorators for the new field.

-  @ApiProperty({ type: Boolean })
+  @ApiProperty({
+    type: Boolean,
+    description: 'Indicates whether the business report is currently being monitored',
+    example: true,
+  })
+  @IsBoolean()
+  @IsNotEmpty()
   monitoringStatus!: boolean;
apps/backoffice-v2/src/pages/Statistics/components/PortfolioAnalytics/hooks/usePortfolioAnalyticsLogic.tsx (1)

23-29: Consider memoizing the sort comparator function.

The sort comparator function is recreated on every render. Consider extracting and memoizing it for better performance.

+ const sortComparator = useCallback(
+   (a: { count: number }, b: { count: number }) =>
+     riskIndicatorsSorting === 'asc' ? a.count - b.count : b.count - a.count,
+   [riskIndicatorsSorting],
+ );

  const filteredRiskIndicators = useMemo(
    () =>
      violationCounts
-       .sort((a, b) => (riskIndicatorsSorting === 'asc' ? a.count - b.count : b.count - a.count))
+       .sort(sortComparator)
        .slice(0, 5),
    [violationCounts, riskIndicatorsSorting, sortComparator],
  );
packages/ui/src/components/templates/report/components/WebsitesCompany/WebsitesCompany.tsx (2)

29-33: Consider extracting tooltip configuration to constants.

The tooltip configuration object could be reused across different components. Consider extracting it to a shared constants file.

+ // In a shared constants file
+ export const CENTERED_TOOLTIP_CONFIG = {
+   tooltipContent: {
+     align: 'center',
+   },
+ } as const;

- props={{
-   tooltipContent: {
-     align: 'center',
-   },
- }}
+ props={CENTERED_TOOLTIP_CONFIG}

62-64: Improve accessibility of the no-data message.

The message for no company reputation analysis could benefit from semantic HTML and ARIA attributes.

- <li>No indications of negative company reputation were detected.</li>
+ <li role="status" aria-live="polite" className="text-muted">
+   No indications of negative company reputation were detected.
+ </li>
apps/backoffice-v2/src/pages/Statistics/components/PortfolioAnalytics/PortfolioAnalytics.tsx (1)

36-38: Improve number formatting consistency.

The conditional formatting for added merchants differs from other metrics. Consider consistent formatting across all metrics.

- {addedMerchantsCount > 0
-   ? `+${Intl.NumberFormat('en').format(addedMerchantsCount)}`
-   : 0}
+ {`${addedMerchantsCount > 0 ? '+' : ''}${Intl.NumberFormat('en').format(addedMerchantsCount)}`}
services/workflows-service/src/business-report/dtos/business-report-list.dto.ts (1)

97-102: Consider adding validation for page size boundaries.

The page size validation could be more specific about the minimum value.

  page: z
    .object({
      number: z.coerce.number().int().positive(),
-     size: z.coerce.number().int().positive().max(100),
+     size: z.coerce.number().int().min(1).max(100)
+       .describe('Page size must be between 1 and 100'),
    })
    .optional(),
apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/hooks/usePortfolioRiskStatisticsLogic/usePortfolioRiskStatisticsLogic.tsx (1)

51-59: Consider extracting date utility function.

The getLast30DaysDateRange function could be moved to a shared utilities file as it might be useful in other components.

+// In src/common/utils/date-utils.ts
+export const getLast30DaysDateRange = () => {
+  const today = dayjs();
+  const thirtyDaysAgo = today.subtract(30, 'day');
+
+  return {
+    from: thirtyDaysAgo.format('YYYY-MM-DD'),
+    to: today.format('YYYY-MM-DD'),
+  };
+};
apps/backoffice-v2/src/pages/MerchantMonitoring/schemas.ts (1)

12-22: Consider using TypeScript enum or as const object.

The alert status mappings could benefit from stronger typing. Consider using a TypeScript enum or a const object with explicit types.

-export const IS_ALERT_TO_DISPLAY_TEXT = {
+export const IS_ALERT_TO_DISPLAY_TEXT = {
   All: 'All',
   true: 'Alerted',
   false: 'Not Alerted',
-} as const;
+} as const satisfies Record<string, string>;

-export const DISPLAY_TEXT_TO_IS_ALERT = {
+export const DISPLAY_TEXT_TO_IS_ALERT = {
   All: 'All',
   Alerted: true,
   'Not Alerted': false,
-} as const;
+} as const satisfies Record<string, boolean | string>;
apps/backoffice-v2/src/pages/Statistics/components/MonthPicker/MonthPicker.tsx (2)

22-43: Extract utility functions for better maintainability.

Consider extracting date comparison functions to improve code organization and reusability.

+const isDateAfterToday = (date: dayjs.Dayjs) => date.isAfter(today, 'month');
+const isDateBeforeMinDate = (date: dayjs.Dayjs, minDate: dayjs.Dayjs) =>
+  date.isBefore(minDate, 'month');

 const isMonthDisabled = (monthIndex: number) => {
   const monthDate = dayjs().year(currentYear).month(monthIndex).startOf('month');
-  return monthDate.isAfter(today, 'month');
+  return isDateAfterToday(monthDate);
 };

84-89: Simplify complex conditional logic.

The disabled condition could be simplified for better readability.

-disabled={
-  isMonthDisabled(index) ||
-  (dayjsMinDate &&
-    currentYear === dayjsMinDate.year() &&
-    index < dayjsMinDate.month())
-}
+disabled={isMonthDisabled(index) || isBeforeMinDate(index, currentYear, dayjsMinDate)}
apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx (1)

24-37: Consider adding error handling for date parsing.

The useDefaultDateRange hook sets a default 30-day range, but it should handle potential dayjs parsing errors.

 const useDefaultDateRange = () => {
   const [{ from, to }, setSearchParams] = useZodSearchParams(MerchantMonitoringSearchSchema);

   useEffect(() => {
     if (from || to) {
       return;
     }

+    try {
       setSearchParams({
         from: dayjs().subtract(30, 'day').format('YYYY-MM-DD'),
         to: dayjs().format('YYYY-MM-DD'),
       });
+    } catch (error) {
+      console.error('Error setting default date range:', error);
+    }
   }, []);
 };
apps/backoffice-v2/src/domains/business-reports/fetchers.ts (1)

122-133: Add retry logic for count endpoint.

The countBusinessReports function should include retry logic for better reliability.

 export const countBusinessReports = async (params: BusinessReportsParams) => {
   const queryParams = qs.stringify(params, { encode: false });
 
+  const MAX_RETRIES = 3;
+  let retries = 0;
+
+  while (retries < MAX_RETRIES) {
+    try {
       const [data, error] = await apiClient({
         endpoint: `../external/business-reports/count/?${queryParams}`,
         method: Method.GET,
         schema: BusinessReportsCountSchema,
         timeout: 30_000,
       });
 
-      return handleZodError(error, data);
+      const result = handleZodError(error, data);
+      if (result) return result;
+    } catch (error) {
+      if (retries === MAX_RETRIES - 1) throw error;
+      retries++;
+      await new Promise(resolve => setTimeout(resolve, 1000 * retries));
+    }
+  }
 };
apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/MerchantMonitoringBusinessReport.page.tsx (1)

117-127: Add tooltip to monitoring status indicator.

The monitoring status indicator should have a tooltip explaining its meaning.

 <div className={`flex items-center space-x-2 text-sm`}>
   <span className={`text-slate-400`}>Monitoring Status</span>
+  <Tooltip content={businessReport?.monitoringStatus ? 'Monitoring Active' : 'Monitoring Inactive'}>
     <span
       className={ctw('select-none rounded-full d-3', {
         'bg-success': businessReport?.monitoringStatus,
         'bg-slate-400': !businessReport?.monitoringStatus,
       })}
     >
       &nbsp;
     </span>
+  </Tooltip>
 </div>
apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx (1)

243-252: Consider adding a loading skeleton for the results badge.

While the badge is hidden during loading state, consider adding a skeleton loader to maintain layout stability and improve user experience.

 <div>
   {!isLoadingBusinessReports && (
     <Badge
       variant="secondary"
       className="rounded-full px-3 py-1 text-sm font-semibold text-gray-700"
     >
       {totalItems} results
     </Badge>
   )}
+  {isLoadingBusinessReports && (
+    <Skeleton className="h-7 w-24 rounded-full" />
+  )}
 </div>
services/workflows-service/src/auth/session-serializer.ts (2)

Line range hint 55-61: Consider using type inference instead of type assertion.

The type assertion as AuthenticatedEntity & { projectIds: string[] | null } can be replaced with proper type inference by defining the type upfront.

-      const authenticatedEntity = {
+      const authenticatedEntity: AuthenticatedEntity & { projectIds: string[] | null } = {
         user: userData,
         projectIds: userToProjects?.map(userToProject => userToProject.projectId) || null,
         type: 'user',
-      } as AuthenticatedEntity & { projectIds: string[] | null };
+      };

58-58: Consider returning empty array instead of null for projectIds.

Using an empty array instead of null for projectIds would be more consistent with array operations and eliminate the need for null checks in consuming code.

-        projectIds: userToProjects?.map(userToProject => userToProject.projectId) || null,
+        projectIds: userToProjects?.map(userToProject => userToProject.projectId) || [],
apps/backoffice-v2/public/locales/en/toast.json (1)

89-96: LGTM! Consider adding error details placeholder.

The new toast messages maintain consistency with existing patterns. Consider adding an error details placeholder similar to other error messages in the file (e.g., \n\n{{errorMessage}}).

   "business_monitoring_off": {
     "success": "Merchant monitoring has been turned off successfully.",
-    "error": "Error occurred while turning merchant monitoring off."
+    "error": "Error occurred while turning merchant monitoring off.\n\n{{errorMessage}}"
   },
   "business_monitoring_on": {
     "success": "Merchant monitoring has been turned on successfully.",
-    "error": "Error occurred while turning merchant monitoring on."
+    "error": "Error occurred while turning merchant monitoring on.\n\n{{errorMessage}}"
   },
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2d281d7 and e9c4abd.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (53)
  • apps/backoffice-v2/public/locales/en/toast.json (1 hunks)
  • apps/backoffice-v2/src/common/components/templates/Providers/Providers.tsx (1 hunks)
  • apps/backoffice-v2/src/common/hooks/useHomeLogic/useHomeLogic.ts (1 hunks)
  • apps/backoffice-v2/src/domains/auth/validation-schemas.ts (1 hunks)
  • apps/backoffice-v2/src/domains/business-reports/fetchers.ts (4 hunks)
  • apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportMetricsQuery/useBusinessReportMetricsQuery.ts (2 hunks)
  • apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx (2 hunks)
  • apps/backoffice-v2/src/domains/business-reports/query-keys.ts (1 hunks)
  • apps/backoffice-v2/src/pages/Home/Home.page.tsx (0 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx (7 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringTable/columns.tsx (4 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx (7 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoring/schemas.ts (3 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/MerchantMonitoringBusinessReport.page.tsx (4 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/fetchers.ts (1 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/hooks/useMerchantMonitoringBusinessReportLogic/useMerchantMonitoringBusinessReportLogic.tsx (5 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/mutations/useTurnMonitoringOffMutation/useTurnMonitoringOffMutation.tsx (1 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/mutations/useTurnMonitoringOnMutation/useTurnMonitoringOnMutation.tsx (1 hunks)
  • apps/backoffice-v2/src/pages/MerchantMonitoringCreateCheck/hooks/useMerchantMonitoringCreateBusinessReportPageLogic/useMerchantMonitoringCreateBusinessReportPageLogic.tsx (1 hunks)
  • apps/backoffice-v2/src/pages/Root/Root.page.tsx (1 hunks)
  • apps/backoffice-v2/src/pages/Statistics/Statistics.page.tsx (1 hunks)
  • apps/backoffice-v2/src/pages/Statistics/components/MonthPicker/MonthPicker.tsx (1 hunks)
  • apps/backoffice-v2/src/pages/Statistics/components/PortfolioAnalytics/PortfolioAnalytics.tsx (1 hunks)
  • apps/backoffice-v2/src/pages/Statistics/components/PortfolioAnalytics/hooks/usePortfolioAnalyticsLogic.tsx (1 hunks)
  • apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/PortfolioRiskStatistics.tsx (5 hunks)
  • apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/hooks/usePortfolioRiskStatisticsLogic/usePortfolioRiskStatisticsLogic.tsx (4 hunks)
  • apps/backoffice-v2/src/pages/Statistics/hooks/useStatisticsLogic.tsx (1 hunks)
  • apps/kyb-app/CHANGELOG.md (1 hunks)
  • apps/kyb-app/package.json (2 hunks)
  • packages/react-pdf-toolkit/CHANGELOG.md (1 hunks)
  • packages/react-pdf-toolkit/package.json (2 hunks)
  • packages/ui/CHANGELOG.md (1 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/components/atoms/Chart/Chart.tsx (1 hunks)
  • packages/ui/src/components/atoms/Chart/index.tsx (1 hunks)
  • packages/ui/src/components/atoms/index.ts (1 hunks)
  • packages/ui/src/components/molecules/ContentTooltip/ContentTooltip.stories.tsx (1 hunks)
  • packages/ui/src/components/molecules/ContentTooltip/ContentTooltip.tsx (1 hunks)
  • packages/ui/src/components/templates/report/components/AdsAndSocialMedia/AdsAndSocialMedia.tsx (7 hunks)
  • packages/ui/src/components/templates/report/components/Ecosystem/Ecosystem.tsx (2 hunks)
  • packages/ui/src/components/templates/report/components/WebsiteCredibility/WebsiteCredibility.tsx (11 hunks)
  • packages/ui/src/components/templates/report/components/WebsiteLineOfBusiness/WebsiteLineOfBusiness.tsx (3 hunks)
  • packages/ui/src/components/templates/report/components/WebsitesCompany/WebsitesCompany.tsx (3 hunks)
  • packages/ui/src/components/templates/report/hooks/useReportTabs/useReportTabs.tsx (4 hunks)
  • services/workflows-service/prisma/data-migrations (1 hunks)
  • services/workflows-service/src/auth/session-serializer.ts (1 hunks)
  • services/workflows-service/src/business-report/business-report.controller.external.ts (4 hunks)
  • services/workflows-service/src/business-report/dtos/business-report-list.dto.ts (3 hunks)
  • services/workflows-service/src/business-report/dtos/business-report-metrics.dto.ts (1 hunks)
  • services/workflows-service/src/business-report/dtos/business-report.dto.ts (1 hunks)
  • services/workflows-service/src/business-report/merchant-monitoring-client.ts (6 hunks)
  • services/workflows-service/src/business/business.controller.external.ts (3 hunks)
  • services/workflows-service/src/workflow/cron/ongoing-monitoring.cron.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/backoffice-v2/src/pages/Home/Home.page.tsx
✅ Files skipped from review due to trivial changes (9)
  • packages/ui/src/components/atoms/Chart/index.tsx
  • packages/ui/package.json
  • services/workflows-service/prisma/data-migrations
  • apps/kyb-app/package.json
  • apps/backoffice-v2/src/pages/MerchantMonitoringCreateCheck/hooks/useMerchantMonitoringCreateBusinessReportPageLogic/useMerchantMonitoringCreateBusinessReportPageLogic.tsx
  • packages/react-pdf-toolkit/package.json
  • apps/kyb-app/CHANGELOG.md
  • packages/react-pdf-toolkit/CHANGELOG.md
  • packages/ui/CHANGELOG.md
🧰 Additional context used
🪛 Biome (1.9.4)
packages/ui/src/components/atoms/Chart/Chart.tsx

[error] 72-72: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: test_windows
  • GitHub Check: test_linux
  • GitHub Check: build (windows-latest)
  • GitHub Check: spell_check
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: lint
🔇 Additional comments (40)
apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/PortfolioRiskStatistics.tsx (5)

19-20: LGTM! Props interface properly refined.

Good use of TypeScript's Pick utility type to narrow down the props interface to only the required fields. The new imports support the monitoring alerts section.

Also applies to: 22-24


25-38: LGTM! Hook interface properly aligned with component needs.

The hook's interface has been updated to match the component's requirements, and the new return values properly support the monitoring alerts functionality.


42-42: LGTM! Improved heading hierarchy.

The change from h5 to h3 better reflects the content's importance in the document outline.


46-46: LGTM! Clear and descriptive card header.

The updated header text "Merchant Monitoring Risk" clearly describes the section's purpose.


122-122: LGTM! Improved table structure.

The header text change to "Top 10 Content Violations" is more specific, and the padding adjustments improve the table's visual alignment.

Also applies to: 130-130

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

73-74: Clean extraction of complex condition!

Good job extracting the nested optional chaining into a clearly named variable. This improves readability and reduces duplication.


73-85: Verify configuration precedence handling.

The code handles business-level configuration and customer-level defaults, but let's verify there are no other configuration sources that could affect this hierarchy.

✅ Verification successful

Configuration hierarchy is well-defined and complete

The code follows a clear and consistent configuration precedence:

  1. Business-level configuration (business.metadata.featureConfig)
  2. Customer-level configuration (features)
  3. Default fallback (runByDefault option)

No other configuration sources were found that could affect this hierarchy.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other potential configuration sources that might affect the monitoring state

# Look for references to featureConfig
rg -A 3 "featureConfig.*${this.processFeatureName}" --type typescript

# Look for other monitoring state modifications
ast-grep --pattern 'metadata.featureConfig.$_.$_.enabled = $_'

Length of output: 195


Script:

#!/bin/bash
# Search for feature configuration patterns
rg "featureConfig" --type typescript -B 2 -A 2

# Look for metadata configuration patterns
rg "metadata\." --type typescript -B 2 -A 2

# Search for configuration initialization
ast-grep --pattern 'metadata = { featureConfig: $_ }'
ast-grep --pattern 'featureConfig = $_'

Length of output: 16337


Script:

#!/bin/bash
# Search in the specific service directory with explicit path
cd services/workflows-service/src && \
rg "featureConfig" -B 2 -A 2

# Look for configuration related patterns
cd services/workflows-service/src && \
rg "metadata\.(featureConfig|enabled)" -B 2 -A 2

# Search for process feature name references
cd services/workflows-service/src && \
rg "processFeatureName" -B 2 -A 2

Length of output: 8032

services/workflows-service/src/business-report/business-report.controller.external.ts (1)

265-290: ⚠️ Potential issue

Handle potential null values when accessing nested properties

When accessing metadata?.featureConfig?.[FEATURE_LIST.ONGOING_MERCHANT_REPORT]?.enabled, ensure that you account for cases where metadata or featureConfig might be null or undefined to prevent runtime errors.

Apply this diff to safely access nested properties:

-        const isOngoingEnabledForBusiness =
-          metadata?.featureConfig?.[FEATURE_LIST.ONGOING_MERCHANT_REPORT]?.enabled;

+        const isOngoingEnabledForBusiness = Boolean(
+          metadata &&
+            metadata.featureConfig &&
+            metadata.featureConfig[FEATURE_LIST.ONGOING_MERCHANT_REPORT]?.enabled,
+        );

Likely invalid or redundant comment.

packages/ui/src/components/atoms/Chart/Chart.tsx (1)

248-252: Return null early if the legend payload is empty

The check if (!payload?.length) is appropriate. Ensure that this pattern is consistently used in other components like ChartTooltipContent for early returns when there is no data to display.

apps/backoffice-v2/src/domains/auth/validation-schemas.ts (1)

10-10: LGTM! Well-structured schema extension.

The addition of lastActiveAt field with proper datetime validation, nullability, and optional flags aligns well with the user monitoring enhancement objectives.

apps/backoffice-v2/src/common/components/templates/Providers/Providers.tsx (1)

11-13: LGTM! Clean tooltip provider integration.

The TooltipProvider is properly integrated with a reasonable delay duration, enhancing the UI/UX with tooltip functionality.

apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/fetchers.ts (1)

18-18: Verify the need for a 5-minute timeout.

The 300,000ms (5-minute) timeout seems unusually long for a PATCH request. Consider reducing it unless there's a specific requirement.

packages/ui/src/components/atoms/index.ts (1)

28-28: LGTM! Export follows consistent pattern.

The addition of the Chart export follows the established pattern and integrates well with the existing component exports.

apps/backoffice-v2/src/pages/Statistics/hooks/useStatisticsLogic.tsx (1)

21-24: Verify date range calculation.

The code adds exactly one month to the 'from' date, which might not handle edge cases correctly (e.g., different month lengths).

Consider using dayjs's endOf('month') instead:

-    to: dayjs(from).add(1, 'month').format('YYYY-MM-DD'),
+    to: dayjs(from).endOf('month').format('YYYY-MM-DD'),
apps/backoffice-v2/src/domains/business-reports/hooks/queries/useBusinessReportsQuery/useBusinessReportsQuery.tsx (1)

52-52: ⚠️ Potential issue

Verify the impact of simplified enabled condition.

The enabled condition was simplified to only check authentication. This could lead to unnecessary queries when required parameters are missing.

-    enabled: isAuthenticated,
+    enabled: isAuthenticated && 
+      (reportType ? true : false) && // Only enable if reportType is provided or explicitly undefined
+      (!page || (page > 0)), // Ensure valid page number if provided

Run this script to check for potential unnecessary query calls:

apps/backoffice-v2/src/pages/Statistics/components/PortfolioAnalytics/hooks/usePortfolioAnalyticsLogic.tsx (1)

31-42: Consider adding validation for edge cases in width calculation.

The width calculation logic should handle the case when all counts are 0, which could lead to division by zero in the Math.max calculation.

Add validation to prevent potential issues:

  const widths = useMemo(
    () =>
      filteredRiskIndicators.map(item =>
        item.count > 0
          ? Math.max(
-              (item.count / Math.max(...filteredRiskIndicators.map(item => item.count), 0)) * 100,
+              (item.count / Math.max(...filteredRiskIndicators.map(item => item.count), 1)) * 100,
              2,
            )
          : 0,
      ),
    [filteredRiskIndicators],
  );
apps/backoffice-v2/src/pages/Statistics/components/PortfolioRiskStatistics/hooks/usePortfolioRiskStatisticsLogic/usePortfolioRiskStatisticsLogic.tsx (3)

10-15: LGTM! Clean import organization.

The new imports are well-organized and necessary for the added functionality.


80-84: LGTM! Clean return object structure.

The new properties are well-organized and follow a consistent pattern.


64-68: Verify error handling for the business reports query.

The query implementation looks good, but ensure that error states are properly handled in the UI.

apps/backoffice-v2/src/pages/MerchantMonitoring/schemas.ts (1)

120-127: LGTM! Well-structured schema definition.

The isAlert field is well-defined with proper validation and default value.

apps/backoffice-v2/src/pages/Statistics/components/MonthPicker/MonthPicker.tsx (1)

9-21: Consider adding validation for minDate.

The minDate prop should be validated to ensure it's not after the selected date.

if (minDate && dayjs(minDate).isAfter(date)) {
  console.warn('minDate should not be after the selected date');
}
apps/backoffice-v2/src/pages/MerchantMonitoringBusinessReport/hooks/useMerchantMonitoringBusinessReportLogic/useMerchantMonitoringBusinessReportLogic.tsx (1)

109-110: LGTM! Clean hook interface.

The new monitoring functions are properly exposed in the return object.

packages/ui/src/components/templates/report/components/WebsiteLineOfBusiness/WebsiteLineOfBusiness.tsx (1)

21-30: LGTM! Consistent tooltip implementation enhances user experience.

The tooltips are well-implemented with:

  • Clear, contextual descriptions
  • Consistent center alignment
  • Proper semantic HTML structure

Also applies to: 38-52, 63-77, 86-97

apps/backoffice-v2/src/pages/MerchantMonitoring/hooks/useMerchantMonitoringLogic/useMerchantMonitoringLogic.tsx (1)

83-83: Verify isAlert filter implementation.

The isAlert filter is correctly implemented, but ensure all API endpoints support this parameter.

✅ Verification successful

isAlert filter implementation is properly supported

The isAlert parameter is properly supported across the API endpoints:

  • Validated through BusinessReportSchema
  • Included in API requests via queryParams
  • Properly typed and parsed in the backend
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the isAlert parameter is supported across relevant endpoints

# Test: Search for API endpoint definitions that should support isAlert
rg -A 5 "business-reports.*\?" 

Length of output: 3880


Script:

#!/bin/bash
# Check queryParams construction and API handlers
# First, find where queryParams is constructed
rg -l "queryParams.*business-reports" --type typescript

# Then look for API route handlers
rg -l "router\.(get|post).*business-reports" --type typescript

Length of output: 192


Script:

#!/bin/bash
# Search for queryParams construction and API handlers
rg -A 5 "const queryParams.*business.*reports" 

# Search for API route definitions
rg -A 5 "router\.(get|post).*business-reports"

# Search specifically for isAlert parameter handling
rg -A 5 "isAlert.*business.*reports"

Length of output: 136


Script:

#!/bin/bash
# Search for merchant monitoring related files
fd "MerchantMonitoring|merchant-monitoring" --type f

# Search for query parameters in these contexts
rg -A 5 "params.*isAlert|queryParams.*isAlert"

Length of output: 1960


Script:

#!/bin/bash
# Check the table implementation and related schemas
cat "apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringTable/hooks/useMerchantMonitoringTableLogic/useMerchantMonitoringTableLogic.tsx"

# Check business reports fetchers
cat "apps/backoffice-v2/src/domains/business-reports/fetchers.ts"

# Look for schema definitions
rg -A 5 "Schema.*isAlert"

Length of output: 7528

packages/ui/src/components/templates/report/hooks/useReportTabs/useReportTabs.tsx (3)

68-70: LGTM: Social media refactoring

The changes align with the removal of ads-related functionality, focusing solely on social media analysis.


104-121: LGTM: Enhanced UX with informative tooltip

The addition of ContentTooltip improves user experience by providing clear context about the summary section's purpose.


180-180: LGTM: Consistent label update

The tab label change maintains consistency with the removal of ads-related functionality.

services/workflows-service/src/business-report/merchant-monitoring-client.ts (4)

30-32: LGTM: Improved type handling for isAlert field

The preprocessing step and optional field type enhance type safety while maintaining flexibility in handling boolean values.


77-79: LGTM: Added comprehensive merchant metrics

The new numeric fields enhance monitoring capabilities by tracking merchant activity metrics.


227-241: LGTM: Enhanced query flexibility

The optional parameters and new isAlert filter improve the method's versatility for different query scenarios.


285-298: LGTM: Added date range filtering for metrics

The addition of optional date range parameters enables more precise metric analysis.

packages/ui/src/components/templates/report/components/AdsAndSocialMedia/AdsAndSocialMedia.tsx (3)

103-114: LGTM: Enhanced section heading with tooltip

The ContentTooltip addition and title change maintain consistency while improving user understanding.


Line range hint 136-155: LGTM: Refined layout styling

The class name adjustments improve the visual presentation while maintaining functionality.


Line range hint 167-194: LGTM: Enhanced content overflow handling

The styling updates improve the handling of long content and maintain consistent link presentation.

services/workflows-service/src/business/business.controller.external.ts (2)

136-190: LGTM: Well-implemented monitoring state management

The new endpoint properly handles state updates with transaction safety and proper metadata merging.


223-230: LGTM: Consistent metadata handling

The patch method maintains consistency with the new monitoring state endpoint in handling metadata updates.

apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx (1)

198-232: LGTM! Well-structured monitoring alerts dropdown.

The implementation follows the same pattern as the existing report type dropdown, maintaining consistency in the UI.

packages/ui/src/components/templates/report/components/WebsiteCredibility/WebsiteCredibility.tsx (1)

279-318: LGTM! Improved chart visualization.

The switch to AreaChart with gradient fill enhances data visualization and maintains good accessibility with the accessibilityLayer prop.

apps/backoffice-v2/src/pages/Root/Root.page.tsx (1)

46-46: Verify error handling after ServerDownLayout removal.

With the removal of ServerDownLayout, ensure that server connectivity issues are still properly handled and communicated to users.

✅ Verification successful

Error handling is properly maintained after ServerDownLayout removal

The codebase has dedicated error handling components in place:

  • Root.error.tsx serves as the error boundary
  • RouteError and RouteErrorWithProviders handle route-level errors
  • ErrorAlert component for displaying error messages
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for alternative error handling implementations
rg -A 5 "error|fallback|boundary" --type ts --type tsx

Length of output: 84


Script:

#!/bin/bash
# Search for error handling patterns in TypeScript files
rg -t ts "error|fallback|boundary|ErrorBoundary|onError" 

# Search specifically for error-related components and layouts
fd -e tsx -e ts --exec grep -l -i "error\|fallback\|boundary\|ErrorBoundary"

# Look for error boundary implementations
ast-grep --pattern 'class $_ extends ErrorBoundary { $$$ }'

Length of output: 71042


Script:

#!/bin/bash
# Search for error handling in the frontend codebase
fd -t f -e tsx -e ts . apps/backoffice-v2/src | xargs grep -l "Error\|Fallback\|boundary"

# Look for error boundary implementations in React components
ast-grep --pattern 'function $name($props) {
  $$$
  <ErrorBoundary>
    $$$
  </ErrorBoundary>
  $$$
}'

Length of output: 9888

apps/backoffice-v2/src/domains/business-reports/query-keys.ts (1)

36-44: LGTM! Improved query parameter handling.

The conditional inclusion of pagination parameters is well implemented, ensuring clean query objects when optional parameters are omitted.

✅ Verification successful

Pagination implementation is consistent with codebase patterns

The conditional pagination parameter handling in query-keys.ts follows the established pattern used across the codebase, with proper type conversion and consistent structure.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify consistent pagination handling across the codebase
ast-grep --pattern 'page?: {
  number: number;
  size: number;
}'

Length of output: 67


Script:

#!/bin/bash
# Search for pagination-related type definitions and usage
echo "=== Searching for pagination type definitions ==="
rg "type.*Page.*{" -A 3

echo -e "\n=== Searching for page/pageSize parameter usage ==="
rg "page.*size|pageSize" -A 2

echo -e "\n=== Searching for query parameter construction ==="
rg "(\?|&)page=" -A 2

Length of output: 22527

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

♻️ Duplicate comments (1)
packages/ui/src/components/templates/report/components/WebsiteCredibility/WebsiteCredibility.tsx (1)

85-95: ⚠️ Potential issue

Consider edge cases in trend calculation.

The trend calculation function needs additional error handling:

  1. Division by zero when previousMonthValue is 0
  2. NaN handling for invalid number conversions
 const calculateTrend = (data: Array<{ label: string; value: string }>) => {
   if (data.length < 2) {
     return { direction: 'No trend data', percentage: 0 };
   }
   const lastMonthValue = parseInt(data[data.length - 1]?.value ?? '0');
   const previousMonthValue = parseInt(data[data.length - 2]?.value ?? '0');
+  if (isNaN(lastMonthValue) || isNaN(previousMonthValue)) {
+    return { direction: 'No trend data', percentage: 0 };
+  }
+  if (previousMonthValue === 0) {
+    return {
+      direction: lastMonthValue > 0 ? 'up' : 'No trend data',
+      percentage: lastMonthValue > 0 ? 100 : 0,
+    };
+  }
   const percentageChange = ((lastMonthValue - previousMonthValue) / previousMonthValue) * 100;
   const direction = lastMonthValue > previousMonthValue ? 'up' : 'down';

   return { direction, percentage: Math.abs(percentageChange) };
 };
🧹 Nitpick comments (10)
packages/workflow-core/CHANGELOG.md (1)

8-8: Fix typographical error in changelog entry.

There appears to be a stray "s" character in the changelog entry.

-  s Please enter a summary for your changes.
+  Please enter a summary for your changes.
🧰 Tools
🪛 LanguageTool

[typographical] ~8-~8: Consider adding a comma here.
Context: ...5 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

packages/config/CHANGELOG.md (1)

3-7: Consider adding more descriptive changelog entries.

The current changelog entry only mentions "version bump" without providing context about what changed or why. This pattern is consistent across previous versions, making it difficult for users to understand the purpose of each release.

Consider adding more descriptive entries that explain:

  • What changed
  • Why it changed
  • Any breaking changes or migration steps if applicable

Example format:

## 1.1.30

### Patch Changes

- Updated dependencies to align with UI-UX hackathon changes
- Improved configuration options for merchant monitoring
services/workflows-service/CHANGELOG.md (1)

3-12: Add a descriptive changelog summary.

The changelog entry only mentions "version bump" without providing any context about the actual changes. Consider adding a more descriptive summary of the changes made in this version to help users understand what has been updated.

🧰 Tools
🪛 LanguageTool

[typographical] ~8-~8: Consider adding a comma here.
Context: ...9 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

services/websocket-service/CHANGELOG.md (1)

3-9: Consider improving changelog quality.

The changelog currently consists mostly of version bump entries without meaningful descriptions of changes. Consider:

  1. Adding more descriptive entries about what changed in each version
  2. Including links to related PRs or issues
  3. Categorizing changes (e.g., Features, Bug Fixes, etc.)
  4. Mentioning any breaking changes or deprecations
🧰 Tools
🪛 LanguageTool

[typographical] ~8-~8: Consider adding a comma here.
Context: ...0 ### Patch Changes - version bump s Please enter a summary for your changes. ## 0...

(PLEASE_COMMA)

packages/rules-engine/CHANGELOG.md (1)

1-9: Improve changelog documentation practices.

The changelog history shows a pattern of version bumps with minimal descriptions, making it difficult to track meaningful changes between versions. Consider adopting better changelog practices:

  1. Include detailed descriptions of changes
  2. Categorize changes (e.g., Features, Bug Fixes, Breaking Changes)
  3. Reference related PR/issue numbers

Example format:

## [version]

### Features
- Added X functionality (#PR)

### Bug Fixes
- Fixed Y issue (#PR)

### Breaking Changes
- Changed Z behavior (#PR)
🧰 Tools
🪛 LanguageTool

[typographical] ~8-~8: Consider adding a comma here.
Context: ...0 ### Patch Changes - version bump s Please enter a summary for your changes. ## 0...

(PLEASE_COMMA)

packages/ui/src/components/templates/report/components/WebsiteCredibility/WebsiteCredibility.tsx (3)

4-5: Consider organizing imports for better maintainability.

Group imports into sections:

  1. External dependencies
  2. Internal components/utilities
  3. Types/interfaces
+ // External dependencies
import dayjs from 'dayjs';
import { InfoIcon, TrendingDown, TrendingUp } from 'lucide-react';
import { FunctionComponent, useMemo } from 'react';
import { Area, AreaChart, CartesianGrid, Cell, Legend, Pie, PieChart, Tooltip as RechartsTooltip, ResponsiveContainer, XAxis, YAxis } from 'recharts';
import { capitalize } from 'string-ts';

+ // Internal components/utilities
import { ctw } from '@/common';
import { Card, CardContent, CardHeader } from '@/components';
import { CardDescription, CardFooter, CardTitle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/atoms';
import { BallerineLink } from '@/components/atoms/BallerineLink/BallerineLink';
import { ContentTooltip } from '@/components/molecules/ContentTooltip/ContentTooltip';
import { RiskIndicators } from '@/components/molecules/RiskIndicators/RiskIndicators';
import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/atoms';

Also applies to: 8-8, 22-24


104-116: Extract common tooltip configuration to reduce duplication.

Multiple ContentTooltip components share the same configuration. Consider extracting the common props to a constant or creating a wrapper component.

+ const TOOLTIP_PROPS = {
+   tooltipContent: {
+     align: 'center',
+   },
+ };

- <ContentTooltip
-   props={{
-     tooltipContent: {
-       align: 'center',
-     },
-   }}
+ <ContentTooltip
+   props={TOOLTIP_PROPS}

Also applies to: 123-135, 164-176, 203-215, 240-252


300-305: Simplify YAxis domain calculation.

The current domain calculation can be simplified using a more declarative approach.

 <YAxis
-  domain={[0, (dataMax: number) => Math.ceil(dataMax * 1.2)]}
+  domain={[0, 'auto']}
+  allowDataOverflow={false}
   tickFormatter={value =>
     Intl.NumberFormat('en', { notation: 'compact' }).format(value)
   }
 />
examples/headless-example/CHANGELOG.md (1)

7-8: Fix the typo in the changelog entry.

Remove the accidental "s" character from the changelog entry.

Apply this diff to fix the typo:

- - version bump
-   s Please enter a summary for your changes.
+ - version bump
+   Please enter a summary for your changes.
🧰 Tools
🪛 LanguageTool

[typographical] ~8-~8: Consider adding a comma here.
Context: ...4 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

apps/workflows-dashboard/CHANGELOG.md (1)

7-8: Fix the typo in the changelog entry.

Remove the accidental "s" character from the changelog entry.

Apply this diff to fix the typo:

- - version bump
-   s Please enter a summary for your changes.
+ - version bump
+   Please enter a summary for your changes.
🧰 Tools
🪛 LanguageTool

[typographical] ~8-~8: Consider adding a comma here.
Context: ...0 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e9c4abd and e746ce3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (41)
  • apps/backoffice-v2/CHANGELOG.md (1 hunks)
  • apps/backoffice-v2/package.json (3 hunks)
  • apps/kyb-app/CHANGELOG.md (1 hunks)
  • apps/kyb-app/package.json (3 hunks)
  • apps/workflows-dashboard/CHANGELOG.md (1 hunks)
  • apps/workflows-dashboard/package.json (3 hunks)
  • examples/headless-example/CHANGELOG.md (1 hunks)
  • examples/headless-example/package.json (2 hunks)
  • examples/report-generation-example/CHANGELOG.md (1 hunks)
  • examples/report-generation-example/package.json (2 hunks)
  • packages/blocks/CHANGELOG.md (1 hunks)
  • packages/blocks/package.json (3 hunks)
  • packages/common/CHANGELOG.md (1 hunks)
  • packages/common/package.json (2 hunks)
  • packages/config/CHANGELOG.md (1 hunks)
  • packages/config/package.json (1 hunks)
  • packages/eslint-config-react/CHANGELOG.md (1 hunks)
  • packages/eslint-config-react/package.json (2 hunks)
  • packages/eslint-config/CHANGELOG.md (1 hunks)
  • packages/eslint-config/package.json (1 hunks)
  • packages/react-pdf-toolkit/CHANGELOG.md (1 hunks)
  • packages/react-pdf-toolkit/package.json (2 hunks)
  • packages/rules-engine/CHANGELOG.md (1 hunks)
  • packages/rules-engine/package.json (2 hunks)
  • packages/ui/CHANGELOG.md (1 hunks)
  • packages/ui/package.json (3 hunks)
  • packages/ui/src/components/templates/report/components/WebsiteCredibility/WebsiteCredibility.tsx (7 hunks)
  • packages/workflow-core/CHANGELOG.md (1 hunks)
  • packages/workflow-core/package.json (3 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/websocket-service/CHANGELOG.md (1 hunks)
  • services/websocket-service/package.json (1 hunks)
  • services/workflows-service/CHANGELOG.md (1 hunks)
  • services/workflows-service/package.json (3 hunks)
  • services/workflows-service/prisma/data-migrations (1 hunks)
  • websites/docs/package.json (1 hunks)
✅ Files skipped from review due to trivial changes (11)
  • packages/config/package.json
  • packages/eslint-config/package.json
  • services/websocket-service/package.json
  • sdks/web-ui-sdk/package.json
  • examples/report-generation-example/package.json
  • packages/eslint-config-react/package.json
  • packages/workflow-core/package.json
  • sdks/workflow-browser-sdk/CHANGELOG.md
  • examples/headless-example/package.json
  • packages/rules-engine/package.json
  • packages/blocks/package.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/react-pdf-toolkit/package.json
  • packages/ui/package.json
  • services/workflows-service/prisma/data-migrations
  • apps/kyb-app/package.json
  • packages/ui/CHANGELOG.md
🧰 Additional context used
🪛 LanguageTool
sdks/web-ui-sdk/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...7 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

examples/headless-example/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...4 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

apps/backoffice-v2/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...3 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

examples/report-generation-example/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...9 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

sdks/workflow-node-sdk/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...5 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

apps/kyb-app/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...9 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

apps/workflows-dashboard/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...0 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

packages/blocks/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...2 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

packages/common/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...6 ### Patch Changes - version bump s Please enter a summary for your changes. ## 0...

(PLEASE_COMMA)

packages/config/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...0 ### Patch Changes - version bump s Please enter a summary for your changes. ## 1...

(PLEASE_COMMA)

packages/eslint-config-react/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...0 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

packages/eslint-config/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...0 ### Patch Changes - version bump s Please enter a summary for your changes. ## 1...

(PLEASE_COMMA)

packages/react-pdf-toolkit/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...2 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

packages/rules-engine/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...0 ### Patch Changes - version bump s Please enter a summary for your changes. ## 0...

(PLEASE_COMMA)

packages/workflow-core/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...5 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

services/websocket-service/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...0 ### Patch Changes - version bump s Please enter a summary for your changes. ## 0...

(PLEASE_COMMA)

services/workflows-service/CHANGELOG.md

[typographical] ~8-~8: Consider adding a comma here.
Context: ...9 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test_windows
  • GitHub Check: test_linux
  • GitHub Check: build (windows-latest)
  • GitHub Check: spell_check
  • GitHub Check: lint
🔇 Additional comments (17)
packages/workflow-core/CHANGELOG.md (1)

3-10: LGTM! Changelog entry follows the conventional format.

The changelog entry correctly documents:

🧰 Tools
🪛 LanguageTool

[typographical] ~8-~8: Consider adding a comma here.
Context: ...5 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

packages/common/package.json (2)

5-5: LGTM! Version bump follows semantic versioning.

The patch version increment from 0.9.65 to 0.9.66 indicates backward-compatible bug fixes, which aligns with the PR's UI/UX improvements.


41-42: LGTM! Consistent dependency updates.

The minor version bumps for @ballerine/config and @ballerine/eslint-config are consistent and maintain backward compatibility.

packages/eslint-config/CHANGELOG.md (1)

3-7: LGTM! Version bump follows consistent format.

The new version entry and patch changes section follows the established changelog format.

packages/blocks/CHANGELOG.md (1)

3-10: LGTM! Version bump and dependency update.

The version increment and dependency update to @ballerine/[email protected] follow the established pattern in the changelog.

🧰 Tools
🪛 LanguageTool

[typographical] ~8-~8: Consider adding a comma here.
Context: ...2 ### Patch Changes - version bump s Please enter a summary for your changes. - Upd...

(PLEASE_COMMA)

sdks/web-ui-sdk/CHANGELOG.md (1)

9-10: LGTM!

The dependency update section is properly formatted and clearly indicates the version change of @ballerine/common from 0.9.65 to 0.9.66.

apps/kyb-app/CHANGELOG.md (1)

3-7: LGTM! Version entry follows the conventional changelog format.

The new version 0.3.109 is properly documented with all dependency updates clearly listed.

Also applies to: 9-13

examples/report-generation-example/CHANGELOG.md (1)

9-10: LGTM!

The dependency update to @ballerine/[email protected] is properly formatted.

apps/backoffice-v2/CHANGELOG.md (1)

9-15: LGTM!

The dependency updates are properly formatted and include:

packages/eslint-config-react/CHANGELOG.md (1)

9-10: Verify the dependency version bump.

The dependency @ballerine/eslint-config has been updated from 1.1.29 to 1.1.30.

Let's verify if this version exists and if it's the latest version:

✅ Verification successful

Version bump to @ballerine/[email protected] is correct and consistent across the codebase

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the dependency version exists and if it's the latest

# Check package.json files for any mismatched versions of @ballerine/eslint-config
fd package.json --exec rg -l "@ballerine/eslint-config.*1\.1\.(29|30)"

# Check the version in the package's own package.json
fd package.json --exec rg -l "\"version\".*1\.1\.(29|30)" packages/eslint-config/

Length of output: 1418


Script:

#!/bin/bash
# Get the actual version from eslint-config/package.json
echo "Version in eslint-config/package.json:"
cat packages/eslint-config/package.json | grep -A1 '"version"'

echo -e "\nVersions in dependent packages:"
# Check the exact versions in all package.json files
fd package.json --exec grep -H "@ballerine/eslint-config.*1\.1\.(29|30)"

Length of output: 349


Script:

#!/bin/bash
echo "Checking all dependencies in package.json files:"
fd package.json --exec sh -c 'echo "=== $1 ==="; cat "$1" | grep -A 1 "\"@ballerine/eslint-config\":" || true' sh {}

echo -e "\nChecking with different pattern:"
fd package.json --exec sh -c 'echo "=== $1 ==="; cat "$1" | grep -B 2 -A 2 "eslint-config.*1\.1\.(29|30)" || true' sh {}

Length of output: 3414

packages/ui/src/components/templates/report/components/WebsiteCredibility/WebsiteCredibility.tsx (1)

156-158: Well-implemented empty states!

The empty state messages are clear, informative, and consistently implemented across different sections.

Also applies to: 192-197, 233-235

sdks/workflow-browser-sdk/package.json (1)

4-4: Verify package versions and check for security advisories.

The version updates look consistent across packages. Let's verify the versions and check for any security concerns.

Also applies to: 36-37, 44-46

✅ Verification successful

Version updates are consistent and properly coordinated

The changes are part of a coordinated release updating all packages to their next patch version. Current versions exist on npm, and the increments follow semantic versioning guidelines.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify package versions exist and check for security advisories

# Function to check if a package version exists on npm
check_version() {
    local package=$1
    local version=$2
    echo "Checking $package@$version..."
    if npm view "$package@$version" version &>/dev/null; then
        echo "✓ Version exists"
    else
        echo "⨯ Version not found"
    fi
}

# Check all updated package versions
check_version "@ballerine/workflow-browser-sdk" "0.6.85"
check_version "@ballerine/common" "0.9.66"
check_version "@ballerine/workflow-core" "0.6.85"
check_version "@ballerine/config" "1.1.30"
check_version "@ballerine/eslint-config" "1.1.30"

# Check for security advisories
echo "Checking for security advisories..."
for pkg in "@ballerine/common" "@ballerine/workflow-core"; do
    npm audit --package-lock-only "$pkg@latest"
done

Length of output: 2529


Script:

#!/bin/bash
# Check for registry configuration and monorepo setup
echo "=== Package Registry Configuration ==="
cat sdks/workflow-browser-sdk/package.json | grep -A 5 "publishConfig"

echo -e "\n=== Checking Root package.json ==="
cat package.json | grep -A 5 "workspaces"

echo -e "\n=== Checking if packages are published ==="
for pkg in "@ballerine/workflow-browser-sdk" "@ballerine/common" "@ballerine/workflow-core" "@ballerine/config" "@ballerine/eslint-config"; do
    echo "Latest version of $pkg:"
    npm view "$pkg" version || echo "Package not found"
done

Length of output: 1809

websites/docs/package.json (1)

20-20: LGTM! Package version updates are consistent.

The version updates for @ballerine packages are consistent with the coordinated version bump across the project.

Also applies to: 26-27

sdks/workflow-node-sdk/package.json (1)

4-4: LGTM! Package version updates are consistent.

The version updates are consistent across the package and its dependencies, maintaining proper version alignment.

Also applies to: 31-31, 39-39, 41-41

apps/workflows-dashboard/package.json (1)

4-4: Verify the version jump for @ballerine/ui package.

While most version updates are single patch increments, @ballerine/ui jumps from 0.5.60 to 0.5.62. Please verify if this double version bump is intentional and if any intermediate version (0.5.61) should be considered.

Also applies to: 19-20, 67-68

✅ Verification successful

Version jump for @ballerine/ui package appears intentional

The version update from 0.5.60 to 0.5.62 is consistently applied across all dependent packages in the monorepo, suggesting this was a coordinated and intentional version bump.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check the version history of @ballerine/ui package
gh api graphql -f query='
{
  repository(owner: "ballerine-io", name: "ballerine") {
    packages(first: 1, names: ["@ballerine/ui"]) {
      nodes {
        versions(first: 3, orderBy: {field: CREATED_AT, direction: DESC}) {
          nodes {
            version
            createdAt
          }
        }
      }
    }
  }
}'

Length of output: 682


Script:

#!/bin/bash
# Search for @ballerine/ui version patterns in package.json files
rg '"@ballerine/ui":\s*"\^?0\.5\.(60|61|62)"' -A 1 -B 1

# Find all package.json files that contain @ballerine/ui
fd package.json --exec grep -l "@ballerine/ui"

Length of output: 1171


Script:

#!/bin/bash
# Check the ui package's own package.json
cat packages/ui/package.json | grep -A 1 -B 1 '"version":'

# Look for recent version changes in ui package
git log -n 5 --oneline packages/ui/package.json

Length of output: 123

services/workflows-service/package.json (1)

4-4: LGTM! Package version updates are consistent.

The version updates are consistent across all dependencies, with proper alignment between workflow-core and workflow-node-sdk packages.

Also applies to: 53-55, 116-117

apps/backoffice-v2/package.json (1)

3-3: Verify version consistency across packages.

Please verify the following version inconsistencies:

  1. @ballerine/react-pdf-toolkit jumps from 1.2.60 to 1.2.62
  2. @ballerine/ui shows different upgrade paths:
    • In this file: 0.5.61 -> 0.5.62
    • In workflows-dashboard: 0.5.60 -> 0.5.62

Also applies to: 55-60, 152-153

✅ Verification successful

Version consistency verified across packages

The current state shows all packages are using consistent versions:

  • @ballerine/ui is at ^0.5.62 across all apps
  • @ballerine/react-pdf-toolkit is at ^1.2.62
  • These versions match their respective source package versions

The version jumps appear to be intentional releases, and any intermediate inconsistencies have been resolved.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check version history of the packages
echo "Checking @ballerine/react-pdf-toolkit versions:"
gh api graphql -f query='
{
  repository(owner: "ballerine-io", name: "ballerine") {
    packages(first: 1, names: ["@ballerine/react-pdf-toolkit"]) {
      nodes {
        versions(first: 3, orderBy: {field: CREATED_AT, direction: DESC}) {
          nodes {
            version
            createdAt
          }
        }
      }
    }
  }
}'

echo "Checking @ballerine/ui versions:"
gh api graphql -f query='
{
  repository(owner: "ballerine-io", name: "ballerine") {
    packages(first: 1, names: ["@ballerine/ui"]) {
      nodes {
        versions(first: 3, orderBy: {field: CREATED_AT, direction: DESC}) {
          nodes {
            version
            createdAt
          }
        }
      }
    }
  }
}'

Length of output: 1560


Script:

#!/bin/bash
# Check version history without createdAt field
echo "Checking @ballerine/react-pdf-toolkit versions:"
gh api graphql -f query='
{
  repository(owner: "ballerine-io", name: "ballerine") {
    packages(first: 1, names: ["@ballerine/react-pdf-toolkit"]) {
      nodes {
        versions(first: 3, orderBy: {field: CREATED_AT, direction: DESC}) {
          nodes {
            version
          }
        }
      }
    }
  }
}'

echo "Checking @ballerine/ui versions:"
gh api graphql -f query='
{
  repository(owner: "ballerine-io", name: "ballerine") {
    packages(first: 1, names: ["@ballerine/ui"]) {
      nodes {
        versions(first: 3, orderBy: {field: CREATED_AT, direction: DESC}) {
          nodes {
            version
          }
        }
      }
    }
  }
}'

# Search for package.json files containing these dependencies
echo "Searching for package.json files with these dependencies:"
rg -l "(@ballerine/react-pdf-toolkit|@ballerine/ui)" -g "package.json"

Length of output: 1328


Script:

#!/bin/bash
echo "Checking @ballerine/ui versions in apps:"
echo "backoffice-v2:"
rg "@ballerine/ui.*\"" apps/backoffice-v2/package.json

echo "\nworkflows-dashboard:"
rg "@ballerine/ui.*\"" apps/workflows-dashboard/package.json

echo "\nChecking @ballerine/react-pdf-toolkit versions in apps:"
echo "backoffice-v2:"
rg "@ballerine/react-pdf-toolkit.*\"" apps/backoffice-v2/package.json

echo "\nworkflows-dashboard:"
rg "@ballerine/react-pdf-toolkit.*\"" apps/workflows-dashboard/package.json

echo "\nChecking source package versions:"
echo "packages/ui/package.json version:"
rg "\"version\":" packages/ui/package.json

echo "\npackages/react-pdf-toolkit/package.json version:"
rg "\"version\":" packages/react-pdf-toolkit/package.json

Length of output: 1192

packages/eslint-config/CHANGELOG.md Show resolved Hide resolved
packages/config/CHANGELOG.md Show resolved Hide resolved
services/workflows-service/CHANGELOG.md Show resolved Hide resolved
packages/blocks/CHANGELOG.md Show resolved Hide resolved
packages/common/CHANGELOG.md Show resolved Hide resolved
apps/kyb-app/CHANGELOG.md Show resolved Hide resolved
packages/rules-engine/CHANGELOG.md Show resolved Hide resolved
apps/backoffice-v2/CHANGELOG.md Show resolved Hide resolved
packages/eslint-config-react/CHANGELOG.md Show resolved Hide resolved
- Merge nested span into TextWithNAFallback for better clarity
- Remove unused import of CardTitle in WebsiteCredibility component

(your code's like a good magician—just when I think I see the trick, it disappears)
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

♻️ Duplicate comments (1)
packages/ui/src/components/templates/report/components/WebsiteCredibility/WebsiteCredibility.tsx (1)

85-96: ⚠️ Potential issue

Consider edge cases in trend calculation.

The trend calculation function needs additional error handling:

  1. Division by zero when previousMonthValue is 0
  2. NaN handling for invalid number conversions
 const calculateTrend = (data: Array<{ label: string; value: string }>) => {
   if (data.length < 2) {
     return { direction: 'No trend data', percentage: 0 };
   }

   const lastMonthValue = parseInt(data[data.length - 1]?.value ?? '0');
   const previousMonthValue = parseInt(data[data.length - 2]?.value ?? '0');
+  if (isNaN(lastMonthValue) || isNaN(previousMonthValue)) {
+    return { direction: 'No trend data', percentage: 0 };
+  }
+  if (previousMonthValue === 0) {
+    return {
+      direction: lastMonthValue > 0 ? 'up' : 'No trend data',
+      percentage: lastMonthValue > 0 ? 100 : 0,
+    };
+  }
   const percentageChange = ((lastMonthValue - previousMonthValue) / previousMonthValue) * 100;
   const direction = lastMonthValue > previousMonthValue ? 'up' : 'down';

   return { direction, percentage: Math.abs(percentageChange) };
 };
🧹 Nitpick comments (6)
packages/ui/src/components/templates/report/components/WebsiteCredibility/WebsiteCredibility.tsx (3)

4-5: Consider organizing imports for better maintainability.

Group imports in the following order:

  1. External dependencies
  2. Internal components/utilities
  3. Types/interfaces
+ // External dependencies
import { CartesianGrid, Cell, Legend, Pie, PieChart, Tooltip as RechartsTooltip, ResponsiveContainer, XAxis, YAxis } from 'recharts';
import { Area, AreaChart } from 'recharts';
import { InfoIcon, TrendingDown, TrendingUp } from 'lucide-react';
import dayjs from 'dayjs';
import { capitalize } from 'string-ts';

+ // Internal components/utilities
import { Card, CardContent, CardHeader } from '@/components';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/atoms';
import { BallerineLink } from '@/components/atoms/BallerineLink/BallerineLink';
import { ctw } from '@/common';
import { ContentTooltip } from '@/components/molecules/ContentTooltip/ContentTooltip';
import { RiskIndicators } from '@/components/molecules/RiskIndicators/RiskIndicators';
import { CardDescription, CardFooter } from '@/components/atoms';
import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/atoms';

Also applies to: 8-8, 22-25


105-117: Extract common tooltip configuration to reduce duplication.

Multiple ContentTooltip components share the same props configuration. Consider extracting this into a constant or creating a wrapper component.

+const TOOLTIP_PROPS = {
+  tooltipContent: {
+    align: 'center',
+  },
+} as const;

+const AnalysisTooltip: FunctionComponent<{ title: string; description: string }> = ({
+  title,
+  description,
+}) => (
+  <ContentTooltip
+    description={<p>{description}</p>}
+    props={TOOLTIP_PROPS}
+  >
+    <h3 className="font-bold">{title}</h3>
+  </ContentTooltip>
+);

-<ContentTooltip
-  description={<p>Evaluates the trustworthiness...</p>}
-  props={{
-    tooltipContent: {
-      align: 'center',
-    },
-  }}
->
+<AnalysisTooltip
+  title="Website Credibility Analysis"
+  description="Evaluates the trustworthiness..."
+/>

Also applies to: 124-136, 165-177, 204-216, 241-253


Line range hint 267-331: Improve chart implementation maintainability and consistency.

Consider the following improvements:

  1. Extract chart configuration
  2. Simplify tooltip content
  3. Use consistent number formatting
+const CHART_CONFIG = {
+  desktop: {
+    label: 'Monthly Visitors',
+    color: '#007aff',
+  },
+} as const;

+const formatNumber = (value: number) => 
+  Intl.NumberFormat('en', { notation: 'compact' }).format(value);

+const MonthlyVisitorsTooltip: FunctionComponent<{
+  active: boolean;
+  payload: any[];
+  label: string;
+}> = ({ active, payload, label }) => {
+  if (!active || !payload?.length) return null;
+  
+  const visitors = parseInt(String(payload[0]?.value));
+  return (
+    <div className="rounded-md border border-gray-400 bg-white px-4 py-2 text-gray-600">
+      <p className="max-w-xs">
+        {`On ${label} the company's website had approx. ${formatNumber(visitors)} visitors`}
+      </p>
+    </div>
+  );
+};

 <ChartContainer
   className="h-[20rem] w-full"
-  config={{
-    desktop: {
-      label: 'Monthly Visitors',
-      color: '#007aff',
-    },
-  }}
+  config={CHART_CONFIG}
 >
   {/* ... */}
   <RechartsTooltip
-    content={({ active, payload, label }) => {
-      if (active && payload && payload.length) {
-        return (
-          <div className="rounded-md border border-gray-400 bg-white px-4 py-2 text-gray-600">
-            <p className="max-w-xs">{`On ${label} the company's website had approx. ${Intl.NumberFormat(
-              'en',
-            ).format(parseInt(String(payload.at(0)?.value)))} visitors`}</p>
-          </div>
-        );
-      }
-      return null;
-    }}
+    content={MonthlyVisitorsTooltip}
   />
apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringTable/columns.tsx (3)

69-93: Simplify riskScore column implementation and improve type safety.

The riskScore column implementation could be improved for better readability and type safety.

Consider this refactored version:

  columnHelper.accessor('riskScore', {
    cell: info => {
      const riskScore = info.getValue();
-      const severity = getSeverityFromRiskScore(riskScore);
+      const severity = getSeverityFromRiskScore(riskScore) as keyof typeof severityToClassName | undefined;

-      return (
-        <div className="flex items-center gap-2">
-          {!riskScore && riskScore !== 0 && <TextWithNAFallback className={'py-0.5'} />}
-          {(riskScore || riskScore === 0) && (
-            <Badge
-              className={ctw(
-                severityToClassName[
-                  (severity?.toUpperCase() as keyof typeof severityToClassName) ?? 'DEFAULT'
-                ],
-                'w-20 py-0.5 font-bold',
-              )}
-            >
-              {titleCase(severity ?? '')}
-            </Badge>
-          )}
-        </div>
-      );
+      if (riskScore === null || riskScore === undefined) {
+        return <TextWithNAFallback className={'py-0.5'} />;
+      }
+
+      return (
+        <Badge
+          className={ctw(
+            severityToClassName[severity?.toUpperCase() ?? 'DEFAULT'],
+            'w-20 py-0.5 font-bold',
+          )}
+        >
+          {titleCase(severity ?? '')}
+        </Badge>
+      );
    },
    header: 'Risk Level',
  }),

145-154: Add tooltips and improve accessibility for alert column.

The alert column should provide more context through tooltips and better accessibility support.

Consider this enhancement:

  columnHelper.accessor('isAlert', {
    cell: ({ getValue }) => {
-      return getValue() ? (
-        <WarningFilledSvg className={`d-6`} />
-      ) : (
-        <Minus className={`text-[#D9D9D9] d-6`} />
-      );
+      return (
+        <Tooltip delayDuration={300}>
+          <TooltipTrigger aria-label={getValue() ? 'Alert Present' : 'No Alert'}>
+            {getValue() ? (
+              <WarningFilledSvg className={`d-6`} />
+            ) : (
+              <Minus className={`text-[#D9D9D9] d-6`} />
+            )}
+          </TooltipTrigger>
+          <TooltipContent>
+            {getValue() ? 'This merchant has active alerts' : 'No alerts present'}
+          </TooltipContent>
+        </Tooltip>
+      );
    },
    header: 'Alert',
  }),

178-196: Remove commented out code.

Large blocks of commented out code should be removed as they can be retrieved from version control if needed.

Remove the commented out merchantId column code. If this code needs to be referenced later, it can be found in the git history.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e746ce3 and 9b1491b.

📒 Files selected for processing (2)
  • apps/backoffice-v2/src/pages/MerchantMonitoring/components/MerchantMonitoringTable/columns.tsx (4 hunks)
  • packages/ui/src/components/templates/report/components/WebsiteCredibility/WebsiteCredibility.tsx (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: test_linux
  • GitHub Check: test_windows
  • GitHub Check: build (windows-latest)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: lint

@tomer-shvadron tomer-shvadron merged commit 19fb361 into dev Jan 14, 2025
18 checks passed
@tomer-shvadron tomer-shvadron deleted the mm-ui-ux-hackathon-jan-2025 branch January 14, 2025 11:01
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.

5 participants