Compare commits
2
Commits
8119aaad66
...
173d6d2e61
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
173d6d2e61 | ||
|
|
409a02561d |
@@ -17,6 +17,18 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
|
|||||||
|
|
||||||
### Sicherheit
|
### Sicherheit
|
||||||
|
|
||||||
|
## [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
|
## [0.26.1] – 2026-10-10
|
||||||
|
|
||||||
### Sicherheit
|
### Sicherheit
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Zeitübersicht
|
## Zeitübersicht
|
||||||
|
|
||||||
**Gesamt:** 24 h 38 min
|
**Gesamt:** 25 h 28 min
|
||||||
|
|
||||||
| Issue | Zeit |
|
| Issue | Zeit |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -50,6 +50,7 @@
|
|||||||
| #042 QDevice im Cluster | 0 h 20 min |
|
| #042 QDevice im Cluster | 0 h 20 min |
|
||||||
| #043 Laufzeiten bearbeiten | 1 h 05 min |
|
| #043 Laufzeiten bearbeiten | 1 h 05 min |
|
||||||
| #044 Eigenbedarf | 0 h 40 min |
|
| #044 Eigenbedarf | 0 h 40 min |
|
||||||
|
| #045 Wiederherstellung geprobt | 0 h 50 min |
|
||||||
|
|
||||||
| Meilenstein | Zeit |
|
| Meilenstein | Zeit |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -72,7 +73,7 @@
|
|||||||
|
|
||||||
## 2026-09-17 · Sitzung 1 · 19:36–laufend
|
## 2026-09-17 · Sitzung 1 · 19:36–laufend
|
||||||
**Issue:** #001–#007 (Meilensteine v0.1.0 bis v0.4.0)
|
**Issue:** #001–#007 (Meilensteine v0.1.0 bis v0.4.0)
|
||||||
**Version:** 0.26.1
|
**Version:** 0.27.0
|
||||||
|
|
||||||
### Erledigt
|
### Erledigt
|
||||||
- Auftrag gelesen, Rückfragen gestellt
|
- Auftrag gelesen, Rückfragen gestellt
|
||||||
@@ -228,6 +229,9 @@
|
|||||||
- `npm audit` turnusmäßig geprüft: zwei neue hohe Meldungen (`sharp`/librsvg, `source-map-js`). Beide angehoben, Tests und Build grün
|
- `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
|
- 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.)
|
||||||
|
|
||||||
### Nächster Schritt
|
### Nächster Schritt
|
||||||
- #016 Benutzerhandbuch mit Screenshots, danach #017 Favicons und #019 CI-Pipeline
|
- #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)
|
- Für 1.0.0 fehlt noch: PMG (kein Host verfügbar) und der Fall „aktive Subscription auf PBS“ (#023)
|
||||||
|
|||||||
+3
-2
@@ -30,7 +30,8 @@ echo "Sichere ProxLedger (${ART}) nach ${ZIEL} …"
|
|||||||
|
|
||||||
if [ "$ART" = "docker" ]; then
|
if [ "$ART" = "docker" ]; then
|
||||||
echo "Sichere Datenbank …"
|
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"
|
| gzip > "${ZIEL}/datenbank-${STAND}.sql.gz"
|
||||||
|
|
||||||
echo "Sichere hochgeladene Dateien …"
|
echo "Sichere hochgeladene Dateien …"
|
||||||
@@ -48,7 +49,7 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
echo "Sichere Datenbank …"
|
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 …"
|
echo "Sichere hochgeladene Dateien …"
|
||||||
UPLOADS="${UPLOAD_DIR:-${VERZEICHNIS}/data/uploads}"
|
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
|
## Zurückspielen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Docker
|
bash deploy/restore.sh /var/backups/proxledger # jüngste Sicherung
|
||||||
docker compose down
|
bash deploy/restore.sh /var/backups/proxledger 20261010-192437 # bestimmter Stand
|
||||||
docker compose up -d postgres
|
```
|
||||||
gunzip -c sicherung.sql.gz | docker compose exec -T postgres psql -U proxledger proxledger
|
|
||||||
|
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
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Danach die `.env` mit **demselben** `APP_SECRET` zurücklegen wie zum Zeitpunkt der Sicherung. Ein
|
Bei der Installation als Dienst stattdessen `psql "$DATABASE_URL"` und `tar -xzf … -C /opt/proxledger/data`.
|
||||||
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.
|
## 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
|
## Das Wichtigste
|
||||||
|
|
||||||
**Eine Sicherung, die nie zurückgespielt wurde, ist keine Sicherung.** Spielen Sie sie einmal in eine
|
**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
|
Testumgebung ein und melden Sie sich dort an. Erst dann wissen Sie, dass Sicherung und `APP_SECRET`
|
||||||
`APP_SECRET` zusammenpassen.
|
zusammenpassen.
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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 |
|
| [#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 |
|
| [#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 |
|
| [#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** |
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
# Roadmap
|
# Roadmap
|
||||||
|
|
||||||
Stand: 04.10.2026, Fassung 0.26.0
|
Stand: 10.10.2026, Fassung 0.27.0
|
||||||
|
|
||||||
Die erste Fassung dieser Roadmap entstand vor dem produktiven Einsatz. Seitdem läuft ProxLedger mit
|
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
|
echten Daten, und das hat die Reihenfolge deutlich verändert: Was aus der Benutzung kam, war fast
|
||||||
@@ -26,7 +26,7 @@ Kein neuer Funktionsumfang – es fehlt Erprobung.
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **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 |
|
| **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 |
|
| **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 |
|
| **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 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "proxledger",
|
"name": "proxledger",
|
||||||
"version": "0.26.1",
|
"version": "0.27.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
Reference in New Issue
Block a user