diff --git a/package-lock.json b/package-lock.json
index 3d33297..b059721 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,7 +26,6 @@
         "morgan": "^1.10.0",
         "ms": "^2.1.3",
         "multer": "^1.4.5-lts.2",
-        "mysql": "^2.18.1",
         "node-schedule": "^2.1.1",
         "nodemailer": "^7.0.2",
         "pdf-lib": "^1.17.1",
@@ -39,7 +38,6 @@
         "sharp-ico": "^0.1.5",
         "socket.io": "^4.8.1",
         "speakeasy": "^2.0.0",
-        "sqlite3": "^5.1.7",
         "typeorm": "^0.3.22",
         "uuid": "^11.1.0",
         "validator": "^13.15.0"
@@ -54,7 +52,6 @@
         "@types/morgan": "^1.9.9",
         "@types/ms": "^2.1.0",
         "@types/multer": "^1.4.12",
-        "@types/mysql": "^2.15.27",
         "@types/node": "^22.15.12",
         "@types/node-schedule": "^2.1.7",
         "@types/nodemailer": "^6.4.17",
@@ -131,7 +128,8 @@
       "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
       "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
       "license": "MIT",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/@img/sharp-darwin-arm64": {
       "version": "0.34.1",
@@ -640,6 +638,7 @@
       "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "@gar/promisify": "^1.0.1",
         "semver": "^7.3.5"
@@ -652,6 +651,7 @@
       "deprecated": "This functionality has been moved to @npmcli/fs",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "mkdirp": "^1.0.4",
         "rimraf": "^3.0.2"
@@ -666,6 +666,7 @@
       "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "bin": {
         "mkdirp": "bin/cmd.js"
       },
@@ -740,6 +741,7 @@
       "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "engines": {
         "node": ">= 6"
       }
@@ -922,16 +924,6 @@
         "@types/express": "*"
       }
     },
-    "node_modules/@types/mysql": {
-      "version": "2.15.27",
-      "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz",
-      "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
     "node_modules/@types/node": {
       "version": "22.15.12",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.12.tgz",
@@ -1059,7 +1051,8 @@
       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
       "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
       "license": "ISC",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/accepts": {
       "version": "2.0.0",
@@ -1115,6 +1108,7 @@
       "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "humanize-ms": "^1.2.1"
       },
@@ -1128,6 +1122,7 @@
       "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "clean-stack": "^2.0.0",
         "indent-string": "^4.0.0"
@@ -1189,7 +1184,8 @@
       "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
       "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
       "license": "ISC",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/are-we-there-yet": {
       "version": "3.0.1",
@@ -1198,6 +1194,7 @@
       "deprecated": "This package is no longer supported.",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "delegates": "^1.0.0",
         "readable-stream": "^3.6.0"
@@ -1212,6 +1209,7 @@
       "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "inherits": "^2.0.3",
         "string_decoder": "^1.1.1",
@@ -1398,20 +1396,13 @@
         "node": ">=10.0.0"
       }
     },
-    "node_modules/bignumber.js": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
-      "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
-      "license": "MIT",
-      "engines": {
-        "node": "*"
-      }
-    },
     "node_modules/bindings": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
       "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "file-uri-to-path": "1.0.0"
       }
@@ -1421,6 +1412,8 @@
       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
       "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "buffer": "^5.5.0",
         "inherits": "^2.0.4",
@@ -1446,6 +1439,8 @@
         }
       ],
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "base64-js": "^1.3.1",
         "ieee754": "^1.1.13"
@@ -1456,6 +1451,8 @@
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
       "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "inherits": "^2.0.3",
         "string_decoder": "^1.1.1",
@@ -1491,6 +1488,7 @@
       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "balanced-match": "^1.0.0",
         "concat-map": "0.0.1"
@@ -1567,6 +1565,7 @@
       "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "@npmcli/fs": "^1.0.0",
         "@npmcli/move-file": "^1.0.1",
@@ -1597,6 +1596,7 @@
       "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "yallist": "^4.0.0"
       },
@@ -1610,6 +1610,7 @@
       "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "bin": {
         "mkdirp": "bin/cmd.js"
       },
@@ -1669,6 +1670,8 @@
       "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
       "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
       "license": "ISC",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=10"
       }
@@ -1692,6 +1695,7 @@
       "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=6"
       }
@@ -1757,6 +1761,7 @@
       "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "bin": {
         "color-support": "bin.js"
       }
@@ -1766,7 +1771,8 @@
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
       "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
       "license": "MIT",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/concat-stream": {
       "version": "1.6.2",
@@ -1788,7 +1794,8 @@
       "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
       "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
       "license": "ISC",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/content-disposition": {
       "version": "1.0.0",
@@ -1987,6 +1994,8 @@
       "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
       "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "mimic-response": "^3.1.0"
       },
@@ -2002,6 +2011,8 @@
       "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
       "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4.0.0"
       }
@@ -2025,7 +2036,8 @@
       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
       "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
       "license": "MIT",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/depd": {
       "version": "2.0.0",
@@ -2135,6 +2147,7 @@
       "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "iconv-lite": "^0.6.2"
       }
@@ -2281,7 +2294,8 @@
       "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
       "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
       "license": "MIT",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/error-ex": {
       "version": "1.3.2",
@@ -2403,6 +2417,8 @@
       "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
       "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
       "license": "(MIT OR WTFPL)",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=6"
       }
@@ -2525,7 +2541,9 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
       "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
-      "license": "MIT"
+      "license": "MIT",
+      "optional": true,
+      "peer": true
     },
     "node_modules/finalhandler": {
       "version": "2.1.0",
@@ -2607,13 +2625,17 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
       "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
-      "license": "MIT"
+      "license": "MIT",
+      "optional": true,
+      "peer": true
     },
     "node_modules/fs-minipass": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
       "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
       "license": "ISC",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "minipass": "^3.0.0"
       },
@@ -2626,7 +2648,8 @@
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
       "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
       "license": "ISC",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/function-bind": {
       "version": "1.1.2",
@@ -2644,6 +2667,7 @@
       "deprecated": "This package is no longer supported.",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "aproba": "^1.0.3 || ^2.0.0",
         "color-support": "^1.1.3",
@@ -2737,7 +2761,9 @@
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
       "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
-      "license": "MIT"
+      "license": "MIT",
+      "optional": true,
+      "peer": true
     },
     "node_modules/glob": {
       "version": "7.2.3",
@@ -2746,6 +2772,7 @@
       "deprecated": "Glob versions prior to v9 are no longer supported",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
@@ -2778,7 +2805,8 @@
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
       "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
       "license": "ISC",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/handlebars": {
       "version": "4.7.8",
@@ -2818,7 +2846,8 @@
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
       "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
       "license": "ISC",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/hasown": {
       "version": "2.0.2",
@@ -2846,7 +2875,8 @@
       "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
       "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
       "license": "BSD-2-Clause",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/http-errors": {
       "version": "2.0.0",
@@ -2896,6 +2926,7 @@
       "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "ms": "^2.0.0"
       }
@@ -2971,6 +3002,7 @@
       "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=0.8.19"
       }
@@ -2981,6 +3013,7 @@
       "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=8"
       }
@@ -2990,7 +3023,8 @@
       "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
       "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
       "license": "ISC",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/inflight": {
       "version": "1.0.6",
@@ -2999,6 +3033,7 @@
       "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "once": "^1.3.0",
         "wrappy": "1"
@@ -3014,7 +3049,9 @@
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
       "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
-      "license": "ISC"
+      "license": "ISC",
+      "optional": true,
+      "peer": true
     },
     "node_modules/ip": {
       "version": "2.0.1",
@@ -3064,7 +3101,8 @@
       "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
       "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
       "license": "MIT",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/is-promise": {
       "version": "4.0.0",
@@ -3287,6 +3325,7 @@
       "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "agentkeepalive": "^4.1.3",
         "cacache": "^15.2.0",
@@ -3315,6 +3354,7 @@
       "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "debug": "4"
       },
@@ -3328,6 +3368,7 @@
       "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "@tootallnate/once": "1",
         "agent-base": "6",
@@ -3343,6 +3384,7 @@
       "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "agent-base": "6",
         "debug": "4"
@@ -3357,6 +3399,7 @@
       "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "yallist": "^4.0.0"
       },
@@ -3370,6 +3413,7 @@
       "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -3380,6 +3424,7 @@
       "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "agent-base": "^6.0.2",
         "debug": "^4.3.3",
@@ -3445,6 +3490,8 @@
       "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
       "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=10"
       },
@@ -3458,6 +3505,7 @@
       "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "brace-expansion": "^1.1.7"
       },
@@ -3479,6 +3527,8 @@
       "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
       "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
       "license": "ISC",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "yallist": "^4.0.0"
       },
@@ -3492,6 +3542,7 @@
       "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "minipass": "^3.0.0"
       },
@@ -3505,6 +3556,7 @@
       "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "minipass": "^3.1.0",
         "minipass-sized": "^1.0.3",
@@ -3523,6 +3575,7 @@
       "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "minipass": "^3.0.0"
       },
@@ -3536,6 +3589,7 @@
       "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "minipass": "^3.0.0"
       },
@@ -3549,6 +3603,7 @@
       "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "minipass": "^3.0.0"
       },
@@ -3561,6 +3616,8 @@
       "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
       "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "minipass": "^3.0.0",
         "yallist": "^4.0.0"
@@ -3591,7 +3648,9 @@
       "version": "0.5.3",
       "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
       "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
-      "license": "MIT"
+      "license": "MIT",
+      "optional": true,
+      "peer": true
     },
     "node_modules/moment": {
       "version": "2.30.1",
@@ -3712,42 +3771,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/mysql": {
-      "version": "2.18.1",
-      "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
-      "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
-      "license": "MIT",
-      "dependencies": {
-        "bignumber.js": "9.0.0",
-        "readable-stream": "2.3.7",
-        "safe-buffer": "5.1.2",
-        "sqlstring": "2.3.1"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mysql/node_modules/readable-stream": {
-      "version": "2.3.7",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
-      "license": "MIT",
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
-      }
-    },
-    "node_modules/mysql/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "license": "MIT"
-    },
     "node_modules/nanoid": {
       "version": "3.3.11",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
@@ -3770,7 +3793,9 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
       "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
-      "license": "MIT"
+      "license": "MIT",
+      "optional": true,
+      "peer": true
     },
     "node_modules/negotiator": {
       "version": "1.0.0",
@@ -3801,6 +3826,8 @@
       "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz",
       "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "semver": "^7.3.5"
       },
@@ -3812,7 +3839,9 @@
       "version": "7.1.1",
       "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
       "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
-      "license": "MIT"
+      "license": "MIT",
+      "optional": true,
+      "peer": true
     },
     "node_modules/node-gyp": {
       "version": "8.4.1",
@@ -3820,6 +3849,7 @@
       "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "env-paths": "^2.2.0",
         "glob": "^7.1.4",
@@ -3868,6 +3898,7 @@
       "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "abbrev": "1"
       },
@@ -3885,6 +3916,7 @@
       "deprecated": "This package is no longer supported.",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "are-we-there-yet": "^3.0.0",
         "console-control-strings": "^1.1.0",
@@ -3986,6 +4018,7 @@
       "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "aggregate-error": "^3.0.0"
       },
@@ -4103,6 +4136,7 @@
       "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -4401,6 +4435,8 @@
       "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
       "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "detect-libc": "^2.0.0",
         "expand-template": "^2.0.3",
@@ -4426,13 +4462,17 @@
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
       "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
-      "license": "ISC"
+      "license": "ISC",
+      "optional": true,
+      "peer": true
     },
     "node_modules/prebuild-install/node_modules/readable-stream": {
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
       "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "inherits": "^2.0.3",
         "string_decoder": "^1.1.1",
@@ -4447,6 +4487,8 @@
       "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
       "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "chownr": "^1.1.1",
         "mkdirp-classic": "^0.5.2",
@@ -4459,6 +4501,8 @@
       "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
       "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "bl": "^4.0.3",
         "end-of-stream": "^1.4.1",
@@ -4490,7 +4534,8 @@
       "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
       "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
       "license": "ISC",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/promise-retry": {
       "version": "2.0.1",
@@ -4498,6 +4543,7 @@
       "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "err-code": "^2.0.2",
         "retry": "^0.12.0"
@@ -4725,6 +4771,8 @@
       "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
       "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
       "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "deep-extend": "^0.6.0",
         "ini": "~1.3.0",
@@ -4792,6 +4840,7 @@
       "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "engines": {
         "node": ">= 4"
       }
@@ -4803,6 +4852,7 @@
       "deprecated": "Rimraf versions prior to v4 are no longer supported",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "glob": "^7.1.3"
       },
@@ -5100,7 +5150,8 @@
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
       "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "license": "ISC",
-      "optional": true
+      "optional": true,
+      "peer": true
     },
     "node_modules/simple-concat": {
       "version": "1.0.1",
@@ -5120,7 +5171,9 @@
           "url": "https://feross.org/support"
         }
       ],
-      "license": "MIT"
+      "license": "MIT",
+      "optional": true,
+      "peer": true
     },
     "node_modules/simple-get": {
       "version": "4.0.1",
@@ -5141,6 +5194,8 @@
         }
       ],
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "decompress-response": "^6.0.0",
         "once": "^1.3.1",
@@ -5420,6 +5475,8 @@
       "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==",
       "hasInstallScript": true,
       "license": "BSD-3-Clause",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "bindings": "^1.5.0",
         "node-addon-api": "^7.0.0",
@@ -5438,21 +5495,13 @@
         }
       }
     },
-    "node_modules/sqlstring": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
-      "integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
     "node_modules/ssri": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
       "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "minipass": "^3.1.1"
       },
@@ -5564,6 +5613,8 @@
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
       "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -5573,6 +5624,8 @@
       "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
       "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
       "license": "ISC",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "chownr": "^2.0.0",
         "fs-minipass": "^2.0.0",
@@ -5615,6 +5668,8 @@
       "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
       "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
       "license": "ISC",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=8"
       }
@@ -5624,6 +5679,8 @@
       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
       "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "bin": {
         "mkdirp": "bin/cmd.js"
       },
@@ -5722,6 +5779,8 @@
       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
       "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
       "license": "Apache-2.0",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "safe-buffer": "^5.0.1"
       },
@@ -5970,6 +6029,7 @@
       "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "unique-slug": "^2.0.0"
       }
@@ -5980,6 +6040,7 @@
       "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "imurmurhash": "^0.1.4"
       }
@@ -6064,6 +6125,7 @@
       "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
       "license": "ISC",
       "optional": true,
+      "peer": true,
       "dependencies": {
         "string-width": "^1.0.2 || 2 || 3 || 4"
       }
@@ -6180,7 +6242,9 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-      "license": "ISC"
+      "license": "ISC",
+      "optional": true,
+      "peer": true
     },
     "node_modules/yargs": {
       "version": "17.7.2",
diff --git a/package.json b/package.json
index faa74d8..f1c2150 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,6 @@
     "morgan": "^1.10.0",
     "ms": "^2.1.3",
     "multer": "^1.4.5-lts.2",
-    "mysql": "^2.18.1",
     "node-schedule": "^2.1.1",
     "nodemailer": "^7.0.2",
     "pdf-lib": "^1.17.1",
@@ -55,7 +54,6 @@
     "sharp-ico": "^0.1.5",
     "socket.io": "^4.8.1",
     "speakeasy": "^2.0.0",
-    "sqlite3": "^5.1.7",
     "typeorm": "^0.3.22",
     "uuid": "^11.1.0",
     "validator": "^13.15.0"
@@ -70,7 +68,6 @@
     "@types/morgan": "^1.9.9",
     "@types/ms": "^2.1.0",
     "@types/multer": "^1.4.12",
-    "@types/mysql": "^2.15.27",
     "@types/node": "^22.15.12",
     "@types/node-schedule": "^2.1.7",
     "@types/nodemailer": "^6.4.17",
diff --git a/src/data-source.ts b/src/data-source.ts
index 7f8a9e0..ed56dad 100644
--- a/src/data-source.ts
+++ b/src/data-source.ts
@@ -1,7 +1,7 @@
 import "dotenv/config";
 import "reflect-metadata";
 import { DataSource } from "typeorm";
-import { configCheck, DB_HOST, DB_NAME, DB_PASSWORD, DB_PORT, DB_TYPE, DB_USERNAME } from "./env.defaults";
+import { configCheck, DB_HOST, DB_NAME, DB_PASSWORD, DB_PORT, DB_USERNAME } from "./env.defaults";
 
 import { user } from "./entity/management/user";
 import { refresh } from "./entity/refresh";
@@ -45,27 +45,16 @@ import { webapi } from "./entity/management/webapi";
 import { webapiPermission } from "./entity/management/webapi_permission";
 import { salutation } from "./entity/configuration/salutation";
 import { setting } from "./entity/management/setting";
-
-import { BackupAndResetDatabase1738166124200 } from "./migrations/1738166124200-BackupAndResetDatabase";
-import { CreateSchema1738166167472 } from "./migrations/1738166167472-CreateSchema";
-import { TemplatesAndProtocolSort1742549956787 } from "./migrations/1742549956787-templatesAndProtocolSort";
-import { QueryToUUID1742922178643 } from "./migrations/1742922178643-queryToUUID";
-import { NewsletterColumnType1744351418751 } from "./migrations/1744351418751-newsletterColumnType";
-import { QueryUpdatedAt1744795756230 } from "./migrations/1744795756230-QueryUpdatedAt";
-import { SettingsFromEnv1745059495807 } from "./migrations/1745059495807-settingsFromEnv";
-import { MemberCreatedAt1746006549262 } from "./migrations/1746006549262-memberCreatedAt";
-import { UserLoginRoutine1746252454922 } from "./migrations/1746252454922-UserLoginRoutine";
-import { SettingsFromEnv_SET1745059495808 } from "./migrations/1745059495808-settingsFromEnv_set";
-import { AddDateToNewsletter1748509435932 } from "./migrations/1748509435932-addDateToNewsletter";
-import { AddMembershipTotalView1748607842929 } from "./migrations/1748607842929-addMembershipTotalView";
 import { education } from "./entity/configuration/education";
 import { memberEducations } from "./entity/club/member/memberEducations";
-import { MemberExtendData1748953828644 } from "./migrations/1748953828644-memberExtendData";
+
+import { BackupAndResetDatabase1749296262915 } from "./migrations/1749296262915-BackupAndResetDatabase";
+import { CreateSchema1749296280721 } from "./migrations/1749296280721-CreateSchema";
 
 configCheck();
 
 const dataSource = new DataSource({
-  type: DB_TYPE as any,
+  type: "postgres",
   host: DB_HOST,
   port: DB_PORT,
   username: DB_USERNAME,
@@ -73,7 +62,6 @@ const dataSource = new DataSource({
   database: DB_NAME,
   synchronize: false,
   logging: process.env.NODE_ENV ? true : ["schema", "error", "warn", "log", "migration"],
-  bigNumberStrings: false,
   entities: [
     user,
     refresh,
@@ -120,21 +108,7 @@ const dataSource = new DataSource({
     webapiPermission,
     setting,
   ],
-  migrations: [
-    BackupAndResetDatabase1738166124200,
-    CreateSchema1738166167472,
-    TemplatesAndProtocolSort1742549956787,
-    QueryToUUID1742922178643,
-    NewsletterColumnType1744351418751,
-    QueryUpdatedAt1744795756230,
-    SettingsFromEnv1745059495807,
-    SettingsFromEnv_SET1745059495808,
-    MemberCreatedAt1746006549262,
-    UserLoginRoutine1746252454922,
-    AddDateToNewsletter1748509435932,
-    AddMembershipTotalView1748607842929,
-    MemberExtendData1748953828644,
-  ],
+  migrations: [BackupAndResetDatabase1749296262915, CreateSchema1749296280721],
   migrationsRun: true,
   migrationsTransactionMode: "each",
   subscribers: [],
diff --git a/src/entity/club/calendar.ts b/src/entity/club/calendar.ts
index 6e64553..a647e61 100644
--- a/src/entity/club/calendar.ts
+++ b/src/entity/club/calendar.ts
@@ -45,7 +45,7 @@ export class calendar {
   @UpdateDateColumn()
   updatedAt: Date;
 
-  @Column({ type: "varchar", nullable: true, default: null, unique: true })
+  @Column({ type: "varchar", length: "255", nullable: true, default: null, unique: true })
   webpageId: string;
 
   @ManyToOne(() => calendarType, (t) => t.calendar, {
diff --git a/src/entity/club/member/member.ts b/src/entity/club/member/member.ts
index 5f349c3..0720f57 100644
--- a/src/entity/club/member/member.ts
+++ b/src/entity/club/member/member.ts
@@ -8,6 +8,7 @@ import {
   OneToMany,
   OneToOne,
   PrimaryColumn,
+  PrimaryGeneratedColumn,
 } from "typeorm";
 import { membership } from "./membership";
 import { memberAwards } from "./memberAwards";
@@ -20,7 +21,7 @@ import { memberEducations } from "./memberEducations";
 
 @Entity()
 export class member {
-  @PrimaryColumn({ generated: "uuid", type: "varchar" })
+  @PrimaryGeneratedColumn("uuid")
   id: string;
 
   @Column({ type: "varchar", length: 255 })
diff --git a/src/entity/configuration/query.ts b/src/entity/configuration/query.ts
index 68f95be..419ad43 100644
--- a/src/entity/configuration/query.ts
+++ b/src/entity/configuration/query.ts
@@ -1,8 +1,8 @@
-import { Column, Entity, PrimaryColumn, UpdateDateColumn } from "typeorm";
+import { Column, Entity, PrimaryColumn, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
 
 @Entity()
 export class query {
-  @PrimaryColumn({ generated: "uuid", type: "varchar" })
+  @PrimaryGeneratedColumn("uuid")
   id: string;
 
   @Column({ type: "varchar", length: 255, unique: true })
diff --git a/src/entity/management/user.ts b/src/entity/management/user.ts
index d659acb..27cd06a 100644
--- a/src/entity/management/user.ts
+++ b/src/entity/management/user.ts
@@ -1,4 +1,4 @@
-import { Column, Entity, JoinTable, ManyToMany, OneToMany, PrimaryColumn } from "typeorm";
+import { Column, Entity, JoinTable, ManyToMany, OneToMany, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm";
 import { role } from "./role";
 import { userPermission } from "./user_permission";
 import { LoginRoutineEnum } from "../../enums/loginRoutineEnum";
@@ -7,7 +7,7 @@ import { APPLICATION_SECRET } from "../../env.defaults";
 
 @Entity()
 export class user {
-  @PrimaryColumn({ generated: "uuid", type: "varchar" })
+  @PrimaryGeneratedColumn("uuid")
   id: string;
 
   @Column({ type: "varchar", unique: true, length: 255 })
diff --git a/src/env.defaults.ts b/src/env.defaults.ts
index c6df8ae..7a408d6 100644
--- a/src/env.defaults.ts
+++ b/src/env.defaults.ts
@@ -2,9 +2,8 @@ import "dotenv/config";
 import ms from "ms";
 import ip from "ip";
 
-export const DB_TYPE = process.env.DB_TYPE ?? "mysql";
 export const DB_HOST = process.env.DB_HOST ?? "";
-export const DB_PORT = Number(process.env.DB_PORT ?? 3306);
+export const DB_PORT = Number(process.env.DB_PORT ?? 5432);
 export const DB_NAME = process.env.DB_NAME ?? "";
 export const DB_USERNAME = process.env.DB_USERNAME ?? "";
 export const DB_PASSWORD = process.env.DB_PASSWORD ?? "";
@@ -39,7 +38,6 @@ export const TRUST_PROXY = ((): Array<string> | string | boolean | number | null
 })();
 
 export function configCheck() {
-  if (DB_TYPE != "mysql" && DB_TYPE != "postgres") throw new Error("set valid value to DB_TYPE (mysql|postgres)");
   if (DB_HOST == "" || typeof DB_HOST != "string") throw new Error("set valid value to DB_HOST");
   if (DB_NAME == "" || typeof DB_NAME != "string") throw new Error("set valid value to DB_NAME");
   if (DB_USERNAME == "" || typeof DB_USERNAME != "string") throw new Error("set valid value to DB_USERNAME");
diff --git a/src/factory/admin/club/member/dateMappingHelper.ts b/src/factory/admin/club/member/dateMappingHelper.ts
index 8fdd072..40bab62 100644
--- a/src/factory/admin/club/member/dateMappingHelper.ts
+++ b/src/factory/admin/club/member/dateMappingHelper.ts
@@ -1,14 +1,5 @@
-import { DB_TYPE } from "../../../../env.defaults";
-
 export default abstract class DateMappingHelper {
   static mapDate(entry: any) {
-    switch (DB_TYPE) {
-      case "postgres":
-        return `${entry?.years ?? 0} years ${entry?.months ?? 0} months ${entry?.days ?? 0} days`;
-      case "mysql":
-        return entry.toString();
-      case "sqlite":
-        return entry;
-    }
+    return `${entry?.years ?? 0} years ${entry?.months ?? 0} months ${entry?.days ?? 0} days`;
   }
 }
diff --git a/src/migrations/1738166167472-CreateSchema.ts b/src/migrations/1738166167472-CreateSchema.ts
deleted file mode 100644
index df9c6fd..0000000
--- a/src/migrations/1738166167472-CreateSchema.ts
+++ /dev/null
@@ -1,177 +0,0 @@
-import { MigrationInterface, QueryRunner } from "typeorm";
-import {
-  invite_table,
-  refresh_table,
-  reset_table,
-  role_permission_table,
-  role_table,
-  user_permission_table,
-  user_roles_table,
-  user_table,
-  webapi_permission_table,
-  webapi_table,
-} from "./baseSchemaTables/admin";
-import { templateUsage } from "../entity/configuration/templateUsage";
-import {
-  award_table,
-  communication_type_table,
-  executive_position_table,
-  member_awards_table,
-  member_communication_table,
-  member_executive_positions_table,
-  member_executive_positions_view_mysql,
-  member_executive_positions_view_postgres,
-  member_executive_positions_view_sqlite,
-  member_qualifications_table,
-  member_qualifications_view_mysql,
-  member_qualifications_view_postgres,
-  member_qualifications_view_sqlite,
-  member_table,
-  member_view_mysql,
-  member_view_postgres,
-  member_view_sqlite,
-  membership_status_table,
-  membership_table,
-  membership_view_mysql,
-  membership_view_postgres,
-  membership_view_sqlite,
-  qualification_table,
-  salutation_table,
-} from "./baseSchemaTables/member";
-import { query_table, template_table, template_usage_table } from "./baseSchemaTables/query_template";
-import {
-  protocol_agenda_table,
-  protocol_decision_table,
-  protocol_presence_table,
-  protocol_printout_table,
-  protocol_table,
-  protocol_voting_table,
-} from "./baseSchemaTables/protocol";
-import { calendar_table, calendar_type_table } from "./baseSchemaTables/calendar";
-import {
-  newsletter_config_table,
-  newsletter_dates_table,
-  newsletter_recipients_table,
-  newsletter_table,
-} from "./baseSchemaTables/newsletter";
-import { DB_TYPE } from "../env.defaults";
-
-export class CreateSchema1738166167472 implements MigrationInterface {
-  name = "CreateSchema1738166167472";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.createTable(reset_table, true, true, true);
-    await queryRunner.createTable(invite_table, true, true, true);
-    await queryRunner.createTable(role_table, true, true, true);
-    await queryRunner.createTable(role_permission_table, true, true, true);
-    await queryRunner.createTable(user_table, true, true, true);
-    await queryRunner.createTable(user_roles_table, true, true, true);
-    await queryRunner.createTable(user_permission_table, true, true, true);
-    await queryRunner.createTable(refresh_table, true, true, true);
-    await queryRunner.createTable(webapi_table, true, true, true);
-    await queryRunner.createTable(webapi_permission_table, true, true, true);
-
-    await queryRunner.createTable(salutation_table, true, true, true);
-    await queryRunner.createTable(award_table, true, true, true);
-    await queryRunner.createTable(communication_type_table, true, true, true);
-    await queryRunner.createTable(membership_status_table, true, true, true);
-    await queryRunner.createTable(executive_position_table, true, true, true);
-    await queryRunner.createTable(qualification_table, true, true, true);
-    await queryRunner.createTable(member_table, true, true, true);
-    await queryRunner.createTable(member_awards_table, true, true, true);
-    await queryRunner.createTable(member_communication_table, true, true, true);
-    await queryRunner.createTable(membership_table, true, true, true);
-    await queryRunner.createTable(member_executive_positions_table, true, true, true);
-    await queryRunner.createTable(member_qualifications_table, true, true, true);
-
-    if (DB_TYPE == "postgres") await queryRunner.createView(member_view_postgres, true);
-    else if (DB_TYPE == "mysql") await queryRunner.createView(member_view_mysql, true);
-    else if (DB_TYPE == "sqlite") await queryRunner.createView(member_view_sqlite, true);
-    if (DB_TYPE == "postgres") await queryRunner.createView(membership_view_postgres, true);
-    else if (DB_TYPE == "mysql") await queryRunner.createView(membership_view_mysql, true);
-    else if (DB_TYPE == "sqlite") await queryRunner.createView(membership_view_sqlite, true);
-    if (DB_TYPE == "postgres") await queryRunner.createView(member_qualifications_view_postgres, true);
-    else if (DB_TYPE == "mysql") await queryRunner.createView(member_qualifications_view_mysql, true);
-    else if (DB_TYPE == "sqlite") await queryRunner.createView(member_qualifications_view_sqlite, true);
-    if (DB_TYPE == "postgres") await queryRunner.createView(member_executive_positions_view_postgres, true);
-    else if (DB_TYPE == "mysql") await queryRunner.createView(member_executive_positions_view_mysql, true);
-    else if (DB_TYPE == "sqlite") await queryRunner.createView(member_executive_positions_view_sqlite, true);
-
-    await queryRunner.createTable(query_table, true, true, true);
-    await queryRunner.createTable(template_table, true, true, true);
-    await queryRunner.createTable(template_usage_table, true, true, true);
-
-    await queryRunner.manager
-      .createQueryBuilder()
-      .insert()
-      .into(templateUsage)
-      .values([{ scope: "newsletter" }, { scope: "protocol" }, { scope: "member.list" }])
-      .orIgnore()
-      .execute();
-
-    await queryRunner.createTable(protocol_table, true, true, true);
-    await queryRunner.createTable(protocol_agenda_table, true, true, true);
-    await queryRunner.createTable(protocol_decision_table, true, true, true);
-    await queryRunner.createTable(protocol_presence_table, true, true, true);
-    await queryRunner.createTable(protocol_voting_table, true, true, true);
-    await queryRunner.createTable(protocol_printout_table, true, true, true);
-
-    await queryRunner.createTable(calendar_type_table, true, true, true);
-    await queryRunner.createTable(calendar_table, true, true, true);
-
-    await queryRunner.createTable(newsletter_config_table, true, true, true);
-    await queryRunner.createTable(newsletter_table, true, true, true);
-    await queryRunner.createTable(newsletter_dates_table, true, true, true);
-    await queryRunner.createTable(newsletter_recipients_table, true, true, true);
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.dropTable("newsletter_dates", true, true, true);
-    await queryRunner.dropTable("newsletter_recipients", true, true, true);
-    await queryRunner.dropTable("newsletter", true, true, true);
-    await queryRunner.dropTable("newsletter_config", true, true, true);
-
-    await queryRunner.dropTable("calendar", true, true, true);
-    await queryRunner.dropTable("calendar_type", true, true, true);
-
-    await queryRunner.dropTable("protocol_agenda", true, true, true);
-    await queryRunner.dropTable("protocol_decision", true, true, true);
-    await queryRunner.dropTable("protocol_presence", true, true, true);
-    await queryRunner.dropTable("protocol_voting", true, true, true);
-    await queryRunner.dropTable("protocol_printout", true, true, true);
-    await queryRunner.dropTable("protocol", true, true, true);
-
-    await queryRunner.dropTable("template_usage", true, true, true);
-    await queryRunner.dropTable("template", true, true, true);
-    await queryRunner.dropTable("query", true, true, true);
-
-    await queryRunner.dropView("member_view");
-    await queryRunner.dropView("membership_view");
-    await queryRunner.dropView("member_qualifications_view");
-    await queryRunner.dropView("member_executive_positions_view");
-
-    await queryRunner.dropTable("member_awards", true, true, true);
-    await queryRunner.dropTable("communication", true, true, true);
-    await queryRunner.dropTable("membership", true, true, true);
-    await queryRunner.dropTable("member_executive_positions", true, true, true);
-    await queryRunner.dropTable("member_qualifications", true, true, true);
-    await queryRunner.dropTable("member", true, true, true);
-    await queryRunner.dropTable("salutation", true, true, true);
-    await queryRunner.dropTable("award", true, true, true);
-    await queryRunner.dropTable("communication_type", true, true, true);
-    await queryRunner.dropTable("membership_status", true, true, true);
-    await queryRunner.dropTable("executive_position", true, true, true);
-    await queryRunner.dropTable("qualification", true, true, true);
-
-    await queryRunner.dropTable("webapi_permission", true, true, true);
-    await queryRunner.dropTable("webapi", true, true, true);
-    await queryRunner.dropTable("refresh", true, true, true);
-    await queryRunner.dropTable("user_permission", true, true, true);
-    await queryRunner.dropTable("user_roles", true, true, true);
-    await queryRunner.dropTable("user", true, true, true);
-    await queryRunner.dropTable("role_permission", true, true, true);
-    await queryRunner.dropTable("role", true, true, true);
-    await queryRunner.dropTable("invite", true, true, true);
-    await queryRunner.dropTable("reset", true, true, true);
-  }
-}
diff --git a/src/migrations/1742549956787-templatesAndProtocolSort.ts b/src/migrations/1742549956787-templatesAndProtocolSort.ts
deleted file mode 100644
index cc86bf8..0000000
--- a/src/migrations/1742549956787-templatesAndProtocolSort.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
-import { templateUsage } from "../entity/configuration/templateUsage";
-import { getTypeByORM, getDefaultByORM } from "./ormHelper";
-
-export class TemplatesAndProtocolSort1742549956787 implements MigrationInterface {
-  name = "TemplatesAndProtocolSort1742549956787";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.manager
-      .createQueryBuilder()
-      .insert()
-      .into(templateUsage)
-      .values([{ scope: "member" }])
-      .orIgnore()
-      .execute();
-
-    await queryRunner.manager
-      .createQueryBuilder()
-      .delete()
-      .from(templateUsage)
-      .where({ scope: "member.list" })
-      .execute();
-
-    await queryRunner.addColumn(
-      "protocol_agenda",
-      new TableColumn({ name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) })
-    );
-
-    await queryRunner.addColumn(
-      "protocol_decision",
-      new TableColumn({ name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) })
-    );
-
-    await queryRunner.addColumn(
-      "protocol_voting",
-      new TableColumn({ name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) })
-    );
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.dropColumn("protocol_agenda", "sort");
-    await queryRunner.dropColumn("protocol_decision", "sort");
-    await queryRunner.dropColumn("protocol_voting", "sort");
-
-    await queryRunner.manager
-      .createQueryBuilder()
-      .insert()
-      .into(templateUsage)
-      .values([{ scope: "member.list" }])
-      .orIgnore()
-      .execute();
-
-    await queryRunner.manager.createQueryBuilder().delete().from(templateUsage).where({ scope: "member" }).execute();
-  }
-}
diff --git a/src/migrations/1742922178643-queryToUUID.ts b/src/migrations/1742922178643-queryToUUID.ts
deleted file mode 100644
index 3902fb9..0000000
--- a/src/migrations/1742922178643-queryToUUID.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { MigrationInterface, QueryRunner, TableColumn, TableForeignKey } from "typeorm";
-import { getTypeByORM, isIncrementPrimary, isUUIDPrimary } from "./ormHelper";
-import { query } from "../entity/configuration/query";
-
-export class QueryToUUID1742922178643 implements MigrationInterface {
-  name = "QueryToUUID1742922178643";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    const table = await queryRunner.getTable("newsletter");
-    const foreignKey = table.foreignKeys.find((fk) => fk.columnNames.indexOf("recipientsByQueryId") !== -1);
-    await queryRunner.dropForeignKey("newsletter", foreignKey);
-
-    // const entries = await queryRunner.manager.getRepository("query").find({ select: { title: true, query: true } });
-    // await queryRunner.clearTable("query");
-
-    await queryRunner.dropColumn("newsletter", "recipientsByQueryId");
-    await queryRunner.dropColumn("query", "id");
-
-    await queryRunner.addColumn(
-      "query",
-      new TableColumn({
-        name: "id",
-        ...getTypeByORM("uuid"),
-        ...isUUIDPrimary,
-      })
-    );
-    await queryRunner.addColumn(
-      "newsletter",
-      new TableColumn({
-        name: "recipientsByQueryId",
-        ...getTypeByORM("uuid", true),
-      })
-    );
-
-    // await queryRunner.manager.getRepository("query").save(entries);
-
-    await queryRunner.createForeignKey(
-      "newsletter",
-      new TableForeignKey({
-        columnNames: ["recipientsByQueryId"],
-        referencedColumnNames: ["id"],
-        referencedTableName: "query",
-        onDelete: "CASCADE",
-        onUpdate: "RESTRICT",
-      })
-    );
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    const table = await queryRunner.getTable("newsletter");
-    const foreignKey = table.foreignKeys.find((fk) => fk.columnNames.indexOf("recipientsByQueryId") !== -1);
-    await queryRunner.dropForeignKey("newsletter", foreignKey);
-
-    const entries = await queryRunner.manager.getRepository(query).find({ select: { title: true, query: true } });
-    await queryRunner.clearTable("query");
-
-    await queryRunner.dropColumn("newsletter", "recipientsByQueryId");
-    await queryRunner.dropColumn("query", "id");
-
-    await queryRunner.addColumn(
-      "query",
-      new TableColumn({
-        name: "id",
-        ...getTypeByORM("int"),
-        ...isIncrementPrimary,
-      })
-    );
-    await queryRunner.addColumn(
-      "newsletter",
-      new TableColumn({
-        name: "recipientsByQueryId",
-        ...getTypeByORM("int", true),
-      })
-    );
-
-    await queryRunner.manager
-      .createQueryBuilder()
-      .insert()
-      .into("query")
-      .values(entries.map((e, i) => ({ ...e, id: i + 1 })))
-      .execute();
-
-    await queryRunner.createForeignKey(
-      "newsletter",
-      new TableForeignKey({
-        columnNames: ["recipientsByQueryId"],
-        referencedColumnNames: ["id"],
-        referencedTableName: "query",
-        onDelete: "CASCADE",
-        onUpdate: "RESTRICT",
-      })
-    );
-  }
-}
diff --git a/src/migrations/1744351418751-newsletterColumnType.ts b/src/migrations/1744351418751-newsletterColumnType.ts
deleted file mode 100644
index 686869e..0000000
--- a/src/migrations/1744351418751-newsletterColumnType.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
-import { getDefaultByORM, getTypeByORM } from "./ormHelper";
-import { newsletter } from "../entity/club/newsletter/newsletter";
-
-export class NewsletterColumnType1744351418751 implements MigrationInterface {
-  name = "NewsletterColumnType1744351418751";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    let newsletters = await queryRunner.manager
-      .getRepository("newsletter")
-      .find({ select: { id: true, newsletterTitle: true, newsletterSignatur: true } });
-
-    await queryRunner.dropColumn("newsletter", "newsletterTitle");
-    await queryRunner.dropColumn("newsletter", "newsletterSignatur");
-
-    await queryRunner.addColumn(
-      "newsletter",
-      new TableColumn({ name: "newsletterTitle", ...getTypeByORM("text"), default: getDefaultByORM("string") })
-    );
-    await queryRunner.addColumn(
-      "newsletter",
-      new TableColumn({ name: "newsletterSignatur", ...getTypeByORM("text"), default: getDefaultByORM("string") })
-    );
-
-    await queryRunner.manager.getRepository("newsletter").save(newsletters);
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    let newsletters = await queryRunner.manager
-      .getRepository("newsletter")
-      .find({ select: { id: true, newsletterTitle: true, newsletterSignatur: true } });
-
-    await queryRunner.dropColumn("newsletter", "newsletterTitle");
-    await queryRunner.dropColumn("newsletter", "newsletterSignatur");
-
-    await queryRunner.addColumn(
-      "newsletter",
-      new TableColumn({ name: "newsletterTitle", ...getTypeByORM("varchar"), default: getDefaultByORM("string") })
-    );
-    await queryRunner.addColumn(
-      "newsletter",
-      new TableColumn({ name: "newsletterSignatur", ...getTypeByORM("varchar"), default: getDefaultByORM("string") })
-    );
-
-    await queryRunner.manager.getRepository("newsletter").save(newsletters);
-  }
-}
diff --git a/src/migrations/1744795756230-QueryUpdatedAt.ts b/src/migrations/1744795756230-QueryUpdatedAt.ts
deleted file mode 100644
index 428ba0c..0000000
--- a/src/migrations/1744795756230-QueryUpdatedAt.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
-import { getTypeByORM, getDefaultByORM } from "./ormHelper";
-
-export class QueryUpdatedAt1744795756230 implements MigrationInterface {
-  name = "QueryUpdatedAt1744795756230";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.addColumn(
-      "query",
-      new TableColumn({
-        name: "updatedAt",
-        ...getTypeByORM("datetime", false, 6),
-        default: getDefaultByORM("currentTimestamp", 6),
-        onUpdate: getDefaultByORM<string>("currentTimestamp", 6),
-      })
-    );
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.dropColumn("query", "updatedAt");
-  }
-}
diff --git a/src/migrations/1745059495807-settingsFromEnv.ts b/src/migrations/1745059495807-settingsFromEnv.ts
deleted file mode 100644
index 1af7e08..0000000
--- a/src/migrations/1745059495807-settingsFromEnv.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { MigrationInterface, QueryRunner } from "typeorm";
-import { setting_table } from "./baseSchemaTables/admin";
-import SettingHelper from "../helpers/settingsHelper";
-import ms from "ms";
-
-export class SettingsFromEnv1745059495807 implements MigrationInterface {
-  name = "SettingsFromEnv1745059495807";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.createTable(setting_table, true, true, true);
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.dropTable(setting_table.name, true, true, true);
-  }
-}
diff --git a/src/migrations/1745059495808-settingsFromEnv_set.ts b/src/migrations/1745059495808-settingsFromEnv_set.ts
deleted file mode 100644
index 3a5729b..0000000
--- a/src/migrations/1745059495808-settingsFromEnv_set.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { MigrationInterface, QueryRunner } from "typeorm";
-import { setting_table } from "./baseSchemaTables/admin";
-import SettingHelper from "../helpers/settingsHelper";
-import ms from "ms";
-
-export class SettingsFromEnv_SET1745059495808 implements MigrationInterface {
-  name = "SettingsFromEnv_SET1745059495808";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    // transfer settings of env to database
-    await SettingHelper.setSetting("club.name", process.env.CLUB_NAME);
-    await SettingHelper.setSetting("club.website", process.env.CLUB_WEBSITE);
-    await SettingHelper.setSetting("session.jwt_expiration", process.env.JWT_EXPIRATION as ms.StringValue);
-    await SettingHelper.setSetting("session.refresh_expiration", process.env.REFRESH_EXPIRATION as ms.StringValue);
-    await SettingHelper.setSetting(
-      "session.pwa_refresh_expiration",
-      process.env.PWA_REFRESH_EXPIRATION as ms.StringValue
-    );
-    await SettingHelper.setSetting("mail.username", process.env.MAIL_USERNAME);
-    await SettingHelper.setSetting("mail.password", process.env.MAIL_PASSWORD);
-    await SettingHelper.setSetting("mail.host", process.env.MAIL_HOST);
-    await SettingHelper.setSetting("mail.port", Number(process.env.MAIL_PORT ?? "578"));
-    await SettingHelper.setSetting("mail.secure", process.env.MAIL_SECURE == "true");
-    await SettingHelper.setSetting("backup.interval", Number(process.env.BACKUP_INTERVAL ?? "1"));
-    await SettingHelper.setSetting("backup.copies", Number(process.env.BACKUP_COPIES ?? "7"));
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {}
-}
diff --git a/src/migrations/1746006549262-memberCreatedAt.ts b/src/migrations/1746006549262-memberCreatedAt.ts
deleted file mode 100644
index 08f7669..0000000
--- a/src/migrations/1746006549262-memberCreatedAt.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
-import { getTypeByORM, getDefaultByORM } from "./ormHelper";
-
-export class MemberCreatedAt1746006549262 implements MigrationInterface {
-  name = "MemberCreatedAt1746006549262";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.addColumn(
-      "member",
-      new TableColumn({
-        name: "createdAt",
-        ...getTypeByORM("datetime", false, 6),
-        default: getDefaultByORM("currentTimestamp", 6),
-      })
-    );
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.dropColumn("member", "createdAt");
-  }
-}
diff --git a/src/migrations/1746252454922-UserLoginRoutine.ts b/src/migrations/1746252454922-UserLoginRoutine.ts
deleted file mode 100644
index b11f9b0..0000000
--- a/src/migrations/1746252454922-UserLoginRoutine.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
-import { getDefaultByORM, getTypeByORM } from "./ormHelper";
-import { LoginRoutineEnum } from "../enums/loginRoutineEnum";
-import { CodingHelper } from "../helpers/codingHelper";
-import { APPLICATION_SECRET } from "../env.defaults";
-
-export class UserLoginRoutine1746252454922 implements MigrationInterface {
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    let users = await queryRunner.manager.getRepository("user").find({ select: ["id", "secret"] });
-
-    await queryRunner.dropColumns("user", ["secret", "static"]);
-
-    await queryRunner.addColumns("user", [
-      new TableColumn({ name: "secret", ...getTypeByORM("text"), default: getDefaultByORM("string") }),
-      new TableColumn({
-        name: "routine",
-        ...getTypeByORM("varchar"),
-        default: getDefaultByORM("string", LoginRoutineEnum.totp),
-      }),
-    ]);
-
-    await queryRunner.manager.getRepository("user").save(users.map((u) => ({ id: u.id, secret: u.secret })));
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    let users = await queryRunner.manager.getRepository("user").find({ select: ["id", "secret"] });
-
-    await queryRunner.dropColumn("user", "secret");
-
-    await queryRunner.addColumns("user", [
-      new TableColumn({ name: "secret", ...getTypeByORM("varchar"), default: getDefaultByORM("string") }),
-      new TableColumn({ name: "static", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) }),
-    ]);
-
-    await queryRunner.manager.getRepository("user").save(users.map((u) => ({ id: u.id, secret: u.secret })));
-
-    await queryRunner.dropColumn("user", "routine");
-  }
-}
diff --git a/src/migrations/1748509435932-addDateToNewsletter.ts b/src/migrations/1748509435932-addDateToNewsletter.ts
deleted file mode 100644
index 5f4b8fa..0000000
--- a/src/migrations/1748509435932-addDateToNewsletter.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
-import { getTypeByORM, getDefaultByORM } from "./ormHelper";
-
-export class AddDateToNewsletter1748509435932 implements MigrationInterface {
-  name = "AddDateToNewsletter1748509435932";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.addColumn(
-      "newsletter",
-      new TableColumn({
-        name: "createdAt",
-        ...getTypeByORM("datetime", false, 6),
-        default: getDefaultByORM("currentTimestamp", 6),
-      })
-    );
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.dropColumn("newsletter", "createdAt");
-  }
-}
diff --git a/src/migrations/1748607842929-addMembershipTotalView.ts b/src/migrations/1748607842929-addMembershipTotalView.ts
deleted file mode 100644
index 97cfea0..0000000
--- a/src/migrations/1748607842929-addMembershipTotalView.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { MigrationInterface, QueryRunner } from "typeorm";
-import { DB_TYPE } from "../env.defaults";
-import {
-  membership_total_view_mysql,
-  membership_total_view_postgres,
-  membership_total_view_sqlite,
-} from "./baseSchemaTables/member";
-
-export class AddMembershipTotalView1748607842929 implements MigrationInterface {
-  name = "AddMembershipTotalView1748607842929";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    if (DB_TYPE == "postgres") await queryRunner.createView(membership_total_view_postgres, true);
-    else if (DB_TYPE == "mysql") await queryRunner.createView(membership_total_view_mysql, true);
-    else if (DB_TYPE == "sqlite") await queryRunner.createView(membership_total_view_sqlite, true);
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.dropView("membership_total_view");
-  }
-}
diff --git a/src/migrations/1748953828644-memberExtendData.ts b/src/migrations/1748953828644-memberExtendData.ts
deleted file mode 100644
index a2ccb44..0000000
--- a/src/migrations/1748953828644-memberExtendData.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
-import {
-  education_table,
-  member_educations_table,
-  member_view2_mysql,
-  member_view2_postgres,
-  member_view2_sqlite,
-} from "./baseSchemaTables/member";
-import { getDefaultByORM, getTypeByORM } from "./ormHelper";
-import { DB_TYPE } from "../env.defaults";
-
-export class MemberExtendData1748953828644 implements MigrationInterface {
-  name = "MemberExtendData1748953828644";
-
-  public async up(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.createTable(education_table, true, true, true);
-    await queryRunner.createTable(member_educations_table, true, true, true);
-    await queryRunner.addColumn(
-      "member",
-      new TableColumn({ name: "note", ...getTypeByORM("varchar", true), default: getDefaultByORM("null") })
-    );
-
-    await queryRunner.dropView("member_view");
-    if (DB_TYPE == "postgres") await queryRunner.createView(member_view2_postgres, true);
-    else if (DB_TYPE == "mysql") await queryRunner.createView(member_view2_mysql, true);
-    else if (DB_TYPE == "sqlite") await queryRunner.createView(member_view2_sqlite, true);
-  }
-
-  public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.dropTable(member_educations_table, true, true, true);
-    await queryRunner.dropTable(education_table, true, true, true);
-    await queryRunner.dropColumn("member", "note");
-  }
-}
diff --git a/src/migrations/1738166124200-BackupAndResetDatabase.ts b/src/migrations/1749296262915-BackupAndResetDatabase.ts
similarity index 76%
rename from src/migrations/1738166124200-BackupAndResetDatabase.ts
rename to src/migrations/1749296262915-BackupAndResetDatabase.ts
index f0656ba..8280d8c 100644
--- a/src/migrations/1738166124200-BackupAndResetDatabase.ts
+++ b/src/migrations/1749296262915-BackupAndResetDatabase.ts
@@ -1,21 +1,19 @@
 import { MigrationInterface, QueryRunner, Table } from "typeorm";
-import BackupHelper from "../helpers/backupHelper";
-import { getDefaultByORM, getTypeByORM, isIncrementPrimary } from "./ormHelper";
 import InternalException from "../exceptions/internalException";
-import { DB_TYPE } from "../env.defaults";
+import BackupHelper from "../helpers/backupHelper";
+import { getTypeByORM, isIncrementPrimary, getDefaultByORM } from "./ormHelper";
 
-export class BackupAndResetDatabase1738166124200 implements MigrationInterface {
-  name = "BackupAndResetDatabase1738166124200";
+export class BackupAndResetDatabase1749296262915 implements MigrationInterface {
+  name = "BackupAndResetDatabase1749296262915";
 
   public async up(queryRunner: QueryRunner): Promise<void> {
-    let query = DB_TYPE == "postgres" ? "SELECT name FROM migrations" : "SELECT `name` FROM `migrations`";
-    let migrations = await queryRunner.query(query);
+    let migrations = await queryRunner.query("SELECT name FROM migrations");
     if (
       (await queryRunner.hasTable("user")) &&
-      migrations.findIndex((m: any) => m.name == "MoveSendNewsletterFlag1737816852011") == -1
+      migrations.findIndex((m: any) => m.name == "MemberExtendData1748953828644") == -1
     ) {
       throw new InternalException(
-        "Cannot update due to skiped version. Update to v1.2.2 Version first to prevent data loss and get access to the newer Versions."
+        "Cannot update due to skiped version. Update to v1.6.0 Version first to prevent data loss and get access to the newer Versions."
       );
     }
 
diff --git a/src/migrations/1749296280721-CreateSchema.ts b/src/migrations/1749296280721-CreateSchema.ts
new file mode 100644
index 0000000..638455c
--- /dev/null
+++ b/src/migrations/1749296280721-CreateSchema.ts
@@ -0,0 +1,176 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+import {
+  reset_table,
+  invite_table,
+  role_table,
+  role_permission_table,
+  user_table,
+  user_roles_table,
+  user_permission_table,
+  refresh_table,
+  webapi_table,
+  webapi_permission_table,
+  setting_table,
+} from "./baseSchemaTables/admin";
+import { calendar_type_table, calendar_table } from "./baseSchemaTables/calendar";
+import {
+  salutation_table,
+  award_table,
+  communication_type_table,
+  membership_status_table,
+  executive_position_table,
+  qualification_table,
+  member_table,
+  member_awards_table,
+  member_communication_table,
+  membership_table,
+  member_executive_positions_table,
+  member_qualifications_table,
+  member_view,
+  membership_view,
+  member_qualifications_view,
+  member_executive_positions_view,
+  education_table,
+  member_educations_table,
+  membership_total_view,
+} from "./baseSchemaTables/member";
+import {
+  newsletter_config_table,
+  newsletter_table,
+  newsletter_dates_table,
+  newsletter_recipients_table,
+} from "./baseSchemaTables/newsletter";
+import {
+  protocol_table,
+  protocol_agenda_table,
+  protocol_decision_table,
+  protocol_presence_table,
+  protocol_voting_table,
+  protocol_printout_table,
+} from "./baseSchemaTables/protocol";
+import { query_table, template_table, template_usage_table } from "./baseSchemaTables/query_template";
+import { availableTemplates } from "../type/templateTypes";
+
+export class CreateSchema1749296280721 implements MigrationInterface {
+  name = "CreateSchema1749296280721";
+
+  public async up(queryRunner: QueryRunner): Promise<void> {
+    await queryRunner.createTable(reset_table, true, true, true);
+    await queryRunner.createTable(invite_table, true, true, true);
+    await queryRunner.createTable(role_table, true, true, true);
+    await queryRunner.createTable(role_permission_table, true, true, true);
+    await queryRunner.createTable(user_table, true, true, true);
+    await queryRunner.createTable(user_roles_table, true, true, true);
+    await queryRunner.createTable(user_permission_table, true, true, true);
+    await queryRunner.createTable(refresh_table, true, true, true);
+    await queryRunner.createTable(webapi_table, true, true, true);
+    await queryRunner.createTable(webapi_permission_table, true, true, true);
+    await queryRunner.createTable(setting_table, true, true, true);
+
+    await queryRunner.createTable(salutation_table, true, true, true);
+    await queryRunner.createTable(award_table, true, true, true);
+    await queryRunner.createTable(communication_type_table, true, true, true);
+    await queryRunner.createTable(membership_status_table, true, true, true);
+    await queryRunner.createTable(executive_position_table, true, true, true);
+    await queryRunner.createTable(qualification_table, true, true, true);
+    await queryRunner.createTable(education_table, true, true, true);
+    await queryRunner.createTable(member_table, true, true, true);
+    await queryRunner.createTable(member_awards_table, true, true, true);
+    await queryRunner.createTable(member_communication_table, true, true, true);
+    await queryRunner.createTable(membership_table, true, true, true);
+    await queryRunner.createTable(member_executive_positions_table, true, true, true);
+    await queryRunner.createTable(member_qualifications_table, true, true, true);
+    await queryRunner.createTable(member_educations_table, true, true, true);
+
+    await queryRunner.createView(member_view, true);
+    await queryRunner.createView(membership_view, true);
+    await queryRunner.createView(membership_total_view, true);
+    await queryRunner.createView(member_qualifications_view, true);
+    await queryRunner.createView(member_executive_positions_view, true);
+
+    await queryRunner.createTable(query_table, true, true, true);
+    await queryRunner.createTable(template_table, true, true, true);
+    await queryRunner.createTable(template_usage_table, true, true, true);
+
+    await queryRunner.manager
+      .createQueryBuilder()
+      .insert()
+      .into(template_usage_table.name)
+      .values(
+        availableTemplates.map((at) => ({
+          scope: at,
+        }))
+      )
+      .orIgnore()
+      .execute();
+
+    await queryRunner.createTable(protocol_table, true, true, true);
+    await queryRunner.createTable(protocol_agenda_table, true, true, true);
+    await queryRunner.createTable(protocol_decision_table, true, true, true);
+    await queryRunner.createTable(protocol_presence_table, true, true, true);
+    await queryRunner.createTable(protocol_voting_table, true, true, true);
+    await queryRunner.createTable(protocol_printout_table, true, true, true);
+
+    await queryRunner.createTable(calendar_type_table, true, true, true);
+    await queryRunner.createTable(calendar_table, true, true, true);
+
+    await queryRunner.createTable(newsletter_config_table, true, true, true);
+    await queryRunner.createTable(newsletter_table, true, true, true);
+    await queryRunner.createTable(newsletter_dates_table, true, true, true);
+    await queryRunner.createTable(newsletter_recipients_table, true, true, true);
+  }
+
+  public async down(queryRunner: QueryRunner): Promise<void> {
+    await queryRunner.dropTable(newsletter_dates_table, true, true, true);
+    await queryRunner.dropTable(newsletter_recipients_table, true, true, true);
+    await queryRunner.dropTable(newsletter_table, true, true, true);
+    await queryRunner.dropTable(newsletter_config_table, true, true, true);
+
+    await queryRunner.dropTable(calendar_table, true, true, true);
+    await queryRunner.dropTable(calendar_type_table, true, true, true);
+
+    await queryRunner.dropTable(protocol_agenda_table, true, true, true);
+    await queryRunner.dropTable(protocol_decision_table, true, true, true);
+    await queryRunner.dropTable(protocol_presence_table, true, true, true);
+    await queryRunner.dropTable(protocol_voting_table, true, true, true);
+    await queryRunner.dropTable(protocol_printout_table, true, true, true);
+    await queryRunner.dropTable(protocol_table, true, true, true);
+
+    await queryRunner.dropTable(template_usage_table, true, true, true);
+    await queryRunner.dropTable(template_table, true, true, true);
+    await queryRunner.dropTable(query_table, true, true, true);
+
+    await queryRunner.dropView(member_view);
+    await queryRunner.dropView(membership_view);
+    await queryRunner.dropView(membership_total_view);
+    await queryRunner.dropView(member_qualifications_view);
+    await queryRunner.dropView(member_executive_positions_view);
+
+    await queryRunner.dropTable(member_awards_table, true, true, true);
+    await queryRunner.dropTable(member_communication_table, true, true, true);
+    await queryRunner.dropTable(membership_table, true, true, true);
+    await queryRunner.dropTable(member_executive_positions_table, true, true, true);
+    await queryRunner.dropTable(member_qualifications_table, true, true, true);
+    await queryRunner.dropTable(member_educations_table, true, true, true);
+    await queryRunner.dropTable(member_table, true, true, true);
+    await queryRunner.dropTable(salutation_table, true, true, true);
+    await queryRunner.dropTable(award_table, true, true, true);
+    await queryRunner.dropTable(communication_type_table, true, true, true);
+    await queryRunner.dropTable(membership_status_table, true, true, true);
+    await queryRunner.dropTable(executive_position_table, true, true, true);
+    await queryRunner.dropTable(qualification_table, true, true, true);
+    await queryRunner.dropTable(education_table, true, true, true);
+
+    await queryRunner.dropTable(setting_table, true, true, true);
+    await queryRunner.dropTable(webapi_permission_table, true, true, true);
+    await queryRunner.dropTable(webapi_table, true, true, true);
+    await queryRunner.dropTable(refresh_table, true, true, true);
+    await queryRunner.dropTable(user_permission_table, true, true, true);
+    await queryRunner.dropTable(user_roles_table, true, true, true);
+    await queryRunner.dropTable(user_table, true, true, true);
+    await queryRunner.dropTable(role_permission_table, true, true, true);
+    await queryRunner.dropTable(role_table, true, true, true);
+    await queryRunner.dropTable(invite_table, true, true, true);
+    await queryRunner.dropTable(reset_table, true, true, true);
+  }
+}
diff --git a/src/migrations/baseSchemaTables/admin.ts b/src/migrations/baseSchemaTables/admin.ts
index 6ece9ad..b898aba 100644
--- a/src/migrations/baseSchemaTables/admin.ts
+++ b/src/migrations/baseSchemaTables/admin.ts
@@ -1,5 +1,6 @@
-import { Table, TableForeignKey } from "typeorm";
+import { Table, TableForeignKey, TableIndex, TableUnique } from "typeorm";
 import { getDefaultByORM, getTypeByORM, isIncrementPrimary, isUUIDPrimary } from "../ormHelper";
+import { LoginRoutineEnum } from "../../enums/loginRoutineEnum";
 
 export const invite_table = new Table({
   name: "invite",
@@ -16,7 +17,12 @@ export const role_table = new Table({
   name: "role",
   columns: [
     { name: "id", ...getTypeByORM("int"), ...isIncrementPrimary },
-    { name: "role", ...getTypeByORM("varchar"), isUnique: true },
+    { name: "role", ...getTypeByORM("varchar") },
+  ],
+  uniques: [
+    new TableUnique({
+      columnNames: ["role"],
+    }),
   ],
 });
 
@@ -45,8 +51,8 @@ export const user_table = new Table({
     { name: "username", ...getTypeByORM("varchar"), isUnique: true },
     { name: "firstname", ...getTypeByORM("varchar") },
     { name: "lastname", ...getTypeByORM("varchar") },
-    { name: "secret", ...getTypeByORM("varchar") },
-    { name: "static", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
+    { name: "secret", ...getTypeByORM("text") },
+    { name: "routine", ...getTypeByORM("varchar"), default: getDefaultByORM("string", LoginRoutineEnum.totp) },
     { name: "isOwner", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
   ],
 });
@@ -73,6 +79,14 @@ export const user_roles_table = new Table({
       onUpdate: "RESTRICT",
     }),
   ],
+  indices: [
+    new TableIndex({
+      columnNames: ["userId"],
+    }),
+    new TableIndex({
+      columnNames: ["roleId"],
+    }),
+  ],
 });
 
 export const user_permission_table = new Table({
@@ -114,11 +128,19 @@ export const webapi_table = new Table({
   name: "webapi",
   columns: [
     { name: "id", ...getTypeByORM("int"), ...isIncrementPrimary },
-    { name: "token", ...getTypeByORM("varchar"), isUnique: true },
-    { name: "title", ...getTypeByORM("varchar"), isUnique: true },
+    { name: "token", ...getTypeByORM("text") },
+    { name: "title", ...getTypeByORM("varchar") },
     { name: "createdAt", ...getTypeByORM("datetime", false, 6), default: getDefaultByORM("currentTimestamp", 6) },
-    { name: "lastUsage", ...getTypeByORM("datetime", true, 6), default: getDefaultByORM("null") },
-    { name: "expiry", ...getTypeByORM("date", true), default: getDefaultByORM("null") },
+    { name: "lastUsage", ...getTypeByORM("datetime", true, 6) },
+    { name: "expiry", ...getTypeByORM("date", true) },
+  ],
+  uniques: [
+    new TableUnique({
+      columnNames: ["token"],
+    }),
+    new TableUnique({
+      columnNames: ["title"],
+    }),
   ],
 });
 
diff --git a/src/migrations/baseSchemaTables/calendar.ts b/src/migrations/baseSchemaTables/calendar.ts
index 155dc46..8d6e758 100644
--- a/src/migrations/baseSchemaTables/calendar.ts
+++ b/src/migrations/baseSchemaTables/calendar.ts
@@ -1,4 +1,4 @@
-import { Table, TableForeignKey } from "typeorm";
+import { Table, TableForeignKey, TableUnique } from "typeorm";
 import { getDefaultByORM, getTypeByORM, isIncrementPrimary, isUUIDPrimary } from "../ormHelper";
 
 export const calendar_type_table = new Table({
@@ -32,7 +32,7 @@ export const calendar_table = new Table({
       default: getDefaultByORM("currentTimestamp", 6),
       onUpdate: getDefaultByORM<string>("currentTimestamp", 6),
     },
-    { name: "webpageId", ...getTypeByORM("varchar", true), default: getDefaultByORM("null"), isUnique: true },
+    { name: "webpageId", ...getTypeByORM("varchar", true) },
     { name: "typeId", ...getTypeByORM("int") },
   ],
   foreignKeys: [
@@ -44,4 +44,9 @@ export const calendar_table = new Table({
       onUpdate: "RESTRICT",
     }),
   ],
+  uniques: [
+    new TableUnique({
+      columnNames: ["webpageId"],
+    }),
+  ],
 });
diff --git a/src/migrations/baseSchemaTables/member.ts b/src/migrations/baseSchemaTables/member.ts
index 663da51..be77d69 100644
--- a/src/migrations/baseSchemaTables/member.ts
+++ b/src/migrations/baseSchemaTables/member.ts
@@ -1,4 +1,4 @@
-import { Table, TableForeignKey, View } from "typeorm";
+import { Table, TableForeignKey, TableUnique, View } from "typeorm";
 import { getDefaultByORM, getTypeByORM, isIncrementPrimary, isUUIDPrimary } from "../ormHelper";
 
 export const salutation_table = new Table({
@@ -66,11 +66,13 @@ export const member_table = new Table({
   columns: [
     { name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
     { name: "salutationId", ...getTypeByORM("int") },
-    { name: "internalId", ...getTypeByORM("varchar", true), default: getDefaultByORM("null"), isUnique: true },
+    { name: "internalId", ...getTypeByORM("varchar", true) },
     { name: "firstname", ...getTypeByORM("varchar") },
     { name: "lastname", ...getTypeByORM("varchar") },
     { name: "nameaffix", ...getTypeByORM("varchar") },
     { name: "birthdate", ...getTypeByORM("date") },
+    { name: "createdAt", ...getTypeByORM("datetime", false, 6), default: getDefaultByORM("currentTimestamp", 6) },
+    { name: "note", ...getTypeByORM("varchar", true) },
   ],
   foreignKeys: [
     new TableForeignKey({
@@ -81,6 +83,11 @@ export const member_table = new Table({
       onUpdate: "RESTRICT",
     }),
   ],
+  uniques: [
+    new TableUnique({
+      columnNames: ["internalId"],
+    }),
+  ],
 });
 
 export const membership_table = new Table({
@@ -172,7 +179,7 @@ export const member_awards_table = new Table({
   name: "member_awards",
   columns: [
     { name: "id", ...getTypeByORM("int"), ...isIncrementPrimary },
-    { name: "given", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
+    { name: "given", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", true) },
     { name: "note", ...getTypeByORM("varchar"), isNullable: true },
     { name: "date", ...getTypeByORM("date") },
     { name: "memberId", ...getTypeByORM("uuid") },
@@ -203,13 +210,13 @@ export const member_communication_table = new Table({
     { name: "preferred", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
     { name: "isSendNewsletter", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
     { name: "isSMSAlarming", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
-    { name: "mobile", ...getTypeByORM("varchar"), isNullable: true },
-    { name: "email", ...getTypeByORM("varchar"), isNullable: true },
-    { name: "postalCode", ...getTypeByORM("varchar"), default: getDefaultByORM("null"), isNullable: true },
-    { name: "city", ...getTypeByORM("varchar"), isNullable: true },
-    { name: "street", ...getTypeByORM("varchar"), isNullable: true },
+    { name: "mobile", ...getTypeByORM("varchar", true) },
+    { name: "email", ...getTypeByORM("varchar", true) },
+    { name: "postalCode", ...getTypeByORM("varchar", true) },
+    { name: "city", ...getTypeByORM("varchar", true) },
+    { name: "street", ...getTypeByORM("varchar", true) },
     { name: "streetNumber", ...getTypeByORM("int", true) },
-    { name: "streetNumberAddition", ...getTypeByORM("varchar"), isNullable: true },
+    { name: "streetNumberAddition", ...getTypeByORM("varchar", true) },
     { name: "memberId", ...getTypeByORM("uuid") },
     { name: "typeId", ...getTypeByORM("int") },
   ],
@@ -261,180 +268,30 @@ export const member_educations_table = new Table({
 });
 
 /** views */
-export const member_view_mysql = new View({
-  name: "member_view",
-  expression: `
-    SELECT 
-      \`member\`.\`id\` AS \`id\`, 
-      \`member\`.\`internalId\` AS \`internalId\`, 
-      \`member\`.\`firstname\` AS \`firstname\`, 
-      \`member\`.\`lastname\` AS \`lastname\`, 
-      \`member\`.\`nameaffix\` AS \`nameaffix\`, 
-      \`member\`.\`birthdate\` AS \`birthdate\`, 
-      \`salutation\`.\`salutation\` AS \`salutation\`, 
-      TIMESTAMPDIFF(YEAR, \`member\`.\`birthdate\`, CURDATE()) AS \`todayAge\`, 
-      YEAR(CURDATE()) - YEAR(\`member\`.\`birthdate\`) AS \`ageThisYear\`, 
-      CONCAT(
-        TIMESTAMPDIFF(YEAR, \`member\`.\`birthdate\`, CURDATE()), ' years ',
-        TIMESTAMPDIFF(MONTH, \`member\`.\`birthdate\`, CURDATE()) % 12, ' months ',
-        TIMESTAMPDIFF(DAY, 
-            DATE_ADD(
-                \`member\`.\`birthdate\`, 
-                INTERVAL TIMESTAMPDIFF(MONTH, \`member\`.\`birthdate\`, CURDATE()) MONTH
-            ),
-            CURDATE()
-        ), ' days'
-      ) AS \`exactAge\` 
-    FROM \`member\` \`member\` 
-    LEFT JOIN \`salutation\` \`salutation\` ON \`salutation\`.\`id\`=\`member\`.\`salutationId\`
-  `,
-});
 
-export const member_view_postgres = new View({
+export const member_view = new View({
   name: "member_view",
   expression: `
     SELECT 
       "member"."id" AS "id", 
-      "member"."internalId" AS "internalId", 
       "member"."firstname" AS "firstname", 
       "member"."lastname" AS "lastname", 
       "member"."nameaffix" AS "nameaffix", 
       "member"."birthdate" AS "birthdate", 
-      "salutation"."salutation" AS "salutation", 
-      DATE_PART('year', AGE(CURRENT_DATE, member.birthdate)) AS "todayAge", 
-      EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM member.birthdate) AS "ageThisYear", 
-      AGE(CURRENT_DATE, member.birthdate) AS "exactAge" 
-    FROM "member" "member" 
-    LEFT JOIN "salutation" "salutation" ON "salutation"."id"="member"."salutationId"
-  `,
-});
-
-export const member_view_sqlite = new View({
-  name: "member_view",
-  expression: `
-    SELECT 
-      member.id AS id, 
-      member.internalId AS internalId, 
-      member.firstname AS firstname, 
-      member.lastname AS lastname, 
-      member.nameaffix AS nameaffix, 
-      member.birthdate AS birthdate, 
-      salutation.salutation AS salutation, 
-      (strftime('%Y', 'now') - strftime('%Y', member.birthdate) - (strftime('%m-%d', 'now') < strftime('%m-%d', member.birthdate))) AS todayAge, 
-      FLOOR(strftime('%Y', 'now') - strftime('%Y', member.birthdate)) AS ageThisYear, 
-      (strftime('%Y', 'now') - strftime('%Y', member.birthdate)) || ' years ' ||
-        (strftime('%m', 'now') - strftime('%m', member.birthdate)) || ' months ' ||
-        (strftime('%d', 'now') - strftime('%d', member.birthdate)) || ' days' 
-      AS exactAge
-    FROM member member 
-    LEFT JOIN salutation salutation ON salutation.id=member.salutationId
-  `,
-});
-
-export const member_view2_mysql = new View({
-  name: "member_view",
-  expression: `
-    SELECT 
-      \`member\`.\`id\` AS \`id\`, 
-      \`member\`.\`internalId\` AS \`internalId\`, 
-      \`member\`.\`note\` AS \`note\`, 
-      \`member\`.\`firstname\` AS \`firstname\`, 
-      \`member\`.\`lastname\` AS \`lastname\`, 
-      \`member\`.\`nameaffix\` AS \`nameaffix\`, 
-      \`member\`.\`birthdate\` AS \`birthdate\`, 
-      \`salutation\`.\`salutation\` AS \`salutation\`, 
-      TIMESTAMPDIFF(YEAR, \`member\`.\`birthdate\`, CURDATE()) AS \`todayAge\`, 
-      YEAR(CURDATE()) - YEAR(\`member\`.\`birthdate\`) AS \`ageThisYear\`, 
-      CONCAT(
-        TIMESTAMPDIFF(YEAR, \`member\`.\`birthdate\`, CURDATE()), ' years ',
-        TIMESTAMPDIFF(MONTH, \`member\`.\`birthdate\`, CURDATE()) % 12, ' months ',
-        TIMESTAMPDIFF(DAY, 
-            DATE_ADD(
-                \`member\`.\`birthdate\`, 
-                INTERVAL TIMESTAMPDIFF(MONTH, \`member\`.\`birthdate\`, CURDATE()) MONTH
-            ),
-            CURDATE()
-        ), ' days'
-      ) AS \`exactAge\` 
-    FROM \`member\` \`member\` 
-    LEFT JOIN \`salutation\` \`salutation\` ON \`salutation\`.\`id\`=\`member\`.\`salutationId\`
-  `,
-});
-
-export const member_view2_postgres = new View({
-  name: "member_view",
-  expression: `
-    SELECT 
-      "member"."id" AS "id", 
       "member"."internalId" AS "internalId", 
       "member"."note" AS "note",
-      "member"."firstname" AS "firstname", 
-      "member"."lastname" AS "lastname", 
-      "member"."nameaffix" AS "nameaffix", 
-      "member"."birthdate" AS "birthdate", 
       "salutation"."salutation" AS "salutation", 
-      DATE_PART('year', AGE(CURRENT_DATE, member.birthdate)) AS "todayAge", 
-      EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM member.birthdate) AS "ageThisYear", 
-      AGE(CURRENT_DATE, member.birthdate) AS "exactAge" 
+      DATE_PART('year', AGE(CURRENT_DATE, "member"."birthdate")) AS "todayAge", 
+      EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM "member"."birthdate") AS "ageThisYear", 
+      AGE(CURRENT_DATE, "member"."birthdate") AS "exactAge" 
     FROM "member" "member" 
     LEFT JOIN "salutation" "salutation" ON "salutation"."id"="member"."salutationId"
-  `,
+  `
+    .replace(/\s+/g, " ")
+    .trim(),
 });
 
-export const member_view2_sqlite = new View({
-  name: "member_view",
-  expression: `
-    SELECT 
-      member.id AS id, 
-      member.internalId AS internalId, 
-      member.note AS note, 
-      member.firstname AS firstname, 
-      member.lastname AS lastname, 
-      member.nameaffix AS nameaffix, 
-      member.birthdate AS birthdate, 
-      salutation.salutation AS salutation, 
-      (strftime('%Y', 'now') - strftime('%Y', member.birthdate) - (strftime('%m-%d', 'now') < strftime('%m-%d', member.birthdate))) AS todayAge, 
-      FLOOR(strftime('%Y', 'now') - strftime('%Y', member.birthdate)) AS ageThisYear, 
-      (strftime('%Y', 'now') - strftime('%Y', member.birthdate)) || ' years ' ||
-        (strftime('%m', 'now') - strftime('%m', member.birthdate)) || ' months ' ||
-        (strftime('%d', 'now') - strftime('%d', member.birthdate)) || ' days' 
-      AS exactAge
-    FROM member member 
-    LEFT JOIN salutation salutation ON salutation.id=member.salutationId
-  `,
-});
-
-export const member_executive_positions_view_mysql = new View({
-  name: "member_executive_positions_view",
-  expression: `
-    SELECT 
-      \`executivePosition\`.\`id\` AS \`positionId\`, 
-      \`executivePosition\`.\`position\` AS \`position\`, 
-      \`member\`.\`id\` AS \`memberId\`, 
-      \`member\`.\`firstname\` AS \`memberFirstname\`, 
-      \`member\`.\`lastname\` AS \`memberLastname\`, 
-      \`member\`.\`nameaffix\` AS \`memberNameaffix\`, 
-      \`member\`.\`birthdate\` AS \`memberBirthdate\`, 
-      \`salutation\`.\`salutation\` AS \`memberSalutation\`, 
-      SUM(DATEDIFF(COALESCE(\`memberExecutivePositions\`.\`end\`, CURDATE()), \`memberExecutivePositions\`.\`start\`)) AS \`durationInDays\`, 
-      SUM(TIMESTAMPDIFF(YEAR, \`memberExecutivePositions\`.\`start\`, COALESCE(\`memberExecutivePositions\`.\`end\`, CURDATE()))) AS \`durationInYears\`,
-      CONCAT(
-        SUM(FLOOR(TIMESTAMPDIFF(DAY, \`memberExecutivePositions\`.\`start\`, COALESCE(\`memberExecutivePositions\`.\`end\`, CURDATE())) / 365.25)),
-        ' years ',
-        SUM(FLOOR(MOD(TIMESTAMPDIFF(MONTH, \`memberExecutivePositions\`.\`start\`, COALESCE(\`memberExecutivePositions\`.\`end\`, CURDATE())), 12))),
-        ' months ',
-        SUM(FLOOR(MOD(TIMESTAMPDIFF(DAY, \`memberExecutivePositions\`.\`start\`, COALESCE(\`memberExecutivePositions\`.\`end\`, CURDATE())), 30))),
-        ' days'
-      ) AS \`exactDuration\`
-    FROM \`member_executive_positions\` \`memberExecutivePositions\` 
-    LEFT JOIN \`executive_position\` \`executivePosition\` ON \`executivePosition\`.\`id\`=\`memberExecutivePositions\`.\`executivePositionId\` 
-    LEFT JOIN \`member\` \`member\` ON \`member\`.\`id\`=\`memberExecutivePositions\`.\`memberId\`  
-    LEFT JOIN \`salutation\` \`salutation\` ON \`salutation\`.\`id\`=\`member\`.\`salutationId\` 
-    GROUP BY \`executivePosition\`.\`id\`, \`member\`.\`id\`, \`salutation\`.\`id\`
-  `,
-});
-
-export const member_executive_positions_view_postgres = new View({
+export const member_executive_positions_view = new View({
   name: "member_executive_positions_view",
   expression: `
     SELECT 
@@ -454,66 +311,12 @@ export const member_executive_positions_view_postgres = new View({
     LEFT JOIN "member" "member" ON "member"."id"="memberExecutivePositions"."memberId"  
     LEFT JOIN "salutation" "salutation" ON "salutation"."id"="member"."salutationId" 
     GROUP BY "executivePosition"."id", "member"."id", "salutation"."id"
-  `,
+  `
+    .replace(/\s+/g, " ")
+    .trim(),
 });
 
-export const member_executive_positions_view_sqlite = new View({
-  name: "member_executive_positions_view",
-  expression: `
-    SELECT 
-      executivePosition.id AS positionId, 
-      executivePosition.position AS position, 
-      member.id AS memberId, 
-      member.firstname AS memberFirstname, 
-      member.lastname AS memberLastname, 
-      member.nameaffix AS memberNameaffix, 
-      member.birthdate AS memberBirthdate, 
-      salutation.salutation AS memberSalutation, 
-      SUM(JULIANDAY(COALESCE(memberExecutivePositions.end, DATE('now'))) - JULIANDAY(memberExecutivePositions.start)) AS durationInDays,
-      SUM(FLOOR((JULIANDAY(COALESCE(memberExecutivePositions.end, DATE('now'))) - JULIANDAY(memberExecutivePositions.start)) / 365.25)) AS durationInYears,
-      SUM((strftime('%Y', COALESCE(memberExecutivePositions.end, DATE('now'))) - strftime('%Y', memberExecutivePositions.start))) || ' years ' ||
-        SUM((strftime('%m', COALESCE(memberExecutivePositions.end, DATE('now'))) - strftime('%m', memberExecutivePositions.start))) || ' months ' ||
-        SUM((strftime('%d', COALESCE(memberExecutivePositions.end, DATE('now'))) - strftime('%d', memberExecutivePositions.start))) || ' days'
-      AS exactDuration
-    FROM member_executive_positions memberExecutivePositions 
-    LEFT JOIN executive_position executivePosition ON executivePosition.id=memberExecutivePositions.executivePositionId 
-    LEFT JOIN member member ON member.id=memberExecutivePositions.memberId  
-    LEFT JOIN salutation salutation ON salutation.id=member.salutationId 
-    GROUP BY executivePosition.id, member.id, salutation.id
-  `,
-});
-
-export const member_qualifications_view_mysql = new View({
-  name: "member_qualifications_view",
-  expression: `
-    SELECT 
-      \`qualification\`.\`id\` AS \`qualificationId\`, 
-      \`qualification\`.\`qualification\` AS \`qualification\`, 
-      \`member\`.\`id\` AS \`memberId\`, 
-      \`member\`.\`firstname\` AS \`memberFirstname\`, 
-      \`member\`.\`lastname\` AS \`memberLastname\`, 
-      \`member\`.\`nameaffix\` AS \`memberNameaffix\`, 
-      \`member\`.\`birthdate\` AS \`memberBirthdate\`, 
-      \`salutation\`.\`salutation\` AS \`memberSalutation\`,  
-      SUM(DATEDIFF(COALESCE(\`memberQualifications\`.\`end\`, CURDATE()), \`memberQualifications\`.\`start\`)) AS \`durationInDays\`, 
-      SUM(TIMESTAMPDIFF(YEAR, \`memberQualifications\`.\`start\`, COALESCE(\`memberQualifications\`.\`end\`, CURDATE()))) AS \`durationInYears\`,
-      CONCAT(
-        SUM(FLOOR(TIMESTAMPDIFF(DAY, \`memberQualifications\`.\`start\`, COALESCE(\`memberQualifications\`.\`end\`, CURDATE())) / 365.25)),
-        ' years ',
-        SUM(FLOOR(MOD(TIMESTAMPDIFF(MONTH, \`memberQualifications\`.\`start\`, COALESCE(\`memberQualifications\`.\`end\`, CURDATE())), 12))),
-        ' months ',
-        SUM(FLOOR(MOD(TIMESTAMPDIFF(DAY, \`memberQualifications\`.\`start\`, COALESCE(\`memberQualifications\`.\`end\`, CURDATE())), 30))),
-        ' days'
-      ) AS \`exactDuration\` 
-    FROM \`member_qualifications\` \`memberQualifications\` 
-    LEFT JOIN \`qualification\` \`qualification\` ON \`qualification\`.\`id\`=\`memberQualifications\`.\`qualificationId\`  
-    LEFT JOIN \`member\` \`member\` ON \`member\`.\`id\`=\`memberQualifications\`.\`memberId\`  
-    LEFT JOIN \`salutation\` \`salutation\` ON \`salutation\`.\`id\`=\`member\`.\`salutationId\` 
-    GROUP BY \`qualification\`.\`id\`, \`member\`.\`id\`, \`salutation\`.\`id\`
-  `,
-});
-
-export const member_qualifications_view_postgres = new View({
+export const member_qualifications_view = new View({
   name: "member_qualifications_view",
   expression: `
     SELECT 
@@ -533,66 +336,12 @@ export const member_qualifications_view_postgres = new View({
     LEFT JOIN "member" "member" ON "member"."id"="memberQualifications"."memberId"  
     LEFT JOIN "salutation" "salutation" ON "salutation"."id"="member"."salutationId" 
     GROUP BY "qualification"."id", "member"."id", "salutation"."id"
-  `,
+  `
+    .replace(/\s+/g, " ")
+    .trim(),
 });
 
-export const member_qualifications_view_sqlite = new View({
-  name: "member_qualifications_view",
-  expression: `
-    SELECT 
-      qualification.id AS qualificationId, 
-      qualification.qualification AS qualification, 
-      member.id AS memberId, 
-      member.firstname AS memberFirstname, 
-      member.lastname AS memberLastname, 
-      member.nameaffix AS memberNameaffix, 
-      member.birthdate AS memberBirthdate, 
-      salutation.salutation AS memberSalutation, 
-      SUM(JULIANDAY(COALESCE(memberQualifications.end, DATE('now'))) - JULIANDAY(memberQualifications.start)) AS durationInDays,
-      SUM(FLOOR((JULIANDAY(COALESCE(memberQualifications.end, DATE('now'))) - JULIANDAY(memberQualifications.start)) / 365.25)) AS durationInYears,
-      SUM((strftime('%Y', COALESCE(memberQualifications.end, DATE('now'))) - strftime('%Y', memberQualifications.start))) || ' years ' ||
-        SUM((strftime('%m', COALESCE(memberQualifications.end, DATE('now'))) - strftime('%m', memberQualifications.start))) || ' months ' ||
-        SUM((strftime('%d', COALESCE(memberQualifications.end, DATE('now'))) - strftime('%d', memberQualifications.start))) || ' days'
-      AS exactDuration
-    FROM member_qualifications memberQualifications 
-    LEFT JOIN qualification qualification ON qualification.id=memberQualifications.qualificationId 
-    LEFT JOIN member member ON member.id=memberQualifications.memberId  
-    LEFT JOIN salutation salutation ON salutation.id=member.salutationId 
-    GROUP BY qualification.id, member.id, salutation.id
-  `,
-});
-
-export const membership_view_mysql = new View({
-  name: "membership_view",
-  expression: `
-    SELECT 
-      \`status\`.\`id\` AS \`statusId\`, 
-      \`status\`.\`status\` AS \`status\`, 
-      \`member\`.\`id\` AS \`memberId\`, 
-      \`member\`.\`firstname\` AS \`memberFirstname\`, 
-      \`member\`.\`lastname\` AS \`memberLastname\`, 
-      \`member\`.\`nameaffix\` AS \`memberNameaffix\`, 
-      \`member\`.\`birthdate\` AS \`memberBirthdate\`, 
-      \`salutation\`.\`salutation\` AS \`memberSalutation\`,  
-      SUM(DATEDIFF(COALESCE(\`membership\`.\`end\`, CURDATE()), \`membership\`.\`start\`)) AS \`durationInDays\`, 
-      SUM(TIMESTAMPDIFF(YEAR, \`membership\`.\`start\`, COALESCE(\`membership\`.\`end\`, CURDATE()))) AS \`durationInYears\`,
-      CONCAT(
-        SUM(FLOOR(TIMESTAMPDIFF(DAY, \`membership\`.\`start\`, COALESCE(\`membership\`.\`end\`, CURDATE())) / 365.25)),
-        ' years ',
-        SUM(FLOOR(MOD(TIMESTAMPDIFF(MONTH, \`membership\`.\`start\`, COALESCE(\`membership\`.\`end\`, CURDATE())), 12))),
-        ' months ',
-        SUM(FLOOR(MOD(TIMESTAMPDIFF(DAY, \`membership\`.\`start\`, COALESCE(\`membership\`.\`end\`, CURDATE())), 30))),
-        ' days'
-      ) AS \`exactDuration\`
-    FROM \`membership\` \`membership\` 
-    LEFT JOIN \`membership_status\` \`status\` ON \`status\`.\`id\`=\`membership\`.\`statusId\`  
-    LEFT JOIN \`member\` \`member\` ON \`member\`.\`id\`=\`membership\`.\`memberId\`  
-    LEFT JOIN \`salutation\` \`salutation\` ON \`salutation\`.\`id\`=\`member\`.\`salutationId\` 
-    GROUP BY \`status\`.\`id\`, \`member\`.\`id\`, \`salutation\`.\`id\`
-  `,
-});
-
-export const membership_view_postgres = new View({
+export const membership_view = new View({
   name: "membership_view",
   expression: `
     SELECT
@@ -611,65 +360,13 @@ export const membership_view_postgres = new View({
     LEFT JOIN "membership_status" "status" ON "status"."id"="membership"."statusId"
     LEFT JOIN "member" "member" ON "member"."id"="membership"."memberId"
     LEFT JOIN "salutation" "salutation" ON "salutation"."id"="member"."salutationId"
-    GROUP BY "status"."id","member"."id", "salutation"."id"
-  `,
+    GROUP BY "status"."id", "member"."id", "salutation"."id"
+  `
+    .replace(/\s+/g, " ")
+    .trim(),
 });
 
-export const membership_view_sqlite = new View({
-  name: "membership_view",
-  expression: `
-    SELECT 
-      status.id AS statusId, 
-      status.status AS status, 
-      member.id AS memberId, 
-      member.firstname AS memberFirstname, 
-      member.lastname AS memberLastname, 
-      member.nameaffix AS memberNameaffix, 
-      member.birthdate AS memberBirthdate, 
-      salutation.salutation AS memberSalutation, 
-      SUM(JULIANDAY(COALESCE(membership.end, DATE('now'))) - JULIANDAY(membership.start)) AS durationInDays,
-      SUM(FLOOR((JULIANDAY(COALESCE(membership.end, DATE('now'))) - JULIANDAY(membership.start)) / 365.25)) AS durationInYears,
-      SUM((strftime('%Y', COALESCE(membership.end, DATE('now'))) - strftime('%Y', membership.start))) || ' years ' ||
-        SUM((strftime('%m', COALESCE(membership.end, DATE('now'))) - strftime('%m', membership.start))) || ' months ' ||
-        SUM((strftime('%d', COALESCE(membership.end, DATE('now'))) - strftime('%d', membership.start))) || ' days'
-      AS exactDuration
-    FROM membership membership 
-    LEFT JOIN membership_status status ON status.id=membership.statusId 
-    LEFT JOIN member member ON member.id=membership.memberId  
-    LEFT JOIN salutation salutation ON salutation.id=member.salutationId 
-    GROUP BY status.id, member.id, salutation.id
-  `,
-});
-
-export const membership_total_view_mysql = new View({
-  name: "membership_total_view",
-  expression: `
-    SELECT 
-      \`member\`.\`id\` AS \`memberId\`, 
-      \`member\`.\`firstname\` AS \`memberFirstname\`, 
-      \`member\`.\`lastname\` AS \`memberLastname\`, 
-      \`member\`.\`nameaffix\` AS \`memberNameaffix\`, 
-      \`member\`.\`birthdate\` AS \`memberBirthdate\`, 
-      \`salutation\`.\`salutation\` AS \`memberSalutation\`,  
-      SUM(DATEDIFF(COALESCE(\`membership\`.\`end\`, CURDATE()), \`membership\`.\`start\`)) AS \`durationInDays\`, 
-      SUM(TIMESTAMPDIFF(YEAR, \`membership\`.\`start\`, COALESCE(\`membership\`.\`end\`, CURDATE()))) AS \`durationInYears\`,
-      CONCAT(
-        SUM(FLOOR(TIMESTAMPDIFF(DAY, \`membership\`.\`start\`, COALESCE(\`membership\`.\`end\`, CURDATE())) / 365.25)),
-        ' years ',
-        SUM(FLOOR(MOD(TIMESTAMPDIFF(MONTH, \`membership\`.\`start\`, COALESCE(\`membership\`.\`end\`, CURDATE())), 12))),
-        ' months ',
-        SUM(FLOOR(MOD(TIMESTAMPDIFF(DAY, \`membership\`.\`start\`, COALESCE(\`membership\`.\`end\`, CURDATE())), 30))),
-        ' days'
-      ) AS \`exactDuration\`
-    FROM \`membership\` \`membership\` 
-    LEFT JOIN \`membership_status\` \`status\` ON \`status\`.\`id\`=\`membership\`.\`statusId\`  
-    LEFT JOIN \`member\` \`member\` ON \`member\`.\`id\`=\`membership\`.\`memberId\`  
-    LEFT JOIN \`salutation\` \`salutation\` ON \`salutation\`.\`id\`=\`member\`.\`salutationId\` 
-    GROUP BY \`member\`.\`id\`, \`salutation\`.\`id\`
-  `,
-});
-
-export const membership_total_view_postgres = new View({
+export const membership_total_view = new View({
   name: "membership_total_view",
   expression: `
     SELECT
@@ -687,29 +384,7 @@ export const membership_total_view_postgres = new View({
     LEFT JOIN "member" "member" ON "member"."id"="membership"."memberId"
     LEFT JOIN "salutation" "salutation" ON "salutation"."id"="member"."salutationId"
     GROUP BY "member"."id", "salutation"."id"
-  `,
-});
-
-export const membership_total_view_sqlite = new View({
-  name: "membership_total_view",
-  expression: `
-    SELECT 
-      member.id AS memberId, 
-      member.firstname AS memberFirstname, 
-      member.lastname AS memberLastname, 
-      member.nameaffix AS memberNameaffix, 
-      member.birthdate AS memberBirthdate, 
-      salutation.salutation AS memberSalutation, 
-      SUM(JULIANDAY(COALESCE(membership.end, DATE('now'))) - JULIANDAY(membership.start)) AS durationInDays,
-      SUM(FLOOR((JULIANDAY(COALESCE(membership.end, DATE('now'))) - JULIANDAY(membership.start)) / 365.25)) AS durationInYears,
-      SUM((strftime('%Y', COALESCE(membership.end, DATE('now'))) - strftime('%Y', membership.start))) || ' years ' ||
-        SUM((strftime('%m', COALESCE(membership.end, DATE('now'))) - strftime('%m', membership.start))) || ' months ' ||
-        SUM((strftime('%d', COALESCE(membership.end, DATE('now'))) - strftime('%d', membership.start))) || ' days'
-      AS exactDuration
-    FROM membership membership 
-    LEFT JOIN membership_status status ON status.id=membership.statusId 
-    LEFT JOIN member member ON member.id=membership.memberId  
-    LEFT JOIN salutation salutation ON salutation.id=member.salutationId 
-    GROUP BY member.id, salutation.id
-  `,
+  `
+    .replace(/\s+/g, " ")
+    .trim(),
 });
diff --git a/src/migrations/baseSchemaTables/newsletter.ts b/src/migrations/baseSchemaTables/newsletter.ts
index 537428f..2141cc7 100644
--- a/src/migrations/baseSchemaTables/newsletter.ts
+++ b/src/migrations/baseSchemaTables/newsletter.ts
@@ -1,4 +1,4 @@
-import { Table, TableForeignKey } from "typeorm";
+import { Table, TableForeignKey, TableUnique } from "typeorm";
 import { getDefaultByORM, getTypeByORM, isIncrementPrimary } from "../ormHelper";
 
 export const newsletter_table = new Table({
@@ -7,11 +7,12 @@ export const newsletter_table = new Table({
     { name: "id", ...getTypeByORM("int"), ...isIncrementPrimary },
     { name: "title", ...getTypeByORM("varchar") },
     { name: "description", ...getTypeByORM("varchar"), default: getDefaultByORM("string") },
-    { name: "newsletterTitle", ...getTypeByORM("varchar"), default: getDefaultByORM("string") },
+    { name: "newsletterTitle", ...getTypeByORM("text"), default: getDefaultByORM("string") },
     { name: "newsletterText", ...getTypeByORM("text"), default: getDefaultByORM("string") },
-    { name: "newsletterSignatur", ...getTypeByORM("varchar"), default: getDefaultByORM("string") },
+    { name: "newsletterSignatur", ...getTypeByORM("text"), default: getDefaultByORM("string") },
     { name: "isSent", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
-    { name: "recipientsByQueryId", ...getTypeByORM("int", true) },
+    { name: "recipientsByQueryId", ...getTypeByORM("uuid", true) },
+    { name: "createdAt", ...getTypeByORM("datetime", false, 6), default: getDefaultByORM("currentTimestamp", 6) },
   ],
   foreignKeys: [
     new TableForeignKey({
@@ -22,6 +23,11 @@ export const newsletter_table = new Table({
       onUpdate: "RESTRICT",
     }),
   ],
+  uniques: [
+    new TableUnique({
+      columnNames: ["title"],
+    }),
+  ],
 });
 
 export const newsletter_dates_table = new Table({
diff --git a/src/migrations/baseSchemaTables/protocol.ts b/src/migrations/baseSchemaTables/protocol.ts
index fd1cc89..c04fca3 100644
--- a/src/migrations/baseSchemaTables/protocol.ts
+++ b/src/migrations/baseSchemaTables/protocol.ts
@@ -1,11 +1,11 @@
-import { Table, TableForeignKey } from "typeorm";
+import { Table, TableForeignKey, TableUnique } from "typeorm";
 import { getDefaultByORM, getTypeByORM, isIncrementPrimary } from "../ormHelper";
 
 export const protocol_table = new Table({
   name: "protocol",
   columns: [
     { name: "id", ...getTypeByORM("int"), ...isIncrementPrimary },
-    { name: "title", ...getTypeByORM("varchar") },
+    { name: "title", ...getTypeByORM("varchar"), isUnique: true },
     { name: "date", ...getTypeByORM("date") },
     { name: "starttime", ...getTypeByORM("time", true) },
     { name: "endtime", ...getTypeByORM("time", true) },
@@ -19,6 +19,7 @@ export const protocol_agenda_table = new Table({
     { name: "id", ...getTypeByORM("int"), ...isIncrementPrimary },
     { name: "topic", ...getTypeByORM("varchar") },
     { name: "context", ...getTypeByORM("text"), default: getDefaultByORM("string") },
+    { name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) },
     { name: "protocolId", ...getTypeByORM("int") },
   ],
   foreignKeys: [
@@ -38,6 +39,7 @@ export const protocol_decision_table = new Table({
     { name: "id", ...getTypeByORM("int"), ...isIncrementPrimary },
     { name: "topic", ...getTypeByORM("varchar") },
     { name: "context", ...getTypeByORM("text"), default: getDefaultByORM("string") },
+    { name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) },
     { name: "protocolId", ...getTypeByORM("int") },
   ],
   foreignKeys: [
@@ -86,6 +88,7 @@ export const protocol_voting_table = new Table({
     { name: "favour", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) },
     { name: "abstain", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) },
     { name: "against", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) },
+    { name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) },
     { name: "protocolId", ...getTypeByORM("int") },
   ],
   foreignKeys: [
diff --git a/src/migrations/baseSchemaTables/query_template.ts b/src/migrations/baseSchemaTables/query_template.ts
index da4eb44..2d8c4c8 100644
--- a/src/migrations/baseSchemaTables/query_template.ts
+++ b/src/migrations/baseSchemaTables/query_template.ts
@@ -1,12 +1,18 @@
 import { Table, TableForeignKey } from "typeorm";
-import { getDefaultByORM, getTypeByORM, isIncrementPrimary } from "../ormHelper";
+import { getDefaultByORM, getTypeByORM, isIncrementPrimary, isUUIDPrimary } from "../ormHelper";
 
 export const query_table = new Table({
   name: "query",
   columns: [
-    { name: "id", ...getTypeByORM("int"), ...isIncrementPrimary },
+    { name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
     { name: "title", ...getTypeByORM("varchar"), isUnique: true },
     { name: "query", ...getTypeByORM("text"), default: getDefaultByORM("string") },
+    {
+      name: "updatedAt",
+      ...getTypeByORM("datetime", false, 6),
+      default: getDefaultByORM("currentTimestamp", 6),
+      onUpdate: getDefaultByORM<string>("currentTimestamp", 6),
+    },
   ],
 });
 
diff --git a/src/migrations/ormHelper.ts b/src/migrations/ormHelper.ts
index 8ebe5c9..c376f2b 100644
--- a/src/migrations/ormHelper.ts
+++ b/src/migrations/ormHelper.ts
@@ -1,5 +1,3 @@
-import { DB_TYPE } from "../env.defaults";
-
 export type ORMType = "int" | "bigint" | "boolean" | "date" | "datetime" | "time" | "text" | "varchar" | "uuid";
 export type ORMDefault = "currentTimestamp" | "string" | "boolean" | "number" | "null";
 export type ColumnConfig = {
@@ -15,83 +13,38 @@ export type Primary = {
 };
 
 export function getTypeByORM(type: ORMType, nullable: boolean = false, length: number = 255): ColumnConfig {
-  const dbType = DB_TYPE;
-
-  const typeMap: Record<string, Record<ORMType, string>> = {
-    mysql: {
-      int: "int",
-      bigint: "bigint",
-      boolean: "tinyint",
-      date: "date",
-      datetime: "datetime",
-      time: "time",
-      text: "text",
-      varchar: "varchar",
-      uuid: "varchar",
-    },
-    postgres: {
-      int: "integer",
-      bigint: "bigint",
-      boolean: "boolean",
-      date: "date",
-      datetime: "timestamp",
-      time: "time",
-      text: "text",
-      varchar: "character varying",
-      uuid: "uuid",
-    },
-    sqlite: {
-      int: "integer",
-      bigint: "integer",
-      boolean: "integer",
-      date: "date",
-      datetime: "datetime",
-      time: "text",
-      text: "text",
-      varchar: "varchar",
-      uuid: "varchar",
-    },
+  const typeMap: Record<ORMType, string> = {
+    int: "integer",
+    bigint: "bigint",
+    boolean: "boolean",
+    date: "date",
+    datetime: "timestamp",
+    time: "time",
+    text: "text",
+    varchar: "character varying",
+    uuid: "uuid",
   };
 
   let obj: ColumnConfig = {
-    type: typeMap[dbType]?.[type] || type,
+    type: typeMap[type] || type,
     isNullable: nullable,
   };
   if (type == "datetime") obj.precision = length;
-  else if (dbType != "sqlite" && (obj.type == "varchar" || type == "varchar")) obj.length = `${length}`;
-  else if (dbType != "postgres" && type == "uuid") obj.length = "36";
+  else if (obj.type == "varchar" || type == "varchar") obj.length = `${length}`;
 
   return obj;
 }
 
 export function getDefaultByORM<T = string | null>(type: ORMDefault, data?: string | number | boolean): T {
-  const dbType = DB_TYPE;
-
-  const typeMap: Record<string, Record<ORMDefault, string | null>> = {
-    mysql: {
-      currentTimestamp: `CURRENT_TIMESTAMP(${data ?? 6})`,
-      string: `'${data ?? ""}'`,
-      boolean: Boolean(data).toString(),
-      number: Number(data).toString(),
-      null: null,
-    },
-    postgres: {
-      currentTimestamp: `now()`,
-      string: `'${data ?? ""}'`,
-      boolean: Boolean(data) == true ? "true" : "false",
-      number: Number(data).toString(),
-      null: null,
-    },
-    sqlite: {
-      currentTimestamp: `datetime('now')`,
-      string: `'${data ?? ""}'`,
-      boolean: Boolean(data) == true ? "1" : "0",
-      number: Number(data).toString(),
-      null: null,
-    },
+  const typeMap: Record<ORMDefault, string | null> = {
+    currentTimestamp: `now()`,
+    string: `'${data ?? ""}'`,
+    boolean: Boolean(data) == true ? "true" : "false",
+    number: Number(data).toString(),
+    null: null,
   };
 
-  return (typeMap[dbType]?.[type] || type) as T;
+  return (typeMap[type] || type) as T;
 }
 
 export const isIncrementPrimary: Primary = {
diff --git a/src/service/club/member/memberService.ts b/src/service/club/member/memberService.ts
index b6f4d5c..0aed9aa 100644
--- a/src/service/club/member/memberService.ts
+++ b/src/service/club/member/memberService.ts
@@ -3,7 +3,6 @@ import { dataSource } from "../../../data-source";
 import { member } from "../../../entity/club/member/member";
 import DatabaseActionException from "../../../exceptions/databaseActionException";
 import { memberView } from "../../../views/memberView";
-import { DB_TYPE } from "../../../env.defaults";
 
 export default abstract class MemberService {
   /**
@@ -194,17 +193,13 @@ export default abstract class MemberService {
         "member.firstMembershipEntry",
         "member.memberships",
         "membership_first",
-        DB_TYPE == "postgres"
-          ? 'membership_first.memberId = member.id AND membership_first.start = (SELECT MIN("m_first"."start") FROM "membership" "m_first" WHERE "m_first"."memberId" = "member"."id")'
-          : "membership_first.memberId = member.id AND membership_first.start = (SELECT MIN(m_first.start) FROM membership m_first WHERE m_first.memberId = member.id)"
+        'membership_first.memberId = member.id AND membership_first.start = (SELECT MIN("m_first"."start") FROM "membership" "m_first" WHERE "m_first"."memberId" = "member"."id")'
       )
       .leftJoinAndMapOne(
         "member.lastMembershipEntry",
         "member.memberships",
         "membership_last",
-        DB_TYPE == "postgres"
-          ? 'membership_last.memberId = member.id AND membership_last.start = (SELECT MAX("m_last"."start") FROM "membership" "m_last" WHERE "m_last"."memberId" = "member"."id")'
-          : "membership_last.memberId = member.id AND membership_last.start = (SELECT MAX(m_last.start) FROM membership m_last WHERE m_last.memberId = member.id)"
+        'membership_last.memberId = member.id AND membership_last.start = (SELECT MAX("m_last"."start") FROM "membership" "m_last" WHERE "m_last"."memberId" = "member"."id")'
       )
       .leftJoinAndSelect("membership_first.status", "status_first")
       .leftJoinAndSelect("membership_last.status", "status_last")
diff --git a/src/views/memberExecutivePositionView.ts b/src/views/memberExecutivePositionView.ts
index 8b8f328..d7b1be5 100644
--- a/src/views/memberExecutivePositionView.ts
+++ b/src/views/memberExecutivePositionView.ts
@@ -1,36 +1,5 @@
 import { DataSource, ViewColumn, ViewEntity } from "typeorm";
 import { memberExecutivePositions } from "../entity/club/member/memberExecutivePositions";
-import { DB_TYPE } from "../env.defaults";
-
-let durationInDays: string;
-let durationInYears: string;
-let exactDuration: string;
-if (DB_TYPE == "postgres") {
-  durationInDays = `SUM(COALESCE("memberExecutivePositions"."end", CURRENT_DATE) - "memberExecutivePositions"."start")`;
-  durationInYears = `SUM(EXTRACT(YEAR FROM AGE(COALESCE("memberExecutivePositions"."end", CURRENT_DATE), "memberExecutivePositions"."start")))`;
-  exactDuration = `SUM(AGE(COALESCE("memberExecutivePositions"."end", CURRENT_DATE), "memberExecutivePositions"."start"))`;
-} else if (DB_TYPE == "mysql") {
-  durationInDays = `SUM(DATEDIFF(COALESCE(memberExecutivePositions.end, CURDATE()), memberExecutivePositions.start))`;
-  durationInYears = `SUM(TIMESTAMPDIFF(YEAR, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURDATE())))`;
-  exactDuration = `
-    CONCAT(
-      SUM(FLOOR(TIMESTAMPDIFF(DAY, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURDATE())) / 365.25)),
-      ' years ',
-      SUM(FLOOR(MOD(TIMESTAMPDIFF(MONTH, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURDATE())), 12))),
-      ' months ',
-      SUM(FLOOR(MOD(TIMESTAMPDIFF(DAY, memberExecutivePositions.start, COALESCE(memberExecutivePositions.end, CURDATE())), 30))),
-      ' days'
-    )
-  `;
-} else if (DB_TYPE == "sqlite") {
-  durationInDays = `SUM(JULIANDAY(COALESCE(memberExecutivePositions.end, DATE('now'))) - JULIANDAY(memberExecutivePositions.start))`;
-  durationInYears = `SUM(FLOOR((JULIANDAY(COALESCE(memberExecutivePositions.end, DATE('now'))) - JULIANDAY(memberExecutivePositions.start)) / 365.25))`;
-  exactDuration = `
-    SUM((strftime('%Y', COALESCE(memberExecutivePositions.end, DATE('now'))) - strftime('%Y', memberExecutivePositions.start))) || ' years ' ||
-      SUM((strftime('%m', COALESCE(memberExecutivePositions.end, DATE('now'))) - strftime('%m', memberExecutivePositions.start))) || ' months ' ||
-      SUM((strftime('%d', COALESCE(memberExecutivePositions.end, DATE('now'))) - strftime('%d', memberExecutivePositions.start))) || ' days'
-  `;
-}
 
 @ViewEntity({
   expression: (datasource: DataSource) =>
@@ -45,9 +14,18 @@ if (DB_TYPE == "postgres") {
       .addSelect("member.nameaffix", "memberNameaffix")
       .addSelect("member.birthdate", "memberBirthdate")
       .addSelect("salutation.salutation", "memberSalutation")
-      .addSelect(durationInDays, "durationInDays")
-      .addSelect(durationInYears, "durationInYears")
-      .addSelect(exactDuration, "exactDuration")
+      .addSelect(
+        `SUM(COALESCE("memberExecutivePositions"."end", CURRENT_DATE) - "memberExecutivePositions"."start")`,
+        "durationInDays"
+      )
+      .addSelect(
+        `SUM(EXTRACT(YEAR FROM AGE(COALESCE("memberExecutivePositions"."end", CURRENT_DATE), "memberExecutivePositions"."start")))`,
+        "durationInYears"
+      )
+      .addSelect(
+        `SUM(AGE(COALESCE("memberExecutivePositions"."end", CURRENT_DATE), "memberExecutivePositions"."start"))`,
+        "exactDuration"
+      )
       .leftJoin("memberExecutivePositions.executivePosition", "executivePosition")
       .leftJoin("memberExecutivePositions.member", "member")
       .leftJoin("member.salutation", "salutation")
diff --git a/src/views/memberQualificationsView.ts b/src/views/memberQualificationsView.ts
index 6f88f39..5111511 100644
--- a/src/views/memberQualificationsView.ts
+++ b/src/views/memberQualificationsView.ts
@@ -1,36 +1,5 @@
 import { DataSource, ViewColumn, ViewEntity } from "typeorm";
 import { memberQualifications } from "../entity/club/member/memberQualifications";
-import { DB_TYPE } from "../env.defaults";
-
-let durationInDays: string;
-let durationInYears: string;
-let exactDuration: string;
-if (DB_TYPE == "postgres") {
-  durationInDays = `SUM(COALESCE("memberQualifications"."end", CURRENT_DATE) - "memberQualifications"."start") `;
-  durationInYears = `SUM(EXTRACT(YEAR FROM AGE(COALESCE("memberQualifications"."end", CURRENT_DATE), "memberQualifications"."start")))`;
-  exactDuration = `SUM(AGE(COALESCE("memberQualifications"."end", CURRENT_DATE), "memberQualifications"."start"))`;
-} else if (DB_TYPE == "mysql") {
-  durationInDays = `SUM(DATEDIFF(COALESCE(memberQualifications.end, CURDATE()), memberQualifications.start))`;
-  durationInYears = `SUM(TIMESTAMPDIFF(YEAR, memberQualifications.start, COALESCE(memberQualifications.end, CURDATE())))`;
-  exactDuration = `
-    CONCAT(
-      SUM(FLOOR(TIMESTAMPDIFF(DAY, memberQualifications.start, COALESCE(memberQualifications.end, CURDATE())) / 365.25)),
-      ' years ',
-      SUM(FLOOR(MOD(TIMESTAMPDIFF(MONTH, memberQualifications.start, COALESCE(memberQualifications.end, CURDATE())), 12))),
-      ' months ',
-      SUM(FLOOR(MOD(TIMESTAMPDIFF(DAY, memberQualifications.start, COALESCE(memberQualifications.end, CURDATE())), 30))),
-      ' days'
-    )
-  `;
-} else if (DB_TYPE == "sqlite") {
-  durationInDays = `SUM(JULIANDAY(COALESCE(memberQualifications.end, DATE('now'))) - JULIANDAY(memberQualifications.start))`;
-  durationInYears = `SUM(FLOOR((JULIANDAY(COALESCE(memberQualifications.end, DATE('now'))) - JULIANDAY(memberQualifications.start)) / 365.25))`;
-  exactDuration = `
-    SUM((strftime('%Y', COALESCE(memberQualifications.end, DATE('now'))) - strftime('%Y', memberQualifications.start))) || ' years ' ||
-      SUM((strftime('%m', COALESCE(memberQualifications.end, DATE('now'))) - strftime('%m', memberQualifications.start))) || ' months ' ||
-      SUM((strftime('%d', COALESCE(memberQualifications.end, DATE('now'))) - strftime('%d', memberQualifications.start))) || ' days'
-  `;
-}
 
 @ViewEntity({
   expression: (datasource: DataSource) =>
@@ -45,9 +14,18 @@ if (DB_TYPE == "postgres") {
       .addSelect("member.nameaffix", "memberNameaffix")
       .addSelect("member.birthdate", "memberBirthdate")
       .addSelect("salutation.salutation", "memberSalutation")
-      .addSelect(durationInDays, "durationInDays")
-      .addSelect(durationInYears, "durationInYears")
-      .addSelect(exactDuration, "exactDuration")
+      .addSelect(
+        `SUM(COALESCE("memberQualifications"."end", CURRENT_DATE) - "memberQualifications"."start")`,
+        "durationInDays"
+      )
+      .addSelect(
+        `SUM(EXTRACT(YEAR FROM AGE(COALESCE("memberQualifications"."end", CURRENT_DATE), "memberQualifications"."start")))`,
+        "durationInYears"
+      )
+      .addSelect(
+        `SUM(AGE(COALESCE("memberQualifications"."end", CURRENT_DATE), "memberQualifications"."start"))`,
+        "exactDuration"
+      )
       .leftJoin("memberQualifications.qualification", "qualification")
       .leftJoin("memberQualifications.member", "member")
       .leftJoin("member.salutation", "salutation")
diff --git a/src/views/memberView.ts b/src/views/memberView.ts
index 260e0ff..1ffc058 100644
--- a/src/views/memberView.ts
+++ b/src/views/memberView.ts
@@ -1,39 +1,5 @@
 import { DataSource, ViewColumn, ViewEntity } from "typeorm";
 import { member } from "../entity/club/member/member";
-import { DB_TYPE } from "../env.defaults";
-
-let todayAge: string;
-let ageThisYear: string;
-let exactAge: string;
-if (DB_TYPE == "postgres") {
-  todayAge = `DATE_PART('year', AGE(CURRENT_DATE, member.birthdate))`;
-  ageThisYear = `EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM member.birthdate)`;
-  exactAge = `AGE(CURRENT_DATE, member.birthdate)`;
-} else if (DB_TYPE == "mysql") {
-  todayAge = `TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE()) AS todayAge`;
-  ageThisYear = `YEAR(CURDATE()) - YEAR(member.birthdate) AS ageThisYear`;
-  exactAge = `
-    CONCAT(
-      TIMESTAMPDIFF(YEAR, member.birthdate, CURDATE()), ' years ',
-      TIMESTAMPDIFF(MONTH, member.birthdate, CURDATE()) % 12, ' months ',
-      TIMESTAMPDIFF(DAY, 
-          DATE_ADD(
-              member.birthdate, 
-              INTERVAL TIMESTAMPDIFF(MONTH, member.birthdate, CURDATE()) MONTH
-          ),
-          CURDATE()
-      ), ' days'
-    )
-  `;
-} else if (DB_TYPE == "sqlite") {
-  todayAge = `(strftime('%Y', 'now') - strftime('%Y', member.birthdate) - (strftime('%m-%d', 'now') < strftime('%m-%d', member.birthdate)))`;
-  ageThisYear = `strftime('%Y', 'now') - strftime('%Y', member.birthdate)`;
-  exactAge = `
-    (strftime('%Y', 'now') - strftime('%Y', member.birthdate)) || ' years ' ||
-    (strftime('%m', 'now') - strftime('%m', member.birthdate)) || ' months ' ||
-    (strftime('%d', 'now') - strftime('%d', member.birthdate)) || ' days'
-  `;
-}
 
 @ViewEntity({
   expression: (datasource: DataSource) =>
@@ -48,9 +14,9 @@ if (DB_TYPE == "postgres") {
       .addSelect("member.nameaffix", "nameaffix")
       .addSelect("member.birthdate", "birthdate")
       .addSelect("salutation.salutation", "salutation")
-      .addSelect(todayAge, "todayAge")
-      .addSelect(ageThisYear, "ageThisYear")
-      .addSelect(exactAge, "exactAge")
+      .addSelect(`DATE_PART('year', AGE(CURRENT_DATE, member.birthdate))`, "todayAge")
+      .addSelect(`EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM member.birthdate)`, "ageThisYear")
+      .addSelect(`AGE(CURRENT_DATE, member.birthdate)`, "exactAge")
       .leftJoin("member.salutation", "salutation"),
 })
 export class memberView {
diff --git a/src/views/membershipsView.ts b/src/views/membershipsView.ts
index 7807f8e..d64da63 100644
--- a/src/views/membershipsView.ts
+++ b/src/views/membershipsView.ts
@@ -1,36 +1,5 @@
 import { DataSource, ViewColumn, ViewEntity } from "typeorm";
 import { membership } from "../entity/club/member/membership";
-import { DB_TYPE } from "../env.defaults";
-
-let durationInDays: string;
-let durationInYears: string;
-let exactDuration: string;
-if (DB_TYPE == "postgres") {
-  durationInDays = `SUM(COALESCE("membership"."end", CURRENT_DATE) - "membership"."start") `;
-  durationInYears = `SUM(EXTRACT(YEAR FROM AGE(COALESCE("membership"."end", CURRENT_DATE), "membership"."start")))`;
-  exactDuration = `SUM(AGE(COALESCE("membership"."end", CURRENT_DATE), "membership"."start"))`;
-} else if (DB_TYPE == "mysql") {
-  durationInDays = `SUM(DATEDIFF(COALESCE(membership.end, CURDATE()), membership.start))`;
-  durationInYears = `SUM(TIMESTAMPDIFF(YEAR, membership.start, COALESCE(membership.end, CURDATE())))`;
-  exactDuration = `
-    CONCAT(
-      SUM(FLOOR(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURDATE())) / 365.25)),
-      ' years ',
-      SUM(FLOOR(MOD(TIMESTAMPDIFF(MONTH, membership.start, COALESCE(membership.end, CURDATE())), 12))),
-      ' months ',
-      SUM(FLOOR(MOD(TIMESTAMPDIFF(DAY, membership.start, COALESCE(membership.end, CURDATE())), 30))),
-      ' days'
-    )
-  `;
-} else if (DB_TYPE == "sqlite") {
-  durationInDays = `SUM(JULIANDAY(COALESCE(membership.end, DATE('now'))) - JULIANDAY(membership.start))`;
-  durationInYears = `SUM(FLOOR((JULIANDAY(COALESCE(membership.end, DATE('now'))) - JULIANDAY(membership.start)) / 365.25))`;
-  exactDuration = `
-    SUM((strftime('%Y', COALESCE(membership.end, DATE('now'))) - strftime('%Y', membership.start))) || ' years ' ||
-      SUM((strftime('%m', COALESCE(membership.end, DATE('now'))) - strftime('%m', membership.start))) || ' months ' ||
-      SUM((strftime('%d', COALESCE(membership.end, DATE('now'))) - strftime('%d', membership.start))) || ' days'
-  `;
-}
 
 @ViewEntity({
   expression: (datasource: DataSource) =>
@@ -45,9 +14,12 @@ if (DB_TYPE == "postgres") {
       .addSelect("member.nameaffix", "memberNameaffix")
       .addSelect("member.birthdate", "memberBirthdate")
       .addSelect("salutation.salutation", "memberSalutation")
-      .addSelect(durationInDays, "durationInDays")
-      .addSelect(durationInYears, "durationInYears")
-      .addSelect(exactDuration, "exactDuration")
+      .addSelect(`SUM(COALESCE("membership"."end", CURRENT_DATE) - "membership"."start") `, "durationInDays")
+      .addSelect(
+        `SUM(EXTRACT(YEAR FROM AGE(COALESCE("membership"."end", CURRENT_DATE), "membership"."start")))`,
+        "durationInYears"
+      )
+      .addSelect(`SUM(AGE(COALESCE("membership"."end", CURRENT_DATE), "membership"."start"))`, "exactDuration")
       .leftJoin("membership.status", "status")
       .leftJoin("membership.member", "member")
       .leftJoin("member.salutation", "salutation")
@@ -101,14 +73,17 @@ export class membershipView {
       .addSelect("member.nameaffix", "memberNameaffix")
       .addSelect("member.birthdate", "memberBirthdate")
       .addSelect("salutation.salutation", "memberSalutation")
-      .addSelect(durationInDays, "durationInDays")
-      .addSelect(durationInYears, "durationInYears")
-      .addSelect(exactDuration, "exactDuration")
+      .addSelect(`SUM(COALESCE("membership"."end", CURRENT_DATE) - "membership"."start") `, "durationInDays")
+      .addSelect(
+        `SUM(EXTRACT(YEAR FROM AGE(COALESCE("membership"."end", CURRENT_DATE), "membership"."start")))`,
+        "durationInYears"
+      )
+      .addSelect(`SUM(AGE(COALESCE("membership"."end", CURRENT_DATE), "membership"."start"))`, "exactDuration")
       .leftJoin("membership.status", "status")
       .leftJoin("membership.member", "member")
       .leftJoin("member.salutation", "salutation")
-      .groupBy("status.id")
-      .addGroupBy("member.id"),
+      .groupBy("member.id")
+      .addGroupBy("salutation.id"),
 })
 export class membershipTotalView {
   @ViewColumn()