From 8f60b376c672e4fea41e70569c198ea90edbec57 Mon Sep 17 00:00:00 2001
From: Yoan VALLET <ext.sopra.yvallet@grandlyon.com>
Date: Tue, 21 Dec 2021 09:50:35 +0000
Subject: [PATCH] feat: add __IS_ALPHA__ env in webpack config

---
 .vscode/settings.json                         |   1 -
 app.config.alpha.js                           |   3 +-
 app.config.environment.alpha.js               |   2 +-
 app.config.environment.dev.js                 |   2 +-
 app.config.environment.prod.js                |  33 ++++++
 app.config.js                                 |   7 +-
 app.config.services.alpha.js                  | 100 ++++++++++++++++++
 app.config.services.js                        |   1 +
 .../Feedback/FeedbackModal.spec.tsx           |  26 +++--
 src/components/Feedback/FeedbackModal.tsx     |   4 +-
 src/components/Home/ConsumptionView.tsx       |   1 -
 .../Onboarding/WelcomeModal.spec.tsx          |   7 ++
 src/components/Onboarding/WelcomeModal.tsx    |   6 +-
 src/services/environement.service.spec.ts     |  38 +++----
 ...ment.service.ts => environment.service.ts} |  13 ++-
 src/services/partnersInfo.service.spec.ts     |   8 ++
 src/services/partnersInfo.service.ts          |   4 +-
 src/styles/index.css                          |   2 +-
 src/targets/services/aggregatorUsageEvents.ts |   8 +-
 src/targets/services/consumptionAlert.ts      |   6 +-
 .../services/monthlyReportNotification.ts     |  12 +--
 21 files changed, 215 insertions(+), 69 deletions(-)
 create mode 100644 app.config.environment.prod.js
 create mode 100644 app.config.services.alpha.js
 rename src/services/{environement.service.ts => environment.service.ts} (55%)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index 95c8a54b8..6c8a184c1 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -23,7 +23,6 @@
     "javascriptreact",
     "typescript",
     "typescriptreact",
-    }
   ],
   "gitlab.instanceUrl": "https://forge.grandlyon.com/web-et-numerique/llle_project/ecolyo",
   "gitlab.ignoreCertificateErrors": true,
diff --git a/app.config.alpha.js b/app.config.alpha.js
index 8c1500828..23d023ab4 100644
--- a/app.config.alpha.js
+++ b/app.config.alpha.js
@@ -25,11 +25,12 @@ const configs = [
   require('cozy-scripts/config/webpack.config.progress'),
   addAnalyzer ? require('cozy-scripts/config/webpack.config.analyzer') : null,
   // require('cozy-scripts/config/webpack.config.services'),
-  require('./app.config.services'), // Override the services config
+  require('./app.config.services.alpha'), // Override the services config
   require(`cozy-scripts/config/webpack.target.${target}`),
 ]
 
 configs.push(require('./app.config.environment.alpha'))
 
 //module.exports = merge.apply(null, configs)
+// eslint-disable-next-line prefer-spread
 module.exports = [merge.apply(null, configs)] // cozy builder expects an array
diff --git a/app.config.environment.alpha.js b/app.config.environment.alpha.js
index 9f389dacb..65e849511 100644
--- a/app.config.environment.alpha.js
+++ b/app.config.environment.alpha.js
@@ -13,7 +13,7 @@ module.exports = {
     new webpack.optimize.OccurrenceOrderPlugin(),
     new webpack.DefinePlugin({
       'process.env.NODE_ENV': JSON.stringify('production'), // to compile on production mode (redux)
-      'process.env.IS_ALPHA': JSON.stringify('true'),
+      __IS_ALPHA__: true,
       __DEVELOPMENT__: false,
       __DEVTOOLS__: false,
       __STACK_ASSETS__: target !== 'mobile',
diff --git a/app.config.environment.dev.js b/app.config.environment.dev.js
index bdfec3f9e..86282e3bc 100644
--- a/app.config.environment.dev.js
+++ b/app.config.environment.dev.js
@@ -18,7 +18,7 @@ const stackProvidedLibsConfig = {
   plugins: [
     new webpack.DefinePlugin({
       'process.env.NODE_ENV': JSON.stringify('development'),
-      'process.env.IS_ALPHA': JSON.stringify('true'), //set this variable true for dev so tests runs with alpha variable
+      __IS_ALPHA__: true,
       __STACK_ASSETS__: true,
     }),
   ],
diff --git a/app.config.environment.prod.js b/app.config.environment.prod.js
new file mode 100644
index 000000000..9e5401b8d
--- /dev/null
+++ b/app.config.environment.prod.js
@@ -0,0 +1,33 @@
+'use strict'
+
+const webpack = require('webpack')
+const TerserPlugin = require('terser-webpack-plugin')
+
+const { target } = require('cozy-scripts/config/webpack.vars')
+
+module.exports = {
+  mode: 'production',
+  plugins: [
+    // use a hash as chunk id to avoid id changes of not changing chunk
+    new webpack.HashedModuleIdsPlugin(),
+    new webpack.optimize.OccurrenceOrderPlugin(),
+    new webpack.DefinePlugin({
+      'process.env.NODE_ENV': JSON.stringify('production'), // to compile on production mode (redux)
+      __IS_ALPHA__: false,
+      __DEVELOPMENT__: false,
+      __DEVTOOLS__: false,
+      __STACK_ASSETS__: target !== 'mobile',
+    }),
+  ],
+  optimization: {
+    minimizer: [
+      new TerserPlugin({
+        parallel: true,
+        //To fix a SAfari 10 bug : https://github.com/zeit/next.js/issues/5630
+        terserOptions: {
+          safari10: true,
+        },
+      }),
+    ],
+  },
+}
diff --git a/app.config.js b/app.config.js
index 766c8fbe9..5bd0f5e6b 100644
--- a/app.config.js
+++ b/app.config.js
@@ -17,7 +17,6 @@ const {
 const configs = [
   require('cozy-scripts/config/webpack.config.base'),
   require('cozy-scripts/config/webpack.config.chunks'),
-  //require('cozy-scripts/config/webpack.config.react'),
   require('./app.config.react'), // Override the react config
   require('cozy-scripts/config/webpack.config.cozy-ui'),
   require('cozy-scripts/config/webpack.config.cozy-ui.react'),
@@ -28,16 +27,16 @@ const configs = [
   require('cozy-scripts/config/webpack.config.manifest'),
   require('cozy-scripts/config/webpack.config.progress'),
   addAnalyzer ? require('cozy-scripts/config/webpack.config.analyzer') : null,
-  // require('cozy-scripts/config/webpack.config.services'),
   require('./app.config.services'), // Override the services config
   require(`cozy-scripts/config/webpack.target.${target}`),
 ]
 
-if (environment === 'production' && process.env.IS_ALPHA !== 'true') {
-  configs.push(require('cozy-scripts/config/webpack.environment.prod'))
+if (environment === 'production') {
+  configs.push(require('./app.config.environment.prod'))
 } else {
   configs.push(require('./app.config.environment.dev'))
 }
 
 //module.exports = merge.apply(null, configs)
+// eslint-disable-next-line prefer-spread
 module.exports = [merge.apply(null, configs)] // cozy builder expects an array
diff --git a/app.config.services.alpha.js b/app.config.services.alpha.js
new file mode 100644
index 000000000..f7edfa487
--- /dev/null
+++ b/app.config.services.alpha.js
@@ -0,0 +1,100 @@
+/* eslint-disable @typescript-eslint/no-var-requires */
+'use strict'
+
+/**
+ * This file overrides the default services webpack config.
+ * This services config enables the use of TypeScript.
+ *
+ * @override node_modules/cozy-scripts/config/webpack.config.services.js
+ */
+
+const webpack = require('webpack')
+const path = require('path')
+const fs = require('fs-extra')
+const paths = require('cozy-scripts/utils/paths')
+const {
+  eslintFix,
+  getFilename,
+  target,
+} = require('cozy-scripts/config/webpack.vars')
+
+const servicesFolder = paths.appServicesFolder()
+const servicesPaths = fs.existsSync(servicesFolder)
+  ? fs.readdirSync(servicesFolder)
+  : []
+
+const servicesEntries = {}
+servicesPaths.forEach(file => {
+  if (!file.match(/^[^.]*.ts$/)) return
+  const filename = file.match(/^([^.]*).ts$/)[1]
+  servicesEntries[filename] = path.resolve(path.join(servicesFolder, file))
+})
+
+const config = {
+  __mergeStrategy: {
+    smart: false,
+    strategy: {
+      plugins: 'replace',
+      output: 'replace',
+      entry: 'replace',
+      optimization: 'replace',
+      module: 'replace',
+      externals: 'replace',
+    },
+  },
+  entry: servicesEntries,
+  output: {
+    path: paths.appServicesBuild(),
+    filename: `${getFilename(false)}.js`,
+  },
+  target: 'node',
+  optimization: {}, // reset optimization property
+  devtool: false,
+  externals: [], // reset externals property
+  module: {
+    rules: [
+      {
+        enforce: 'pre',
+        test: /\.ts$/,
+        loader: require.resolve('cozy-scripts/node_modules/eslint-loader'),
+        exclude: /node_modules/,
+        options: {
+          extends: ['cozy-app'],
+          fix: eslintFix,
+          emitWarning: true,
+        },
+      },
+      {
+        test: /\.hbs$/,
+        loader: 'handlebars-loader',
+      },
+      {
+        test: path.resolve(__dirname, 'node_modules/uglify-js/tools/node.js'),
+        loader: 'null-loader',
+      },
+      {
+        test: /\.ts$/,
+        exclude: /(node_modules|cozy-(bar|client-js))/,
+        loader: require.resolve('cozy-scripts/node_modules/babel-loader'),
+        options: {
+          cacheDirectory: 'cozy-scripts/node_modules/.cache/babel-loader/node',
+          babelrc: false,
+          presets: [['cozy-app', { node: true, react: false }]],
+        },
+      },
+    ],
+  },
+  plugins: [
+    new webpack.DefinePlugin({
+      __TARGET__: JSON.stringify('services'),
+      __IS_ALPHA__: true,
+    }),
+  ],
+}
+
+/* We don't build services if no services and if on mobile build */
+const addServicesConfig =
+  target === 'browser' && Object.keys(servicesEntries).length
+
+// only for browser target (services are usable only on cozy-stack)
+module.exports = addServicesConfig ? { multiple: { services: config } } : {}
diff --git a/app.config.services.js b/app.config.services.js
index 8dd5d50ea..edc28bebe 100644
--- a/app.config.services.js
+++ b/app.config.services.js
@@ -87,6 +87,7 @@ const config = {
   plugins: [
     new webpack.DefinePlugin({
       __TARGET__: JSON.stringify('services'),
+      __IS_ALPHA__: false,
     }),
   ],
 }
diff --git a/src/components/Feedback/FeedbackModal.spec.tsx b/src/components/Feedback/FeedbackModal.spec.tsx
index a5c818cd0..f57ee8d62 100644
--- a/src/components/Feedback/FeedbackModal.spec.tsx
+++ b/src/components/Feedback/FeedbackModal.spec.tsx
@@ -12,15 +12,6 @@ import {
 } from '../../../tests/__mocks__/store'
 import { act } from 'react-dom/test-utils'
 
-const mockSendMail = jest.fn()
-jest.mock('services/mail.service', () => {
-  return jest.fn(() => {
-    return {
-      SendMail: mockSendMail,
-    }
-  })
-})
-
 jest.mock('cozy-ui/transpiled/react/I18n', () => {
   return {
     useI18n: jest.fn(() => {
@@ -31,6 +22,23 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
   }
 })
 
+jest.mock('services/environment.service', () => {
+  return jest.fn(() => {
+    return {
+      isProduction: () => true,
+    }
+  })
+})
+
+const mockSendMail = jest.fn()
+jest.mock('services/mail.service', () => {
+  return jest.fn(() => {
+    return {
+      SendMail: mockSendMail,
+    }
+  })
+})
+
 const handleFeedbackModalClose = jest.fn()
 
 const mockUseSelector = jest.spyOn(reactRedux, 'useSelector')
diff --git a/src/components/Feedback/FeedbackModal.tsx b/src/components/Feedback/FeedbackModal.tsx
index f3e7f2733..d2db8f2d0 100644
--- a/src/components/Feedback/FeedbackModal.tsx
+++ b/src/components/Feedback/FeedbackModal.tsx
@@ -22,7 +22,7 @@ import MailService from 'services/mail.service'
 import './feedbackModal.scss'
 import useExploration from 'components/Hooks/useExploration'
 import { UserExplorationID } from 'enum/userExploration.enum'
-import EnvironementService from 'services/environement.service'
+import EnvironmentService from 'services/environment.service'
 
 const FEEDBACK_EMAIL = 'ecolyo@grandlyon.com'
 const browser = detect()
@@ -86,7 +86,7 @@ const FeedbackModal: React.FC<FeedbackModalProps> = ({
         '\n' +
         envInfo
 
-      const subjectEnv = new EnvironementService().isProduction()
+      const subjectEnv = new EnvironmentService().isProduction()
         ? '[Ecolyo]'
         : '[Ecolyo - alpha]'
 
diff --git a/src/components/Home/ConsumptionView.tsx b/src/components/Home/ConsumptionView.tsx
index 0e0836b24..f207ac8b6 100644
--- a/src/components/Home/ConsumptionView.tsx
+++ b/src/components/Home/ConsumptionView.tsx
@@ -32,7 +32,6 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({
   fluidType,
 }: ConsumptionViewProps) => {
   const client = useClient()
-
   const dispatch = useDispatch()
   const { currentTimeStep, loading } = useSelector(
     (state: AppStore) => state.ecolyo.chart
diff --git a/src/components/Onboarding/WelcomeModal.spec.tsx b/src/components/Onboarding/WelcomeModal.spec.tsx
index a635a8211..9be659c49 100644
--- a/src/components/Onboarding/WelcomeModal.spec.tsx
+++ b/src/components/Onboarding/WelcomeModal.spec.tsx
@@ -31,6 +31,13 @@ jest.mock('components/Hooks/userInstanceSettings', () => {
     },
   }))
 })
+jest.mock('services/environment.service', () => {
+  return jest.fn(() => {
+    return {
+      getPublicURL: () => 'https://ecolyo-agent-rec.grandlyon.com',
+    }
+  })
+})
 const mockSendMail = jest.fn()
 jest.mock('services/mail.service', () => {
   return jest.fn(() => {
diff --git a/src/components/Onboarding/WelcomeModal.tsx b/src/components/Onboarding/WelcomeModal.tsx
index 24fd01ea7..8db78b491 100644
--- a/src/components/Onboarding/WelcomeModal.tsx
+++ b/src/components/Onboarding/WelcomeModal.tsx
@@ -5,7 +5,7 @@ import { useI18n } from 'cozy-ui/transpiled/react/I18n'
 import { useClient } from 'cozy-client'
 import { Button, Dialog, IconButton } from '@material-ui/core'
 import userInstanceSettings from 'components/Hooks/userInstanceSettings'
-import EnvironementService from 'services/environement.service'
+import EnvironmentService from 'services/environment.service'
 import MailService from 'services/mail.service'
 import Icon from 'cozy-ui/transpiled/react/Icon'
 import CloseIcon from 'assets/icons/ico/close.svg'
@@ -31,8 +31,8 @@ const WelcomeModal = ({ open }: WelcomeModalProps) => {
     if (instanceSettings.public_name !== '') {
       username = instanceSettings.public_name
     }
-    const environementService = new EnvironementService()
-    const baseUrl = environementService.getPublicURL()
+    const environmentService = new EnvironmentService()
+    const baseUrl = environmentService.getPublicURL()
     const template = welcomeTemplate({
       title: 'Bienvenue sur Ecolyo !',
       username: username,
diff --git a/src/services/environement.service.spec.ts b/src/services/environement.service.spec.ts
index be29f5336..3ff3841ee 100644
--- a/src/services/environement.service.spec.ts
+++ b/src/services/environement.service.spec.ts
@@ -1,37 +1,23 @@
-import EnvironementService from './environement.service'
+import EnvironmentService from './environment.service'
 
 describe('Environement service', () => {
-  const OLD_ENV = process.env
-  beforeEach(() => {
-    jest.resetModules() // Most important - it clears the cache
-    process.env = { ...OLD_ENV } // Make a copy
-  })
-
-  afterAll(() => {
-    process.env = OLD_ENV // Restore old environment
-  })
-  const environementService = new EnvironementService()
+  const environmentService = new EnvironmentService()
 
   describe('isProduction method', () => {
-    it('should return true', async () => {
-      process.env.IS_ALPHA = 'toto'
-      process.env.NODE_ENV = 'production'
-      const result = environementService.isProduction()
+    it('should return true and prod url', async () => {
+      global.__IS_ALPHA__ = false
+      const result = environmentService.isProduction()
       expect(result).toEqual(true)
+      const url = environmentService.getPublicURL()
+      expect(url).toEqual('https://ecolyo-agent.grandlyon.com')
     })
 
-    it('should return false, developement case', async () => {
-      process.env.IS_ALPHA = 'true'
-      process.env.NODE_ENV = 'development'
-      const result = environementService.isProduction()
-      expect(result).toEqual(false)
-    })
-
-    it('should return false, alpha case', async () => {
-      process.env.IS_ALPHA = 'true'
-      process.env.NODE_ENV = 'production'
-      const result = environementService.isProduction()
+    it('should return false and rec url, alpha case', async () => {
+      global.__IS_ALPHA__ = true
+      const result = environmentService.isProduction()
       expect(result).toEqual(false)
+      const url = environmentService.getPublicURL()
+      expect(url).toEqual('https://ecolyo-agent-rec.grandlyon.com')
     })
   })
 })
diff --git a/src/services/environement.service.ts b/src/services/environment.service.ts
similarity index 55%
rename from src/services/environement.service.ts
rename to src/services/environment.service.ts
index 268d43798..0fb89f8f4 100644
--- a/src/services/environement.service.ts
+++ b/src/services/environment.service.ts
@@ -1,16 +1,21 @@
-export default class EnvironementService {
+declare const __IS_ALPHA__: boolean
+
+export default class EnvironmentService {
   private isAlpha() {
-    return process.env.IS_ALPHA
+    if (__IS_ALPHA__) {
+      return __IS_ALPHA__
+    }
+    return false
   }
 
   public isProduction() {
-    if (this.isAlpha() !== 'true') {
+    if (!this.isAlpha()) {
       return true
     }
     return false
   }
   public getPublicURL() {
-    if (this.isAlpha() !== 'true') {
+    if (!this.isAlpha()) {
       return 'https://ecolyo-agent.grandlyon.com'
     } else {
       return 'https://ecolyo-agent-rec.grandlyon.com'
diff --git a/src/services/partnersInfo.service.spec.ts b/src/services/partnersInfo.service.spec.ts
index 2a66339fd..f96b94fb4 100644
--- a/src/services/partnersInfo.service.spec.ts
+++ b/src/services/partnersInfo.service.spec.ts
@@ -2,6 +2,14 @@ import { PartnersInfo } from 'models/partnersInfo.model'
 import mockClient from '../../tests/__mocks__/client'
 import PartnersInfoService from './partnersInfo.service'
 
+jest.mock('services/environment.service', () => {
+  return jest.fn(() => {
+    return {
+      isProduction: () => true,
+    }
+  })
+})
+
 describe('PartnersInfo service', () => {
   const partnersInfoService = new PartnersInfoService(mockClient)
 
diff --git a/src/services/partnersInfo.service.ts b/src/services/partnersInfo.service.ts
index 202629f7b..2ac011189 100644
--- a/src/services/partnersInfo.service.ts
+++ b/src/services/partnersInfo.service.ts
@@ -1,6 +1,6 @@
 import { Client } from 'cozy-client'
 import { PartnersInfo } from 'models/partnersInfo.model'
-import EnvironementService from './environement.service'
+import EnvironmentService from './environment.service'
 
 export default class PartnersInfoService {
   private readonly _client: Client
@@ -15,7 +15,7 @@ export default class PartnersInfoService {
    * Else, throw an error
    */
   public async getPartnersInfo(): Promise<PartnersInfo> {
-    const env = new EnvironementService()
+    const env = new EnvironmentService()
     const remoteUrl = env.isProduction()
       ? `/remote/org.ecolyo.backoffice.partners.info`
       : `/remote/org.ecolyo.backoffice.partners.info.rec`
diff --git a/src/styles/index.css b/src/styles/index.css
index 4db44fc1b..049ceff48 100644
--- a/src/styles/index.css
+++ b/src/styles/index.css
@@ -1147,7 +1147,7 @@ button.btn-profile-back {
   cursor: pointer; }
   /* line 15, src/styles/base/_mixins.scss */
   button.btn-profile-back span:first-child {
-    color: #7b7b7b; }
+    color: #a0a0a0; }
   /* line 24, src/styles/base/_mixins.scss */
   button.btn-profile-back:disabled {
     cursor: not-allowed; }
diff --git a/src/targets/services/aggregatorUsageEvents.ts b/src/targets/services/aggregatorUsageEvents.ts
index 3760f051f..854e74c7a 100644
--- a/src/targets/services/aggregatorUsageEvents.ts
+++ b/src/targets/services/aggregatorUsageEvents.ts
@@ -12,7 +12,7 @@ import FluidService from 'services/fluid.service'
 import { FluidState, FluidType } from 'enum/fluid.enum'
 import { getFluidType } from 'utils/utils'
 import { TimeStep } from 'enum/timeStep.enum'
-import EnvironementService from 'services/environement.service'
+import EnvironmentService from 'services/environment.service'
 import { DaccEvent } from 'enum/dacc.enum'
 import { UsageEventProperties } from 'enum/usageEventProperties.enum'
 import ChallengeService from 'services/challenge.service'
@@ -49,10 +49,10 @@ const sendIndicator = async (
   client: Client
 ): Promise<boolean> => {
   try {
-    const environementService = new EnvironementService()
+    const environmentService = new EnvironmentService()
     log(
       'info',
-      environementService.isProduction()
+      environmentService.isProduction()
         ? 'Sending data to dacc'
         : 'Sending data to dacc-dev'
     )
@@ -62,7 +62,7 @@ const sendIndicator = async (
       .getStackClient()
       .fetchJSON(
         'POST',
-        environementService.isProduction()
+        environmentService.isProduction()
           ? '/remote/cc.cozycloud.dacc'
           : '/remote/cc.cozycloud.dacc.dev',
         {
diff --git a/src/targets/services/consumptionAlert.ts b/src/targets/services/consumptionAlert.ts
index 772273944..b34de110b 100644
--- a/src/targets/services/consumptionAlert.ts
+++ b/src/targets/services/consumptionAlert.ts
@@ -10,7 +10,7 @@ import mjml2html from 'mjml'
 import { FluidType } from 'enum/fluid.enum'
 import ConsumptionService from 'services/consumption.service'
 import { getPreviousMonthName } from 'utils/utils'
-import EnvironementService from 'services/environement.service'
+import EnvironmentService from 'services/environment.service'
 
 const log = logger.namespace('alert')
 
@@ -75,10 +75,10 @@ const consumptionAlert = async ({ client }: ConsumptionAlertProps) => {
   const mailService = new MailService()
   const today = DateTime.local().setZone('utc', { keepLocalTime: true })
 
-  const environementService = new EnvironementService()
+  const environmentService = new EnvironmentService()
   const template = consumptionLimit({
     title: 'Ça déborde !',
-    baseUrl: environementService.getPublicURL(),
+    baseUrl: environmentService.getPublicURL(),
     username: username,
     clientUrl: `${appLink}/#/consumption/water`,
     unsubscribeUrl: `${appLink}/#/options`,
diff --git a/src/targets/services/monthlyReportNotification.ts b/src/targets/services/monthlyReportNotification.ts
index ac208e6e8..e6f0e0b33 100644
--- a/src/targets/services/monthlyReportNotification.ts
+++ b/src/targets/services/monthlyReportNotification.ts
@@ -12,7 +12,7 @@ import { FluidType } from 'enum/fluid.enum'
 import { TimeStep } from 'enum/timeStep.enum'
 import ConsumptionService from 'services/consumption.service'
 import { MonthlReport } from 'models/monthlyReport.model'
-import EnvironementService from 'services/environement.service'
+import EnvironmentService from 'services/environment.service'
 import { getMonthNameWithPrep, getPreviousMonthName } from 'utils/utils'
 
 const log = logger.namespace('report')
@@ -138,10 +138,10 @@ const getMonthlyReport = async (
   client: Client
 ): Promise<MonthlReport> => {
   try {
-    const environementService = new EnvironementService()
+    const environmentService = new EnvironmentService()
     log(
       'info',
-      environementService.isProduction()
+      environmentService.isProduction()
         ? 'Fetching data from BO prod'
         : 'Fetching data from BO rec'
     )
@@ -150,7 +150,7 @@ const getMonthlyReport = async (
       .getStackClient()
       .fetchJSON(
         'GET',
-        environementService.isProduction()
+        environmentService.isProduction()
           ? `/remote/org.ecolyo.backoffice?year=${year}&month=${month}`
           : `/remote/org.ecolyo.backoffice.rec?year=${year}&month=${month}`
       )
@@ -260,8 +260,8 @@ const monthlyReportNotification = async ({
     .setZone('utc', { keepLocalTime: true })
     .minus({ month: 1 })
 
-  const environementService = new EnvironementService()
-  const baseUrl = environementService.getPublicURL()
+  const environmentService = new EnvironmentService()
+  const baseUrl = environmentService.getPublicURL()
 
   const template = monthlyReportTemplate({
     title: 'Du nouveau dans votre espace Ecolyo !',
-- 
GitLab