Compare commits
6
Commits
8119aaad66
..
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a4026fb44 | ||
|
|
9f75b9b015 | ||
|
|
0e48f1e3fa | ||
|
|
476ecb3be1 | ||
|
|
173d6d2e61 | ||
|
|
409a02561d |
@@ -17,6 +17,43 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
|
||||
|
||||
### Sicherheit
|
||||
|
||||
## [1.0.0] – 2026-10-23
|
||||
|
||||
Erste stabile Fassung. Kein neuer Funktionsumfang gegenüber 0.27.1 – was fehlte, war Erprobung, und
|
||||
die ist erbracht:
|
||||
|
||||
- **Ein Lizenzjahr vollständig durchlaufen.** Für `hv-pve-01` und `hv-pve-02` (Robert Hofmann GmbH):
|
||||
Warnung vor dem Ablauf am 17.10.2026, Verlängerung, Proxmox-Rechnung 291017 mit Rabatt je Position,
|
||||
Kundenrechnung, beide bezahlt. Die Folgelaufzeiten stehen auf 17.10.2027.
|
||||
- **Proxmox Backup Server mit aktiver Lizenz bestätigt.** Drei PBS-Hosts melden Key und Ablaufdatum.
|
||||
- **Proxmox VE** ist seit dem Feldtest im September bestätigt: mit und ohne Subscription, einzeln und
|
||||
im Cluster, mit und ohne QDevice.
|
||||
- **Wiederherstellung geprobt** (#045): Daten zerstört, zurückgespielt, geprüft.
|
||||
|
||||
Im Betrieb seit dem 03.10.2026 mit 16 Hosts, vier Kunden und echten Rechnungen.
|
||||
|
||||
**Weiterhin ungeprüft:** Proxmox Mail Gateway – dort wird derzeit kein Host betrieben; der Zweig ist
|
||||
im Handbuch als ungeprüft gekennzeichnet (#023). Ebenso steht die Wiederherstellungsprobe für die
|
||||
Installation als Dienst noch aus; geprobt ist der Docker-Weg.
|
||||
|
||||
## [0.27.1] – 2026-10-23
|
||||
|
||||
### Sicherheit
|
||||
- **Next.js auf 16.4.2.** Für 16.0.0 bis 16.4.0 wurden drei Lücken gemeldet, zwei davon **kritisch**: Remote Code Execution über die Bildoptimierung mit SVG-Dateien (GHSA-2464-fhr4-w9xw), Remote Code Execution in `use cache` (GHSA-673q-mjm6-r5xr) und eine Blockade über Server Actions (GHSA-p3m5-59mp-jv5r)
|
||||
- ProxLedger nutzt weder `next/image` noch `use cache`; die Blockade über Server Actions betraf die Installation dagegen unmittelbar. **Wer öffentlich erreichbar ist, sollte sofort aktualisieren.**
|
||||
|
||||
## [0.27.0] – 2026-10-10
|
||||
|
||||
### Hinzugefügt
|
||||
- `deploy/restore.sh`: spielt Datenbank **und** hochgeladene PDFs aus einer Sicherung zurück, startet die Dienste und prüft die Erreichbarkeit (#045)
|
||||
|
||||
### Behoben
|
||||
- **Sicherungen ließen sich nur in eine leere Datenbank zurückspielen** – im Ernstfall also gerade nicht. `pg_dump` läuft jetzt mit `--clean --if-exists` (#045)
|
||||
- Für die hochgeladenen PDFs gab es keinen beschriebenen Weg zurück (#045)
|
||||
|
||||
### Dokumentation
|
||||
- `docs/betrieb/sicherung.md` beschreibt den **geprobten** Ablauf: Daten zerstört, zurückgespielt, geprüft (#045)
|
||||
|
||||
## [0.26.1] – 2026-10-10
|
||||
|
||||
### Sicherheit
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Zeitübersicht
|
||||
|
||||
**Gesamt:** 24 h 38 min
|
||||
**Gesamt:** 25 h 28 min
|
||||
|
||||
| Issue | Zeit |
|
||||
|---|---|
|
||||
@@ -50,6 +50,7 @@
|
||||
| #042 QDevice im Cluster | 0 h 20 min |
|
||||
| #043 Laufzeiten bearbeiten | 1 h 05 min |
|
||||
| #044 Eigenbedarf | 0 h 40 min |
|
||||
| #045 Wiederherstellung geprobt | 0 h 50 min |
|
||||
|
||||
| Meilenstein | Zeit |
|
||||
|---|---|
|
||||
@@ -72,7 +73,7 @@
|
||||
|
||||
## 2026-09-17 · Sitzung 1 · 19:36–laufend
|
||||
**Issue:** #001–#007 (Meilensteine v0.1.0 bis v0.4.0)
|
||||
**Version:** 0.26.1
|
||||
**Version:** 1.0.0
|
||||
|
||||
### Erledigt
|
||||
- Auftrag gelesen, Rückfragen gestellt
|
||||
@@ -228,6 +229,19 @@
|
||||
- `npm audit` turnusmäßig geprüft: zwei neue hohe Meldungen (`sharp`/librsvg, `source-map-js`). Beide angehoben, Tests und Build grün
|
||||
- Produktivinstanz antwortet: `https://proxledger.wilde-ste.de/api/gesundheit` meldet Datenbank erreichbar
|
||||
|
||||
- Wiederherstellung geprobt (#045): Daten zerstört, zurückgespielt, geprüft. Zwei Lücken kamen erst dabei heraus – ohne `--clean` ließ sich nur in eine leere Datenbank zurückspielen, und für die PDFs gab es gar keinen Weg
|
||||
- Damit ist einer der vier Punkte bis 1.0.0 erledigt. Offen bleiben PMG, PBS mit Lizenz und ein vollständiger Lizenzjahr-Durchlauf (17.10.)
|
||||
|
||||
### 23.10.2026 – Wartungsblick
|
||||
- `npm audit`: drei neue Meldungen zu Next.js ≤ 16.4.0, zwei davon kritisch (RCE über Bildoptimierung und `use cache`, dazu eine Blockade über Server Actions). Auf 16.4.2 angehoben, alles grün
|
||||
- Geprüft, was davon ProxLedger trifft: `next/image` und `use cache` werden nicht genutzt, Server Actions dagegen überall – die Blockade war also echt
|
||||
- Erinnerung an mich: Zwei Wartungsblicke in Folge haben hohe bis kritische Meldungen gefunden. Der wöchentliche Lauf in der CI ist überfällig
|
||||
|
||||
### 23.10.2026 – 1.0.0
|
||||
- Florian hat den Beleg geliefert: `hv-pve-01` und `hv-pve-02` sind verlängert, beide Rechnungen bezahlt, die Folgelaufzeiten stehen auf 17.10.2027. Dazu drei PBS-Hosts mit aktiver Lizenz
|
||||
- PMG wird zurückgestellt – kein Host im Betrieb. Die Lücke bleibt im Handbuch benannt, statt sie wegzudefinieren
|
||||
- Damit ist 1.0.0 gerechtfertigt: nicht weil nichts mehr fehlt, sondern weil das, was fehlte, erprobt wurde
|
||||
|
||||
### Nächster Schritt
|
||||
- #016 Benutzerhandbuch mit Screenshots, danach #017 Favicons und #019 CI-Pipeline
|
||||
- Für 1.0.0 fehlt noch: PMG (kein Host verfügbar) und der Fall „aktive Subscription auf PBS“ (#023)
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
Zentrales Dashboard für den Subscription-Status aller Proxmox-Hosts (VE, Backup Server, Mail Gateway).
|
||||
Auf jedem Host meldet ein schlanker Agent täglich per HTTPS seinen Status (Push-Modell) – auch aus Kundennetzen hinter NAT.
|
||||
|
||||
> **Status:** einsatzbereit. Der Agent ist auf echten Hosts erprobt – Proxmox VE 9.2 mit und ohne
|
||||
> Subscription, im Cluster und einzeln, sowie Proxmox Backup Server 4.2 (#018, #023).
|
||||
> Ungeprüft: Mail Gateway und eine aktive Subscription auf PBS. Was bis 1.0 fehlt, steht in
|
||||
> [docs/roadmap.md](docs/roadmap.md).
|
||||
> **Status: 1.0.0 – im produktiven Einsatz.** Seit dem 03.10.2026 mit echten Daten in Betrieb; ein
|
||||
> Lizenzjahr ist vollständig durchlaufen (Warnung → Verlängerung → Einkauf → Kundenrechnung → bezahlt).
|
||||
> Erprobt auf Proxmox VE 9.2 mit und ohne Subscription, einzeln und im Cluster, sowie auf Proxmox
|
||||
> Backup Server 4.2 mit und ohne Lizenz. **Ungeprüft:** Mail Gateway – dort wird derzeit kein Host
|
||||
> betrieben. Was als Nächstes ansteht, steht in [docs/roadmap.md](docs/roadmap.md).
|
||||
|
||||
## Schnellstart
|
||||
|
||||
|
||||
+3
-2
@@ -30,7 +30,8 @@ echo "Sichere ProxLedger (${ART}) nach ${ZIEL} …"
|
||||
|
||||
if [ "$ART" = "docker" ]; then
|
||||
echo "Sichere Datenbank …"
|
||||
docker compose exec -T postgres pg_dump -U "${POSTGRES_USER:-proxledger}" "${POSTGRES_DB:-proxledger}" \
|
||||
docker compose exec -T postgres pg_dump --clean --if-exists \
|
||||
-U "${POSTGRES_USER:-proxledger}" "${POSTGRES_DB:-proxledger}" \
|
||||
| gzip > "${ZIEL}/datenbank-${STAND}.sql.gz"
|
||||
|
||||
echo "Sichere hochgeladene Dateien …"
|
||||
@@ -48,7 +49,7 @@ else
|
||||
}
|
||||
|
||||
echo "Sichere Datenbank …"
|
||||
pg_dump "$DATABASE_URL" | gzip > "${ZIEL}/datenbank-${STAND}.sql.gz"
|
||||
pg_dump --clean --if-exists "$DATABASE_URL" | gzip > "${ZIEL}/datenbank-${STAND}.sql.gz"
|
||||
|
||||
echo "Sichere hochgeladene Dateien …"
|
||||
UPLOADS="${UPLOAD_DIR:-${VERZEICHNIS}/data/uploads}"
|
||||
|
||||
Executable
+127
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env bash
|
||||
# ProxLedger aus einer Sicherung wiederherstellen (#046).
|
||||
#
|
||||
# bash deploy/restore.sh /var/backups/proxledger # jüngste Sicherung
|
||||
# bash deploy/restore.sh /var/backups/proxledger 20261010-192437
|
||||
# bash deploy/restore.sh … --ja # ohne Rückfrage
|
||||
#
|
||||
# Spielt Datenbank und hochgeladene PDFs zurück. Die `.env` wird **nicht** angefasst:
|
||||
# Sie trägt APP_SECRET, und ein falscher Wert dort macht gespeicherte Zugangsdaten unlesbar.
|
||||
# Die passende Fassung liegt als env-<Stand>.txt in der Sicherung – im Zweifel von Hand vergleichen.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
VERZEICHNIS=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
cd "$VERZEICHNIS"
|
||||
|
||||
blau() { printf '\033[1;36m› %s\033[0m\n' "$*"; }
|
||||
gruen() { printf '\033[1;32m✓ %s\033[0m\n' "$*"; }
|
||||
fehler() {
|
||||
printf '\033[1;31m✗ %s\033[0m\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
QUELLE="${1:-/var/backups/proxledger}"
|
||||
STAND="${2:-}"
|
||||
[ "${2:-}" = "--ja" ] && STAND=""
|
||||
OHNE_RUECKFRAGE="nein"
|
||||
for argument in "$@"; do [ "$argument" = "--ja" ] && OHNE_RUECKFRAGE="ja"; done
|
||||
|
||||
[ -d "$QUELLE" ] || fehler "Kein Sicherungsordner unter ${QUELLE}."
|
||||
|
||||
# Jüngste Sicherung nehmen, wenn kein Stand angegeben ist.
|
||||
if [ -z "$STAND" ]; then
|
||||
DATENBANK=$(ls -1t "${QUELLE}"/datenbank-*.sql.gz 2>/dev/null | head -n1 || true)
|
||||
else
|
||||
DATENBANK="${QUELLE}/datenbank-${STAND}.sql.gz"
|
||||
fi
|
||||
|
||||
[ -n "${DATENBANK:-}" ] && [ -f "$DATENBANK" ] || fehler "Keine Datenbanksicherung in ${QUELLE} gefunden."
|
||||
UPLOADS="${DATENBANK/datenbank-/uploads-}"
|
||||
UPLOADS="${UPLOADS/.sql.gz/.tar.gz}"
|
||||
|
||||
# Siehe deploy/update.sh – der Dienst ist das eindeutigere Merkmal.
|
||||
if systemctl cat proxledger.service >/dev/null 2>&1; then
|
||||
ART="dienst"
|
||||
else
|
||||
ART="docker"
|
||||
fi
|
||||
|
||||
printf '\033[1;33m! Achtung: Der aktuelle Datenbestand wird durch die Sicherung ersetzt.\033[0m\n'
|
||||
echo " Installationsart: ${ART}"
|
||||
echo " Datenbank: $(basename "$DATENBANK")"
|
||||
echo " Uploads: $([ -f "$UPLOADS" ] && basename "$UPLOADS" || echo 'keine in dieser Sicherung')"
|
||||
|
||||
if [ "$OHNE_RUECKFRAGE" != "ja" ]; then
|
||||
read -r -p "Wirklich zurückspielen? [tippen Sie ja] " antwort
|
||||
[ "$antwort" = "ja" ] || fehler "Abgebrochen."
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------- Datenbank
|
||||
blau "Datenbank zurückspielen …"
|
||||
if [ "$ART" = "docker" ]; then
|
||||
# Web und Worker anhalten: Sie würden während des Einspielens weiterschreiben.
|
||||
docker compose stop web worker >/dev/null 2>&1 || true
|
||||
docker compose up -d postgres >/dev/null
|
||||
# Kurz warten, bis Postgres Verbindungen annimmt.
|
||||
for _ in $(seq 1 30); do
|
||||
docker compose exec -T postgres pg_isready -U "${POSTGRES_USER:-proxledger}" >/dev/null 2>&1 && break
|
||||
sleep 1
|
||||
done
|
||||
gunzip -c "$DATENBANK" | docker compose exec -T postgres psql -U "${POSTGRES_USER:-proxledger}" \
|
||||
-d "${POSTGRES_DB:-proxledger}" >/dev/null
|
||||
else
|
||||
systemctl stop proxledger proxledger-worker >/dev/null 2>&1 || true
|
||||
# shellcheck disable=SC1091
|
||||
set -o allexport
|
||||
. ./.env
|
||||
set +o allexport
|
||||
[ -n "${DATABASE_URL:-}" ] || fehler "DATABASE_URL fehlt in der .env."
|
||||
gunzip -c "$DATENBANK" | psql "$DATABASE_URL" >/dev/null
|
||||
fi
|
||||
gruen "Datenbank zurückgespielt."
|
||||
|
||||
# ---------------------------------------------------------------- Uploads
|
||||
if [ -f "$UPLOADS" ]; then
|
||||
blau "Hochgeladene PDFs zurückspielen …"
|
||||
if [ "$ART" = "docker" ]; then
|
||||
# Das Archiv enthält den Pfad /data/uploads – deshalb nach / entpacken.
|
||||
docker compose run --rm -T --entrypoint tar web -xzf - -C / < "$UPLOADS"
|
||||
else
|
||||
ZIEL_UPLOADS="${UPLOAD_DIR:-${VERZEICHNIS}/data/uploads}"
|
||||
mkdir -p "$(dirname "$ZIEL_UPLOADS")"
|
||||
tar -xzf "$UPLOADS" -C "$(dirname "$ZIEL_UPLOADS")"
|
||||
fi
|
||||
gruen "PDFs zurückgespielt."
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------- Starten und prüfen
|
||||
blau "Dienste starten …"
|
||||
if [ "$ART" = "docker" ]; then
|
||||
docker compose up -d >/dev/null
|
||||
else
|
||||
systemctl start proxledger proxledger-worker
|
||||
fi
|
||||
|
||||
PORT="${PORT:-3000}"
|
||||
for versuch in $(seq 1 45); do
|
||||
if [ "$ART" = "docker" ]; then
|
||||
erreichbar=$(docker compose exec -T web wget -qO- "http://127.0.0.1:3000/api/gesundheit" >/dev/null 2>&1 && echo ja || echo nein)
|
||||
else
|
||||
erreichbar=$(curl -fsS -o /dev/null --max-time 2 "http://localhost:${PORT}/api/gesundheit" && echo ja || echo nein)
|
||||
fi
|
||||
|
||||
if [ "$erreichbar" = "ja" ]; then
|
||||
gruen "ProxLedger läuft wieder (nach ${versuch} s)."
|
||||
echo
|
||||
echo "Bitte jetzt anmelden und stichprobenartig prüfen, ob die Daten vollständig sind."
|
||||
echo "Passt das Passwort nicht, stammt die Sicherung aus einer Zeit vor der letzten Änderung –"
|
||||
echo "dann hilft: npm run benutzer -- passwort <email>"
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
fehler "Das Dashboard antwortet nicht. Protokoll ansehen: docker compose logs -n 50 web"
|
||||
@@ -27,19 +27,51 @@ ruft es als Erstes auf und bricht ab, wenn es fehlschlägt.
|
||||
## Zurückspielen
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker compose down
|
||||
docker compose up -d postgres
|
||||
gunzip -c sicherung.sql.gz | docker compose exec -T postgres psql -U proxledger proxledger
|
||||
bash deploy/restore.sh /var/backups/proxledger # jüngste Sicherung
|
||||
bash deploy/restore.sh /var/backups/proxledger 20261010-192437 # bestimmter Stand
|
||||
```
|
||||
|
||||
Das Skript hält Dashboard und Worker an, spielt Datenbank **und** hochgeladene PDFs zurück, startet
|
||||
alles wieder und prüft, ob das Dashboard antwortet. Vorher fragt es nach; `--ja` überspringt die
|
||||
Rückfrage (für Skripte).
|
||||
|
||||
Die `.env` fasst es bewusst **nicht** an: Sie trägt `APP_SECRET`, und ein falscher Wert dort macht die
|
||||
gespeicherten Zugangsdaten für SMTP und Webhook unlesbar. Die zum Stand passende Fassung liegt als
|
||||
`env-<Stand>.txt` in der Sicherung – im Zweifel von Hand vergleichen.
|
||||
|
||||
### Von Hand, wenn es sein muss
|
||||
|
||||
```bash
|
||||
docker compose stop web worker
|
||||
gunzip -c datenbank-20261010-192437.sql.gz | docker compose exec -T postgres psql -U proxledger proxledger
|
||||
docker compose run --rm -T --entrypoint tar web -xzf - -C / < uploads-20261010-192437.tar.gz
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Danach die `.env` mit **demselben** `APP_SECRET` zurücklegen wie zum Zeitpunkt der Sicherung. Ein
|
||||
anderer Wert lässt die gespeicherten Zugangsdaten unlesbar werden; das Dashboard sagt das beim
|
||||
nächsten Versand deutlich, aber die Werte müssen dann neu eingetragen werden.
|
||||
Bei der Installation als Dienst stattdessen `psql "$DATABASE_URL"` und `tar -xzf … -C /opt/proxledger/data`.
|
||||
|
||||
## Geprobt am 10.10.2026
|
||||
|
||||
Nicht behauptet, sondern durchgespielt – mit einem eigenen Stapel:
|
||||
|
||||
1. Stand festgehalten (9 Hosts, 4 Kunden, 10 Laufzeiten), ein Kunde zur Wiedererkennung umbenannt,
|
||||
eine PDF-Datei abgelegt
|
||||
2. Sicherung angelegt
|
||||
3. **Alle Daten zerstört** (`docker compose down -v` – Datenbank und Upload-Volume weg)
|
||||
4. `deploy/restore.sh` aufgerufen
|
||||
|
||||
Ergebnis: Datenbank vollständig zurück (die umbenannte Kundin war wieder da), die PDF-Datei lag mit
|
||||
den richtigen Rechten im Upload-Ordner, Anmeldung mit dem alten Passwort funktionierte.
|
||||
|
||||
Dabei zwei Lücken gefunden und geschlossen: Die Sicherung ließ sich nur in eine **leere** Datenbank
|
||||
zurückspielen (jetzt `pg_dump --clean --if-exists`), und für die hochgeladenen PDFs gab es überhaupt
|
||||
keinen beschriebenen Weg.
|
||||
|
||||
> Geprobt wurde der Docker-Weg. Für die Installation als Dienst ist derselbe Ablauf im Skript
|
||||
> vorgesehen, aber noch nicht unter echten Bedingungen gelaufen.
|
||||
|
||||
## Das Wichtigste
|
||||
|
||||
**Eine Sicherung, die nie zurückgespielt wurde, ist keine Sicherung.** Spielen Sie sie einmal in eine
|
||||
leere Testumgebung ein und melden Sie sich dort an. Erst dann wissen Sie, dass Sicherung und
|
||||
`APP_SECRET` zusammenpassen.
|
||||
Testumgebung ein und melden Sie sich dort an. Erst dann wissen Sie, dass Sicherung und `APP_SECRET`
|
||||
zusammenpassen.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# #023 Feldtest auf Proxmox Backup Server und Mail Gateway
|
||||
**Status:** offen
|
||||
**Status:** erledigt
|
||||
**Meilenstein:** v1.0.0
|
||||
**Labels:** agent, feldtest
|
||||
**Geschätzt:** 2 h **Tatsächlich:** 0 h 35 min (PBS erledigt, PMG offen)
|
||||
**Geschätzt:** 2 h **Tatsächlich:** 0 h 35 min
|
||||
|
||||
## Ziel
|
||||
Der Feldtest in #018 lief auf zwei Proxmox-VE-Hosts. Für Backup Server und Mail Gateway beruht die
|
||||
@@ -23,7 +23,7 @@ falsch erwiesen (`--output-format json` gibt es dort nicht). Das gehört vor 1.0
|
||||
- [x] Erhobene Ausgaben als Testfälle in `tests/agent-skript.test.ts` aufnehmen – der heutige
|
||||
PBS-Testfall ist erfunden (JSON) und damit womöglich am echten Verhalten vorbei
|
||||
- [x] Agent auf einem PBS-Host installieren, einen Report abwarten, wieder deinstallieren
|
||||
- [ ] PMG offen lassen und die Lücke im Handbuch benennen
|
||||
- [x] PMG: von Florian am 23.10.2026 zurückgestellt – wird derzeit nicht betrieben, die Lücke bleibt im Handbuch benannt
|
||||
|
||||
## Notizen
|
||||
Der Cluster-Abgleich aus #022 betrifft nur PVE: PBS und PMG kennen kein `pvecm`, dort bleibt die
|
||||
@@ -67,3 +67,14 @@ ist auch der letzte offene Punkt aus #018 erledigt.
|
||||
|
||||
**Weiterhin offen:** PMG (kein Host) und der Fall „aktive Subscription auf PBS“ (nur unlizenzierte
|
||||
Hosts verfügbar). Dieses Issue bleibt deshalb offen.
|
||||
|
||||
## Abschluss am 23.10.2026
|
||||
|
||||
**PBS mit aktiver Lizenz: bestätigt.** In der produktiven Installation melden `pbs-cloud-01`,
|
||||
`bup-pbs-01` und `bup-lwwif-pbs-01` ihre `pbsb-…`-Keys samt Ablaufdatum (04.10.2027). Damit ist auch
|
||||
der lizenzierte Fall auf Proxmox Backup Server belegt – nach dem Fund der Rahmentabelle (#037) war
|
||||
das der letzte offene Punkt dieses Produktzweigs.
|
||||
|
||||
**PMG: zurückgestellt.** Florian betreibt derzeit kein Mail Gateway; der Feldtest entfällt bis auf
|
||||
Weiteres. Im Handbuch steht weiterhin, dass dieser Zweig ungeprüft ist und der erste PMG-Host nach
|
||||
der Installation einmal gegenzuprüfen gehört (`proxledger-agent --dry-run`).
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# #045 Wiederherstellung proben und Skript dafür
|
||||
**Status:** erledigt
|
||||
**Meilenstein:** v0.27.0
|
||||
**Labels:** deployment, doku
|
||||
**Geschätzt:** 2 h **Tatsächlich:** 0 h 50 min
|
||||
|
||||
## Ziel
|
||||
Einer der vier Punkte bis 1.0.0: eine Sicherung **einmal wirklich zurückspielen**. Bis dahin war nur
|
||||
geprüft, dass `deploy/backup.sh` Dateien schreibt.
|
||||
|
||||
## Ablauf der Probe
|
||||
Mit einem eigenen Docker-Stapel, getrennt von allen anderen Daten:
|
||||
|
||||
1. Datenstand festgehalten (9 Hosts, 4 Kunden, 10 Laufzeiten), einen Kunden zur Wiedererkennung in
|
||||
`Marke-192641` umbenannt, eine PDF-Datei in den Upload-Ordner gelegt
|
||||
2. Sicherung angelegt
|
||||
3. **Alle Daten zerstört** – `docker compose down -v`, also Datenbank- und Upload-Volume weg
|
||||
4. Zurückgespielt und geprüft
|
||||
|
||||
**Ergebnis:** Datenbank vollständig zurück (die Marke war wieder da), die PDF-Datei lag mit den
|
||||
richtigen Rechten im Upload-Ordner, Anmeldung mit dem alten Passwort funktionierte.
|
||||
|
||||
## Zwei Lücken, die erst die Probe gezeigt hat
|
||||
1. **Die Sicherung ließ sich nur in eine leere Datenbank zurückspielen.** `pg_dump` ohne `--clean`
|
||||
scheitert an bestehenden Tabellen – genau im Ernstfall, wenn man in eine laufende Installation
|
||||
zurückspielen will. Jetzt `--clean --if-exists`; gegengeprüft gegen eine Datenbank mit Daten:
|
||||
null Fehlerzeilen, der zwischenzeitlich geänderte Wert war wieder auf dem Stand der Sicherung.
|
||||
2. **Für die hochgeladenen PDFs gab es keinen beschriebenen Weg.** Gesichert wurden sie, zurückspielen
|
||||
musste man selbst herausfinden.
|
||||
|
||||
## Ergebnis
|
||||
- `deploy/restore.sh`: hält die Dienste an, spielt Datenbank und PDFs zurück, startet wieder und prüft
|
||||
die Erreichbarkeit. Fragt vorher nach, `--ja` überspringt das.
|
||||
- Die `.env` wird bewusst **nicht** überschrieben: Sie trägt `APP_SECRET`, und ein falscher Wert dort
|
||||
macht die gespeicherten Zugangsdaten unlesbar. Die passende Fassung liegt als `env-<Stand>.txt` daneben.
|
||||
- `docs/betrieb/sicherung.md` beschreibt den geprobten Ablauf samt Handarbeit als Rückfallebene.
|
||||
|
||||
## Offen
|
||||
Geprobt wurde der Docker-Weg. Für die Installation als Dienst ist derselbe Ablauf im Skript
|
||||
vorgesehen, aber noch nicht unter echten Bedingungen gelaufen.
|
||||
@@ -26,7 +26,7 @@ Details und Architektur: [../architektur.md](../architektur.md). Zeiten werden a
|
||||
| [#020](020-gitea-issue-abgleich.md) | Issues nach Gitea übertragen | erledigt | v0.4.1 | 2 h | 0 h 10 min |
|
||||
| [#021](021-geheimnisse-verschluesseln.md) | Zugangsdaten verschlüsselt speichern | erledigt | v0.13.1 | 2 h | 0 h 20 min |
|
||||
| [#022](022-cluster-abgleich.md) | Cluster-Abgleich | erledigt | v0.14.0 | 3 h | 0 h 25 min |
|
||||
| [#023](023-feldtest-pbs-pmg.md) | Feldtest auf PBS und PMG | offen | v1.0.0 | 2 h | 0 h 35 min (PBS erledigt, PMG offen) |
|
||||
| [#023](023-feldtest-pbs-pmg.md) | Feldtest auf PBS und PMG | erledigt | v1.0.0 | 2 h | 0 h 35 min |
|
||||
| [#024](024-owasp-haertung.md) | Härtung nach OWASP | erledigt | v0.15.0 | 4 h | 0 h 45 min |
|
||||
| [#025](025-einstellungen.md) | Einstellungen im Dashboard | erledigt | v0.16.0 | 5 h | 1 h 10 min |
|
||||
| [#026](026-auslieferung.md) | Auslieferung finalisieren | erledigt | v0.17.0 | 3 h | 0 h 40 min |
|
||||
@@ -48,4 +48,5 @@ Details und Architektur: [../architektur.md](../architektur.md). Zeiten werden a
|
||||
| [#042](042-qdevice-cluster.md) | Cluster-Knoten falsch gelesen bei QDevice | erledigt | v0.24.1 | 1 h | 0 h 20 min |
|
||||
| [#043](043-laufzeiten-bearbeiten.md) | Laufzeiten anlegen, bearbeiten, zusammenführen | erledigt | v0.25.0 | 4 h | 1 h 05 min |
|
||||
| [#044](044-eigenbedarf.md) | Eigene Hosts ohne Weiterberechnung | erledigt | v0.26.0 | 2 h | 0 h 40 min |
|
||||
| | **Summe** | | | **175 h** | **24 h 38 min** |
|
||||
| [#045](045-wiederherstellung-geprobt.md) | Wiederherstellung proben und Skript dafür | erledigt | v0.27.0 | 2 h | 0 h 50 min |
|
||||
| | **Summe** | | | **177 h** | **25 h 28 min** |
|
||||
|
||||
+19
-6
@@ -1,6 +1,6 @@
|
||||
# Roadmap
|
||||
|
||||
Stand: 04.10.2026, Fassung 0.26.0
|
||||
Stand: 23.10.2026, Fassung 1.0.0
|
||||
|
||||
Die erste Fassung dieser Roadmap entstand vor dem produktiven Einsatz. Seitdem läuft ProxLedger mit
|
||||
echten Daten, und das hat die Reihenfolge deutlich verändert: Was aus der Benutzung kam, war fast
|
||||
@@ -18,15 +18,28 @@ Stellen.
|
||||
|
||||
---
|
||||
|
||||
## Bis 1.0.0
|
||||
## 1.0.0 ist erreicht (23.10.2026)
|
||||
|
||||
Kein neuer Funktionsumfang – es fehlt Erprobung.
|
||||
Alle Kriterien erfüllt:
|
||||
|
||||
| Punkt | Warum | Aufwand |
|
||||
|---|---|---|
|
||||
| Punkt | Stand |
|
||||
|---|---|
|
||||
| Ein Lizenzjahr vollständig durchlaufen | **erledigt** – `hv-pve-01` und `hv-pve-02` am 17.10.2026, beide Rechnungen bezahlt |
|
||||
| PBS mit aktiver Lizenz | **erledigt** – drei PBS-Hosts melden Key und Ablauf |
|
||||
| Sicherung zurückspielen | **erledigt** ([#045](issues/045-wiederherstellung-geprobt.md)) |
|
||||
| PMG im Feldtest | **zurückgestellt** – wird derzeit nicht betrieben ([#023](issues/023-feldtest-pbs-pmg.md)) |
|
||||
|
||||
Zwei kleinere Punkte bleiben offen, keiner davon hält 1.0.0 auf:
|
||||
|
||||
- Die Wiederherstellungsprobe für die **Installation als Dienst** (geprobt ist der Docker-Weg).
|
||||
- Ein **wöchentlicher `npm audit`-Lauf in der CI**. Zwei Wartungsblicke hintereinander haben hohe bis
|
||||
kritische Meldungen gefunden – zuletzt zwei kritische Lücken in Next.js. Bei einem öffentlich
|
||||
erreichbaren Dashboard gehört das automatisiert.
|
||||
|
||||
---|---|---|
|
||||
| **PMG im Feldtest** ([#023](issues/023-feldtest-pbs-pmg.md)) | Der einzige Produktzweig ohne echten Host. Bei PBS lag die Annahme daneben, und der Agent hätte dort nichts gemeldet. | 1 h, sobald ein Host da ist |
|
||||
| **PBS mit aktiver Lizenz** | Bisher nur „keine Subscription“ geprüft. | 30 min |
|
||||
| **Sicherung einmal zurückspielen** | Eine Sicherung, die nie zurückgespielt wurde, ist keine. | 30 min |
|
||||
| ~~Sicherung einmal zurückspielen~~ | **Erledigt am 10.10.2026** ([#045](issues/045-wiederherstellung-geprobt.md)) – dabei kamen zwei Lücken heraus. Offen bleibt die Probe für die Installation als Dienst. | – |
|
||||
| **Ein Lizenzjahr durchlaufen lassen** | Warnung → Verlängerung → Einkauf → Kundenrechnung → bezahlt, einmal vollständig in echt. Die nächsten Abläufe stehen am 17.10.2026 an. | nur Zeit |
|
||||
|
||||
---
|
||||
|
||||
Generated
+51
-51
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "proxledger",
|
||||
"version": "0.26.0",
|
||||
"version": "0.27.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "proxledger",
|
||||
"version": "0.26.0",
|
||||
"version": "0.27.0",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@node-rs/argon2": "^2.2.1",
|
||||
@@ -20,7 +20,7 @@
|
||||
"bootstrap-icons": "^1.13.1",
|
||||
"croner": "^10.0.1",
|
||||
"jose": "^6.2.12",
|
||||
"next": "^16.4.0",
|
||||
"next": "^16.4.2",
|
||||
"nodemailer": "^10.0.10",
|
||||
"openid-client": "^6.8.8",
|
||||
"react": "19.2.8",
|
||||
@@ -35,7 +35,7 @@
|
||||
"dotenv": "^17.4.2",
|
||||
"esbuild": "^0.28.2",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "^16.4.0",
|
||||
"eslint-config-next": "^16.4.2",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"prettier": "^3.9.7",
|
||||
"prisma": "^7.10.0",
|
||||
@@ -1646,15 +1646,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.4.0.tgz",
|
||||
"integrity": "sha512-pyLlT5oafGlX8X7xjgGNXz5dNIDSxREm+qD6i9VLSZiZFopA/XWl8NM/KPmLx/8EG/++c49iid3gNWSQW1+2dQ==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.4.2.tgz",
|
||||
"integrity": "sha512-nTUTFH7G5/J/fmpkjVLegOkqyKOP0CEsJcMsyO4UCYeN1su+YMW/MfaSErnJskL7XM+UDK6aTvslxsRCyya/sA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@next/eslint-plugin-next": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.4.0.tgz",
|
||||
"integrity": "sha512-ffeflB/dL8RrvWejQximw01pOpKHN692Y3FjDB82DCd0YVvXvBD6vY7mcZp27yvSVFVM6wA73xVodEKF4spizA==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.4.2.tgz",
|
||||
"integrity": "sha512-gCTWlw0e+Y6kajpFyKKgA195jUJCRhlzJE0lV7ufe8a+ghIsANWZ0/FiJwg6DuOG1+OvRbcZDcFBoRh3mNJx0g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1695,9 +1695,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-arm64": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.4.0.tgz",
|
||||
"integrity": "sha512-yyZ+9MgViAKLLb5l1gPBGjRwnq3teNLb5Zx6JEw8LzNSTjlsnp+baUHFxTgl7PpjCmKf48VQfyipG1eBflb48Q==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.4.2.tgz",
|
||||
"integrity": "sha512-ONkhFvZNFWlsEHOM/81AtxdyuJP2KRYKYR0JxPwvcu1AuPMMMgcL+wW2luldJvMtZwKtUxoSkCychW5wIeoYSw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1711,9 +1711,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-x64": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.4.0.tgz",
|
||||
"integrity": "sha512-RePEEejEj1Auf5s9qEcG0JbcDP3ceNUS/ofNX8AhxzgIjTVlZIHMatlp16YplcSMpsVo/ZMQHJTjbMYJznjGUg==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.4.2.tgz",
|
||||
"integrity": "sha512-luPCMbOsCoaF+kXJEUjmjmOZg1lC3BflhmUu+ZmW4tBu2vW/4AXak8JBFvePizGkxVmNiAw/r9ra+6UviCWtWQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1727,9 +1727,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.4.0.tgz",
|
||||
"integrity": "sha512-HhsyCqd+NpmvDDVY/LqkAN24f+QVvXh3ie+PfcwKinWL2Mu826JymQxJXGjAIfmJ4VlHjp4Pe/nZtXtUoEMAqw==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.4.2.tgz",
|
||||
"integrity": "sha512-xhwFTAncJyaCNy5KqKKuKaIIdCy1/1ZV1s5S1G0hhT7wGMkDTlfJ6aQbfRFnIG/s3/kDrxQ8aycVe+c5QnP8ow==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1746,9 +1746,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-musl": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.4.0.tgz",
|
||||
"integrity": "sha512-sN9Pf+Zh+RpZAOmbR7d8KAA8T61CVhawtbEJ2Bk6QrRzx6Z/6haaF4UiwBzytM96GRRRWZh9/WALIEO3npMamA==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.4.2.tgz",
|
||||
"integrity": "sha512-T1PNmfbPcxr5ndtWUL/3wQtLXsz808lq6sc2GrNT5k2oquF7UyqZddHSuAewHVsWsGXe6nsl9HoN1YNriVjuSg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1765,9 +1765,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-gnu": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.4.0.tgz",
|
||||
"integrity": "sha512-D5M5xLWQVd1CvR+L7BickM1weRfmM41x3L1NWcnKY/oyJJqr1qwaCgmu3dMAhLBOMdZwSuDCRV6DJRRpiUkbDQ==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.4.2.tgz",
|
||||
"integrity": "sha512-N9cDUOCGtkJG5PNKDFZUF3xXndrJJcpLp121uAGjIGvO/U2p9tfdNOM9htj7+5f72l0m8rMw/cvYacUJBQoudg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1784,9 +1784,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-musl": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.4.0.tgz",
|
||||
"integrity": "sha512-8d5WLS6a9YalqpOgXdlbvonFu+sIgjA+CO6tGzetrpPVcUL56foa7B7664h41rAlbLi5fJwK4vWji3zf4QDy+w==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.4.2.tgz",
|
||||
"integrity": "sha512-yY2uh1YhX6ufuYy2FCbw1dqblbhI57GLYAJfCkqD9auTv6pLrH67Uccjc3QMKBeCYAG6lkgu08ExmX1bbjejjQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1803,9 +1803,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.4.0.tgz",
|
||||
"integrity": "sha512-sQuOIiW3snb48UwrBcDMvFA/u03qtw2LeuSIxFIQ9AJuW9UG/4Ddsfo+eV73PnZwBhyncMtsKVh7PrzMol2/fA==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.4.2.tgz",
|
||||
"integrity": "sha512-j/ArWRIHpMMB6wYLMhr2puTguBt70lNU/Cmjl9p6dTDE8DGknYJMP9PdwPk2dqpCNL/KIX9yfngDvIesxJPmsg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1819,9 +1819,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-x64-msvc": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.4.0.tgz",
|
||||
"integrity": "sha512-6/33lCuxpdHUy27RegyGM/5uTpF7YZd3UR4D0gpkOA/tWY5YR7msbQjqPgCZmSmxrrTLGCXYA4A8vT2H5DPGTQ==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.4.2.tgz",
|
||||
"integrity": "sha512-AA4edyWHDko3NCSo0x6GomsdgFb0oR1J3MXU1b5xt6FRFg4AucrMPW3S0hCe/9onU0O1BbpGQBsqo1r0Gneu1g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -5889,13 +5889,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-config-next": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.4.0.tgz",
|
||||
"integrity": "sha512-2RHLYswzc+hNRktWAjIL6XAvwb1cKcjLawJ5KWywAxn/JivNHtG42ZigL1yobVXDqsimuuL2F9jcEcnHFzbppQ==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.4.2.tgz",
|
||||
"integrity": "sha512-P33vjcETMXc+qBjpF77TeJHZLzk6cPcTy8KjpxLucYB3mCIFIORMcZ+cBXcAiIYjE5RM7jyknEEOwMNdnx/ADQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@next/eslint-plugin-next": "16.4.0",
|
||||
"@next/eslint-plugin-next": "16.4.2",
|
||||
"eslint-import-resolver-node": "^0.3.6",
|
||||
"eslint-import-resolver-typescript": "^3.5.2",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
@@ -8184,12 +8184,12 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/next": {
|
||||
"version": "16.4.0",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-16.4.0.tgz",
|
||||
"integrity": "sha512-N2C+9q89Z/oLrsepSRS4jRMtwmUZAoZuAHU0e9T6+sAB5DdhADmrnOW+zjYijlrYFmVfmQhGVGy9eMFoB7UgKg==",
|
||||
"version": "16.4.2",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-16.4.2.tgz",
|
||||
"integrity": "sha512-r+oBJojfefUjOiWkBhXgLS+igxX/7BWyK59uHnyOyplMSLtBZ+QLP3okrdYTbrfrbrmNTVWLBPaHDX9KRaIt3w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@next/env": "16.4.0",
|
||||
"@next/env": "16.4.2",
|
||||
"@swc/helpers": "0.5.23",
|
||||
"baseline-browser-mapping": "^2.9.19",
|
||||
"caniuse-lite": "^1.0.30001579",
|
||||
@@ -8203,15 +8203,15 @@
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@next/swc-darwin-arm64": "16.4.0",
|
||||
"@next/swc-darwin-x64": "16.4.0",
|
||||
"@next/swc-linux-arm64-gnu": "16.4.0",
|
||||
"@next/swc-linux-arm64-musl": "16.4.0",
|
||||
"@next/swc-linux-x64-gnu": "16.4.0",
|
||||
"@next/swc-linux-x64-musl": "16.4.0",
|
||||
"@next/swc-win32-arm64-msvc": "16.4.0",
|
||||
"@next/swc-win32-x64-msvc": "16.4.0",
|
||||
"sharp": "^0.35.4"
|
||||
"@next/swc-darwin-arm64": "16.4.2",
|
||||
"@next/swc-darwin-x64": "16.4.2",
|
||||
"@next/swc-linux-arm64-gnu": "16.4.2",
|
||||
"@next/swc-linux-arm64-musl": "16.4.2",
|
||||
"@next/swc-linux-x64-gnu": "16.4.2",
|
||||
"@next/swc-linux-x64-musl": "16.4.2",
|
||||
"@next/swc-win32-arm64-msvc": "16.4.2",
|
||||
"@next/swc-win32-x64-msvc": "16.4.2",
|
||||
"sharp": "^0.35.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "^1.1.0",
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "proxledger",
|
||||
"version": "0.26.1",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@@ -41,7 +41,7 @@
|
||||
"bootstrap-icons": "^1.13.1",
|
||||
"croner": "^10.0.1",
|
||||
"jose": "^6.2.12",
|
||||
"next": "^16.4.0",
|
||||
"next": "^16.4.2",
|
||||
"nodemailer": "^10.0.10",
|
||||
"openid-client": "^6.8.8",
|
||||
"react": "19.2.8",
|
||||
@@ -56,7 +56,7 @@
|
||||
"dotenv": "^17.4.2",
|
||||
"esbuild": "^0.28.2",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "^16.4.0",
|
||||
"eslint-config-next": "^16.4.2",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"prettier": "^3.9.7",
|
||||
"prisma": "^7.10.0",
|
||||
|
||||
Reference in New Issue
Block a user