diff --git a/.github/workflows/dev-pipeline.yml b/.github/workflows/dev-pipeline.yml index 4446c5a3..c0de330f 100644 --- a/.github/workflows/dev-pipeline.yml +++ b/.github/workflows/dev-pipeline.yml @@ -1,10 +1,10 @@ -name: Dev Pipeline +name: Development Pipeline on: pull_request: - branches: [main] + branches: [dev] push: - branches: [main] + branches: [dev] jobs: deploy: @@ -26,8 +26,8 @@ jobs: export PATH=$HOME/.nvm/versions/node/v22.14.0/bin:$PATH echo $PATH cd ~/online-energieausweis - git reset --hard origin/main + git reset --hard origin/dev git clean -f -d - git pull origin main + git pull origin dev git status make prod \ No newline at end of file diff --git a/.github/workflows/prod-pipeline.yml b/.github/workflows/prod-pipeline.yml new file mode 100644 index 00000000..261b8b90 --- /dev/null +++ b/.github/workflows/prod-pipeline.yml @@ -0,0 +1,31 @@ +name: Production Pipeline + +on: + push: + branches: [main] + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Bun + run: | + curl -fsSL https://bun.sh/install | bash + + - uses: appleboy/ssh-action@master + with: + host: ${{ secrets.PROD_HOST }} + username: ${{ secrets.PROD_USERNAME }} + password: ${{ secrets.PROD_PASSWORD }} + port: 22 + script: | + export PATH=$HOME/.bun/bin:$PATH + export PATH=$HOME/.nvm/versions/node/v22.14.0/bin:$PATH + echo $PATH + cd ~/online-energieausweis + git reset --hard origin/main + git clean -f -d + git pull origin main + git status + make prod \ No newline at end of file diff --git a/backup-database.bash b/backup-database.bash index 420566aa..dca6ef52 100644 --- a/backup-database.bash +++ b/backup-database.bash @@ -2,20 +2,27 @@ FILE_NAME=data-dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql.br FILE_NAME_COMPLETE=full-dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql.br -# Wir exportieren die Datenbank und komprimieren sie. -docker exec -t online-energieausweis-database-1 pg_dump --data-only -U main main | brotli --best > $FILE_NAME -docker exec -t online-energieausweis-database-1 pg_dumpall -c -U main | brotli --best > $FILE_NAME_COMPLETE # Das wird benötigt für AWS Ionos Kompatibilität. export AWS_REQUEST_CHECKSUM_CALCULATION=when_required export AWS_RESPONSE_CHECKSUM_VALIDATION=when_required +# Wir exportieren die Datenbank und komprimieren sie. # IMPORTANT: Dieser Befehl benötigt das `ionos` Profil, sonst wird er nicht funktionieren. # Das Profil kann mit `aws configure --profile ionos` erstellt werden. # Den Key dafür findet man auf https://dcd.ionos.com/latest/?lang=en#/key-management +docker exec -t online-energieausweis-database-1 pg_dump --data-only -U main main | brotli --best > $FILE_NAME + aws s3 cp $FILE_NAME s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3-eu-central-1.ionoscloud.com --storage-class STANDARD + +echo "Uploaded $FILE_NAME" + +docker exec -t online-energieausweis-database-1 pg_dumpall -c -U main | brotli --best > $FILE_NAME_COMPLETE + aws s3 cp $FILE_NAME_COMPLETE s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3-eu-central-1.ionoscloud.com --storage-class STANDARD +echo "Uploaded $FILE_NAME_COMPLETE" + # Wir entfernen das Backup rm $FILE_NAME rm $FILE_NAME_COMPLETE \ No newline at end of file diff --git a/package.json b/package.json index 93239d0c..f2cc686e 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "postcss-import": "^16.1.0", "postcss-nesting": "^13.0.1", "prettier": "^2.8.8", - "prisma": "^6.4.1", + "prisma": "6.4.1", "prisma-dbml-generator": "^0.12.0", "prisma-generator-fake-data": "^0.14.3", "tsx": "^4.19.3", diff --git a/prisma/migrations/20250409152238_ausweis_id/migration.sql b/prisma/migrations/20250409152238_ausweis_id/migration.sql new file mode 100644 index 00000000..eb2b5b04 --- /dev/null +++ b/prisma/migrations/20250409152238_ausweis_id/migration.sql @@ -0,0 +1,17 @@ +-- AlterTable +ALTER TABLE "BedarfsausweisGewerbe" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'BedarfsausweisGewerbe'; + +-- AlterTable +ALTER TABLE "BedarfsausweisWohnen" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'BedarfsausweisWohnen'; + +-- AlterTable +ALTER TABLE "GEGNachweisGewerbe" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'GEGNachweisGewerbe'; + +-- AlterTable +ALTER TABLE "GEGNachweisWohnen" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'GEGNachweisWohnen'; + +-- AlterTable +ALTER TABLE "VerbrauchsausweisGewerbe" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'VerbrauchsausweisGewerbe'; + +-- AlterTable +ALTER TABLE "VerbrauchsausweisWohnen" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'VerbrauchsausweisWohnen'; diff --git a/prisma/schema/BedarfsausweisGewerbe.prisma b/prisma/schema/BedarfsausweisGewerbe.prisma index 476c21f7..bc4d983a 100644 --- a/prisma/schema/BedarfsausweisGewerbe.prisma +++ b/prisma/schema/BedarfsausweisGewerbe.prisma @@ -26,6 +26,7 @@ model BedarfsausweisGewerbe { klimatisierung Boolean? @default(false) nachweistyp AusweisTyp @default(Standard) + ausweisart Ausweisart @default(BedarfsausweisGewerbe) created_at DateTime @default(now()) updated_at DateTime @updatedAt @default(now()) diff --git a/prisma/schema/BedarfsausweisWohnen.prisma b/prisma/schema/BedarfsausweisWohnen.prisma index 3a05d2b5..e3074294 100644 --- a/prisma/schema/BedarfsausweisWohnen.prisma +++ b/prisma/schema/BedarfsausweisWohnen.prisma @@ -100,6 +100,7 @@ model BedarfsausweisWohnen { pruefpunkt_fenster Boolean? @default(false) ausweistyp AusweisTyp @default(Standard) + ausweisart Ausweisart @default(BedarfsausweisWohnen) benutzer Benutzer? @relation(fields: [benutzer_id], references: [id], onDelete: NoAction, onUpdate: NoAction) diff --git a/prisma/schema/GEGNachweisGewerbe.prisma b/prisma/schema/GEGNachweisGewerbe.prisma index 8bff4bdf..3a344706 100644 --- a/prisma/schema/GEGNachweisGewerbe.prisma +++ b/prisma/schema/GEGNachweisGewerbe.prisma @@ -17,6 +17,7 @@ model GEGNachweisGewerbe { beschreibung String? @db.Text nachweistyp AusweisTyp @default(Standard) + ausweisart Ausweisart @default(GEGNachweisGewerbe) created_at DateTime @default(now()) updated_at DateTime @updatedAt @default(now()) diff --git a/prisma/schema/GEGNachweisWohnen.prisma b/prisma/schema/GEGNachweisWohnen.prisma index 57a16db5..974b696c 100644 --- a/prisma/schema/GEGNachweisWohnen.prisma +++ b/prisma/schema/GEGNachweisWohnen.prisma @@ -17,6 +17,7 @@ model GEGNachweisWohnen { beschreibung String? @db.Text nachweistyp AusweisTyp @default(Standard) + ausweisart Ausweisart @default(GEGNachweisWohnen) created_at DateTime @default(now()) updated_at DateTime @updatedAt @default(now()) diff --git a/prisma/schema/VerbrauchsausweisGewerbe.prisma b/prisma/schema/VerbrauchsausweisGewerbe.prisma index 43811388..9281dd18 100644 --- a/prisma/schema/VerbrauchsausweisGewerbe.prisma +++ b/prisma/schema/VerbrauchsausweisGewerbe.prisma @@ -74,6 +74,7 @@ model VerbrauchsausweisGewerbe { updated_at DateTime @updatedAt @default(now()) ausweistyp AusweisTyp @default(Standard) + ausweisart Ausweisart @default(VerbrauchsausweisGewerbe) pruefpunkt_heizungsalter Boolean? @default(false) pruefpunkt_verbrauch_niedrig Boolean? @default(false) diff --git a/prisma/schema/VerbrauchsausweisWohnen.prisma b/prisma/schema/VerbrauchsausweisWohnen.prisma index a741aa90..2f93801c 100644 --- a/prisma/schema/VerbrauchsausweisWohnen.prisma +++ b/prisma/schema/VerbrauchsausweisWohnen.prisma @@ -75,6 +75,7 @@ model VerbrauchsausweisWohnen { kontrolldatei_angefragt Boolean? @default(false) ausweistyp AusweisTyp @default(Standard) + ausweisart Ausweisart @default(VerbrauchsausweisWohnen) created_at DateTime @default(now()) updated_at DateTime @updatedAt @default(now()) diff --git a/public/pdf/templates/GEG24_Nichtwohngebaeude.pdf b/public/pdf/templates/GEG24_Nichtwohngebaeude.pdf index c5734609..476ccc13 100644 Binary files a/public/pdf/templates/GEG24_Nichtwohngebaeude.pdf and b/public/pdf/templates/GEG24_Nichtwohngebaeude.pdf differ diff --git a/recover-db-dev.bash b/recover-db-dev.bash new file mode 100644 index 00000000..e7b58155 --- /dev/null +++ b/recover-db-dev.bash @@ -0,0 +1,41 @@ +#!/bin/bash + +# === Configuration === +BUCKET_NAME="ibc-db-backup" +ENDPOINT_URL="https://s3-eu-central-1.ionoscloud.com" +LOCAL_DOWNLOAD_DIR="./" # Where to save the file + +# === Get latest file from IONOS S3 bucket === +LATEST_FILE=$(aws s3api list-objects-v2 \ + --bucket "$BUCKET_NAME" \ + --prefix "data-dump" \ + --endpoint-url "$ENDPOINT_URL" \ + --query 'Contents | sort_by(@, &LastModified) | [-1].Key' \ + --output text) + +# === Check if file was found === +if [ "$LATEST_FILE" == "None" ] || [ -z "$LATEST_FILE" ]; then + echo "❌ No matching .sql.br file found." + exit 1 +fi + +FILENAME=$(basename "$LATEST_FILE") +SQL_FILE="${FILENAME%.br}" # Remove .br suffix + +echo "📥 Downloading $LATEST_FILE" +aws s3 cp "s3://$BUCKET_NAME/$LATEST_FILE" "$LOCAL_DOWNLOAD_DIR" \ + --endpoint-url "$ENDPOINT_URL" + +# === Decompress with Brotli === +echo "🗜️ Decompressing $FILENAME -> $SQL_FILE" +brotli -d "$FILENAME" + +# === Import into Postgres inside Docker === +echo "🐘 Importing into PostgreSQL (online-energieausweis-database-1:main)" +docker exec -i "online-energieausweis-database-1" env PGPASSWORD="hHMP8cd^N3SnzGRR" \ + psql -U "main" -d "main" < "$SQL_FILE" + +echo "✅ Import complete." + +# === Optional: Clean up +rm "$FILENAME" "$SQL_FILE" \ No newline at end of file diff --git a/src/astro-typesafe-api-caller.ts b/src/astro-typesafe-api-caller.ts deleted file mode 100644 index 89d66c9f..00000000 --- a/src/astro-typesafe-api-caller.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { createCallerFactory } from "astro-typesafe-api/server"; - -export const createCaller = createCallerFactory({ - "bild": await import("../src/pages/api/bild.ts"), - "klimafaktoren": await import("../src/pages/api/klimafaktoren.ts"), - "postleitzahlen": await import("../src/pages/api/postleitzahlen.ts"), - "unterlage": await import("../src/pages/api/unterlage.ts"), - "aufnahme": await import("../src/pages/api/aufnahme/index.ts"), - "admin/ausstellen": await import("../src/pages/api/admin/ausstellen.ts"), - "admin/bestellbestaetigung": await import("../src/pages/api/admin/bestellbestaetigung.ts"), - "admin/erinnern": await import("../src/pages/api/admin/erinnern.ts"), - "admin/nicht-ausstellen": await import("../src/pages/api/admin/nicht-ausstellen.ts"), - "admin/post-ausstellen": await import("../src/pages/api/admin/post-ausstellen.ts"), - "admin/registriernummer": await import("../src/pages/api/admin/registriernummer.ts"), - "admin/stornieren": await import("../src/pages/api/admin/stornieren.ts"), - "auth/access-token": await import("../src/pages/api/auth/access-token.ts"), - "auth/passwort-vergessen": await import("../src/pages/api/auth/passwort-vergessen.ts"), - "auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"), - "ausweise": await import("../src/pages/api/ausweise/index.ts"), - "aufnahme": await import("../src/pages/api/aufnahme/index.ts"), - "bedarfsausweis-gewerbe/[id]": await import("../src/pages/api/bedarfsausweis-gewerbe/[id].ts"), - "bedarfsausweis-gewerbe": await import("../src/pages/api/bedarfsausweis-gewerbe/index.ts"), - "bedarfsausweis-wohnen/[id]": await import("../src/pages/api/bedarfsausweis-wohnen/[id].ts"), - "bedarfsausweis-wohnen": await import("../src/pages/api/bedarfsausweis-wohnen/index.ts"), - "bilder/[id]": await import("../src/pages/api/bilder/[id].ts"), - "geg-nachweis-gewerbe/[id]": await import("../src/pages/api/geg-nachweis-gewerbe/[id].ts"), - "geg-nachweis-gewerbe": await import("../src/pages/api/geg-nachweis-gewerbe/index.ts"), - "geg-nachweis-wohnen/[id]": await import("../src/pages/api/geg-nachweis-wohnen/[id].ts"), - "geg-nachweis-wohnen": await import("../src/pages/api/geg-nachweis-wohnen/index.ts"), - "objekt": await import("../src/pages/api/objekt/index.ts"), - "rechnung/[id]": await import("../src/pages/api/rechnung/[id].ts"), - "rechnung/anfordern": await import("../src/pages/api/rechnung/anfordern.ts"), - "rechnung": await import("../src/pages/api/rechnung/index.ts"), - "ticket": await import("../src/pages/api/ticket/index.ts"), - "user": await import("../src/pages/api/user/index.ts"), - "user/self": await import("../src/pages/api/user/self.ts"), - "verbrauchsausweis-gewerbe/[id]": await import("../src/pages/api/verbrauchsausweis-gewerbe/[id].ts"), - "verbrauchsausweis-gewerbe": await import("../src/pages/api/verbrauchsausweis-gewerbe/index.ts"), - "verbrauchsausweis-wohnen/[id]": await import("../src/pages/api/verbrauchsausweis-wohnen/[id].ts"), - "verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"), - "webhooks/mollie": await import("../src/pages/api/webhooks/mollie.ts"), - "verbrauchsausweis-wohnen/[id]": await import("../src/pages/api/verbrauchsausweis-wohnen/[id].ts"), - "verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"), - "aufnahme/[id]/bilder": await import("../src/pages/api/aufnahme/[id]/bilder.ts"), - "aufnahme/[id]": await import("../src/pages/api/aufnahme/[id]/index.ts"), - "aufnahme/[id]/unterlagen": await import("../src/pages/api/aufnahme/[id]/unterlagen.ts"), - "objekt/[id]": await import("../src/pages/api/objekt/[id]/index.ts"), -}) \ No newline at end of file diff --git a/src/client/lib/ausweisSpeichern.ts b/src/client/lib/ausweisSpeichern.ts index 6362640d..3c93be7e 100644 --- a/src/client/lib/ausweisSpeichern.ts +++ b/src/client/lib/ausweisSpeichern.ts @@ -1,5 +1,4 @@ import { api } from "astro-typesafe-api/client"; -import { exclude } from "#lib/exclude.js"; import Cookies from "js-cookie"; import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js"; import { @@ -566,7 +565,7 @@ export async function ausweisSpeichern( return; } - aufnahme.id = aufnahme_id; + aufnahme.id = aufnahme_id as string; if (ausweisart == Enums.Ausweisart.VerbrauchsausweisWohnen) { const id = await verbrauchsausweisWohnenSpeichern( diff --git a/src/components/Ausweis/PerformanceScore.svelte b/src/components/Ausweis/PerformanceScore.svelte index a5dc68e0..5a40e520 100644 --- a/src/components/Ausweis/PerformanceScore.svelte +++ b/src/components/Ausweis/PerformanceScore.svelte @@ -1,5 +1,4 @@ -