diff --git a/apps/backoffice-v2/CHANGELOG.md b/apps/backoffice-v2/CHANGELOG.md index 1df2604b9f..6012fa1880 100644 --- a/apps/backoffice-v2/CHANGELOG.md +++ b/apps/backoffice-v2/CHANGELOG.md @@ -1,5 +1,14 @@ # @ballerine/backoffice-v2 +## 0.7.36 + +### Patch Changes + +- Updated dependencies + - @ballerine/common@0.9.26 + - @ballerine/workflow-browser-sdk@0.6.37 + - @ballerine/workflow-node-sdk@0.6.37 + ## 0.7.35 ### Patch Changes diff --git a/apps/backoffice-v2/package.json b/apps/backoffice-v2/package.json index aa73e6d9fe..25f3490a3a 100644 --- a/apps/backoffice-v2/package.json +++ b/apps/backoffice-v2/package.json @@ -1,6 +1,6 @@ { "name": "@ballerine/backoffice-v2", - "version": "0.7.35", + "version": "0.7.36", "description": "Ballerine - Backoffice", "homepage": "https://github.com/ballerine-io/ballerine", "repository": { @@ -51,11 +51,11 @@ }, "dependencies": { "@ballerine/blocks": "0.2.12", - "@ballerine/common": "0.9.25", + "@ballerine/common": "0.9.26", "@ballerine/react-pdf-toolkit": "^1.2.20", "@ballerine/ui": "^0.5.20", - "@ballerine/workflow-browser-sdk": "0.6.36", - "@ballerine/workflow-node-sdk": "0.6.36", + "@ballerine/workflow-browser-sdk": "0.6.37", + "@ballerine/workflow-node-sdk": "0.6.37", "@fontsource/inter": "^4.5.15", "@formkit/auto-animate": "1.0.0-beta.5", "@hookform/resolvers": "^3.1.0", diff --git a/apps/backoffice-v2/public/locales/en/toast.json b/apps/backoffice-v2/public/locales/en/toast.json index 775825ab57..5809b1b785 100644 --- a/apps/backoffice-v2/public/locales/en/toast.json +++ b/apps/backoffice-v2/public/locales/en/toast.json @@ -85,5 +85,11 @@ "success": "Merchant check created successfully.", "error": "Error occurred while creating a merchant check.", "is_example": "Please contact Ballerine at oss@ballerine.com for access to this feature." + }, + "batch_business_report_creation": { + "no_file": "No file selected.", + "success": "Merchant checks created successfully.", + "error": "Error occurred while creating merchant checks.", + "is_example": "Please contact Ballerine at oss@ballerine.com for access to this feature." } } diff --git a/apps/backoffice-v2/src/Router/Router.tsx b/apps/backoffice-v2/src/Router/Router.tsx index f1d7075071..561776160a 100644 --- a/apps/backoffice-v2/src/Router/Router.tsx +++ b/apps/backoffice-v2/src/Router/Router.tsx @@ -29,6 +29,7 @@ import { MerchantMonitoringBusinessReport } from '@/pages/MerchantMonitoringBusi import { MerchantMonitoringLayout } from '@/domains/business-reports/components/MerchantMonitoringLayout/MerchantMonitoringLayout'; import { NotFoundRedirectWithProviders } from '@/pages/NotFound/NotFoundRedirectWithProviders'; import { RouteErrorWithProviders } from '@/common/components/atoms/RouteError/RouteErrorWithProviders'; +import { MerchantMonitoringUploadMultiplePage } from '@/pages/MerchantMonitoringUploadMultiple/MerchantMonitoringUploadMultiple.page'; const router = createBrowserRouter([ { @@ -94,6 +95,11 @@ const router = createBrowserRouter([ element: , errorElement: , }, + { + path: '/:locale/merchant-monitoring/upload-multiple-merchants', + element: , + errorElement: , + }, ], }, { diff --git a/apps/backoffice-v2/src/common/api-client/interfaces.ts b/apps/backoffice-v2/src/common/api-client/interfaces.ts index fb0299ee1d..7d5b364bdf 100644 --- a/apps/backoffice-v2/src/common/api-client/interfaces.ts +++ b/apps/backoffice-v2/src/common/api-client/interfaces.ts @@ -14,6 +14,7 @@ export interface IApiClient { timeout?: number; schema: TZodSchema; isBlob?: boolean; + isFormData?: boolean; }): Promise<[z.infer, undefined] | [undefined, Error]>; (params: { @@ -24,6 +25,7 @@ export interface IApiClient { timeout?: number; schema: TZodSchema; isBlob?: boolean; + isFormData?: boolean; }): Promise<[z.infer, undefined] | [undefined, Error]>; (params: { diff --git a/apps/backoffice-v2/src/common/components/atoms/Button/Button.tsx b/apps/backoffice-v2/src/common/components/atoms/Button/Button.tsx index 6679461766..c5151286b2 100644 --- a/apps/backoffice-v2/src/common/components/atoms/Button/Button.tsx +++ b/apps/backoffice-v2/src/common/components/atoms/Button/Button.tsx @@ -45,9 +45,11 @@ export interface ButtonProps export const Button = React.forwardRef( ({ className, variant, size, asChild = false, ...props }, ref) => { const Comp = asChild ? Slot : 'button'; + return ( ); }, ); + Button.displayName = 'Button'; diff --git a/apps/backoffice-v2/src/common/utils/fetcher/fetcher.ts b/apps/backoffice-v2/src/common/utils/fetcher/fetcher.ts index 7a2cec3261..42f4001598 100644 --- a/apps/backoffice-v2/src/common/utils/fetcher/fetcher.ts +++ b/apps/backoffice-v2/src/common/utils/fetcher/fetcher.ts @@ -4,6 +4,9 @@ import { handlePromise } from '../handle-promise/handle-promise'; import { isZodError } from '../is-zod-error/is-zod-error'; import { IFetcher } from './interfaces'; +const handleBody = ({ body, isFormData }: { body: unknown; isFormData: boolean }) => + isFormData ? body : JSON.stringify(body); + export const fetcher: IFetcher = async ({ url, method, @@ -15,6 +18,7 @@ export const fetcher: IFetcher = async ({ timeout = 10000, schema, isBlob = false, + isFormData = false, }) => { const controller = new AbortController(); const { signal } = controller; @@ -26,8 +30,8 @@ export const fetcher: IFetcher = async ({ ...options, method, signal, - body: method !== 'GET' && body ? JSON.stringify(body) : undefined, - headers, + body: method !== 'GET' && body ? handleBody({ body, isFormData }) : undefined, + headers: isFormData ? undefined : headers, }), ); clearTimeout(timeoutRef); diff --git a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts index faef1932f0..174e485ee7 100644 --- a/apps/backoffice-v2/src/domains/business-reports/fetchers.ts +++ b/apps/backoffice-v2/src/domains/business-reports/fetchers.ts @@ -172,3 +172,32 @@ export const createBusinessReport = async ({ return handleZodError(error, businessReport); }; + +export const createBusinessReportBatch = async ({ + merchantSheet, + isExample, + reportType, +}: { + merchantSheet: File; + isExample: boolean; + reportType: TBusinessReportType; +}) => { + if (isExample) { + toast.info(t('toast:batch_business_report_creation.is_example')); + + return; + } + + const formData = new FormData(); + formData.append('file', merchantSheet); + + const [batchId, error] = await apiClient({ + endpoint: `business-reports/upload-batch/${reportType}`, + method: Method.POST, + schema: z.object({ batchId: z.string() }), + body: formData, + isFormData: true, + }); + + return handleZodError(error, batchId); +}; diff --git a/apps/backoffice-v2/src/domains/business-reports/hooks/mutations/useCreateBusinessReportBatchMutation/useCreateBusinessReportBatchMutation.tsx b/apps/backoffice-v2/src/domains/business-reports/hooks/mutations/useCreateBusinessReportBatchMutation/useCreateBusinessReportBatchMutation.tsx new file mode 100644 index 0000000000..94b06489d8 --- /dev/null +++ b/apps/backoffice-v2/src/domains/business-reports/hooks/mutations/useCreateBusinessReportBatchMutation/useCreateBusinessReportBatchMutation.tsx @@ -0,0 +1,50 @@ +import { t } from 'i18next'; +import { toast } from 'sonner'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import { HttpError } from '@/common/errors/http-error'; +import { TBusinessReportType } from '@/domains/business-reports/types'; +import { createBusinessReportBatch } from '@/domains/business-reports/fetchers'; +import { useCustomerQuery } from '@/domains/customer/hook/queries/useCustomerQuery/useCustomerQuery'; +import { isObject } from '@ballerine/common'; + +export const useCreateBusinessReportBatchMutation = ({ + reportType, + onSuccess, +}: { + reportType: TBusinessReportType; + onSuccess?: (data: TData) => void; +}) => { + const queryClient = useQueryClient(); + + const { data: customer } = useCustomerQuery(); + + return useMutation({ + mutationFn: (merchantSheet: File) => + createBusinessReportBatch({ + reportType, + merchantSheet, + isExample: customer?.config?.isExample ?? false, + }), + onSuccess: data => { + void queryClient.invalidateQueries(); + + toast.success(t(`toast:batch_business_report_creation.success`)); + + onSuccess?.(data); + }, + onError: (error: unknown) => { + if (error instanceof HttpError && error.code === 400) { + toast.error(error.message); + + return; + } + + toast.error( + t(`toast:batch_business_report_creation.error`, { + errorMessage: isObject(error) && 'message' in error ? error.message : error, + }), + ); + }, + }); +}; diff --git a/apps/backoffice-v2/src/domains/business-reports/hooks/mutations/useCreateBusinessReportMutation/useCreateBusinessReportMutation.tsx b/apps/backoffice-v2/src/domains/business-reports/hooks/mutations/useCreateBusinessReportMutation/useCreateBusinessReportMutation.tsx index 1062d0d2d7..d9ffee539c 100644 --- a/apps/backoffice-v2/src/domains/business-reports/hooks/mutations/useCreateBusinessReportMutation/useCreateBusinessReportMutation.tsx +++ b/apps/backoffice-v2/src/domains/business-reports/hooks/mutations/useCreateBusinessReportMutation/useCreateBusinessReportMutation.tsx @@ -5,6 +5,7 @@ import { createBusinessReport } from '@/domains/business-reports/fetchers'; import { TBusinessReportType } from '@/domains/business-reports/types'; import { useCustomerQuery } from '@/domains/customer/hook/queries/useCustomerQuery/useCustomerQuery'; import { HttpError } from '@/common/errors/http-error'; +import { isObject } from '@ballerine/common'; export const useCreateBusinessReportMutation = ({ reportType, @@ -39,7 +40,7 @@ export const useCreateBusinessReportMutation = ({ companyName, businessCorrelationId, reportType, - isExample: customer?.config?.isExample, + isExample: customer?.config?.isExample ?? false, }), onSuccess: data => { if (customer?.config?.isExample) { @@ -51,14 +52,18 @@ export const useCreateBusinessReportMutation = ({ toast.success(t(`toast:business_report_creation.success`)); onSuccess?.(data); }, - onError: error => { + onError: (error: unknown) => { if (error instanceof HttpError && error.code === 400) { toast.error(error.message); return; } - toast.error(t(`toast:business_report_creation.error`, { errorMessage: error.message })); + toast.error( + t(`toast:business_report_creation.error`, { + errorMessage: isObject(error) && 'message' in error ? error.message : error, + }), + ); }, }); }; diff --git a/apps/backoffice-v2/src/pages/Home/Home.page.tsx b/apps/backoffice-v2/src/pages/Home/Home.page.tsx index 7c5c8db2ed..c4095f04cd 100644 --- a/apps/backoffice-v2/src/pages/Home/Home.page.tsx +++ b/apps/backoffice-v2/src/pages/Home/Home.page.tsx @@ -1,7 +1,6 @@ import React, { FunctionComponent } from 'react'; import { Outlet } from 'react-router-dom'; import { UserAvatar } from '@/common/components/atoms/UserAvatar/UserAvatar'; -import { DateRangePicker } from '@/common/components/molecules/DateRangePicker/DateRangePicker'; import { useHomeLogic } from '@/common/hooks/useHomeLogic/useHomeLogic'; import { t } from 'i18next'; import { FullScreenLoader } from '@/common/components/molecules/FullScreenLoader/FullScreenLoader'; @@ -41,10 +40,10 @@ export const Home: FunctionComponent = () => { {firstName && ` ${firstName}`} - + {/**/}
{/**/} diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx index 5d69cce188..85b2cd7b84 100644 --- a/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx +++ b/apps/backoffice-v2/src/pages/MerchantMonitoring/MerchantMonitoring.page.tsx @@ -5,7 +5,7 @@ import { useMerchantMonitoringLogic } from '@/pages/MerchantMonitoring/hooks/use import { NoBusinessReports } from '@/pages/MerchantMonitoring/components/NoBusinessReports/NoBusinessReports'; import { MerchantMonitoringTable } from '@/pages/MerchantMonitoring/components/MerchantMonitoringTable/MerchantMonitoringTable'; import { buttonVariants } from '@/common/components/atoms/Button/Button'; -import { Plus } from 'lucide-react'; +import { Plus, Table2 } from 'lucide-react'; import { Link } from 'react-router-dom'; import { Search } from '@/common/components/molecules/Search'; import { Skeleton } from '@ballerine/ui'; @@ -32,16 +32,28 @@ export const MerchantMonitoring: FunctionComponent = () => {

Merchant Monitoring

{!hideCreateMerchantMonitoringButton && ( - - - Create Merchant Check - +
+ + + Upload Multiple Merchants + + + + Create Merchant Check + +
)}
diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/MerchantMonitoringUploadMultiple.page.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/MerchantMonitoringUploadMultiple.page.tsx new file mode 100644 index 0000000000..6ffa7b7d8c --- /dev/null +++ b/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/MerchantMonitoringUploadMultiple.page.tsx @@ -0,0 +1,78 @@ +import { Input } from '@ballerine/ui'; +import { Link } from 'react-router-dom'; +import { ChevronLeft, Download } from 'lucide-react'; +import React, { FunctionComponent } from 'react'; + +import { Card } from '@/common/components/atoms/Card/Card'; +import { Form } from '@/common/components/organisms/Form/Form'; +import { FormItem } from '@/common/components/organisms/Form/Form.Item'; +import { FormField } from '@/common/components/organisms/Form/Form.Field'; +import { FormLabel } from '@/common/components/organisms/Form/Form.Label'; +import { CardContent } from '@/common/components/atoms/Card/Card.Content'; +import { FormControl } from '@/common/components/organisms/Form/Form.Control'; +import { Button, buttonVariants } from '@/common/components/atoms/Button/Button'; +import { FormDescription } from '@/common/components/organisms/Form/Form.Description'; +import { useMerchantMonitoringUploadMultiplePageLogic } from '@/pages/MerchantMonitoringUploadMultiple/hooks/useMerchantMonitoringUploadMultiplePageLogic/useMerchantMonitoringUploadMultiplePageLogic'; + +export const MerchantMonitoringUploadMultiplePage: FunctionComponent = () => { + const { form, onSubmit, onChange, locale, csvTemplateUrl } = + useMerchantMonitoringUploadMultiplePageLogic(); + + return ( +
+
+ + Back to Reports + +
+

Upload Multiple Merchants

+ + +
+ + ( + + Upload Merchants Sheet + + + + File should follow the CSV template + + )} + /> +
+ + + + Download CSV template + +
+ + +
+
+
+ ); +}; diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/create-business-report-batch-schema.ts b/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/create-business-report-batch-schema.ts new file mode 100644 index 0000000000..ba63a61aa7 --- /dev/null +++ b/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/create-business-report-batch-schema.ts @@ -0,0 +1,5 @@ +import { z } from 'zod'; + +export const CreateBusinessReportBatchSchema = z.object({ + merchantSheet: z.union([z.any(), z.undefined()]), +}); diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/hooks/useMerchantMonitoringUploadMultiplePageLogic/batch-report-template.csv b/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/hooks/useMerchantMonitoringUploadMultiplePageLogic/batch-report-template.csv new file mode 100644 index 0000000000..90bfd7f0b0 --- /dev/null +++ b/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/hooks/useMerchantMonitoringUploadMultiplePageLogic/batch-report-template.csv @@ -0,0 +1,4 @@ +websiteUrl,countryCode,lineOfBusiness,parentCompanyName,merchantName,correlationId +https://www.ballerine.com,,,,, +https://www.google.com,US,Search Engine,Alphabet Inc.,Google,1 +https://www.bbc.com,UK,Journalism,BBC Inc.,BBC,2 diff --git a/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/hooks/useMerchantMonitoringUploadMultiplePageLogic/useMerchantMonitoringUploadMultiplePageLogic.tsx b/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/hooks/useMerchantMonitoringUploadMultiplePageLogic/useMerchantMonitoringUploadMultiplePageLogic.tsx new file mode 100644 index 0000000000..9cb81ca5ff --- /dev/null +++ b/apps/backoffice-v2/src/pages/MerchantMonitoringUploadMultiple/hooks/useMerchantMonitoringUploadMultiplePageLogic/useMerchantMonitoringUploadMultiplePageLogic.tsx @@ -0,0 +1,66 @@ +import { z } from 'zod'; +import { t } from 'i18next'; +import { toast } from 'sonner'; +import { useCallback, useMemo } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { SubmitHandler, useForm } from 'react-hook-form'; + +import csvContent from './batch-report-template.csv?raw'; +import { useLocale } from '@/common/hooks/useLocale/useLocale'; +import { CreateBusinessReportBatchSchema } from '@/pages/MerchantMonitoringUploadMultiple/create-business-report-batch-schema'; +import { useCreateBusinessReportBatchMutation } from '@/domains/business-reports/hooks/mutations/useCreateBusinessReportBatchMutation/useCreateBusinessReportBatchMutation'; + +export const useMerchantMonitoringUploadMultiplePageLogic = () => { + const form = useForm<{ merchantSheet: File | undefined }>({ + defaultValues: { + merchantSheet: undefined, + }, + }); + + const locale = useLocale(); + const navigate = useNavigate(); + + const { mutate: mutateCreateBusinessReportBatch } = useCreateBusinessReportBatchMutation({ + reportType: 'MERCHANT_REPORT_T1', + onSuccess: () => { + navigate(`/${locale}/merchant-monitoring`); + }, + }); + + const onSubmit: SubmitHandler> = ({ + merchantSheet, + }) => { + if (!merchantSheet) { + toast.error(t(`toast:batch_business_report_creation.no_file`)); + + return; + } + + mutateCreateBusinessReportBatch(merchantSheet); + }; + + const csvTemplateUrl = useMemo(() => { + const blob = new Blob([csvContent], { type: 'text/csv' }); + + return URL.createObjectURL(blob); + }, []); + + const onChange = useCallback( + (event: React.ChangeEvent) => { + const files = event.target.files; + + if (files && 'length' in files && files.length > 0 && files[0]) { + form.setValue('merchantSheet', files[0]); + } + }, + [form], + ); + + return { + form, + locale, + onSubmit, + onChange, + csvTemplateUrl, + }; +}; diff --git a/apps/kyb-app/CHANGELOG.md b/apps/kyb-app/CHANGELOG.md index 9e93398aae..40403fb718 100644 --- a/apps/kyb-app/CHANGELOG.md +++ b/apps/kyb-app/CHANGELOG.md @@ -1,5 +1,13 @@ # kyb-app +## 0.3.44 + +### Patch Changes + +- Updated dependencies + - @ballerine/common@0.9.26 + - @ballerine/workflow-browser-sdk@0.6.37 + ## 0.3.43 ### Patch Changes diff --git a/apps/kyb-app/package.json b/apps/kyb-app/package.json index 0f31e1e477..b09f196a05 100644 --- a/apps/kyb-app/package.json +++ b/apps/kyb-app/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/kyb-app", "private": true, - "version": "0.3.43", + "version": "0.3.44", "type": "module", "scripts": { "dev": "vite", @@ -15,9 +15,9 @@ }, "dependencies": { "@ballerine/blocks": "0.2.12", - "@ballerine/common": "^0.9.25", + "@ballerine/common": "^0.9.26", "@ballerine/ui": "0.5.22", - "@ballerine/workflow-browser-sdk": "0.6.36", + "@ballerine/workflow-browser-sdk": "0.6.37", "@lukemorales/query-key-factory": "^1.0.3", "@radix-ui/react-icons": "^1.3.0", "@rjsf/core": "^5.9.0", diff --git a/examples/headless-example/CHANGELOG.md b/examples/headless-example/CHANGELOG.md index 97d8376f48..a4644f0b88 100644 --- a/examples/headless-example/CHANGELOG.md +++ b/examples/headless-example/CHANGELOG.md @@ -1,5 +1,13 @@ # @ballerine/headless-example +## 0.3.36 + +### Patch Changes + +- Updated dependencies + - @ballerine/common@0.9.26 + - @ballerine/workflow-browser-sdk@0.6.37 + ## 0.3.35 ### Patch Changes diff --git a/examples/headless-example/package.json b/examples/headless-example/package.json index c8bd9b3fd1..85d946dce1 100644 --- a/examples/headless-example/package.json +++ b/examples/headless-example/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/headless-example", "private": true, - "version": "0.3.35", + "version": "0.3.36", "type": "module", "scripts": { "spellcheck": "cspell \"*\"", @@ -34,8 +34,8 @@ "vite": "^4.5.3" }, "dependencies": { - "@ballerine/common": "0.9.25", - "@ballerine/workflow-browser-sdk": "0.6.36", + "@ballerine/common": "0.9.26", + "@ballerine/workflow-browser-sdk": "0.6.37", "@felte/reporter-svelte": "^1.1.5", "@felte/validator-zod": "^1.0.13", "@fontsource/inter": "^4.5.15", diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 610bf3d20e..d4bbdd7d6d 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,5 +1,11 @@ # @ballerine/common +## 0.9.26 + +### Patch Changes + +- pushing fixes + ## 0.9.25 ### Patch Changes diff --git a/packages/common/package.json b/packages/common/package.json index 9235fc224d..62d8aff31d 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -2,7 +2,7 @@ "private": false, "name": "@ballerine/common", "author": "Ballerine ", - "version": "0.9.25", + "version": "0.9.26", "description": "common", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", diff --git a/packages/common/src/schemas/documents/merchant-screening-plugin-schema.ts b/packages/common/src/schemas/documents/merchant-screening-plugin-schema.ts index a4ae48da40..e06b155eca 100644 --- a/packages/common/src/schemas/documents/merchant-screening-plugin-schema.ts +++ b/packages/common/src/schemas/documents/merchant-screening-plugin-schema.ts @@ -435,12 +435,12 @@ export const MerchantScreeningProcessedSchema = Type.Object({ export const MerchantScreeningPluginSchema = Type.Optional( Type.Object({ - name: Type.Literal('merchantScreening'), - status: TypeStringEnum(ProcessStatuses), + name: Type.Optional(Type.Literal('merchantScreening')), + status: Type.Optional(TypeStringEnum(ProcessStatuses)), invokedAt: Type.Optional(Type.Number()), vendor: Type.Optional(Type.Literal('mastercard')), - logoUrl: Type.String(), - raw: MerchantScreeningRawSchema, - processed: MerchantScreeningProcessedSchema, + logoUrl: Type.Optional(Type.String()), + raw: Type.Optional(MerchantScreeningRawSchema), + processed: Type.Optional(MerchantScreeningProcessedSchema), }), ); diff --git a/packages/workflow-core/CHANGELOG.md b/packages/workflow-core/CHANGELOG.md index d04cc6532d..05b4a476ea 100644 --- a/packages/workflow-core/CHANGELOG.md +++ b/packages/workflow-core/CHANGELOG.md @@ -1,5 +1,13 @@ # @ballerine/workflow-core +## 0.6.37 + +### Patch Changes + +- pushing fixes +- Updated dependencies + - @ballerine/common@0.9.26 + ## 0.6.36 ### Patch Changes diff --git a/packages/workflow-core/package.json b/packages/workflow-core/package.json index bb29ab7dd1..6b11bad9c9 100644 --- a/packages/workflow-core/package.json +++ b/packages/workflow-core/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/workflow-core", "author": "Ballerine ", - "version": "0.6.36", + "version": "0.6.37", "description": "workflow-core", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", @@ -31,7 +31,7 @@ "node": ">=12" }, "dependencies": { - "@ballerine/common": "0.9.25", + "@ballerine/common": "0.9.26", "ajv": "^8.12.0", "i18n-iso-countries": "^7.6.0", "jmespath": "^0.16.0", diff --git a/packages/workflow-core/src/lib/plugins/external-plugin/mastercard-merchant-screening-plugin.ts b/packages/workflow-core/src/lib/plugins/external-plugin/mastercard-merchant-screening-plugin.ts index 6e53f3bbc2..27ab1635cd 100644 --- a/packages/workflow-core/src/lib/plugins/external-plugin/mastercard-merchant-screening-plugin.ts +++ b/packages/workflow-core/src/lib/plugins/external-plugin/mastercard-merchant-screening-plugin.ts @@ -35,7 +35,6 @@ export class MastercardMerchantScreeningPlugin extends ApiPlugin { try { const secrets = await this.secretsManager?.getAll?.(); const url = `${process.env.UNIFIED_API_URL}/merchant-screening/mastercard`; - const method = 'POST'; const entity = isObject(context.entity) ? context.entity : {}; const countrySubdivisionSupportedCountries = ['US', 'CA'] as const; const address = { @@ -72,10 +71,11 @@ export class MastercardMerchantScreeningPlugin extends ApiPlugin { logger.log('Mastercard Merchant Screening Plugin - Sending API request', { url, - method, + method: this.method, }); - const apiResponse = await this.makeApiRequest(url, method, requestPayload, { + const apiResponse = await this.makeApiRequest(url, this.method, requestPayload, { + ...this.headers, Authorization: `Bearer ${process.env.UNIFIED_API_TOKEN}`, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4f9cff54c5..7030bf60dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -64,7 +64,7 @@ importers: specifier: 0.2.12 version: link:../../packages/blocks '@ballerine/common': - specifier: 0.9.25 + specifier: 0.9.26 version: link:../../packages/common '@ballerine/react-pdf-toolkit': specifier: ^1.2.20 @@ -73,10 +73,10 @@ importers: specifier: ^0.5.20 version: link:../../packages/ui '@ballerine/workflow-browser-sdk': - specifier: 0.6.36 + specifier: 0.6.37 version: link:../../sdks/workflow-browser-sdk '@ballerine/workflow-node-sdk': - specifier: 0.6.36 + specifier: 0.6.37 version: link:../../sdks/workflow-node-sdk '@fontsource/inter': specifier: ^4.5.15 @@ -422,13 +422,13 @@ importers: specifier: 0.2.12 version: link:../../packages/blocks '@ballerine/common': - specifier: ^0.9.25 + specifier: ^0.9.26 version: link:../../packages/common '@ballerine/ui': specifier: 0.5.22 version: link:../../packages/ui '@ballerine/workflow-browser-sdk': - specifier: 0.6.36 + specifier: 0.6.37 version: link:../../sdks/workflow-browser-sdk '@lukemorales/query-key-factory': specifier: ^1.0.3 @@ -892,10 +892,10 @@ importers: examples/headless-example: dependencies: '@ballerine/common': - specifier: 0.9.25 + specifier: 0.9.26 version: link:../../packages/common '@ballerine/workflow-browser-sdk': - specifier: 0.6.36 + specifier: 0.6.37 version: link:../../sdks/workflow-browser-sdk '@felte/reporter-svelte': specifier: ^1.1.5 @@ -1828,7 +1828,7 @@ importers: packages/workflow-core: dependencies: '@ballerine/common': - specifier: 0.9.25 + specifier: 0.9.26 version: link:../common ajv: specifier: ^8.12.0 @@ -2003,7 +2003,7 @@ importers: sdks/web-ui-sdk: dependencies: '@ballerine/common': - specifier: 0.9.25 + specifier: 0.9.26 version: link:../../packages/common '@zerodevx/svelte-toast': specifier: ^0.8.0 @@ -2130,10 +2130,10 @@ importers: sdks/workflow-browser-sdk: dependencies: '@ballerine/common': - specifier: 0.9.25 + specifier: 0.9.26 version: link:../../packages/common '@ballerine/workflow-core': - specifier: 0.6.36 + specifier: 0.6.37 version: link:../../packages/workflow-core xstate: specifier: ^4.37.0 @@ -2272,7 +2272,7 @@ importers: sdks/workflow-node-sdk: dependencies: '@ballerine/workflow-core': - specifier: 0.6.36 + specifier: 0.6.37 version: link:../../packages/workflow-core json-logic-js: specifier: ^2.0.2 @@ -2517,13 +2517,13 @@ importers: specifier: 3.347.1 version: 3.347.1 '@ballerine/common': - specifier: 0.9.25 + specifier: 0.9.26 version: link:../../packages/common '@ballerine/workflow-core': - specifier: 0.6.36 + specifier: 0.6.37 version: link:../../packages/workflow-core '@ballerine/workflow-node-sdk': - specifier: 0.6.36 + specifier: 0.6.37 version: link:../../sdks/workflow-node-sdk '@faker-js/faker': specifier: ^7.6.0 @@ -2860,7 +2860,7 @@ importers: specifier: ^4.0.0 version: 4.0.0(astro@3.3.3)(tailwindcss@3.3.5)(ts-node@10.9.1) '@ballerine/common': - specifier: ^0.9.25 + specifier: ^0.9.26 version: link:../../packages/common astro: specifier: 3.3.3 @@ -9592,7 +9592,7 @@ packages: magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.5.4) typescript: 5.5.4 - vite: 5.3.5(@types/node@18.17.19) + vite: 5.3.5(@types/node@20.9.2) dev: true /@jridgewell/gen-mapping@0.3.3: @@ -15945,7 +15945,7 @@ packages: react: 18.2.0 react-docgen: 6.0.4 react-dom: 18.2.0(react@18.2.0) - vite: 5.3.5(@types/node@18.17.19) + vite: 5.3.5(@types/node@20.9.2) transitivePeerDependencies: - '@preact/preset-vite' - encoding @@ -18715,7 +18715,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.3) magic-string: 0.27.0 react-refresh: 0.14.0 - vite: 5.3.5(@types/node@18.17.19) + vite: 5.3.5(@types/node@20.9.2) transitivePeerDependencies: - supports-color dev: true @@ -23489,7 +23489,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@4.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@4.9.5) debug: 3.2.7 eslint: 8.54.0 eslint-import-resolver-node: 0.3.9 @@ -23654,7 +23654,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@4.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@4.9.5) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 @@ -24026,7 +24026,7 @@ packages: '@typescript-eslint/eslint-plugin': optional: true dependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.22.0)(typescript@5.5.4) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.22.0)(typescript@4.9.5) eslint: 8.22.0 eslint-rule-composer: 0.3.0 dev: true @@ -35469,7 +35469,7 @@ packages: debug: 4.3.4(supports-color@8.1.1) globrex: 0.1.2 tsconfck: 2.1.2(typescript@5.5.4) - vite: 5.3.5(@types/node@18.17.19) + vite: 5.3.5(@types/node@20.9.2) transitivePeerDependencies: - supports-color - typescript diff --git a/sdks/web-ui-sdk/CHANGELOG.md b/sdks/web-ui-sdk/CHANGELOG.md index 832876f15b..412743f5a7 100644 --- a/sdks/web-ui-sdk/CHANGELOG.md +++ b/sdks/web-ui-sdk/CHANGELOG.md @@ -1,5 +1,12 @@ # web-ui-sdk +## 1.5.27 + +### Patch Changes + +- Updated dependencies + - @ballerine/common@0.9.26 + ## 1.5.26 ### Patch Changes diff --git a/sdks/web-ui-sdk/package.json b/sdks/web-ui-sdk/package.json index b3811f3986..cf676fe7ab 100644 --- a/sdks/web-ui-sdk/package.json +++ b/sdks/web-ui-sdk/package.json @@ -21,7 +21,7 @@ "types": "dist/index.d.ts", "name": "@ballerine/web-ui-sdk", "private": false, - "version": "1.5.26", + "version": "1.5.27", "type": "module", "files": [ "dist" @@ -96,7 +96,7 @@ "vitest": "^0.24.5" }, "dependencies": { - "@ballerine/common": "0.9.25", + "@ballerine/common": "0.9.26", "@zerodevx/svelte-toast": "^0.8.0", "compressorjs": "^1.1.1", "deepmerge": "^4.3.0", diff --git a/sdks/workflow-browser-sdk/CHANGELOG.md b/sdks/workflow-browser-sdk/CHANGELOG.md index 7d59bbe40d..f87be49f9e 100644 --- a/sdks/workflow-browser-sdk/CHANGELOG.md +++ b/sdks/workflow-browser-sdk/CHANGELOG.md @@ -1,5 +1,13 @@ # @ballerine/workflow-browser-sdk +## 0.6.37 + +### Patch Changes + +- Updated dependencies + - @ballerine/workflow-core@0.6.37 + - @ballerine/common@0.9.26 + ## 0.6.36 ### Patch Changes diff --git a/sdks/workflow-browser-sdk/package.json b/sdks/workflow-browser-sdk/package.json index 531243cbc9..ab095c04f9 100644 --- a/sdks/workflow-browser-sdk/package.json +++ b/sdks/workflow-browser-sdk/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/workflow-browser-sdk", "author": "Ballerine ", - "version": "0.6.36", + "version": "0.6.37", "description": "workflow-browser-sdk", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", @@ -33,8 +33,8 @@ "node": ">=12" }, "dependencies": { - "@ballerine/common": "0.9.25", - "@ballerine/workflow-core": "0.6.36", + "@ballerine/common": "0.9.26", + "@ballerine/workflow-core": "0.6.37", "xstate": "^4.37.0" }, "devDependencies": { diff --git a/sdks/workflow-node-sdk/CHANGELOG.md b/sdks/workflow-node-sdk/CHANGELOG.md index 0308dedbd7..d5b1e29b24 100644 --- a/sdks/workflow-node-sdk/CHANGELOG.md +++ b/sdks/workflow-node-sdk/CHANGELOG.md @@ -1,5 +1,12 @@ # @ballerine/workflow-node-sdk +## 0.6.37 + +### Patch Changes + +- Updated dependencies + - @ballerine/workflow-core@0.6.37 + ## 0.6.36 ### Patch Changes diff --git a/sdks/workflow-node-sdk/package.json b/sdks/workflow-node-sdk/package.json index 941eba249b..f1d376eb5a 100644 --- a/sdks/workflow-node-sdk/package.json +++ b/sdks/workflow-node-sdk/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/workflow-node-sdk", "author": "Ballerine ", - "version": "0.6.36", + "version": "0.6.37", "description": "workflow-node-sdk", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", @@ -28,7 +28,7 @@ "node": ">=12" }, "dependencies": { - "@ballerine/workflow-core": "0.6.36", + "@ballerine/workflow-core": "0.6.37", "json-logic-js": "^2.0.2", "xstate": "^4.36.0" }, diff --git a/services/workflows-service/CHANGELOG.md b/services/workflows-service/CHANGELOG.md index 38bd2aa6f3..26cdd8bd3a 100644 --- a/services/workflows-service/CHANGELOG.md +++ b/services/workflows-service/CHANGELOG.md @@ -1,5 +1,14 @@ # @ballerine/workflows-service +## 0.7.36 + +### Patch Changes + +- Updated dependencies + - @ballerine/workflow-core@0.6.37 + - @ballerine/common@0.9.26 + - @ballerine/workflow-node-sdk@0.6.37 + ## 0.7.35 ### Patch Changes diff --git a/services/workflows-service/package.json b/services/workflows-service/package.json index 22173eefe7..8aa11ef236 100644 --- a/services/workflows-service/package.json +++ b/services/workflows-service/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/workflows-service", "private": false, - "version": "0.7.35", + "version": "0.7.36", "description": "workflow-service", "scripts": { "spellcheck": "cspell \"*\"", @@ -47,9 +47,9 @@ "@aws-sdk/client-secrets-manager": "^3.620.1", "@aws-sdk/lib-storage": "3.347.1", "@aws-sdk/s3-request-presigner": "3.347.1", - "@ballerine/common": "0.9.25", - "@ballerine/workflow-core": "0.6.36", - "@ballerine/workflow-node-sdk": "0.6.36", + "@ballerine/common": "0.9.26", + "@ballerine/workflow-core": "0.6.37", + "@ballerine/workflow-node-sdk": "0.6.37", "@faker-js/faker": "^7.6.0", "@nestjs/axios": "^2.0.0", "@nestjs/common": "^9.3.12", diff --git a/services/workflows-service/prisma/data-migrations b/services/workflows-service/prisma/data-migrations index 6def4e1235..3379373b90 160000 --- a/services/workflows-service/prisma/data-migrations +++ b/services/workflows-service/prisma/data-migrations @@ -1 +1 @@ -Subproject commit 6def4e12358d52f84ff92e083547b63b89d89393 +Subproject commit 3379373b907a01f250b93e729c34d38eb432079f diff --git a/services/workflows-service/src/business-report/business-report.controller.internal.ts b/services/workflows-service/src/business-report/business-report.controller.internal.ts index 4ebd6872f9..088fe25949 100644 --- a/services/workflows-service/src/business-report/business-report.controller.internal.ts +++ b/services/workflows-service/src/business-report/business-report.controller.internal.ts @@ -41,13 +41,17 @@ import { FileInterceptor } from '@nestjs/platform-express'; import { getDiskStorage } from '@/storage/get-file-storage-manager'; import { fileFilter } from '@/storage/file-filter'; import { RemoveTempFileInterceptor } from '@/common/interceptors/remove-temp-file.interceptor'; -import { CreateBatchBusinessReportDto } from '@/business-report/dto/create-batch-business-report.dto'; -import { ApiConsumes } from '@nestjs/swagger'; +import { CreateBusinessReportBatchBodyDto } from '@/business-report/dto/create-business-report-batch-body.dto'; +import { ApiBearerAuth, ApiConsumes } from '@nestjs/swagger'; import type { Response } from 'express'; import { IsBoolean } from 'class-validator'; +import { CreateBusinessReportBatchQueryParamsDto } from '@/business-report/dto/create-business-report-batch-query-params.dto'; +import { TCustomerWithDefinitionsFeatures } from '@/customer/types'; +@ApiBearerAuth() +@swagger.ApiTags('Business Reports') @common.Controller('internal/business-reports') -// @swagger.ApiExcludeController() +@swagger.ApiExcludeController() export class BusinessReportControllerInternal { constructor( protected readonly businessReportService: BusinessReportService, @@ -74,17 +78,10 @@ export class BusinessReportControllerInternal { ) { const customer = await this.customerService.getByProjectId(currentProjectId); - const { maxBusinessReports, withQualityControl } = customer.config || {}; - - if (isNumber(maxBusinessReports) && maxBusinessReports > 0) { - const businessReportsCount = await this.businessReportService.count({}, [currentProjectId]); - - if (businessReportsCount >= maxBusinessReports) { - throw new BadRequestException( - `You have reached the maximum number of business reports allowed (${maxBusinessReports}).`, - ); - } - } + const { withQualityControl } = await this.getCustomerMerchantMonitoringConfig( + customer, + currentProjectId, + ); let business: Pick | undefined; const merchantNameWithDefault = merchantName || 'Not detected'; @@ -350,8 +347,7 @@ export class BusinessReportControllerInternal { }); } - @common.Post('/upload-batch') - @Public() + @common.Post('/upload-batch/:type') @swagger.ApiForbiddenResponse({ type: errors.ForbiddenException }) @ApiConsumes('multipart/form-data') @UseInterceptors( @@ -361,19 +357,23 @@ export class BusinessReportControllerInternal { }), RemoveTempFileInterceptor, ) - async createBatchReport( + async createBusinessReportBatch( @UploadedFile() file: Express.Multer.File, - @Body() body: CreateBatchBusinessReportDto, + @Param() { type }: CreateBusinessReportBatchQueryParamsDto, + @Body() body: CreateBusinessReportBatchBodyDto, @Res() res: Response, @CurrentProject() currentProjectId: TProjectId, ) { const customer = await this.customerService.getByProjectId(currentProjectId); - const { withQualityControl } = customer.config || {}; + const { maxBusinessReports, withQualityControl } = + await this.getCustomerMerchantMonitoringConfig(customer.config, currentProjectId); const result = await this.businessReportService.processBatchFile({ - type: body.type, - file: file, + type, + currentProjectId, + maxBusinessReports, + merchantSheet: file, projectId: currentProjectId, withQualityControl: IsBoolean(withQualityControl) ? withQualityControl : false, }); @@ -382,4 +382,23 @@ export class BusinessReportControllerInternal { res.setHeader('content-type', 'application/json'); res.send(result); } + + private async getCustomerMerchantMonitoringConfig( + config: TCustomerWithDefinitionsFeatures, + currentProjectId: string, + ) { + const { maxBusinessReports, withQualityControl } = config || {}; + + if (isNumber(maxBusinessReports) && maxBusinessReports > 0) { + const businessReportsCount = await this.businessReportService.count({}, [currentProjectId]); + + if (businessReportsCount >= maxBusinessReports) { + throw new BadRequestException( + `You have reached the maximum number of business reports allowed (${maxBusinessReports}).`, + ); + } + } + + return { maxBusinessReports, withQualityControl }; + } } diff --git a/services/workflows-service/src/business-report/business-report.service.ts b/services/workflows-service/src/business-report/business-report.service.ts index 7c8769cc1a..01cb9f427e 100644 --- a/services/workflows-service/src/business-report/business-report.service.ts +++ b/services/workflows-service/src/business-report/business-report.service.ts @@ -131,27 +131,44 @@ export class BusinessReportService { } async processBatchFile({ - file, type, projectId, + merchantSheet, + currentProjectId, + maxBusinessReports, withQualityControl, }: { - file: Express.Multer.File; - type: BusinessReportType; projectId: TProjectId; + type: BusinessReportType; + currentProjectId: string; + maxBusinessReports: number; withQualityControl: boolean; + merchantSheet: Express.Multer.File; }) { const businessReportsRequests = await parseCsv({ - filePath: file.path, + filePath: merchantSheet.path, schema: BusinessReportRequestSchema, logger: this.logger, }); + const businessReportsCount = await this.count({}, [currentProjectId]); + + if (businessReportsCount + businessReportsRequests.length > maxBusinessReports) { + const reportsLeft = maxBusinessReports - businessReportsCount; + + throw new UnprocessableEntityException( + `Batch size is too large, there are too many reports (${reportsLeft} report${ + reportsLeft > 1 ? 's' : '' + } left from a qouta of ${maxBusinessReports})`, + ); + } + if (businessReportsRequests.length > 100) { throw new UnprocessableEntityException('Batch size is too large'); } const batchId = randomUUID(); + await this.prisma.$transaction( async transaction => { const businessCreatePromises = businessReportsRequests.map(async businessReportRequest => { diff --git a/services/workflows-service/src/business-report/dto/create-business-report-batch-body.dto.ts b/services/workflows-service/src/business-report/dto/create-business-report-batch-body.dto.ts new file mode 100644 index 0000000000..13e3c11db5 --- /dev/null +++ b/services/workflows-service/src/business-report/dto/create-business-report-batch-body.dto.ts @@ -0,0 +1,10 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class CreateBusinessReportBatchBodyDto { + @ApiProperty({ + type: 'string', + format: 'binary', + description: 'CSV file for batch business report', + }) + file!: Express.Multer.File; +} diff --git a/services/workflows-service/src/business-report/dto/create-batch-business-report.dto.ts b/services/workflows-service/src/business-report/dto/create-business-report-batch-query-params.dto.ts similarity index 67% rename from services/workflows-service/src/business-report/dto/create-batch-business-report.dto.ts rename to services/workflows-service/src/business-report/dto/create-business-report-batch-query-params.dto.ts index d0840970c5..5e6a9636bf 100644 --- a/services/workflows-service/src/business-report/dto/create-batch-business-report.dto.ts +++ b/services/workflows-service/src/business-report/dto/create-business-report-batch-query-params.dto.ts @@ -2,14 +2,7 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEnum } from 'class-validator'; import { BusinessReportType } from '@prisma/client'; -export class CreateBatchBusinessReportDto { - @ApiProperty({ - type: 'string', - format: 'binary', - description: 'CSV file for batch business report', - }) - file!: Express.Multer.File; - +export class CreateBusinessReportBatchQueryParamsDto { @ApiProperty({ required: true, type: String, diff --git a/services/workflows-service/src/env.ts b/services/workflows-service/src/env.ts index 4d63c817b3..ae9340498a 100644 --- a/services/workflows-service/src/env.ts +++ b/services/workflows-service/src/env.ts @@ -86,9 +86,10 @@ export const serverEnvSchema = { .default('/dev/customers/') .describe('AWS Secrets Manager prefix'), - IN_MEMORY_SECRET_ACQUIRER_ID: z.string().optional(), - IN_MEMORY_SECRET_PRIVATE_KEY: z.string().optional(), - IN_MEMORY_SECRET_CONSUMER_KEY: z.string().optional(), + // IN_MEMORY is reserved for environment variables + IN_MEMORIES_SECRET_ACQUIRER_ID: z.string().optional(), + IN_MEMORIES_SECRET_PRIVATE_KEY: z.string().optional(), + IN_MEMORIES_SECRET_CONSUMER_KEY: z.string().optional(), }; if (!process.env['ENVIRONMENT_NAME'] || process.env['ENVIRONMENT_NAME'] === 'local') { diff --git a/services/workflows-service/src/secrets-manager/in-memory-secrets-manager.ts b/services/workflows-service/src/secrets-manager/in-memory-secrets-manager.ts index 87e84ad10f..b93a5b0d82 100644 --- a/services/workflows-service/src/secrets-manager/in-memory-secrets-manager.ts +++ b/services/workflows-service/src/secrets-manager/in-memory-secrets-manager.ts @@ -3,11 +3,11 @@ import { env } from '@/env'; import { camelCase } from 'lodash'; const inMemoryEnvProvidedSecrets = Object.entries(env).reduce((acc, [key, value]) => { - if (!key.startsWith('IN_MEMORY_SECRET_')) { + if (!key.startsWith('IN_MEMORIES_SECRET_')) { return acc; } - const secretKey = key.replace('IN_MEMORY_SECRET_', ''); + const secretKey = key.replace('IN_MEMORIES_SECRET_', ''); acc[camelCase(secretKey)] = value; diff --git a/websites/docs/package.json b/websites/docs/package.json index 578332adb6..52a8230971 100644 --- a/websites/docs/package.json +++ b/websites/docs/package.json @@ -17,7 +17,7 @@ "dependencies": { "@astrojs/starlight": "0.11.1", "@astrojs/tailwind": "^4.0.0", - "@ballerine/common": "^0.9.25", + "@ballerine/common": "^0.9.26", "astro": "3.3.3", "sharp": "^0.32.4", "shiki": "^0.14.3"