diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cd06272d937f09989f48cacde2eb67761be9c214..5c21bd91918846ee3c7fbeb8ef6b112aad29d324 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,20 +16,9 @@ workflow:
 # Pipeline start
 # =============================================================================
 
-# Run the unit tests
-testing:
-  image: node:22-alpine
-  stage: validate
-  rules:
-    - changes:
-        - src/**/*
-  script:
-    - npm ci
-    - npm test
-
 # Validate the fasta files if they have changed
 validate-fasta-files:
-  image: node:22-alpine
+  image: node:22-alpine3.21
   stage: validate
   rules:
     - changes:
@@ -40,7 +29,7 @@ validate-fasta-files:
 # Build the archive of the fasta files and compute the stats.
 # Commit the files in the data folder, triggering another CI.
 build-archive-and-stats:
-  image: node:22-alpine
+  image: node:22-alpine3.21
   stage: archive
   rules:
     - if: $CI_COMMIT_BRANCH == "master"
diff --git a/Dockerfile b/Dockerfile
index 8805e9642b765f9f45cf65ef59ed735739f1d2a9..545aba352769ee4f80bb65572a7777651fa543dc 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,7 @@
 # Builder image
 # =============
 
-FROM node:22-alpine AS builder
+FROM node:22-alpine3.21 AS builder
 WORKDIR /usr/build
 
 # Copy only the relevant files to build the application
@@ -22,7 +22,7 @@ RUN npm run build
 # Production image
 # ================
 
-FROM node:22-alpine
+FROM node:22-alpine3.21
 WORKDIR /usr/src/absd
 ENV NODE_ENV="production"
 
diff --git a/LICENSE b/LICENSE
index d4dced0f4ea2b57c5f7bda16e91b34c64e1cbf41..5497ce15ea891b55846573a60842e7fe90c12d73 100644
--- a/LICENSE
+++ b/LICENSE
@@ -632,7 +632,7 @@ state the exclusion of warranty; and each file should have at least
 the "copyright" line and a pointer to where the full notice is found.
 
     ABSD
-    Copyright (C) 2023  Institut Pasteur
+    Copyright (C) 2025  Institut Pasteur
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
   If the program does terminal interaction, make it output a short
 notice like this when it starts in an interactive mode:
 
-    <program>  Copyright (C) 2023  Institut Pasteur
+    <program>  Copyright (C) 2025  Institut Pasteur
     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.
diff --git a/biome.json b/biome.json
index b724216311f220e92778bda923ac76e7ed274393..fc39e6cad10ac3ddf37e52a2f48bec917eda66f4 100644
--- a/biome.json
+++ b/biome.json
@@ -22,7 +22,8 @@
 			"recommended": true,
       "complexity": {
         "noForEach": "off",
-        "useArrowFunction": "off"
+        "useArrowFunction": "off",
+        "noStaticOnlyClass": "off"
       }
 		}
 	}
diff --git a/package-lock.json b/package-lock.json
index 7b789b2a249c7ec5d60c55fd54a3c6c43281fa32..99ee1347ec9f68f7a12da5fe7c5de160c5188afd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,21 +10,21 @@
       "license": "GPL-3.0",
       "dependencies": {
         "@fastify/mongodb": "^9.0.2",
-        "@fastify/static": "^8.1.0",
+        "@fastify/static": "^8.1.1",
         "axios": "^1.7.9",
         "env-schema": "^6.0.1",
         "fastify": "^5.2.1",
         "modern-normalize": "^3.0.1",
-        "mongodb": "^6.13.0",
+        "mongodb": "^6.13.1",
         "pinia": "^3.0.1",
-        "plotly.js-dist-min": "^3.0.0",
+        "plotly.js-dist-min": "^3.0.1",
         "qs": "^6.14.0",
         "vue": "^3.5.13",
         "vue-router": "^4.5.0"
       },
       "devDependencies": {
         "@biomejs/biome": "^1.9.4",
-        "@types/node": "^22.13.4",
+        "@types/node": "^22.13.5",
         "@types/plotly.js-dist-min": "^2.3.4",
         "@types/qs": "^6.9.18",
         "@vitejs/plugin-vue": "^5.2.1",
@@ -36,9 +36,8 @@
         "rollup-plugin-brotli": "^3.1.0",
         "rollup-plugin-gzip": "^4.0.1",
         "typescript": "^5.7.3",
-        "vite": "^6.1.0",
-        "vitest": "^3.0.5",
-        "vue-tsc": "^2.2.0"
+        "vite": "^6.2.0",
+        "vue-tsc": "^2.2.4"
       }
     },
     "node_modules/@babel/helper-string-parser": {
@@ -252,9 +251,9 @@
       }
     },
     "node_modules/@esbuild/aix-ppc64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
-      "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz",
+      "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==",
       "cpu": [
         "ppc64"
       ],
@@ -269,9 +268,9 @@
       }
     },
     "node_modules/@esbuild/android-arm": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
-      "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz",
+      "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==",
       "cpu": [
         "arm"
       ],
@@ -286,9 +285,9 @@
       }
     },
     "node_modules/@esbuild/android-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
-      "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz",
+      "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==",
       "cpu": [
         "arm64"
       ],
@@ -303,9 +302,9 @@
       }
     },
     "node_modules/@esbuild/android-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
-      "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz",
+      "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==",
       "cpu": [
         "x64"
       ],
@@ -320,9 +319,9 @@
       }
     },
     "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
-      "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz",
+      "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==",
       "cpu": [
         "arm64"
       ],
@@ -337,9 +336,9 @@
       }
     },
     "node_modules/@esbuild/darwin-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
-      "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz",
+      "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==",
       "cpu": [
         "x64"
       ],
@@ -354,9 +353,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
-      "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz",
+      "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==",
       "cpu": [
         "arm64"
       ],
@@ -371,9 +370,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
-      "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz",
+      "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==",
       "cpu": [
         "x64"
       ],
@@ -388,9 +387,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
-      "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz",
+      "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==",
       "cpu": [
         "arm"
       ],
@@ -405,9 +404,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
-      "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz",
+      "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==",
       "cpu": [
         "arm64"
       ],
@@ -422,9 +421,9 @@
       }
     },
     "node_modules/@esbuild/linux-ia32": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
-      "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz",
+      "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==",
       "cpu": [
         "ia32"
       ],
@@ -439,9 +438,9 @@
       }
     },
     "node_modules/@esbuild/linux-loong64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
-      "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz",
+      "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==",
       "cpu": [
         "loong64"
       ],
@@ -456,9 +455,9 @@
       }
     },
     "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
-      "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz",
+      "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==",
       "cpu": [
         "mips64el"
       ],
@@ -473,9 +472,9 @@
       }
     },
     "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
-      "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz",
+      "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==",
       "cpu": [
         "ppc64"
       ],
@@ -490,9 +489,9 @@
       }
     },
     "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
-      "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz",
+      "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==",
       "cpu": [
         "riscv64"
       ],
@@ -507,9 +506,9 @@
       }
     },
     "node_modules/@esbuild/linux-s390x": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
-      "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz",
+      "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==",
       "cpu": [
         "s390x"
       ],
@@ -524,9 +523,9 @@
       }
     },
     "node_modules/@esbuild/linux-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
-      "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz",
+      "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==",
       "cpu": [
         "x64"
       ],
@@ -541,9 +540,9 @@
       }
     },
     "node_modules/@esbuild/netbsd-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
-      "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz",
+      "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==",
       "cpu": [
         "arm64"
       ],
@@ -558,9 +557,9 @@
       }
     },
     "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
-      "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz",
+      "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==",
       "cpu": [
         "x64"
       ],
@@ -575,9 +574,9 @@
       }
     },
     "node_modules/@esbuild/openbsd-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
-      "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz",
+      "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==",
       "cpu": [
         "arm64"
       ],
@@ -592,9 +591,9 @@
       }
     },
     "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
-      "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz",
+      "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==",
       "cpu": [
         "x64"
       ],
@@ -609,9 +608,9 @@
       }
     },
     "node_modules/@esbuild/sunos-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
-      "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz",
+      "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==",
       "cpu": [
         "x64"
       ],
@@ -626,9 +625,9 @@
       }
     },
     "node_modules/@esbuild/win32-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
-      "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz",
+      "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==",
       "cpu": [
         "arm64"
       ],
@@ -643,9 +642,9 @@
       }
     },
     "node_modules/@esbuild/win32-ia32": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
-      "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz",
+      "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==",
       "cpu": [
         "ia32"
       ],
@@ -660,9 +659,9 @@
       }
     },
     "node_modules/@esbuild/win32-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
-      "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz",
+      "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==",
       "cpu": [
         "x64"
       ],
@@ -767,9 +766,9 @@
       }
     },
     "node_modules/@fastify/static": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/@fastify/static/-/static-8.1.0.tgz",
-      "integrity": "sha512-lPb8+1ulvbGSUSQ0/adBDyp/Ye/MX+pBwhkLAr8/GU88kNnJlSu7KXdyW6CCOROcr5BgrqJD01lEOosozFAegw==",
+      "version": "8.1.1",
+      "resolved": "https://registry.npmjs.org/@fastify/static/-/static-8.1.1.tgz",
+      "integrity": "sha512-TW9eyVHJLytZNpBlSIqd0bl1giJkEaRaPZG+5AT3L/OBKq9U8D7g/OYmc2NPQZnzPURGhMt3IAWuyVkvd2nOkQ==",
       "funding": [
         {
           "type": "github",
@@ -1193,9 +1192,9 @@
       "license": "MIT"
     },
     "node_modules/@types/node": {
-      "version": "22.13.4",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz",
-      "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==",
+      "version": "22.13.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz",
+      "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -1253,129 +1252,6 @@
         "vue": "^3.2.25"
       }
     },
-    "node_modules/@vitest/expect": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.5.tgz",
-      "integrity": "sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/spy": "3.0.5",
-        "@vitest/utils": "3.0.5",
-        "chai": "^5.1.2",
-        "tinyrainbow": "^2.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/mocker": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.5.tgz",
-      "integrity": "sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/spy": "3.0.5",
-        "estree-walker": "^3.0.3",
-        "magic-string": "^0.30.17"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      },
-      "peerDependencies": {
-        "msw": "^2.4.9",
-        "vite": "^5.0.0 || ^6.0.0"
-      },
-      "peerDependenciesMeta": {
-        "msw": {
-          "optional": true
-        },
-        "vite": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@vitest/mocker/node_modules/estree-walker": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
-      "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/estree": "^1.0.0"
-      }
-    },
-    "node_modules/@vitest/pretty-format": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.5.tgz",
-      "integrity": "sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "tinyrainbow": "^2.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/runner": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.5.tgz",
-      "integrity": "sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/utils": "3.0.5",
-        "pathe": "^2.0.2"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/snapshot": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.5.tgz",
-      "integrity": "sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/pretty-format": "3.0.5",
-        "magic-string": "^0.30.17",
-        "pathe": "^2.0.2"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/spy": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.5.tgz",
-      "integrity": "sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "tinyspy": "^3.0.2"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/utils": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.5.tgz",
-      "integrity": "sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/pretty-format": "3.0.5",
-        "loupe": "^3.1.2",
-        "tinyrainbow": "^2.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
     "node_modules/@volar/language-core": {
       "version": "2.4.11",
       "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.11.tgz",
@@ -1496,9 +1372,9 @@
       }
     },
     "node_modules/@vue/language-core": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.0.tgz",
-      "integrity": "sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.4.tgz",
+      "integrity": "sha512-eGGdw7eWUwdIn9Fy/irJ7uavCGfgemuHQABgJ/hU1UgZFnbTg9VWeXvHQdhY+2SPQZWJqWXvRWIg67t4iWEa+Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -1506,7 +1382,7 @@
         "@vue/compiler-dom": "^3.5.0",
         "@vue/compiler-vue2": "^2.7.16",
         "@vue/shared": "^3.5.0",
-        "alien-signals": "^0.4.9",
+        "alien-signals": "^1.0.3",
         "minimatch": "^9.0.3",
         "muggle-string": "^0.4.1",
         "path-browserify": "^1.0.1"
@@ -1651,9 +1527,9 @@
       }
     },
     "node_modules/alien-signals": {
-      "version": "0.4.14",
-      "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-0.4.14.tgz",
-      "integrity": "sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.4.tgz",
+      "integrity": "sha512-DJqqQD3XcsaQcQ1s+iE2jDUZmmQpXwHiR6fCAim/w87luaW+vmLY8fMlrdkmRwzaFXhkxf3rqPCR59tKVv1MDw==",
       "dev": true,
       "license": "MIT"
     },
@@ -1692,16 +1568,6 @@
         "node": ">= 8"
       }
     },
-    "node_modules/assertion-error": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
-      "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      }
-    },
     "node_modules/asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -1876,9 +1742,9 @@
       }
     },
     "node_modules/bson": {
-      "version": "6.10.1",
-      "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.1.tgz",
-      "integrity": "sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA==",
+      "version": "6.10.3",
+      "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.3.tgz",
+      "integrity": "sha512-MTxGsqgYTwfshYWTRdmZRC+M7FnG1b4y7RO7p2k3X24Wq0yv1m77Wsj0BzlPzd/IowgESfsruQCUToa7vbOpPQ==",
       "license": "Apache-2.0",
       "engines": {
         "node": ">=16.20.1"
@@ -1907,16 +1773,6 @@
         "ieee754": "^1.2.1"
       }
     },
-    "node_modules/cac": {
-      "version": "6.7.14",
-      "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
-      "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/call-bind-apply-helpers": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
@@ -1979,23 +1835,6 @@
       ],
       "license": "CC-BY-4.0"
     },
-    "node_modules/chai": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz",
-      "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "assertion-error": "^2.0.1",
-        "check-error": "^2.1.1",
-        "deep-eql": "^5.0.1",
-        "loupe": "^3.1.0",
-        "pathval": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
     "node_modules/chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -2024,16 +1863,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/check-error": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
-      "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 16"
-      }
-    },
     "node_modules/chokidar": {
       "version": "3.5.3",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -2429,16 +2258,6 @@
         }
       }
     },
-    "node_modules/deep-eql": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
-      "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/delayed-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -2620,13 +2439,6 @@
         "node": ">= 0.4"
       }
     },
-    "node_modules/es-module-lexer": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
-      "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/es-object-atoms": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
@@ -2640,9 +2452,9 @@
       }
     },
     "node_modules/esbuild": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
-      "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
+      "version": "0.25.0",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz",
+      "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==",
       "dev": true,
       "hasInstallScript": true,
       "license": "MIT",
@@ -2653,31 +2465,31 @@
         "node": ">=18"
       },
       "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.24.2",
-        "@esbuild/android-arm": "0.24.2",
-        "@esbuild/android-arm64": "0.24.2",
-        "@esbuild/android-x64": "0.24.2",
-        "@esbuild/darwin-arm64": "0.24.2",
-        "@esbuild/darwin-x64": "0.24.2",
-        "@esbuild/freebsd-arm64": "0.24.2",
-        "@esbuild/freebsd-x64": "0.24.2",
-        "@esbuild/linux-arm": "0.24.2",
-        "@esbuild/linux-arm64": "0.24.2",
-        "@esbuild/linux-ia32": "0.24.2",
-        "@esbuild/linux-loong64": "0.24.2",
-        "@esbuild/linux-mips64el": "0.24.2",
-        "@esbuild/linux-ppc64": "0.24.2",
-        "@esbuild/linux-riscv64": "0.24.2",
-        "@esbuild/linux-s390x": "0.24.2",
-        "@esbuild/linux-x64": "0.24.2",
-        "@esbuild/netbsd-arm64": "0.24.2",
-        "@esbuild/netbsd-x64": "0.24.2",
-        "@esbuild/openbsd-arm64": "0.24.2",
-        "@esbuild/openbsd-x64": "0.24.2",
-        "@esbuild/sunos-x64": "0.24.2",
-        "@esbuild/win32-arm64": "0.24.2",
-        "@esbuild/win32-ia32": "0.24.2",
-        "@esbuild/win32-x64": "0.24.2"
+        "@esbuild/aix-ppc64": "0.25.0",
+        "@esbuild/android-arm": "0.25.0",
+        "@esbuild/android-arm64": "0.25.0",
+        "@esbuild/android-x64": "0.25.0",
+        "@esbuild/darwin-arm64": "0.25.0",
+        "@esbuild/darwin-x64": "0.25.0",
+        "@esbuild/freebsd-arm64": "0.25.0",
+        "@esbuild/freebsd-x64": "0.25.0",
+        "@esbuild/linux-arm": "0.25.0",
+        "@esbuild/linux-arm64": "0.25.0",
+        "@esbuild/linux-ia32": "0.25.0",
+        "@esbuild/linux-loong64": "0.25.0",
+        "@esbuild/linux-mips64el": "0.25.0",
+        "@esbuild/linux-ppc64": "0.25.0",
+        "@esbuild/linux-riscv64": "0.25.0",
+        "@esbuild/linux-s390x": "0.25.0",
+        "@esbuild/linux-x64": "0.25.0",
+        "@esbuild/netbsd-arm64": "0.25.0",
+        "@esbuild/netbsd-x64": "0.25.0",
+        "@esbuild/openbsd-arm64": "0.25.0",
+        "@esbuild/openbsd-x64": "0.25.0",
+        "@esbuild/sunos-x64": "0.25.0",
+        "@esbuild/win32-arm64": "0.25.0",
+        "@esbuild/win32-ia32": "0.25.0",
+        "@esbuild/win32-x64": "0.25.0"
       }
     },
     "node_modules/escalade": {
@@ -2717,16 +2529,6 @@
         "node": ">=0.8.x"
       }
     },
-    "node_modules/expect-type": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz",
-      "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
     "node_modules/fast-copy": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz",
@@ -3328,13 +3130,6 @@
       "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
       "dev": true
     },
-    "node_modules/loupe": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz",
-      "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/lru-cache": {
       "version": "11.0.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz",
@@ -3453,20 +3248,20 @@
       }
     },
     "node_modules/mongodb": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.13.0.tgz",
-      "integrity": "sha512-KeESYR5TEaFxOuwRqkOm3XOsMqCSkdeDMjaW5u2nuKfX7rqaofp7JQGoi7sVqQcNJTKuveNbzZtWMstb8ABP6Q==",
+      "version": "6.13.1",
+      "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.13.1.tgz",
+      "integrity": "sha512-gdq40tX8StmhP6akMp1pPoEVv+9jTYFSrga/g23JxajPAQhH39ysZrHGzQCSd9PEOnuEQEdjIWqxO7ZSwC0w7Q==",
       "license": "Apache-2.0",
       "dependencies": {
         "@mongodb-js/saslprep": "^1.1.9",
-        "bson": "^6.10.1",
+        "bson": "^6.10.3",
         "mongodb-connection-string-url": "^3.0.0"
       },
       "engines": {
         "node": ">=16.20.1"
       },
       "peerDependencies": {
-        "@aws-sdk/credential-providers": "^3.188.0",
+        "@aws-sdk/credential-providers": "^3.632.0",
         "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
         "gcp-metadata": "^5.2.0",
         "kerberos": "^2.0.1",
@@ -3706,23 +3501,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/pathe": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
-      "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/pathval": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
-      "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 14.16"
-      }
-    },
     "node_modules/perfect-debounce": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
@@ -3853,15 +3631,15 @@
       "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ=="
     },
     "node_modules/plotly.js-dist-min": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-3.0.0.tgz",
-      "integrity": "sha512-AlU1XkNRzwUI55A+kJYj0xJETp3h7aeFe4O1cmhzOryscYdw9jOywXZo+7Zy+y2kEKq12CnTzII4jV7Vgpy4xQ==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-3.0.1.tgz",
+      "integrity": "sha512-RReOqr6TfoHaTbVAoHR1UbTCOSRDsQ7Hbthd+3XAxOwaKmxCE3oejMhLG7urQSqWC65DAcSKV23kZd8e+7mG7w==",
       "license": "MIT"
     },
     "node_modules/postcss": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
-      "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
+      "version": "8.5.3",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+      "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
       "funding": [
         {
           "type": "opencollective",
@@ -4689,13 +4467,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/siginfo": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
-      "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
-      "dev": true,
-      "license": "ISC"
-    },
     "node_modules/signal-exit": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
@@ -4763,13 +4534,6 @@
         "node": ">= 10.x"
       }
     },
-    "node_modules/stackback": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
-      "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/statuses": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -4779,13 +4543,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/std-env": {
-      "version": "3.8.0",
-      "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz",
-      "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/string_decoder": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@@ -4934,50 +4691,6 @@
         "real-require": "^0.2.0"
       }
     },
-    "node_modules/tinybench": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
-      "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/tinyexec": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
-      "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/tinypool": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz",
-      "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^18.0.0 || >=20.0.0"
-      }
-    },
-    "node_modules/tinyrainbow": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
-      "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/tinyspy": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
-      "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
     "node_modules/to-regex-range": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -5118,14 +4831,14 @@
       "dev": true
     },
     "node_modules/vite": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz",
-      "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==",
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz",
+      "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "esbuild": "^0.24.2",
-        "postcss": "^8.5.1",
+        "esbuild": "^0.25.0",
+        "postcss": "^8.5.3",
         "rollup": "^4.30.1"
       },
       "bin": {
@@ -5189,99 +4902,6 @@
         }
       }
     },
-    "node_modules/vite-node": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.5.tgz",
-      "integrity": "sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "cac": "^6.7.14",
-        "debug": "^4.4.0",
-        "es-module-lexer": "^1.6.0",
-        "pathe": "^2.0.2",
-        "vite": "^5.0.0 || ^6.0.0"
-      },
-      "bin": {
-        "vite-node": "vite-node.mjs"
-      },
-      "engines": {
-        "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/vitest": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.5.tgz",
-      "integrity": "sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/expect": "3.0.5",
-        "@vitest/mocker": "3.0.5",
-        "@vitest/pretty-format": "^3.0.5",
-        "@vitest/runner": "3.0.5",
-        "@vitest/snapshot": "3.0.5",
-        "@vitest/spy": "3.0.5",
-        "@vitest/utils": "3.0.5",
-        "chai": "^5.1.2",
-        "debug": "^4.4.0",
-        "expect-type": "^1.1.0",
-        "magic-string": "^0.30.17",
-        "pathe": "^2.0.2",
-        "std-env": "^3.8.0",
-        "tinybench": "^2.9.0",
-        "tinyexec": "^0.3.2",
-        "tinypool": "^1.0.2",
-        "tinyrainbow": "^2.0.0",
-        "vite": "^5.0.0 || ^6.0.0",
-        "vite-node": "3.0.5",
-        "why-is-node-running": "^2.3.0"
-      },
-      "bin": {
-        "vitest": "vitest.mjs"
-      },
-      "engines": {
-        "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      },
-      "peerDependencies": {
-        "@edge-runtime/vm": "*",
-        "@types/debug": "^4.1.12",
-        "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
-        "@vitest/browser": "3.0.5",
-        "@vitest/ui": "3.0.5",
-        "happy-dom": "*",
-        "jsdom": "*"
-      },
-      "peerDependenciesMeta": {
-        "@edge-runtime/vm": {
-          "optional": true
-        },
-        "@types/debug": {
-          "optional": true
-        },
-        "@types/node": {
-          "optional": true
-        },
-        "@vitest/browser": {
-          "optional": true
-        },
-        "@vitest/ui": {
-          "optional": true
-        },
-        "happy-dom": {
-          "optional": true
-        },
-        "jsdom": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/vscode-uri": {
       "version": "3.0.8",
       "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
@@ -5326,14 +4946,14 @@
       }
     },
     "node_modules/vue-tsc": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.0.tgz",
-      "integrity": "sha512-gtmM1sUuJ8aSb0KoAFmK9yMxb8TxjewmxqTJ1aKphD5Cbu0rULFY6+UQT51zW7SpUcenfPUuflKyVwyx9Qdnxg==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.4.tgz",
+      "integrity": "sha512-3EVHlxtpMXcb5bCaK7QDFTbEkMusDfVk0HVRrkv5hEb+Clpu9a96lKUXJAeD/akRlkoA4H8MCHgBDN19S6FnzA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@volar/typescript": "~2.4.11",
-        "@vue/language-core": "2.2.0"
+        "@vue/language-core": "2.2.4"
       },
       "bin": {
         "vue-tsc": "bin/vue-tsc.js"
@@ -5376,23 +4996,6 @@
         "node": ">= 8"
       }
     },
-    "node_modules/why-is-node-running": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
-      "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "siginfo": "^2.0.0",
-        "stackback": "0.0.2"
-      },
-      "bin": {
-        "why-is-node-running": "cli.js"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/wrap-ansi": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
diff --git a/package.json b/package.json
index d2046610b82c220d69bdcdffdea1db0c4eb12498..90e611ead3818a659465ca521b4448ef6cb0e3a9 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,6 @@
     "dev": "concurrently -n Client,Server -c '#325D79,#45ADA8' 'npm:dev:client' 'npm:dev:server'",
     "dev:client": "vite",
     "dev:server": "nodemon --use-strict src/server/app.js | pino-pretty -t 'yyyy-mm-dd HH:MM:ss'",
-    "test": "NODE_ENV='production' vitest",
     "build": "vue-tsc && vite build",
     "build:db": "node src/scripts/buildDatabase.js",
     "stats": "node src/scripts/displayStatistics",
@@ -30,21 +29,21 @@
   "license": "GPL-3.0",
   "dependencies": {
     "@fastify/mongodb": "^9.0.2",
-    "@fastify/static": "^8.1.0",
+    "@fastify/static": "^8.1.1",
     "axios": "^1.7.9",
     "env-schema": "^6.0.1",
     "fastify": "^5.2.1",
     "modern-normalize": "^3.0.1",
-    "mongodb": "^6.13.0",
+    "mongodb": "^6.13.1",
     "pinia": "^3.0.1",
-    "plotly.js-dist-min": "^3.0.0",
+    "plotly.js-dist-min": "^3.0.1",
     "qs": "^6.14.0",
     "vue": "^3.5.13",
     "vue-router": "^4.5.0"
   },
   "devDependencies": {
     "@biomejs/biome": "^1.9.4",
-    "@types/node": "^22.13.4",
+    "@types/node": "^22.13.5",
     "@types/plotly.js-dist-min": "^2.3.4",
     "@types/qs": "^6.9.18",
     "@vitejs/plugin-vue": "^5.2.1",
@@ -56,8 +55,7 @@
     "rollup-plugin-brotli": "^3.1.0",
     "rollup-plugin-gzip": "^4.0.1",
     "typescript": "^5.7.3",
-    "vite": "^6.1.0",
-    "vitest": "^3.0.5",
-    "vue-tsc": "^2.2.0"
+    "vite": "^6.2.0",
+    "vue-tsc": "^2.2.4"
   }
 }
diff --git a/src/client/api.ts b/src/client/api.ts
index ca2db43e8496af498b7901b333ec183c2f757987..666d89893cf47ac7060361c0a8ee1c7e355297c3 100644
--- a/src/client/api.ts
+++ b/src/client/api.ts
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import axios, { type AxiosResponse } from 'axios'
 import qs from 'qs'
 import type {
diff --git a/src/client/components/AntibodiesTable.vue b/src/client/components/AntibodiesTable.vue
index 2d02d4fcf853cc952f4220c79486699365b22231..7b0ebfaac6453b83da0366796786947e3e68e5e9 100644
--- a/src/client/components/AntibodiesTable.vue
+++ b/src/client/components/AntibodiesTable.vue
@@ -1,5 +1,5 @@
 <template>
-  <section class="data-table">
+  <section class="data-table" :aria-busy="isFetchingAntibodies">
     <div class="table-header">
       <AntibodiesTableTotal />
       <AntibodiesTableDownload />
@@ -79,7 +79,7 @@
             data-label="ID"
             class="link-cell"
           >
-            <span class="loader" v-if="isFetchingAntibodies"></span>
+            <span class="loader" v-if="isFetchingAntibodies" role="progressbar"></span>
             <RouterLink v-else :to="{ name: 'AntibodyPage', params: { hashId: antibody.hashId } }">
               {{ antibody.id }}
             </RouterLink>
@@ -88,28 +88,28 @@
             headers="antibodies-species"
             data-label="SPECIES"
           >
-            <span class="loader" v-if="isFetchingAntibodies"></span>
+            <span class="loader" v-if="isFetchingAntibodies" role="progressbar"></span>
             <i v-else>{{ antibody.species }}</i>
           </td>
           <td
             headers="antibodies-heavy-chain"
             data-label="HEAVY CHAIN"
           >
-            <span class="loader" v-if="isFetchingAntibodies"></span>
+            <span class="loader" v-if="isFetchingAntibodies" role="progressbar"></span>
             <span v-else>{{ antibody.heavyChain.sequence.substring(0, 15) }}...</span>
           </td>
           <td
             headers="antibodies-light-chain"
             data-label="LIGHT CHAIN"
           >
-            <span class="loader" v-if="isFetchingAntibodies"></span>
+            <span class="loader" v-if="isFetchingAntibodies" role="progressbar"></span>
             <span v-else>{{ antibody.lightChain.sequence.substring(0, 15) }}...</span>
           </td>
           <td
             headers="antibodies-sources"
             data-label="SOURCES"
           >
-            <span class="loader" v-if="isFetchingAntibodies"></span>
+            <span class="loader" v-if="isFetchingAntibodies" role="progressbar"></span>
             <span v-else>{{ listSources(antibody).join(', ') }}</span>
           </td>
         </tr>
@@ -207,6 +207,10 @@ function listSources(antibody: Antibody): string[] {
   white-space: nowrap;
 }
 
+span[role=progressbar] {
+  vertical-align: middle;
+}
+
 @media screen and (width < 700px) {
   .table-header {
     justify-content: center;
diff --git a/src/client/components/AppDialog.vue b/src/client/components/AppDialog.vue
index 86f9fb1850c47c4dfa5fda3883e81bcc4a50f2a7..df57505b16e236b88af81ee852d69b6c529349c5 100644
--- a/src/client/components/AppDialog.vue
+++ b/src/client/components/AppDialog.vue
@@ -12,7 +12,10 @@
     >
       <i class="icon-close"></i>
     </button>
-    <slot />
+
+    <section v-if="isVisible()">
+      <slot />
+    </section>
   </dialog>
 </template>
 
diff --git a/src/client/components/TheDownloadPage.vue b/src/client/components/TheDownloadPage.vue
index 8467f5b18f93a164a589f49fd7aab8916a727c2d..5e246495c357c80c2f1b0f05c6dfcc27adbb43e1 100644
--- a/src/client/components/TheDownloadPage.vue
+++ b/src/client/components/TheDownloadPage.vue
@@ -19,7 +19,8 @@
     <div
       v-else
       class="spinner"
-    ></div>
+      role="progressbar">
+    </div>
   </div>
 </template>
 
diff --git a/src/client/components/TheHomePage.vue b/src/client/components/TheHomePage.vue
index e575d38c33580549caaffa245e49d65dd46208df..d81ccf518dc22630ddbb8faae7d0443b4e35e3a0 100644
--- a/src/client/components/TheHomePage.vue
+++ b/src/client/components/TheHomePage.vue
@@ -124,6 +124,13 @@
     </p>
   </section>
 
+  <div class="version-date">
+    Last update:
+    <time :datetime="versionDate">
+      {{ versionDate }}
+    </time>
+  </div>
+
   <SearchBar />
 
   <AntibodiesTable v-if="!noResults" />
@@ -140,6 +147,7 @@ import SearchBar from './SearchBar.vue'
 
 const store = useStore()
 const noResults = computed(() => { return store.noResults })
+const versionDate = computed(() => { return store.antibodiesVersionDate })
 
 /**
  * Fetch the first antibodies on page load in order to
@@ -166,4 +174,12 @@ p {
   max-width: 900px;
   text-align: justify;
 }
+
+.version-date {
+  margin: auto;
+}
+
+.version-date time {
+  font-weight: bold;
+}
 </style>
diff --git a/src/client/main.ts b/src/client/main.ts
index a9c4948a07aab662fe74d7240d5055b3a8fb074a..9a2ceab432b938c487e3d09c7b2e135a0a8c019c 100644
--- a/src/client/main.ts
+++ b/src/client/main.ts
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/client/models/APIRequest.ts b/src/client/models/APIRequest.ts
index ba597dc83eda6ae3aa79b418dff188c25d42d0dd..c3197ad4c14579905dc4b21377b618d4a422e086 100644
--- a/src/client/models/APIRequest.ts
+++ b/src/client/models/APIRequest.ts
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import type {
   APIFetchParams,
   APIFilters,
diff --git a/src/client/router.ts b/src/client/router.ts
index f1c46372de7de2cdf002aca8c986ae14800d2f7f..6636662a552b9e6bd0fbe93da0feded1a5181d01 100644
--- a/src/client/router.ts
+++ b/src/client/router.ts
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/client/store.ts b/src/client/store.ts
index 5d6111d9be0e625db8c7470906e790f82ddeeff4..402666a3012f542cfcdcb98cb0fda0976716f83e 100644
--- a/src/client/store.ts
+++ b/src/client/store.ts
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import type { AxiosError } from 'axios'
 import { defineStore } from 'pinia'
 import sourceMeta from '../../data/sources.json'
@@ -69,6 +85,15 @@ export const useStore = defineStore('store', {
       return Object
         .keys(state.statistics?.antibodiesPerLightSegment || {})
         .sort(alphanumSort)
+    },
+
+    /**
+     * Get the current version date of the database.
+     * @param state - The state of the store
+     * @returns The version date as an ISO string
+     */
+    antibodiesVersionDate: (state): Statistics['versionDate'] => {
+      return state.statistics?.versionDate.replace(/T.*/, "") || ""
     }
   },
   actions: {
diff --git a/src/client/types.ts b/src/client/types.ts
index b04bbfd1beb492f8ef899512e66dc3e3f3f73006..578ea2206466a6b8784879efda71231e03278212 100644
--- a/src/client/types.ts
+++ b/src/client/types.ts
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import type { APIRequest } from './models/APIRequest'
 
 // Types and interfaces used through the application
@@ -62,6 +78,7 @@ export type SourceMeta = Record<FastaHeader['source'], {
  * the application.
  */
 export interface Statistics {
+  versionDate: string
   antibodies: number
   species: Array<Antibody['species']>
   sources: Array<FastaHeader['source']>
diff --git a/src/client/utils/alphanumSort.ts b/src/client/utils/alphanumSort.ts
index b03b916909e25f127a8c84f7aab234a811143885..3955a2c0eda3a38585214f0894cd8f799b951602 100644
--- a/src/client/utils/alphanumSort.ts
+++ b/src/client/utils/alphanumSort.ts
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * A custom strategy to sort the numbers inside a string numerically instead
  * of alphabatically.
diff --git a/src/scripts/buildDatabase.js b/src/scripts/buildDatabase.js
index c18da80b4e88e3dcfae7f8f163566e362ec5e3bd..d24fdc8d5eac1c0fedc4d7add88b076f283cec22 100644
--- a/src/scripts/buildDatabase.js
+++ b/src/scripts/buildDatabase.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import buildDatabase from './databaseBuilder.js'
 import config from '../server/config/env.js'
 
diff --git a/src/scripts/databaseBuilder.js b/src/scripts/databaseBuilder.js
index a13774cb5e7f1244c3dc11fb3195835d0c5ad52f..bf19ad4111fe830e899f4bee31b0214a2e20e6a2 100644
--- a/src/scripts/databaseBuilder.js
+++ b/src/scripts/databaseBuilder.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { createReadStream } from 'node:fs'
 import { readdir, readFile } from 'node:fs/promises'
 import { dirname, resolve } from 'node:path'
diff --git a/src/scripts/displayStatistics.js b/src/scripts/displayStatistics.js
index b851c867782f07d4324a7d34a247c512a428d5e4..2720c09a4dcba62b7e33870361a100425042d852 100644
--- a/src/scripts/displayStatistics.js
+++ b/src/scripts/displayStatistics.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import buildStatistics from './fastaStatsBuilder.js'
 
 /**
diff --git a/src/scripts/fastaStatsBuilder.js b/src/scripts/fastaStatsBuilder.js
index 873be1644d25bda0de326b6739488f1fc8d98a8f..cb4d76dc9fdcffea27d65bf74d718b999845fa13 100644
--- a/src/scripts/fastaStatsBuilder.js
+++ b/src/scripts/fastaStatsBuilder.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { createReadStream } from 'node:fs'
 import { readdir } from 'node:fs/promises'
 import { dirname, resolve } from 'node:path'
diff --git a/src/scripts/fastaValidator.js b/src/scripts/fastaValidator.js
index 0dbf374e836df3e9060aeb9f364eeeaf33e474b9..754927e666d6c556abbab4c6b3c4059b5f418a28 100644
--- a/src/scripts/fastaValidator.js
+++ b/src/scripts/fastaValidator.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { createReadStream } from 'node:fs'
 import { readdir } from 'node:fs/promises'
 import { dirname, resolve } from 'node:path'
diff --git a/src/scripts/streams/BuildAntibodiesStream.js b/src/scripts/streams/BuildAntibodiesStream.js
index 5461dbf9a173f83cffeca33fa36faae333d54906..d27a6723288011666aa3295327684c2c9fcf87a4 100644
--- a/src/scripts/streams/BuildAntibodiesStream.js
+++ b/src/scripts/streams/BuildAntibodiesStream.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { Transform } from "stream";
 
 /**
diff --git a/src/scripts/streams/GenerateHashIdStream.js b/src/scripts/streams/GenerateHashIdStream.js
index 2a70434f0d95a81fcd094f93811f5565524f4b51..d3600f7611464e760c933b4745ea784b846c852b 100644
--- a/src/scripts/streams/GenerateHashIdStream.js
+++ b/src/scripts/streams/GenerateHashIdStream.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { Transform } from "stream";
 import { Antibody } from "../../server/models/Antibody.js";
 
diff --git a/src/scripts/streams/GroupAntibodiesStream.js b/src/scripts/streams/GroupAntibodiesStream.js
index 7c47e16a114c8dcc0b89fad650b3b64e5507b563..7baffc874231e97df8914edc42d8fc6fcde7e98d 100644
--- a/src/scripts/streams/GroupAntibodiesStream.js
+++ b/src/scripts/streams/GroupAntibodiesStream.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { Transform } from "stream";
 
 /**
diff --git a/src/scripts/streams/InsertAntibodiesStream.js b/src/scripts/streams/InsertAntibodiesStream.js
index 9ed83b21810bc5362bcea3a6b34187d5b8136a76..1d99b07c659ebfa6d3abde3015b106f25cd422c3 100644
--- a/src/scripts/streams/InsertAntibodiesStream.js
+++ b/src/scripts/streams/InsertAntibodiesStream.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { MongoClient } from "mongodb";
 import { Writable } from "stream";
 import config from "../../server/config/env.js";
diff --git a/src/scripts/streams/ParseFastaStream.js b/src/scripts/streams/ParseFastaStream.js
index de3155a3678a04aefc00140ecdf3f93338760036..988892ac88a5f64a055b9a85d44d2e537ec819a6 100644
--- a/src/scripts/streams/ParseFastaStream.js
+++ b/src/scripts/streams/ParseFastaStream.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { Transform } from "stream"
 
 /**
diff --git a/src/scripts/streams/SanitizeFastaStream.js b/src/scripts/streams/SanitizeFastaStream.js
index c947742a874c5c77c1fb23716178208dabb23c07..ef9130e9452c098bed158ed8ccfceb2586376613 100644
--- a/src/scripts/streams/SanitizeFastaStream.js
+++ b/src/scripts/streams/SanitizeFastaStream.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { Transform } from "stream";
 
 /**
diff --git a/src/scripts/streams/SplitFastaStream.js b/src/scripts/streams/SplitFastaStream.js
index d7aaf5481a5015dfdb27fbe101290feb82fb755d..0377c5edc19a95319621dbe6d43b1984b67285b3 100644
--- a/src/scripts/streams/SplitFastaStream.js
+++ b/src/scripts/streams/SplitFastaStream.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { Transform } from "stream";
 
 /**
diff --git a/src/scripts/streams/StatisticsStream.js b/src/scripts/streams/StatisticsStream.js
index 1a68970db2470509a79d804b33f19f7d6e7dcda0..e04e6c727510b2e0bce9b4b2d30b1d4fc5c8876a 100644
--- a/src/scripts/streams/StatisticsStream.js
+++ b/src/scripts/streams/StatisticsStream.js
@@ -1,8 +1,22 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { Writable } from 'node:stream'
 import { Antibody } from '../../server/models/Antibody.js'
 
-// =========================================================================
-
 /**
  * Build the statistics by incrementing a given stats object.
  */
diff --git a/src/scripts/streams/ValidateFastaStream.js b/src/scripts/streams/ValidateFastaStream.js
index 246364da6dc5e4c1be6443ccd73e9509d48c83bb..f3129581c3f00e9944d640d15e5a2900c535cbab 100644
--- a/src/scripts/streams/ValidateFastaStream.js
+++ b/src/scripts/streams/ValidateFastaStream.js
@@ -1,3 +1,19 @@
+// ABSD
+// Copyright (C) 2025 Institut Pasteur
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
 import { createHash } from 'crypto';
 import { Writable } from 'stream';
 
diff --git a/src/server/app.js b/src/server/app.js
index 1e0c7913eda6032f357512d87d4d2d9af9f803d2..1670321313ede81f94428628f16459b9bd535325 100644
--- a/src/server/app.js
+++ b/src/server/app.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/config/env.js b/src/server/config/env.js
index df99d1f26b5523d15eebb62a5110388e3a50972e..d467396d818fc2ff58791fb0cec3239010782198 100644
--- a/src/server/config/env.js
+++ b/src/server/config/env.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/config/env.test.js b/src/server/config/env.test.js
deleted file mode 100644
index f026aa22e75fd81a8d0c3614ae0471a1e80adde3..0000000000000000000000000000000000000000
--- a/src/server/config/env.test.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// ABSD
-// Copyright (C) 2023 Institut Pasteur
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import { describe, expect, test } from 'vitest'
-import serverConfig from './env'
-
-describe('Server env config', () => {
-  test('Config should exists', () => {
-    expect(serverConfig).toBeDefined()
-  })
-
-  test('Config should have all and only the defined properties', () => {
-    const envVariables = Object.keys(serverConfig).sort()
-    expect(envVariables).toStrictEqual([
-      "ABSD_DB_HOST",
-      "ABSD_DB_NAME",
-      "ABSD_DB_PORT",
-      "ABSD_SERVER_HOST",
-      "ABSD_SERVER_PORT",
-      "ABSD_SERVER_PROXY",
-      "NODE_ENV",
-    ])
-  })
-
-  test('ABSD_DB_HOST should be a string', () => {
-    expect(serverConfig.ABSD_DB_HOST).toBeTypeOf('string')
-  })
-
-  test('ABSD_DB_NAME should be a string', () => {
-    expect(serverConfig.ABSD_DB_NAME).toBeTypeOf('string')
-  })
-
-  test('ABSD_DB_PORT should be a positive integer', () => {
-    expect(serverConfig.ABSD_DB_PORT).toBeTypeOf('number')
-    expect(serverConfig.ABSD_DB_PORT).toBeGreaterThan(0)
-    expect(serverConfig.ABSD_DB_PORT % 1).toBe(0)
-  })
-
-  test('ABSD_SERVER_HOST should be a string', () => {
-    expect(serverConfig.ABSD_SERVER_HOST).toBeTypeOf('string')
-  })
-
-  test('ABSD_SERVER_PORT should be a positive integer', () => {
-    expect(serverConfig.ABSD_SERVER_PORT).toBeTypeOf('number')
-    expect(serverConfig.ABSD_SERVER_PORT).toBeGreaterThan(0)
-    expect(serverConfig.ABSD_SERVER_PORT % 1).toBe(0)
-  })
-
-  test('ABSD_SERVER_PROXY should be a boolean', () => {
-    expect(serverConfig.ABSD_SERVER_PROXY).toBeTypeOf('boolean')
-  })
-
-  test('NODE_ENV should be either development or production', () => {
-    expect(serverConfig.NODE_ENV).toBeOneOf(['development', 'production'])
-  })
-})
diff --git a/src/server/hooks/buildDBQuery.js b/src/server/hooks/buildDBQuery.js
index 6e28c1cb5aac3e1970fdaaab0c8065ff9147efda..f63af6644fff4e80ae581fa4a451ed8542763ced 100644
--- a/src/server/hooks/buildDBQuery.js
+++ b/src/server/hooks/buildDBQuery.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/hooks/parseRequest.js b/src/server/hooks/parseRequest.js
index a63bc84233f294436d62970c1adf19a4853a9906..a5274b49d6b5336a8ce7ff0870957fce253ffac9 100644
--- a/src/server/hooks/parseRequest.js
+++ b/src/server/hooks/parseRequest.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/models/Antibody.js b/src/server/models/Antibody.js
index 8c8e67b869f63ed729d58197335f813ca7f9e581..67fddcb2b8e3cff2b86068b0526f549210c758cc 100644
--- a/src/server/models/Antibody.js
+++ b/src/server/models/Antibody.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/models/Antibody.test.js b/src/server/models/Antibody.test.js
deleted file mode 100644
index 7dd24c344dbdc7f03a9a42db11e63f6cf29c4119..0000000000000000000000000000000000000000
--- a/src/server/models/Antibody.test.js
+++ /dev/null
@@ -1,140 +0,0 @@
-// ABSD
-// Copyright (C) 2023 Institut Pasteur
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import { describe, expect, test } from "vitest"
-import { Antibody } from "./Antibody"
-
-describe('Antibody class', () => {
-  test('should be a class', () => {
-    const antibody = new Antibody()
-    expect(antibody).toBeInstanceOf(Antibody)
-  })
-
-  test('should define the static method "listSources"', () => {
-    expect(Antibody.listSources).toBeInstanceOf(Function)
-  })
-
-  test('should define the static method "listSegments"', () => {
-    expect(Antibody.listSegments).toBeInstanceOf(Function)
-  })
-
-  test('should define the static method "generateHashId"', () => {
-    expect(Antibody.generateHashId).toBeInstanceOf(Function)
-  })
-
-  test('should define the static method "toFasta"', () => {
-    expect(Antibody.toFasta).toBeInstanceOf(Function)
-  })
-
-  test('should define the static method "toString"', () => {
-    expect(Antibody.toString).toBeInstanceOf(Function)
-  })
-})
-
-describe('Antibody class methods', () => {
-  const antibody = {
-    "id": "368.22.A.0062",
-    "species": "Homo sapiens",
-    "hashId": "53775feae7c2d86939d15177e0b963e20504141de8601e28ab701f9f4fe9d3a2",
-    "lightChain": {
-      "headers": [
-        {
-          "id": "368.22.A.0062",
-          "vGeneSegment": "IGLV4",
-          "source": "CoV-AbDab",
-          "header": "368.22.A.0062_B-cells SARS-CoV2 Human Patient_human_light_"
-        },
-        {
-          "id": "SRR17729722",
-          "vGeneSegment": "IGLV4",
-          "source": "PairedNGS",
-          "header": "PRJNA777934|SRR17729722|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02,IGHG1|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_light"
-        },
-        {
-          "id": "SRR17778139",
-          "vGeneSegment": "IGLV4",
-          "source": "PairedNGS",
-          "header": "PRJNA777934|SRR17778139|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_light"
-        }
-      ],
-      "sequence": "QLVLTQSPSASASLGASVKLTCTLSSGHSSYAIAWHQQQPEKGPRYLMKLNSDGSHSEGDGIPDRFSGSSSGAERYLTISSLQSEDEADYYCQTWGTGIHVFGTGTKVTVL",
-      "rawFasta": "368.22.A.0062|||368.22.A.0062_B-cells SARS-CoV2 Human Patient_human_light_;368.22.A.0062;IGLV4;CoV-AbDab|||PRJNA777934|SRR17729722|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02,IGHG1|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_light;SRR17729722;IGLV4;PairedNGS|||PRJNA777934|SRR17778139|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_light;SRR17778139;IGLV4;PairedNGS"
-    },
-    "heavyChain": {
-      "headers": [
-        {
-          "id": "368.22.A.0062",
-          "vGeneSegment": "IGHV3",
-          "source": "CoV-AbDab",
-          "header": "368.22.A.0062_B-cells SARS-CoV2 Human Patient_human_heavy_"
-        },
-        {
-          "id": "SRR17729722",
-          "vGeneSegment": "IGHV3",
-          "source": "PairedNGS",
-          "header": "PRJNA777934|SRR17729722|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02,IGHG1|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_heavy"
-        },
-        {
-          "id": "SRR17778139",
-          "vGeneSegment": "IGHV3",
-          "source": "PairedNGS",
-          "header": "PRJNA777934|SRR17778139|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_heavy"
-        }
-      ],
-      "sequence": "QVQLVESGGGVVQPGRSLRLSCAASGFTFSGYAMHWVRQAPGKGLEWVAVISYDGSNRYYADSVKGRFSISRDNSKKTLYLQMNSLRDEDTAVYYCAKVEGGNYVGAFDVWGQGTMVTVSS",
-      "rawFasta": "368.22.A.0062|||368.22.A.0062_B-cells SARS-CoV2 Human Patient_human_heavy_;368.22.A.0062;IGHV3;CoV-AbDab|||PRJNA777934|SRR17729722|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02,IGHG1|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_heavy;SRR17729722;IGHV3;PairedNGS|||PRJNA777934|SRR17778139|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_heavy;SRR17778139;IGHV3;PairedNGS"
-    }
-  }
-
-  test('"listSources" should return the list of sources as a Set', () => {
-    const sources = Antibody.listSources(antibody)
-    const expected = new Set()
-      .add('CoV-AbDab')
-      .add('PairedNGS')
-    expect(sources).toStrictEqual(expected)
-  })
-
-  test('"listSegments" should return the list of gene segments as an object containg two Sets', () => {
-    const segments = Antibody.listSegments(antibody)
-    const expected = {
-      heavyChain: new Set().add('IGHV3'),
-      lightChain: new Set().add('IGLV4')
-    }
-    expect(segments).toStrictEqual(expected)
-  })
-
-  test('"generateHashId" should return the SHA256 of the antibody', () => {
-    const hashId = Antibody.generateHashId(antibody)
-    expect(hashId).toBe(antibody.hashId)
-  })
-
-  test('"toFasta" should return the FASTA version of the antibody', () => {
-    const fasta = Antibody.toFasta(antibody)
-    const expected = ">368.22.A.0062|||368.22.A.0062_B-cells SARS-CoV2 Human Patient_human_light_;368.22.A.0062;IGLV4;CoV-AbDab|||PRJNA777934|SRR17729722|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02,IGHG1|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_light;SRR17729722;IGLV4;PairedNGS|||PRJNA777934|SRR17778139|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_light;SRR17778139;IGLV4;PairedNGS"
-      .concat("\nQLVLTQSPSASASLGASVKLTCTLSSGHSSYAIAWHQQQPEKGPRYLMKLNSDGSHSEGDGIPDRFSGSSSGAERYLTISSLQSEDEADYYCQTWGTGIHVFGTGTKVTVL")
-      .concat("\n>368.22.A.0062|||368.22.A.0062_B-cells SARS-CoV2 Human Patient_human_heavy_;368.22.A.0062;IGHV3;CoV-AbDab|||PRJNA777934|SRR17729722|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02,IGHG1|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_heavy;SRR17729722;IGHV3;PairedNGS|||PRJNA777934|SRR17778139|human|GCTGCAGGTACCTACA|IGHV3_30*04,IGHD4_23*01,IGHJ3*02|IGLV4_69*01,IGLJ1*01,IGLC1|AKVEGGNYVGAFDV|QTWGTGIHV_heavy;SRR17778139;IGHV3;PairedNGS")
-      .concat("\nQVQLVESGGGVVQPGRSLRLSCAASGFTFSGYAMHWVRQAPGKGLEWVAVISYDGSNRYYADSVKGRFSISRDNSKKTLYLQMNSLRDEDTAVYYCAKVEGGNYVGAFDVWGQGTMVTVSS")
-
-    expect(fasta).toBe(expected)
-  })
-
-  test('"toString" should return the JSON version of the antibody', () => {
-    const json = Antibody.toString(antibody)
-    const expected = JSON.stringify(antibody)
-
-    expect(json).toBe(expected)
-  })
-})
diff --git a/src/server/models/AntibodyFastaStream.js b/src/server/models/AntibodyFastaStream.js
index 2e1f61a707868267b91df05e2f84252a6cb289b7..87bcaa56d6eaa975ca96f851c89f6b0fdd6d3af5 100644
--- a/src/server/models/AntibodyFastaStream.js
+++ b/src/server/models/AntibodyFastaStream.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/models/AntibodyJsonStream.js b/src/server/models/AntibodyJsonStream.js
index 72f55865b26dd744dc1c8e31c451c2f8df38eef7..8e7a65df4a6ca1f94338990a2941b4c78965bfaa 100644
--- a/src/server/models/AntibodyJsonStream.js
+++ b/src/server/models/AntibodyJsonStream.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/models/ArchiveBuilder.js b/src/server/models/ArchiveBuilder.js
index aa13d4035c7073dfa0845e71198e8ff50fa66d9e..bb25b8d9afc5f177e206e8d48575e54eefe7f6a4 100644
--- a/src/server/models/ArchiveBuilder.js
+++ b/src/server/models/ArchiveBuilder.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/models/ArchiveJobs.js b/src/server/models/ArchiveJobs.js
index 2b36e13263cd56981f7dcd08f7abce2acb12eb0b..e7cb91cafca471ba009067dbb159b17bd93071b7 100644
--- a/src/server/models/ArchiveJobs.js
+++ b/src/server/models/ArchiveJobs.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/models/Statistics.js b/src/server/models/Statistics.js
index d38b5122266020350fe70af4b80ce3b7699c3376..abb570e97c1b2024201cce39bf6fc306dbb2b960 100644
--- a/src/server/models/Statistics.js
+++ b/src/server/models/Statistics.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
  * Statistics about the antibodies.
  */
 export class Statistics {
+  versionDate = ""
   antibodies = 0
   species = new Set()
   sources = new Set()
diff --git a/src/server/routes/antibodiesCountRoute.js b/src/server/routes/antibodiesCountRoute.js
index 26431d1a56e77f4b96974d6e771cab8a70a24572..b16992233c60dd459e032fbeb76a65ebeb998fde 100644
--- a/src/server/routes/antibodiesCountRoute.js
+++ b/src/server/routes/antibodiesCountRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/antibodiesDownloadArchiveFileRoute.js b/src/server/routes/antibodiesDownloadArchiveFileRoute.js
index 684e23d6054ae34320c4608ac9c2d65c31fb553f..865899876a20b944b7f949cc39d2b1b56cd48ade 100644
--- a/src/server/routes/antibodiesDownloadArchiveFileRoute.js
+++ b/src/server/routes/antibodiesDownloadArchiveFileRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/antibodiesDownloadArchiveRoute.js b/src/server/routes/antibodiesDownloadArchiveRoute.js
index 25349e0d189ffdf62376b06503b99d270a050157..acc3e8b22ca45d4b51155c0a3c4f55d11cd4f974 100644
--- a/src/server/routes/antibodiesDownloadArchiveRoute.js
+++ b/src/server/routes/antibodiesDownloadArchiveRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/antibodiesDownloadRoute.js b/src/server/routes/antibodiesDownloadRoute.js
index 5b2b933695b02b4acbc0b931987faa593b2842dc..4163910822c747d9a8d0b53f36aab1f98ee09aeb 100644
--- a/src/server/routes/antibodiesDownloadRoute.js
+++ b/src/server/routes/antibodiesDownloadRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/antibodiesFindByIdRoute.js b/src/server/routes/antibodiesFindByIdRoute.js
index 975b81a785b7dff2e00349c5c45f5cab5ed3982f..63bbeead56bff56ae9c90626ee97df85c92431e0 100644
--- a/src/server/routes/antibodiesFindByIdRoute.js
+++ b/src/server/routes/antibodiesFindByIdRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/antibodiesFindRoute.js b/src/server/routes/antibodiesFindRoute.js
index d4e3b5ca7f5af99619b90893b7503b50e04b10b8..30e649181320a5e4591a79b8ad647f0edffa8226 100644
--- a/src/server/routes/antibodiesFindRoute.js
+++ b/src/server/routes/antibodiesFindRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/antibodiesSourcesRoute.js b/src/server/routes/antibodiesSourcesRoute.js
index 182ba6ac4ba412fb0470b41ce6f8360231ccf222..d55ec2e96f631e8c53e3612f360273371c651c3d 100644
--- a/src/server/routes/antibodiesSourcesRoute.js
+++ b/src/server/routes/antibodiesSourcesRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/antibodiesSpeciesRoute.js b/src/server/routes/antibodiesSpeciesRoute.js
index 91934e8fa932bf5461e24bb0ae474d2b86346485..8b5373240d33912efbb4ffe14dbbdece6341564a 100644
--- a/src/server/routes/antibodiesSpeciesRoute.js
+++ b/src/server/routes/antibodiesSpeciesRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/antibodiesVGeneSegmentsRoute.js b/src/server/routes/antibodiesVGeneSegmentsRoute.js
index 19162c4dca06de3c2d4046bd4aca19c387146f85..b6b3ae72d3f6308a5e3c04002e3036bd3fd2ac74 100644
--- a/src/server/routes/antibodiesVGeneSegmentsRoute.js
+++ b/src/server/routes/antibodiesVGeneSegmentsRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/downloadsFileRoute.js b/src/server/routes/downloadsFileRoute.js
index 93e5c6af602a03a3e6d9054ab63951774131aef6..aa5479894ca317d179c9657ebad741aa6dbf0282 100644
--- a/src/server/routes/downloadsFileRoute.js
+++ b/src/server/routes/downloadsFileRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/downloadsRoute.js b/src/server/routes/downloadsRoute.js
index 39c4bb2389c26ac13f43e4dec2a0f67c5edf1f9a..a9af8157ac8152e387fa6d30a555d4acf8193aac 100644
--- a/src/server/routes/downloadsRoute.js
+++ b/src/server/routes/downloadsRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/healthCheckRoute.js b/src/server/routes/healthCheckRoute.js
index 02a546a8824f8010a67bcbcdde56e68fb031da33..cb7404da3b0c5c1eefe13ad4e03e248277636828 100644
--- a/src/server/routes/healthCheckRoute.js
+++ b/src/server/routes/healthCheckRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/readyCheckRoute.js b/src/server/routes/readyCheckRoute.js
index 2ec8df6c46b393ef58917fe78b819191a7955d28..2b59e122d15bc4dbed277a84d9f46cde57b6da7d 100644
--- a/src/server/routes/readyCheckRoute.js
+++ b/src/server/routes/readyCheckRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/routes/statisticsRoute.js b/src/server/routes/statisticsRoute.js
index ebf884c74f9c29cb27881abe92350474b87d5873..7edee683adaab1b10afe66fb602a094774dce697 100644
--- a/src/server/routes/statisticsRoute.js
+++ b/src/server/routes/statisticsRoute.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/utils/archiveBuilderWorker.js b/src/server/utils/archiveBuilderWorker.js
index a13de23a6abbe5868686b45c24d69ce2a5994931..2b59c38934344b6a895b33fe5673b655d27a2c05 100644
--- a/src/server/utils/archiveBuilderWorker.js
+++ b/src/server/utils/archiveBuilderWorker.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/utils/databaseIsSync.js b/src/server/utils/databaseIsSync.js
index fbeaacf1f0ea23d2ea6f18ca859642ec989ae9ff..a35cc44440b6d50a1d96d2e2a5f85600a0a18380 100644
--- a/src/server/utils/databaseIsSync.js
+++ b/src/server/utils/databaseIsSync.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/utils/escapeString.js b/src/server/utils/escapeString.js
index 2d06104b1da8fbdfed68b48c3927849737ada7dc..c64b7f6460e759a47d9215e22b76295b7780285b 100644
--- a/src/server/utils/escapeString.js
+++ b/src/server/utils/escapeString.js
@@ -1,5 +1,5 @@
 // ABSD
-// Copyright (C) 2023 Institut Pasteur
+// Copyright (C) 2025 Institut Pasteur
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
diff --git a/src/server/utils/escapeString.test.js b/src/server/utils/escapeString.test.js
deleted file mode 100644
index f9eb19af3e025dbc6ea198d3ac5f5b893fef6aa0..0000000000000000000000000000000000000000
--- a/src/server/utils/escapeString.test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// ABSD
-// Copyright (C) 2023 Institut Pasteur
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import { expect, test } from "vitest"
-import escapeString from "./escapeString"
-
-test('Should escape all dangerous characters in a regex', () => {
-  const dangerousString = "abc.de*fgh+ijk?lmn^op$qr{st}u(vw)xyzABCDE|FG\HIJK[LM]NOPQRSTUVWXYZ123456789-_%&#@"
-  const safeString = "abc\\.de\\*fgh\\+ijk\\?lmn\\^op\\$qr\\{st\\}u\\(vw\\)xyzABCDE\\|FGHIJK\\[LM\\]NOPQRSTUVWXYZ123456789-_%&#@"
-
-  expect(escapeString(dangerousString)).toBe(safeString)
-})
diff --git a/vite.config.ts b/vite.config.ts
index f0a8bc86dfa55eeded30af4d2845122fe633e4b2..3bdd5fe50f1706e4186a71709382434ba240f19c 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,4 +1,3 @@
-/// <reference types='vitest' />
 import { defineConfig } from 'vite'
 import vue from '@vitejs/plugin-vue'
 import brotliPlugin from 'rollup-plugin-brotli'
@@ -30,11 +29,5 @@ export default defineConfig({
     __VUE_OPTIONS_API__: false,
     __VUE_PROD_DEVTOOLS__: false,
     __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false
-  },
-  test: {
-    // https://vitest.dev/config/
-    name: 'Server tests',
-    root: 'src/server',
-    include: ['**/*.test.js']
   }
 })