diff --git a/index.js b/index.js
index def95a5c527180b860f64b431caa52d54666c380..5e11de559be0aac0f16709cf0f694408d4d62342 100644
--- a/index.js
+++ b/index.js
@@ -98,7 +98,7 @@ const {
 } = __webpack_require__(1)
 const getAccountId = __webpack_require__(1767)
 const getDataGenericErrors = __webpack_require__(1768)
-const { isAlpha } = __webpack_require__(1769)
+const { isDev } = __webpack_require__(1769)
 const moment = __webpack_require__(1770)
 __webpack_require__(1907)
 moment.locale('fr') // set the language
@@ -118,14 +118,34 @@ Sentry.init({
   // We recommend adjusting this value in production
   tracesSampleRate: 1.0,
   release: version,
-  environment: isAlpha() ? 'development' : 'production',
-  debug: isAlpha(),
+  environment: isDev() ? 'development' : 'production',
+  debug: isDev(),
   integrations: [
     // enable HTTP calls tracing
     new Sentry.Integrations.Http({ tracing: true })
   ]
 })
 
+async function standaloneStart(token, pce) {
+  try {
+    const grdfData = await getData(token, pce)
+    if (!grdfData) {
+      log('debug', 'No consent or data for load curve')
+      return
+    }
+    log('debug', 'Process grdf daily data')
+    const processedLoadData = await processData(
+      grdfData,
+      'com.grandlyon.grdf.day',
+      ['year', 'month', 'day']
+    )
+    log('debug', 'Aggregate grdf load data for month and year')
+    await aggregateMonthAndYearData(processedLoadData)
+  } catch (error) {
+    log('error', 'Standalone failed')
+  }
+}
+
 const manualExecution =
   process.env.COZY_JOB_MANUAL_EXECUTION === 'true' ? true : false
 const startDate = manualExecution
@@ -211,9 +231,15 @@ async function start(fields) {
   }
 }
 
+function buildGetDataUrl(idPCE, startDate, endDate) {
+  const baseUrl = 'https://api.grdf.fr/adict/v2/pce'
+  const queryParams = `date_debut=${startDate}&date_fin=${endDate}`
+  return `${baseUrl}/${idPCE}/donnees_consos_informatives?${queryParams}`
+}
+
 async function getData(token, idPCE) {
   const url = buildGetDataUrl(idPCE, startDate, endDate)
-  const rep = await fetch(url, {
+  const response = await fetch(url, {
     method: 'GET',
     headers: {
       'Content-Type': 'application/x-ndjson',
@@ -267,18 +293,12 @@ async function getData(token, idPCE) {
       log('debug', 'Error from getData')
       throw error
     })
-  const filteredRep = rep.filter(function(el) {
+  const filteredRep = response.filter(function(el) {
     return el.energie != null || el.volume_brut != null
   })
   return filteredRep
 }
 
-function buildGetDataUrl(idPCE, startDate, endDate) {
-  const baseUrl = 'https://api.grdf.fr/adict/v2/pce'
-  const queryParams = `date_debut=${startDate}&date_fin=${endDate}`
-  return `${baseUrl}/${idPCE}/donnees_consos_informatives?${queryParams}`
-}
-
 /**
  * Parse data
  * Remove existing data from DB using hydrateAndFilter
@@ -151714,7 +151734,7 @@ const fs = __webpack_require__(167);
 
 const path = __webpack_require__(160);
 
-let manifest = typeof {"version":"1.2.1","name":"GRDF","type":"konnector","language":"node","icon":"icon.png","slug":"grdfgrandlyon","source":"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git","editor":"Métropole de Lyon","vendor_link":"https://www.grdf.fr/","categories":["energy"],"frequency":"daily","fields":{"access_token":{"type":"hidden"},"refresh_token":{"type":"hidden"}},"oauth":{},"data_types":[],"screenshots":[],"permissions":{"accounts":{"type":"io.cozy.accounts"},"grdf data":{"type":"com.grandlyon.grdf.*"}},"developer":{"name":"Métropole de Lyon","url":"https://www.grandlyon.com/"},"langs":["fr"],"locales":{"fr":{"short_description":"Récupère vos donnéees de courbe de charge depuis l'API GRDF ADICT","long_description":"Ce connecteur récupère la courbe d'energie en kWh enregistrée par un compteur Gazpar","permissions":{"grdf data":{"description":"Requises pour accéder et stocker les données collectées par le compteur Gazpar et exposées par les API GRDF (consommations de gaz au jour, mois et année)."},"accounts":{"description":"Utilisé pour accéder à vos données de consommation."}}},"en":{"short_description":"Gas consumption data fetched from GRDF ADICT API","long_description":"This konnector fetches the data curve in kWh gathered by Gaspar device.","permissions":{"grdf data":{"description":"Required to access and store the data collected by the Gazpar meter and exposed by GRDF APIs (daily, monthly and yearly consumption)."},"accounts":{"description":"Used to access your consumption data."}}}},"manifest_version":"2","on_delete_account":"onDeleteAccount.js"} === 'undefined' ? {} : {"version":"1.2.1","name":"GRDF","type":"konnector","language":"node","icon":"icon.png","slug":"grdfgrandlyon","source":"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git","editor":"Métropole de Lyon","vendor_link":"https://www.grdf.fr/","categories":["energy"],"frequency":"daily","fields":{"access_token":{"type":"hidden"},"refresh_token":{"type":"hidden"}},"oauth":{},"data_types":[],"screenshots":[],"permissions":{"accounts":{"type":"io.cozy.accounts"},"grdf data":{"type":"com.grandlyon.grdf.*"}},"developer":{"name":"Métropole de Lyon","url":"https://www.grandlyon.com/"},"langs":["fr"],"locales":{"fr":{"short_description":"Récupère vos donnéees de courbe de charge depuis l'API GRDF ADICT","long_description":"Ce connecteur récupère la courbe d'energie en kWh enregistrée par un compteur Gazpar","permissions":{"grdf data":{"description":"Requises pour accéder et stocker les données collectées par le compteur Gazpar et exposées par les API GRDF (consommations de gaz au jour, mois et année)."},"accounts":{"description":"Utilisé pour accéder à vos données de consommation."}}},"en":{"short_description":"Gas consumption data fetched from GRDF ADICT API","long_description":"This konnector fetches the data curve in kWh gathered by Gaspar device.","permissions":{"grdf data":{"description":"Required to access and store the data collected by the Gazpar meter and exposed by GRDF APIs (daily, monthly and yearly consumption)."},"accounts":{"description":"Used to access your consumption data."}}}},"manifest_version":"2","on_delete_account":"onDeleteAccount.js"};
+let manifest = typeof {"version":"1.2.0","name":"GRDF","type":"konnector","language":"node","icon":"icon.png","slug":"grdfgrandlyon","source":"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git","editor":"Métropole de Lyon","vendor_link":"https://www.grdf.fr/","categories":["energy"],"frequency":"daily","fields":{"access_token":{"type":"hidden"},"refresh_token":{"type":"hidden"}},"oauth":{},"data_types":[],"screenshots":[],"permissions":{"accounts":{"type":"io.cozy.accounts"},"grdf data":{"type":"com.grandlyon.grdf.*"}},"developer":{"name":"Métropole de Lyon","url":"https://www.grandlyon.com/"},"langs":["fr"],"locales":{"fr":{"short_description":"Récupère vos donnéees de courbe de charge depuis l'API GRDF ADICT","long_description":"Ce connecteur récupère la courbe d'energie en kWh enregistrée par un compteur Gazpar","permissions":{"grdf data":{"description":"Requises pour accéder et stocker les données collectées par le compteur Gazpar et exposées par les API GRDF (consommations de gaz au jour, mois et année)."},"accounts":{"description":"Utilisé pour accéder à vos données de consommation."}}},"en":{"short_description":"Gas consumption data fetched from GRDF ADICT API","long_description":"This konnector fetches the data curve in kWh gathered by Gaspar device.","permissions":{"grdf data":{"description":"Required to access and store the data collected by the Gazpar meter and exposed by GRDF APIs (daily, monthly and yearly consumption)."},"accounts":{"description":"Used to access your consumption data."}}}},"manifest_version":"2","on_delete_account":"onDeleteAccount.js"} === 'undefined' ? {} : {"version":"1.2.0","name":"GRDF","type":"konnector","language":"node","icon":"icon.png","slug":"grdfgrandlyon","source":"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git","editor":"Métropole de Lyon","vendor_link":"https://www.grdf.fr/","categories":["energy"],"frequency":"daily","fields":{"access_token":{"type":"hidden"},"refresh_token":{"type":"hidden"}},"oauth":{},"data_types":[],"screenshots":[],"permissions":{"accounts":{"type":"io.cozy.accounts"},"grdf data":{"type":"com.grandlyon.grdf.*"}},"developer":{"name":"Métropole de Lyon","url":"https://www.grandlyon.com/"},"langs":["fr"],"locales":{"fr":{"short_description":"Récupère vos donnéees de courbe de charge depuis l'API GRDF ADICT","long_description":"Ce connecteur récupère la courbe d'energie en kWh enregistrée par un compteur Gazpar","permissions":{"grdf data":{"description":"Requises pour accéder et stocker les données collectées par le compteur Gazpar et exposées par les API GRDF (consommations de gaz au jour, mois et année)."},"accounts":{"description":"Utilisé pour accéder à vos données de consommation."}}},"en":{"short_description":"Gas consumption data fetched from GRDF ADICT API","long_description":"This konnector fetches the data curve in kWh gathered by Gaspar device.","permissions":{"grdf data":{"description":"Required to access and store the data collected by the Gazpar meter and exposed by GRDF APIs (daily, monthly and yearly consumption)."},"accounts":{"description":"Used to access your consumption data."}}}},"manifest_version":"2","on_delete_account":"onDeleteAccount.js"};
 
 if (false) {}
 
@@ -234712,9 +234732,10 @@ module.exports = getDataGenericErrors
 /* 1769 */
 /***/ (function(module, exports, __webpack_require__) {
 
-function isDev() {
+function isLocal() {
   return (
-     false || "none" === 'test'
+     false ||
+    "none" === 'standalone'
   )
 }
 
@@ -234722,14 +234743,14 @@ function isDev() {
  * Verify if it's an alpha URL
  * @returns {boolean}
  */
-function isAlpha() {
+function isDev() {
   return (
     process.env.COZY_URL.includes('alpha') ||
     process.env.COZY_URL.includes('cozy.tools')
   )
 }
 
-module.exports = { isDev, isAlpha }
+module.exports = { isLocal, isDev }
 
 
 /***/ }),
@@ -276100,7 +276121,7 @@ var SpanStatus; (function (SpanStatus) {
 /* 2047 */
 /***/ (function(module) {
 
-module.exports = JSON.parse("{\"name\":\"grdf\",\"version\":\"1.2.1\",\"description\":\"\",\"repository\":{\"type\":\"git\",\"url\":\"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git\"},\"keywords\":[],\"author\":\"Grand Lyon\",\"license\":\"AGPL-3.0\",\"main\":\"./src/index.js\",\"eslintConfig\":{\"extends\":[\"cozy-app\"]},\"eslintIgnore\":[\"build\",\"data\"],\"husky\":{\"hooks\":{\"pre-commit\":\"yarn lint\"}},\"jest\":{\"setupFiles\":[\"./setupTests.js\"]},\"scripts\":{\"start\":\"node ./src/index.js\",\"dev\":\"cozy-konnector-dev\",\"standalone\":\"cozy-konnector-standalone\",\"onDeleteAccount\":\"cozy-konnector-dev src/onDeleteAccount.js\",\"pretest\":\"npm run clean\",\"test:cov\":\"jest --coverage\",\"test\":\"jest\",\"release\":\"standard-version --no-verify\",\"clean\":\"rm -rf ./data\",\"build\":\"webpack\",\"lint\":\"eslint --fix .\",\"deploy\":\"git-directory-deploy --directory build/ --branch ${DEPLOY_BRANCH:-build}\",\"deploy-dev\":\"git-directory-deploy --directory build/ --branch ${DEPLOY_BRANCH:-build-dev}\",\"deploy-test\":\"git-directory-deploy --directory build/ --branch ${DEPLOY_BRANCH:-build-test}\",\"cozyPublish\":\"cozy-app-publish --token $REGISTRY_TOKEN --build-commit $(git rev-parse ${DEPLOY_BRANCH:-build})\",\"travisDeployKey\":\"./bin/generate_travis_deploy_key\"},\"dependencies\":{\"@sentry/node\":\"^7.28.1\",\"@sentry/tracing\":\"^7.28.1\",\"axios\":\"^0.20.0\",\"cozy-client\":\"23.22.0\",\"cozy-konnector-libs\":\"4.34.5\",\"husky\":\"4.3.0\",\"jest\":\"^28.1.3\",\"jest-fetch-mock\":\"^3.0.3\",\"jsonwebtoken\":\"^8.5.1\",\"moment\":\"^2.29.0\",\"moment-timezone\":\"^0.5.31\"},\"devDependencies\":{\"copy-webpack-plugin\":\"6.1.1\",\"cozy-app-publish\":\"0.25.0\",\"cozy-jobs-cli\":\"1.13.6\",\"eslint-config-cozy-app\":\"1.6.0\",\"git-directory-deploy\":\"1.5.1\",\"husky\":\"4.3.0\",\"jest-junit\":\"^14.0.0\",\"standard-version\":\"^9.5.0\",\"svgo\":\"1.3.2\",\"webpack\":\"4.44.2\",\"webpack-cli\":\"3.3.12\"}}");
+module.exports = JSON.parse("{\"name\":\"grdf\",\"version\":\"1.2.0\",\"description\":\"\",\"repository\":{\"type\":\"git\",\"url\":\"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git\"},\"keywords\":[],\"author\":\"Grand Lyon\",\"license\":\"AGPL-3.0\",\"main\":\"./src/index.js\",\"eslintConfig\":{\"extends\":[\"cozy-app\"]},\"eslintIgnore\":[\"build\",\"data\"],\"husky\":{\"hooks\":{\"pre-commit\":\"yarn lint\"}},\"jest\":{\"setupFiles\":[\"./setupTests.js\"]},\"scripts\":{\"start\":\"node ./src/index.js\",\"dev\":\"cozy-konnector-dev\",\"standalone\":\"cozy-konnector-standalone\",\"onDeleteAccount:standalone\":\"cozy-konnector-standalone src/onDeleteAccount.js\",\"onDeleteAccount\":\"cozy-konnector-dev src/onDeleteAccount.js\",\"pretest\":\"npm run clean\",\"test:cov\":\"jest --coverage\",\"test\":\"jest\",\"release\":\"standard-version --no-verify\",\"clean\":\"rm -rf ./data\",\"build\":\"webpack\",\"lint\":\"eslint --fix .\",\"deploy\":\"git-directory-deploy --directory build/ --branch ${DEPLOY_BRANCH:-build}\",\"deploy-dev\":\"git-directory-deploy --directory build/ --branch ${DEPLOY_BRANCH:-build-dev}\",\"deploy-test\":\"git-directory-deploy --directory build/ --branch ${DEPLOY_BRANCH:-build-test}\",\"cozyPublish\":\"cozy-app-publish --token $REGISTRY_TOKEN --build-commit $(git rev-parse ${DEPLOY_BRANCH:-build})\",\"travisDeployKey\":\"./bin/generate_travis_deploy_key\"},\"dependencies\":{\"@sentry/node\":\"^7.28.1\",\"@sentry/tracing\":\"^7.28.1\",\"axios\":\"^0.20.0\",\"cozy-client\":\"23.22.0\",\"cozy-konnector-libs\":\"4.34.5\",\"husky\":\"4.3.0\",\"jest\":\"^28.1.3\",\"jsonwebtoken\":\"^8.5.1\",\"moment\":\"^2.29.0\",\"moment-timezone\":\"^0.5.31\"},\"devDependencies\":{\"copy-webpack-plugin\":\"6.1.1\",\"cozy-app-publish\":\"0.25.0\",\"cozy-jobs-cli\":\"1.13.6\",\"eslint-config-cozy-app\":\"1.6.0\",\"git-directory-deploy\":\"1.5.1\",\"husky\":\"4.3.0\",\"jest-junit\":\"^14.0.0\",\"standard-version\":\"^9.5.0\",\"svgo\":\"1.3.2\",\"webpack\":\"4.44.2\",\"webpack-cli\":\"3.3.12\"}}");
 
 /***/ })
 /******/ ]);
\ No newline at end of file
diff --git a/manifest.konnector b/manifest.konnector
index 75e5a9da53156a72dd0ad0058122c84e283a5dd8..a5a3348aaad852260f7d6839256edcb717a4a72e 100644
--- a/manifest.konnector
+++ b/manifest.konnector
@@ -1,5 +1,5 @@
 {
-  "version": "1.2.1",
+  "version": "1.2.0",
   "name": "GRDF",
   "type": "konnector",
   "language": "node",
diff --git a/onDeleteAccount.js b/onDeleteAccount.js
index 912dbde6bfd168d68c269d5cd179d6718ee1cd2e..dbb4085640ebbc749fe4d8420f867c5288954d9a 100644
--- a/onDeleteAccount.js
+++ b/onDeleteAccount.js
@@ -151333,7 +151333,7 @@ const fs = __webpack_require__(167);
 
 const path = __webpack_require__(160);
 
-let manifest = typeof {"version":"1.2.1","name":"GRDF","type":"konnector","language":"node","icon":"icon.png","slug":"grdfgrandlyon","source":"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git","editor":"Métropole de Lyon","vendor_link":"https://www.grdf.fr/","categories":["energy"],"frequency":"daily","fields":{"access_token":{"type":"hidden"},"refresh_token":{"type":"hidden"}},"oauth":{},"data_types":[],"screenshots":[],"permissions":{"accounts":{"type":"io.cozy.accounts"},"grdf data":{"type":"com.grandlyon.grdf.*"}},"developer":{"name":"Métropole de Lyon","url":"https://www.grandlyon.com/"},"langs":["fr"],"locales":{"fr":{"short_description":"Récupère vos donnéees de courbe de charge depuis l'API GRDF ADICT","long_description":"Ce connecteur récupère la courbe d'energie en kWh enregistrée par un compteur Gazpar","permissions":{"grdf data":{"description":"Requises pour accéder et stocker les données collectées par le compteur Gazpar et exposées par les API GRDF (consommations de gaz au jour, mois et année)."},"accounts":{"description":"Utilisé pour accéder à vos données de consommation."}}},"en":{"short_description":"Gas consumption data fetched from GRDF ADICT API","long_description":"This konnector fetches the data curve in kWh gathered by Gaspar device.","permissions":{"grdf data":{"description":"Required to access and store the data collected by the Gazpar meter and exposed by GRDF APIs (daily, monthly and yearly consumption)."},"accounts":{"description":"Used to access your consumption data."}}}},"manifest_version":"2","on_delete_account":"onDeleteAccount.js"} === 'undefined' ? {} : {"version":"1.2.1","name":"GRDF","type":"konnector","language":"node","icon":"icon.png","slug":"grdfgrandlyon","source":"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git","editor":"Métropole de Lyon","vendor_link":"https://www.grdf.fr/","categories":["energy"],"frequency":"daily","fields":{"access_token":{"type":"hidden"},"refresh_token":{"type":"hidden"}},"oauth":{},"data_types":[],"screenshots":[],"permissions":{"accounts":{"type":"io.cozy.accounts"},"grdf data":{"type":"com.grandlyon.grdf.*"}},"developer":{"name":"Métropole de Lyon","url":"https://www.grandlyon.com/"},"langs":["fr"],"locales":{"fr":{"short_description":"Récupère vos donnéees de courbe de charge depuis l'API GRDF ADICT","long_description":"Ce connecteur récupère la courbe d'energie en kWh enregistrée par un compteur Gazpar","permissions":{"grdf data":{"description":"Requises pour accéder et stocker les données collectées par le compteur Gazpar et exposées par les API GRDF (consommations de gaz au jour, mois et année)."},"accounts":{"description":"Utilisé pour accéder à vos données de consommation."}}},"en":{"short_description":"Gas consumption data fetched from GRDF ADICT API","long_description":"This konnector fetches the data curve in kWh gathered by Gaspar device.","permissions":{"grdf data":{"description":"Required to access and store the data collected by the Gazpar meter and exposed by GRDF APIs (daily, monthly and yearly consumption)."},"accounts":{"description":"Used to access your consumption data."}}}},"manifest_version":"2","on_delete_account":"onDeleteAccount.js"};
+let manifest = typeof {"version":"1.2.0","name":"GRDF","type":"konnector","language":"node","icon":"icon.png","slug":"grdfgrandlyon","source":"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git","editor":"Métropole de Lyon","vendor_link":"https://www.grdf.fr/","categories":["energy"],"frequency":"daily","fields":{"access_token":{"type":"hidden"},"refresh_token":{"type":"hidden"}},"oauth":{},"data_types":[],"screenshots":[],"permissions":{"accounts":{"type":"io.cozy.accounts"},"grdf data":{"type":"com.grandlyon.grdf.*"}},"developer":{"name":"Métropole de Lyon","url":"https://www.grandlyon.com/"},"langs":["fr"],"locales":{"fr":{"short_description":"Récupère vos donnéees de courbe de charge depuis l'API GRDF ADICT","long_description":"Ce connecteur récupère la courbe d'energie en kWh enregistrée par un compteur Gazpar","permissions":{"grdf data":{"description":"Requises pour accéder et stocker les données collectées par le compteur Gazpar et exposées par les API GRDF (consommations de gaz au jour, mois et année)."},"accounts":{"description":"Utilisé pour accéder à vos données de consommation."}}},"en":{"short_description":"Gas consumption data fetched from GRDF ADICT API","long_description":"This konnector fetches the data curve in kWh gathered by Gaspar device.","permissions":{"grdf data":{"description":"Required to access and store the data collected by the Gazpar meter and exposed by GRDF APIs (daily, monthly and yearly consumption)."},"accounts":{"description":"Used to access your consumption data."}}}},"manifest_version":"2","on_delete_account":"onDeleteAccount.js"} === 'undefined' ? {} : {"version":"1.2.0","name":"GRDF","type":"konnector","language":"node","icon":"icon.png","slug":"grdfgrandlyon","source":"https://forge.grandlyon.com/web-et-numerique/llle_project/grdf-konnector.git","editor":"Métropole de Lyon","vendor_link":"https://www.grdf.fr/","categories":["energy"],"frequency":"daily","fields":{"access_token":{"type":"hidden"},"refresh_token":{"type":"hidden"}},"oauth":{},"data_types":[],"screenshots":[],"permissions":{"accounts":{"type":"io.cozy.accounts"},"grdf data":{"type":"com.grandlyon.grdf.*"}},"developer":{"name":"Métropole de Lyon","url":"https://www.grandlyon.com/"},"langs":["fr"],"locales":{"fr":{"short_description":"Récupère vos donnéees de courbe de charge depuis l'API GRDF ADICT","long_description":"Ce connecteur récupère la courbe d'energie en kWh enregistrée par un compteur Gazpar","permissions":{"grdf data":{"description":"Requises pour accéder et stocker les données collectées par le compteur Gazpar et exposées par les API GRDF (consommations de gaz au jour, mois et année)."},"accounts":{"description":"Utilisé pour accéder à vos données de consommation."}}},"en":{"short_description":"Gas consumption data fetched from GRDF ADICT API","long_description":"This konnector fetches the data curve in kWh gathered by Gaspar device.","permissions":{"grdf data":{"description":"Required to access and store the data collected by the Gazpar meter and exposed by GRDF APIs (daily, monthly and yearly consumption)."},"accounts":{"description":"Used to access your consumption data."}}}},"manifest_version":"2","on_delete_account":"onDeleteAccount.js"};
 
 if (false) {}
 
@@ -234304,7 +234304,31 @@ module.exports = getAccountId
 
 /***/ }),
 /* 1768 */,
-/* 1769 */,
+/* 1769 */
+/***/ (function(module, exports, __webpack_require__) {
+
+function isLocal() {
+  return (
+     false ||
+    "none" === 'standalone'
+  )
+}
+
+/**
+ * Verify if it's an alpha URL
+ * @returns {boolean}
+ */
+function isDev() {
+  return (
+    process.env.COZY_URL.includes('alpha') ||
+    process.env.COZY_URL.includes('cozy.tools')
+  )
+}
+
+module.exports = { isLocal, isDev }
+
+
+/***/ }),
 /* 1770 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -275683,165 +275707,179 @@ moment.locale('fr') // set the language
 moment.tz.setDefault('Europe/Paris') // set the timezone
 const Sentry = __webpack_require__(1910)
 // eslint-disable-next-line
-const Tracing = __webpack_require__(2011) // Needed for tracking performance in Sentry
+const Tracing = __webpack_require__(2011)
+const MAX_RETRIES = 5 // Maximum number of retries
+const INITIAL_BACKOFF = 1000 // Initial backoff interval in ms
+
+async function getAccessToken(accountId, accountRev) {
+  log('info', `getAccessToken: ${accountId} - ${accountRev}`)
+  let body = await cozyClient.fetchJSON(
+    'GET',
+    `/data/io.cozy.accounts/${accountId}?rev=${accountRev}`
+  )
+  if (body.oauth.access_token) {
+    return body
+  } else {
+    throw new Error('cozyClient.fetchJson account_rev has encountered an error')
+  }
+}
+
+async function fetchNewAccessToken(accountSecret) {
+  log(
+    'info',
+    `fetchNewAccessToken: ${accountSecret} - ${accountSecret.client_id}`
+  )
+
+  let url =
+    'https://sofit-sso-oidc.grdf.fr/openam/oauth2/realms/externeGrdf/access_token'
+  return fetch(url, {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/x-www-form-urlencoded'
+    },
+    body: new URLSearchParams({
+      grant_type: 'client_credentials',
+      client_id: `${accountSecret.client_id}`,
+      client_secret: `${accountSecret.client_secret}`,
+      scope: '/adict/v2'
+    }),
+    redirect: 'follow'
+  })
+    .then(async response => {
+      if (response.status !== 200) {
+        throw new Error(response.status + ' - ' + response.statusText)
+      }
+      return response.text()
+    })
+    .then(result => {
+      // split the result into an array of strings containing a single json object
+      // then check if the resulting json has an access_token field
+      // return it if it does or return undefined
+      return result.match(/.+/g).map(jsonString => {
+        const jsonObject = JSON.parse(jsonString)
+        if (jsonObject.access_token) {
+          return jsonObject.access_token
+        }
+      })
+    })
+    .catch(error => {
+      log('debug', 'Error from get access_token [onDeleteAccount]')
+      throw error
+    })
+}
+
+async function fetchDroitAccessGrdf(token, pce) {
+  return fetch('https://api.grdf.fr/adict/v2/droits_acces', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+      Accept: 'application/x-ndjson',
+      Authorization: 'Bearer ' + token
+    },
+    body: JSON.stringify({
+      role_tiers: ['AUTORISE_CONTRAT_FOURNITURE'],
+      etat_droit_acces: ['Active'],
+      id_pce: [pce]
+    }),
+    redirect: 'follow'
+  })
+    .then(async response => {
+      if (response.status !== 200) {
+        throw new Error(response.status + ' - ' + response.statusText)
+      }
+      return response.text()
+    })
+    .then(response => {
+      // Split the response into an array of strings, each containing a single JSON object.
+      // Check if each JSON object has an "id_droit_acces" field.
+      // Return an array of "id_droit_acces" values, or undefined if the field is missing.
+      return response.match(/.+/g).map(jsonString => {
+        const jsonObject = JSON.parse(jsonString)
+        if (jsonObject.id_droit_acces !== null) {
+          return jsonObject.id_droit_acces
+        }
+      })
+    })
+    .catch(error => {
+      log('debug', 'Error from get droits_access')
+      throw error
+    })
+}
+
+async function deleteUserConsent(token, access) {
+  let url = 'https://api.grdf.fr/adict/v2/droit_acces/' + access
+  try {
+    const response = await fetch(url, {
+      method: 'PATCH',
+      headers: {
+        'Cache-Control': 'no-cache',
+        'Content-Type': 'application/json',
+        Authorization: 'Bearer ' + token
+      },
+      body: JSON.stringify({}),
+      redirect: 'follow'
+    })
+    if (response.status !== 200) {
+      throw new Error(response.status + ' - ' + response.statusText)
+    }
+    log('debug', 'Active consent was successfully removed')
+    return true
+  } catch (error) {
+    log('debug', 'Error from delete droits_access')
+    throw error
+  }
+}
 
 async function onDeleteAccount(accountId) {
-  const MAX_RETRIES = 5 // Maximum number of retries
-  const INITIAL_BACKOFF = 1000 // Initial backoff interval in ms
   let retries = 0
   let backoff = INITIAL_BACKOFF
   let accountDeleted = false
-
+  log('info', 'Deleting account ...')
   while (retries < MAX_RETRIES && !accountDeleted) {
     try {
       const accountRev = getAccountRev()
-      if (accountRev) {
-        let body = ''
-        let access_token = ''
-        body = await cozyClient.fetchJSON(
-          'GET',
-          `/data/io.cozy.accounts/${accountId}?rev=${accountRev}`
+      if (!accountRev) {
+        throw new Error(
+          'No account revision was found, something went wrong during the deletion of said account'
         )
-        if (body.oauth.access_token) {
-          access_token = body.oauth.access_token
-        } else {
-          throw new Error(
-            'cozyClient.fetchJson account_rev has encountered an error'
-          )
-        }
-        if (moment().diff(body.oauth.expires_at) > 0) {
-          // token is expired, need a new one. grdf does not provide a refresh token
-          // so we request a new one from a client_credentials query
-          // first we fetch credentials secrets from account-type
-          const accountSecret = getAccountSecret()
-          if (accountSecret) {
-            var myTokenHeaders = new Headers()
-            myTokenHeaders.append(
-              'Content-Type',
-              'application/x-www-form-urlencoded'
-            )
-            var urlencoded = new URLSearchParams()
-            urlencoded.append('grant_type', 'client_credentials')
-            urlencoded.append('client_id', accountSecret.client_id)
-            urlencoded.append('client_secret', accountSecret.client_secret)
-            urlencoded.append('scope', '/adict/v2')
-
-            var requestOptionsToken = {
-              method: 'POST',
-              headers: myTokenHeaders,
-              body: urlencoded,
-              redirect: 'follow'
-            }
+      }
 
-            access_token = await fetch(
-              'https://sofit-sso-oidc.grdf.fr/openam/oauth2/realms/externeGrdf/access_token',
-              requestOptionsToken
-            )
-              .then(async response => {
-                if (response.status !== 200) {
-                  throw new Error(response.status + ' - ' + response.statusText)
-                }
-                return response.text()
-              })
-              .then(result => {
-                return result.match(/.+/g).map(s => {
-                  result = JSON.parse(s)
-                  if (result.access_token) {
-                    return result.access_token
-                  }
-                })
-              })
-              .catch(error => {
-                log('debug', 'Error from get access_token [onDeleteAccount]')
-                throw error
-              })
-          } else {
-            throw new Error(
-              'Access Token is expired and konnector failed to get a new one'
-            )
-          }
-        }
+      const oauthAccount = await getAccessToken(accountId, accountRev)
+      let fetchedNewAccessToken = oauthAccount.oauth.access_token
 
-        var myHeaders = new Headers()
-        myHeaders.append('Content-Type', 'application/json')
-        myHeaders.append('Accept', 'application/x-ndjson')
-        myHeaders.append('Authorization', 'Bearer ' + access_token)
-        var raw = JSON.stringify({
-          role_tiers: ['AUTORISE_CONTRAT_FOURNITURE'],
-          etat_droit_acces: ['Active'],
-          id_pce: [body.oauth_callback_results.pce]
-        })
-        var requestOptions = {
-          method: 'POST',
-          headers: myHeaders,
-          body: raw,
-          redirect: 'follow'
+      if (moment().diff(oauthAccount.oauth.expires_at) <= 0) {
+        log('info', 'Token still valid, no need to fetch a new one')
+      } else {
+        log('info', 'expired token, need a new one')
+        // token is expired, need a new one.
+        // we request a new one from a client_credentials query
+        // with credentials secrets from account-type
+        const accountSecret = getAccountSecret()
+        if (!accountSecret) {
+          throw new Error(
+            'Access Token is expired and konnector failed to get a new one'
+          )
         }
+        fetchedNewAccessToken = await fetchNewAccessToken(accountSecret)
+      }
 
-        let accessRights = await fetch(
-          'https://api.grdf.fr/adict/v2/droits_acces',
-          requestOptions
-        )
-          .then(async response => {
-            if (response.status !== 200) {
-              throw new Error(response.status + ' - ' + response.statusText)
-            }
-            return response.text()
-          })
-          .then(result => {
-            return result.match(/.+/g).map(s => {
-              result = JSON.parse(s)
-              if (result.id_droit_acces !== null) {
-                return result.id_droit_acces
-              }
-            })
-          })
-          .catch(error => {
-            log('debug', 'Error from get droits_access')
-            throw error
-          })
-
-        // remove unwanted commas
-        accessRights = accessRights.toString().replace(/,\s*$/, '')
-        if (accessRights) {
-          var myDeleteHeaders = new Headers()
-          myDeleteHeaders.append('Cache-Control', 'no-cache')
-          myDeleteHeaders.append('Content-Type', 'application/json')
-          myDeleteHeaders.append('Authorization', 'Bearer ' + access_token)
-
-          var deleteRaw = JSON.stringify({})
-
-          var deleteRequestOptions = {
-            method: 'PATCH',
-            headers: myDeleteHeaders,
-            body: deleteRaw,
-            redirect: 'follow'
-          }
+      let accessRights = await fetchDroitAccessGrdf(
+        fetchedNewAccessToken,
+        oauthAccount.oauth_callback_results.pce
+      )
 
-          var url = 'https://api.grdf.fr/adict/v2/droit_acces/' + accessRights
+      // remove unwanted commas
+      accessRights = accessRights.toString().replace(/,\s*$/, '')
 
-          await fetch(url, deleteRequestOptions)
-            .then(async response => {
-              if (response.status !== 200) {
-                throw new Error(response.status + ' - ' + response.statusText)
-              }
-              log('debug', 'Active consent was successfully removed')
-              accountDeleted = true
-              return 'Account deleted successfully'
-            })
-            .catch(error => {
-              log('debug', 'Error from delete droits_access')
-              throw error
-            })
-        } else {
-          log('debug', 'No active consent')
-          throw new Error('No active access right was found for given user')
-        }
-      } else {
-        throw new Error(
-          'No account revision was found, something went wrong during the deletion of said account'
-        )
+      if (!accessRights) {
+        log('debug', 'No active consent')
+        throw new Error('No active access right was found for given user')
       }
+
+      accountDeleted = await deleteUserConsent(
+        fetchedNewAccessToken,
+        accessRights
+      )
     } catch (error) {
       // If the API call fails, log the error and retry with an increased backoff interval
       log(
@@ -275868,14 +275906,13 @@ onDeleteAccount(accountId).then(
   () => {
     log(
       'info',
-      `onDeleteAccount: Successfully retrieved grdf account from account doctype.`
+      `onDeleteAccount GRDF: Successfully delete consent and account.`
     )
   },
   err => {
-    log(
-      'error',
-      `onDeleteAccount: An error occurred during getGrdfAccountInfos script: ${err.message}`
-    )
+    const errorMessage = `onDeleteAccount GRDF: An error occurred during script: ${err.message}`
+    log('error', errorMessage)
+    Sentry.captureException(errorMessage)
   }
 )
 
@@ -275886,13 +275923,20 @@ module.exports = { onDeleteAccount }
 /* 2049 */
 /***/ (function(module, exports, __webpack_require__) {
 
+const { log } = __webpack_require__(1)
+const { isLocal } = __webpack_require__(1769)
+const Sentry = __webpack_require__(1910)
+
 function getAccountRev() {
+  log('info', `getAccountRev: ${JSON.stringify(process.env.COZY_FIELDS)}`)
   try {
-    return  false
-      ? undefined
+    return isLocal()
+      ? 'fakeAccountRev'
       : JSON.parse(process.env.COZY_FIELDS).account_rev
   } catch (err) {
-    throw new Error(`You must provide 'account' in COZY_FIELDS: ${err.message}`)
+    const errorMessage = `You must provide 'account' in COZY_FIELDS: ${err.message}`
+    Sentry.captureException(errorMessage)
+    throw new Error(errorMessage)
   }
 }
 
@@ -275903,15 +275947,20 @@ module.exports = getAccountRev
 /* 2050 */
 /***/ (function(module, exports, __webpack_require__) {
 
+const { log } = __webpack_require__(1)
+const { isLocal } = __webpack_require__(1769)
+const Sentry = __webpack_require__(1910)
+
 function getAccountSecret() {
+  log('info', `getAccountSecret`)
   try {
-    return  false
-      ? undefined
+    return isLocal()
+      ? JSON.parse(process.env.COZY_FIELDS)
       : JSON.parse(process.env.COZY_PARAMETERS).secret
   } catch (err) {
-    throw new Error(
-      `You must provide 'account-types' in COZY_PARAMETERS: ${err.message}`
-    )
+    const errorMessage = `You must provide 'account-types' in COZY_PARAMETERS: ${err.message}`
+    Sentry.captureException(errorMessage)
+    throw new Error(errorMessage)
   }
 }
 
diff --git a/package.json b/package.json
index b8483318b5ffaab5280769fded78a777a084aaeb..7d8f1d826bc16d472cbccfff6b99a24861361461 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "grdf",
-  "version": "1.2.1",
+  "version": "1.2.0",
   "description": "",
   "repository": {
     "type": "git",
@@ -33,6 +33,7 @@
     "start": "node ./src/index.js",
     "dev": "cozy-konnector-dev",
     "standalone": "cozy-konnector-standalone",
+    "onDeleteAccount:standalone": "cozy-konnector-standalone src/onDeleteAccount.js",
     "onDeleteAccount": "cozy-konnector-dev src/onDeleteAccount.js",
     "pretest": "npm run clean",
     "test:cov": "jest --coverage",
@@ -55,7 +56,6 @@
     "cozy-konnector-libs": "4.34.5",
     "husky": "4.3.0",
     "jest": "^28.1.3",
-    "jest-fetch-mock": "^3.0.3",
     "jsonwebtoken": "^8.5.1",
     "moment": "^2.29.0",
     "moment-timezone": "^0.5.31"