diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 12b84f6aeb070eda500128c22861f749f7b38208..27beb8d9e284835150897f81fe7fd45844010380 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,42 +1,13 @@
-stages:
-  - install
-  - test
-  - docker
-  - release
-
-docker:build:
-  stage: docker
-  image: docker:24
-  services:
-    - docker:dind
-  before_script:
-    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
-  script:
-    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG -t $CI_REGISTRY_IMAGE:latest -t $CI_REGISTRY_IMAGE:develop .
-    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
-    - if [[ $CI_COMMIT_TAG == *"develop"* ]]; then
-      docker push $CI_REGISTRY_IMAGE:develop;
-      else
-      docker push $CI_REGISTRY_IMAGE:latest;
-      fi
-  only:
-    - tags
+include:
+  - project: tobiasff3200/ci-cd
+    file: .gitlab-ci.yml
+    inputs:
+      npm-root: "./"
 
-release:
-  image: node:20-buster-slim
-  stage: release
-  before_script:
-    - apt-get update && apt-get install -y --no-install-recommends git-core ca-certificates
-    - npm install -g semantic-release @semantic-release/gitlab @semantic-release/git @semantic-release/changelog @semantic-release/release-notes-generator
-  script:
-    - semantic-release
-  only:
-    - main
-    - develop
+npm:build:
+  rules:
+    - when: never
 
-include:
-  - template: Dependency-Scanning.gitlab-ci.yml
-  - template: Security/License-Scanning.gitlab-ci.yml
-  - template: Security/SAST.gitlab-ci.yml
-  - template: Secret-Detection.gitlab-ci.yml
-  - template: Code-Quality.gitlab-ci.yml
+npm:test:
+  rules:
+    - when: never
diff --git a/.onedev-buildspec.yml b/.onedev-buildspec.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3175e82c6b1c61f8c9cf80be447caf4177f0349e
--- /dev/null
+++ b/.onedev-buildspec.yml
@@ -0,0 +1,37 @@
+version: 25
+jobs:
+  - name: Git Sync Push
+    steps:
+      - !PushRepository
+        name: Push to gitlab.fachschaften.org
+        remoteUrl: https://gitlab.fachschaften.org/tobiasff3200/wishlist.git
+        userName: Tobias
+        passwordSecret: GitLab.Fachschaften.org_Sync_Token
+        force: false
+        condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
+    triggers:
+      - !BranchUpdateTrigger { }
+      - !TagCreateTrigger { }
+    retryCondition: never
+    maxRetries: 3
+    retryDelay: 30
+    timeout: 3600
+  - name: Git Sync Pull
+    steps:
+      - !PullRepository
+        name: Pull from gitlab.fachschaften.org
+        remoteUrl: https://gitlab.fachschaften.org/tobiasff3200/wishlist.git
+        syncToChildProject: false
+        userName: Tobias
+        passwordSecret: GitLab.Fachschaften.org_Sync_Token
+        refs: refs/heads/* refs/tags/*
+        withLfs: true
+        force: false
+        condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
+    triggers:
+      - !ScheduleTrigger
+        cronExpression: 5 4 * * * ?
+    retryCondition: never
+    maxRetries: 3
+    retryDelay: 30
+    timeout: 3600
diff --git a/Dockerfile b/Dockerfile
index 99db2dfcda663e7fc0805a64d8e48caa74b27617..c6d60fc36efdf5826ea872e306e8a4e11a9f0812 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM registry.gitlab.fachschaften.org/tobiasff3200/django-core:v2.0.2 as core
+FROM registry.gitlab.fachschaften.org/tobiasff3200/django-core:v2.0.3 as core
 WORKDIR /app
 COPY . /app/wishlist
 RUN pip install --no-cache-dir -r wishlist/requirements.txt
@@ -8,7 +8,7 @@ RUN sed -i 's/{{app_to_install}}/wishlist/g' core/settings.py
 RUN sed -i 's/{{app_to_install}}/wishlist/g' core/urls.py
 
 
-FROM node:20 AS node
+FROM node:21 AS node
 WORKDIR /app/wishlist
 COPY --from=core /app /app
 RUN npm ci
diff --git a/package-lock.json b/package-lock.json
index 7473029b0b67be23dc891610137b3abb91382509..910ac17ffa9a46088074577376b1c9a152673f04 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,88 +1,10 @@
 {
-  "dependencies": {
-    "camelcase-css": {
-      "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
-      "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
-      "version": "2.0.1"
-    },
-    "css-selector-tokenizer": {
-      "integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==",
-      "requires": {
-        "cssesc": "^3.0.0",
-        "fastparse": "^1.1.2"
-      },
-      "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz",
-      "version": "0.8.0"
-    },
-    "cssesc": {
-      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
-      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
-      "version": "3.0.0"
-    },
-    "culori": {
-      "integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==",
-      "resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz",
-      "version": "3.3.0"
-    },
-    "daisyui": {
-      "integrity": "sha512-Wqk1f3rQbiDSMfzC/ZufQQi139dY4mCMZJ/hmYIIGpCi0MFndU0wJ575tEGzi2YrCZOagsWhbOeWE7DD/B5pVw==",
-      "requires": {
-        "css-selector-tokenizer": "^0.8",
-        "culori": "^3",
-        "picocolors": "^1",
-        "postcss-js": "^4"
-      },
-      "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.4.9.tgz",
-      "version": "4.4.9"
-    },
-    "fastparse": {
-      "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
-      "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
-      "version": "1.1.2"
-    },
-    "nanoid": {
-      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
-      "peer": true,
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
-      "version": "3.3.7"
-    },
-    "picocolors": {
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "version": "1.0.0"
-    },
-    "postcss": {
-      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
-      "peer": true,
-      "requires": {
-        "nanoid": "^3.3.6",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
-      "version": "8.4.31"
-    },
-    "postcss-js": {
-      "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
-      "requires": {
-        "camelcase-css": "^2.0.1"
-      },
-      "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
-      "version": "4.0.1"
-    },
-    "source-map-js": {
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "peer": true,
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "version": "1.0.2"
-    }
-  },
-  "lockfileVersion": 2,
+  "lockfileVersion": 3,
   "name": "wishlist",
   "packages": {
     "": {
       "dependencies": {
-        "daisyui": "^4.4.9"
+        "daisyui": "^4.4.19"
       }
     },
     "node_modules/camelcase-css": {
@@ -135,9 +57,9 @@
         "type": "opencollective",
         "url": "https://opencollective.com/daisyui"
       },
-      "integrity": "sha512-Wqk1f3rQbiDSMfzC/ZufQQi139dY4mCMZJ/hmYIIGpCi0MFndU0wJ575tEGzi2YrCZOagsWhbOeWE7DD/B5pVw==",
-      "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.4.9.tgz",
-      "version": "4.4.9"
+      "integrity": "sha512-IjOLWwnndD4N7Ut5CDxbUsaVtbqXPeVHM92IcgxGFxpuOd3CCKW/PAXZH6JoBTHFRaN57vB9XqEhdWm5yC+bPA==",
+      "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.4.19.tgz",
+      "version": "4.4.19"
     },
     "node_modules/fastparse": {
       "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
diff --git a/package.json b/package.json
index 8a6cd43857965e4730210cb65b14af3e25705aae..e5f575aafd21c95509655a822b4ffb1e1e759a0f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "dependencies": {
-    "daisyui": "^4.4.9"
+    "daisyui": "^4.4.19"
   },
   "scripts": {
     "tailwind": "npx tailwindcss -i static/wishlist/css/main.css -o ../static/core/css/output.css",