feat: Krisenvorrats-Inventar digitalisiert und Import-Skript erstellt

- inventar.md: 38 Artikel aus handschriftlicher Liste erfasst (Lebensmittel,
  Medikamente, Ausrüstung, Hygiene, Energie)
- import-inventar.py: Python-Skript zum einmaligen PUT /api/inventory
  (UTF-8-safe via ensure_ascii=True, kein PowerShell-Encoding-Problem)
- import-inventar.ps1: PowerShell-Variante (Umlaute via [char]-Variablen)
This commit is contained in:
Jens Reinemann 2026-05-17 23:21:07 +02:00
parent 9631ec9a92
commit bed233521e
3 changed files with 455 additions and 79 deletions

203
import-inventar.ps1 Normal file
View file

@ -0,0 +1,203 @@
<#
.SYNOPSIS
Importiert das Bollwerk-Vorratsinventar in den Server (einmaliger PUT).
Verwendet App-Default-Kategorien (IDs 1-7) und Default-Location Keller (ID 1).
.PARAMETER BaseUrl
Server-URL. Standard: https://bollwerk.online
.PARAMETER AdminUser
Admin-Benutzername. Standard: admin
.EXAMPLE
.\import-inventar.ps1
.\import-inventar.ps1 -BaseUrl "http://localhost:8080"
#>
param(
[string]$BaseUrl = "https://bollwerk.online",
[string]$AdminUser = "admin"
)
$ErrorActionPreference = "Stop"
# ---------------------------------------------------------------------------
# Umlaute via [char] - PS 5.1 liest .ps1-Dateien als ANSI/CP1252.
# UTF-8-Umlaute im Quelltext wuerden den Parser brechen (byte 0xB6 = Pilcrow).
# ---------------------------------------------------------------------------
$oe = [char]246 # o-Umlaut
$ue = [char]252 # u-Umlaut
$ae = [char]228 # a-Umlaut
$ss = [char]223 # scharfes S
$ag = [char]224 # a-grave (fuer "a 2300 kcal", "a 20 ml")
# ---------------------------------------------------------------------------
# Passwort sicher einlesen (erscheint NICHT in der History)
# ---------------------------------------------------------------------------
$secure = Read-Host "Admin-Passwort fuer '$AdminUser' @ $BaseUrl" -AsSecureString
$AdminPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure)
)
# ---------------------------------------------------------------------------
# HTTP-Hilfsfunktion (identisch mit run-integration-tests.ps1 UTF-8-safe)
# ---------------------------------------------------------------------------
function Invoke-Api {
param(
[string]$Method,
[string]$Path,
[object]$Body = $null,
[string]$Token = $null
)
$headers = @{ "Content-Type" = "application/json" }
if ($Token) { $headers["Authorization"] = "Bearer $Token" }
$bodyJson = if ($Body) { $Body | ConvertTo-Json -Depth 10 -Compress } else { $null }
if ($bodyJson) {
$sb = [System.Text.StringBuilder]::new($bodyJson.Length * 2)
foreach ($ch in $bodyJson.ToCharArray()) {
if ([int]$ch -gt 127) { [void]$sb.Append('\u{0:x4}' -f [int]$ch) }
else { [void]$sb.Append($ch) }
}
$bodyJson = $sb.ToString()
}
$response = Invoke-RestMethod -Method $Method -Uri "$BaseUrl$Path" `
-Body $bodyJson -Headers $headers -ErrorAction Stop
return $response
}
# ---------------------------------------------------------------------------
# 1. Login
# ---------------------------------------------------------------------------
Write-Host "Logge ein als '$AdminUser'..." -ForegroundColor Cyan
$auth = Invoke-Api -Method POST -Path "/api/auth/login" -Body @{
username = $AdminUser
password = $AdminPassword
}
$token = $auth.accessToken
Write-Host " Token erhalten." -ForegroundColor Green
# ---------------------------------------------------------------------------
# 2. Vorhandenes Inventar pruefen
# ---------------------------------------------------------------------------
Write-Host "Pruefe vorhandenes Inventar..." -ForegroundColor Cyan
$existing = Invoke-Api -Method GET -Path "/api/inventory" -Token $token
if ($existing.items.Count -gt 0) {
Write-Host ""
Write-Host " WARNUNG: Das Inventar enthaelt bereits $($existing.items.Count) Artikel!" -ForegroundColor Yellow
$confirm = Read-Host " Ueberschreiben? (ja/nein)"
if ($confirm -ne "ja") {
Write-Host "Abgebrochen." -ForegroundColor Red
exit 1
}
}
# ---------------------------------------------------------------------------
# 3. Inventar-Daten definieren (aus inventar.md, Stand Mai 2026)
# ---------------------------------------------------------------------------
$now = [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()
function NewItem($name, $catId, $qty, $unit, $expiry, $kcal, $notes) {
@{
id = [System.Guid]::NewGuid().ToString()
name = $name
categoryId = $catId
quantity = [double]$qty
unit = $unit
unitPrice = 0.0
kcalPerUnit = $kcal
expiryDate = $expiry
locationId = 1
notes = if ($notes) { $notes } else { "" }
lastUpdated = $now
}
}
# App-Default-Kategorien (IDs aus SeedDatabaseUseCase)
$categories = @(
@{ id = 1; name = "Lebensmittel" }
@{ id = 2; name = "Wasser" }
@{ id = 3; name = "Medikamente" }
@{ id = 4; name = "Ausr${ue}stung" }
@{ id = 5; name = "Hygiene" }
@{ id = 6; name = "Energie & Licht" }
@{ id = 7; name = "Dokumente" }
)
# App-Default-Lagerort
$locations = @(
@{ id = 1; name = "Keller" }
)
$items = @(
# -- Lebensmittel: Getreide & Huelsenfruechte (cat 1) --------------------
NewItem "Dinkelkorn" 1 16 "Beutel" $null $null "Jahrgang 2019, vakuumiert"
NewItem "Weizen (Naturland)" 1 36 "kg" $null $null "Jahrgang 2023"
NewItem "Dinkel" 1 40 "kg" $null $null "Jahrgang 2023"
NewItem "Bio-Weizen" 1 18 "kg" $null $null "Jahrgang 2019"
NewItem "Bio-Weizen (Neu)" 1 200 "kg" $null $null "Jahrgang 05/2026, Kunststoffbehaelter, O2-Absorber, Trockenmittel, lose luftdicht"
NewItem "Gr${ue}ne Erbsen" 1 10 "kg" $null $null "Jahrgang 2019"
NewItem "Gelbe Sch${ae}lerbsen" 1 10 "kg" $null $null "Jahrgang 2019"
NewItem "Berglinsen (1 kg)" 1 1 "Pkg." "2021-12-31" $null "MHD abgelaufen"
NewItem "Berglinsen (500 g)" 1 4 "Pkg." "2023-12-31" $null "MHD abgelaufen"
NewItem "Wei${ss}e Bohnen" 1 2 "Pkg." "2022-12-31" $null "MHD abgelaufen"
NewItem "Jodsalz" 1 25 "kg" $null $null ""
# -- Lebensmittel: Konserven (cat 1) -------------------------------------
NewItem "Kondensmilch gezuckert (Dovgan)" 1 88 "Dosen" $null $null "MHD pruefen"
NewItem "Corned Beef (Exeter)" 1 48 "Dosen" $null $null "MHD pruefen"
NewItem "Gesch${ae}lte Tomaten" 1 5 "Dosen" $null $null "2x 2,5 kg, MHD abgelaufen"
NewItem "Tomatenmark (200 g)" 1 24 "Dosen" $null $null "MHD abgelaufen"
NewItem "Sardinen" 1 5 "Dosen" $null $null "MHD abgelaufen"
NewItem "Heringsfilet in Tomatenso${ss}e" 1 11 "Dosen" $null $null "MHD abgelaufen"
NewItem "Thunfisch gro${ss} (900 g)" 1 3 "Dosen" $null $null "MHD abgelaufen"
NewItem "Thunfisch klein" 1 9 "Dosen" $null $null "MHD abgelaufen"
NewItem "Brathering Filet" 1 2 "Dosen" $null $null "MHD abgelaufen"
NewItem "Dosenbrot" 1 6 "Dosen" $null $null "MHD abgelaufen"
# -- Lebensmittel: Oele & Fette (cat 1) ----------------------------------
NewItem "Oliven${oe}l (750 ml)" 1 3 "Flaschen" "2022-12-31" $null "MHD abgelaufen"
NewItem "Avocado${oe}l (250 ml)" 1 3 "Flaschen" "2026-12-31" $null "MHD 2026, pruefen"
NewItem "Sonnenblumen${oe}l (1 L)" 1 3 "Flaschen" "2021-12-31" $null "MHD abgelaufen"
NewItem "Sonnenblumen${oe}l (500 ml)" 1 1 "Flaschen" "2023-12-31" $null "MHD abgelaufen"
# -- Lebensmittel: Getraenke (cat 1) -------------------------------------
NewItem "Instant-Kaffee" 1 12 "Stk." "2024-12-31" $null "MHD abgelaufen"
NewItem "Trek'N'Eat Peronin" 1 8 "Stk." "2024-12-31" $null "MHD abgelaufen"
# -- Lebensmittel: Notfallrationen (cat 1) --------------------------------
NewItem "Conserva-Set" 1 30 "Manntage" $null 2300 "${ag} 2300 kcal/Tag, conserva.de"
NewItem "NRG-5 Katadyn (Neubestand)" 1 96 "Tagesrationen" "2036-04-30" 2300 "4x24, Produktion April 2026"
NewItem "NRG-5 Katadyn (Altbestand)" 1 19 "Tagesrationen" "2029-01-31" 2300 "Produktion 2019, 5 Rationen verbraucht"
# -- Medikamente (cat 3) -------------------------------------------------
NewItem "Vitamine" 3 960 "Stk." $null $null "3x240 + 2x120 Tabletten"
# -- Ausruestung (cat 4) -------------------------------------------------
NewItem "PMR-Funkger${ae}t (Midland G9 Pro)" 4 2 "Stk." $null $null ""
# -- Hygiene (cat 5) -----------------------------------------------------
NewItem "Shampoo Mini" 5 50 "Stk." $null $null "${ag} 20 ml"
NewItem "Ethanol" 5 30 "Liter" $null $null ""
NewItem "Isopropanol" 5 4 "Liter" $null $null ""
NewItem "Methanol" 5 1 "Liter" $null $null ""
NewItem "Desinfektionsmittel" 5 5 "Liter" $null $null ""
# -- Energie & Licht (cat 6) ---------------------------------------------
NewItem "Petroleum" 6 50 "Liter" $null $null ""
)
$inventory = @{
version = 1
categories = $categories
locations = $locations
items = $items
settings = @()
deletedItemIds = @()
}
# ---------------------------------------------------------------------------
# 4. PUT /api/inventory
# ---------------------------------------------------------------------------
Write-Host "Lade $($items.Count) Artikel in $($categories.Count) Kategorien hoch..." -ForegroundColor Cyan
$result = Invoke-Api -Method PUT -Path "/api/inventory" -Body $inventory -Token $token
Write-Host ""
Write-Host "Fertig!" -ForegroundColor Green
Write-Host " Artikel hochgeladen : $($result.items.Count)"
Write-Host " Kategorien : $($result.categories.Count)"
Write-Host " Lagerorte : $($result.locations.Count)"

173
import-inventar.py Normal file
View file

@ -0,0 +1,173 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Importiert das Bollwerk-Vorratsinventar in den Server (einmaliger PUT).
Verwendet App-Default-Kategorien (IDs 1-7) und Default-Location Keller (ID 1).
Aufruf:
python import-inventar.py
python import-inventar.py --url http://localhost:8080
"""
import json
import getpass
import time
import uuid
import argparse
import urllib.request
import urllib.error
BASE_URL = "https://bollwerk.online"
ADMIN_USER = "admin"
def api(method, path, body=None, token=None):
url = BASE_URL + path
# ensure_ascii=True kodiert alle Umlaute als \uXXXX kein Encoding-Problem
data = json.dumps(body, ensure_ascii=True).encode("ascii") if body else None
headers = {"Content-Type": "application/json"}
if token:
headers["Authorization"] = f"Bearer {token}"
req = urllib.request.Request(url, data=data, headers=headers, method=method)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read().decode("utf-8"))
def new_item(name, cat_id, qty, unit, expiry=None, kcal=None, notes=""):
now = int(time.time() * 1000)
return {
"id": str(uuid.uuid4()),
"name": name,
"categoryId": cat_id,
"quantity": float(qty),
"unit": unit,
"unitPrice": 0.0,
"kcalPerUnit": kcal,
"expiryDate": expiry,
"locationId": 1,
"notes": notes or "",
"lastUpdated": now,
}
# App-Default-Kategorien (IDs aus SeedDatabaseUseCase)
CATEGORIES = [
{"id": 1, "name": "Lebensmittel"},
{"id": 2, "name": "Wasser"},
{"id": 3, "name": "Medikamente"},
{"id": 4, "name": "Ausrüstung"},
{"id": 5, "name": "Hygiene"},
{"id": 6, "name": "Energie & Licht"},
{"id": 7, "name": "Dokumente"},
]
# App-Default-Lagerort
LOCATIONS = [{"id": 1, "name": "Keller"}]
ITEMS = [
# --- Lebensmittel: Getreide & Hülsenfrüchte (cat 1) ---------------------
new_item("Dinkelkorn", 1, 16, "Beutel", None, None, "Jahrgang 2019, vakuumiert"),
new_item("Weizen (Naturland)", 1, 36, "kg", None, None, "Jahrgang 2023"),
new_item("Dinkel", 1, 40, "kg", None, None, "Jahrgang 2023"),
new_item("Bio-Weizen", 1, 18, "kg", None, None, "Jahrgang 2019"),
new_item("Bio-Weizen (Neu)", 1, 200, "kg", None, None, "Jahrgang 05/2026, Kunststoffbehälter, O2-Absorber, Trockenmittel, lose luftdicht"),
new_item("Grüne Erbsen", 1, 10, "kg", None, None, "Jahrgang 2019"),
new_item("Gelbe Schälerbsen", 1, 10, "kg", None, None, "Jahrgang 2019"),
new_item("Berglinsen (1 kg)", 1, 1, "Pkg.", "2021-12-31", None, "MHD abgelaufen"),
new_item("Berglinsen (500 g)", 1, 4, "Pkg.", "2023-12-31", None, "MHD abgelaufen"),
new_item("Weiße Bohnen", 1, 2, "Pkg.", "2022-12-31", None, "MHD abgelaufen"),
new_item("Jodsalz", 1, 25, "kg", None, None, ""),
# --- Lebensmittel: Konserven (cat 1) ------------------------------------
new_item("Kondensmilch gezuckert (Dovgan)", 1, 88, "Dosen", None, None, "MHD prüfen"),
new_item("Corned Beef (Exeter)", 1, 48, "Dosen", None, None, "MHD prüfen"),
new_item("Geschälte Tomaten", 1, 5, "Dosen", None, None, "2x 2,5 kg, MHD abgelaufen"),
new_item("Tomatenmark (200 g)", 1, 24, "Dosen", None, None, "MHD abgelaufen"),
new_item("Sardinen", 1, 5, "Dosen", None, None, "MHD abgelaufen"),
new_item("Heringsfilet in Tomatensoße", 1, 11, "Dosen", None, None, "MHD abgelaufen"),
new_item("Thunfisch groß (900 g)", 1, 3, "Dosen", None, None, "MHD abgelaufen"),
new_item("Thunfisch klein", 1, 9, "Dosen", None, None, "MHD abgelaufen"),
new_item("Brathering Filet", 1, 2, "Dosen", None, None, "MHD abgelaufen"),
new_item("Dosenbrot", 1, 6, "Dosen", None, None, "MHD abgelaufen"),
# --- Lebensmittel: Öle & Fette (cat 1) ----------------------------------
new_item("Olivenöl (750 ml)", 1, 3, "Flaschen", "2022-12-31", None, "MHD abgelaufen"),
new_item("Avocadoöl (250 ml)", 1, 3, "Flaschen", "2026-12-31", None, "MHD 2026, prüfen"),
new_item("Sonnenblumenöl (1 L)", 1, 3, "Flaschen", "2021-12-31", None, "MHD abgelaufen"),
new_item("Sonnenblumenöl (500 ml)", 1, 1, "Flaschen", "2023-12-31", None, "MHD abgelaufen"),
# --- Lebensmittel: Getränke (cat 1) -------------------------------------
new_item("Instant-Kaffee", 1, 12, "Stk.", "2024-12-31", None, "MHD abgelaufen"),
new_item("Trek'N'Eat Peronin", 1, 8, "Stk.", "2024-12-31", None, "MHD abgelaufen"),
# --- Lebensmittel: Notfallrationen (cat 1) ------------------------------
new_item("Conserva-Set", 1, 30, "Manntage", None, 2300, "à 2300 kcal/Tag, conserva.de"),
new_item("NRG-5 Katadyn (Neubestand)", 1, 96, "Tagesrationen", "2036-04-30", 2300, "4x24, Produktion April 2026"),
new_item("NRG-5 Katadyn (Altbestand)", 1, 19, "Tagesrationen", "2029-01-31", 2300, "Produktion 2019, 5 Rationen verbraucht"),
# --- Medikamente (cat 3) ------------------------------------------------
new_item("Vitamine", 3, 960, "Stk.", None, None, "3x240 + 2x120 Tabletten"),
# --- Ausrüstung (cat 4) -------------------------------------------------
new_item("PMR-Funkgerät (Midland G9 Pro)", 4, 2, "Stk.", None, None, ""),
# --- Hygiene (cat 5) ----------------------------------------------------
new_item("Shampoo Mini", 5, 50, "Stk.", None, None, "à 20 ml"),
new_item("Ethanol", 5, 30, "Liter", None, None, ""),
new_item("Isopropanol", 5, 4, "Liter", None, None, ""),
new_item("Methanol", 5, 1, "Liter", None, None, ""),
new_item("Desinfektionsmittel", 5, 5, "Liter", None, None, ""),
# --- Energie & Licht (cat 6) --------------------------------------------
new_item("Petroleum", 6, 50, "Liter", None, None, ""),
]
def main():
global BASE_URL
parser = argparse.ArgumentParser()
parser.add_argument("--url", default=BASE_URL)
parser.add_argument("--user", default=ADMIN_USER)
args = parser.parse_args()
BASE_URL = args.url.rstrip("/")
password = getpass.getpass(f"Admin-Passwort für '{args.user}' @ {BASE_URL}: ")
print("Logge ein...", end=" ", flush=True)
auth = api("POST", "/api/auth/login", {"username": args.user, "password": password})
token = auth["accessToken"]
print("OK")
print("Prüfe vorhandenes Inventar...", end=" ", flush=True)
existing = api("GET", "/api/inventory", token=token)
count = len(existing.get("items", []))
print(f"{count} Artikel vorhanden.")
if count > 0:
confirm = input(f" WARNUNG: {count} Artikel vorhanden. Überschreiben? (ja/nein): ")
if confirm.strip().lower() != "ja":
print("Abgebrochen.")
return
inventory = {
"version": 1,
"categories": CATEGORIES,
"locations": LOCATIONS,
"items": ITEMS,
"settings": [],
"deletedItemIds": [],
}
print(f"Lade {len(ITEMS)} Artikel hoch...", end=" ", flush=True)
result = api("PUT", "/api/inventory", inventory, token=token)
print("OK")
print()
print("Fertig!")
print(f" Artikel : {len(result.get('items', []))}")
print(f" Kategorien : {len(result.get('categories', []))}")
print(f" Lagerorte : {len(result.get('locations', []))}")
if __name__ == "__main__":
main()

View file

@ -1,104 +1,104 @@
# Bollwerk Vorratsinventar # Bollwerk Vorratsinventar
> Stand: Mai 2026 > Stand: Mai 2026
> Quelle: handschriftliche Notiz, digitalisiert und ergänzt > Kategorien: App-Default (IDs 17), Lagerort: Keller (ID 1)
--- ---
## Getreide & Hülsenfrüchte ## Kategorie 1 Lebensmittel
| Artikel | Menge | Jahrgang / MHD | Lagerung | Notizen | ### Getreide & Hülsenfrüchte
| --- | --- | --- | --- | --- |
| Dinkelkorn | ~16 Beutel | von 2019 | Vakuumbeutel | | | Artikel | Menge | Jahrgang / MHD | Lagerung | Notizen |
| Weizen (Naturland) | 36 kg | von 2023 | | | | ----------------------- | ---------- | -------------- | ---------------------------------------------- | --------------- |
| Dinkel | 40 kg | von 2023 | | | | Dinkelkorn | ~16 Beutel | von 2019 | Vakuumbeutel | |
| Bio-Weizen | 18 kg | von 2019 | | | | Weizen (Naturland) | 36 kg | von 2023 | | |
| Bio-Weizen | 200 kg | 05/2026 | Kunststoffbehälter, O₂-Absorber, Trockenmittel | lose, luftdicht | | Dinkel | 40 kg | von 2023 | | |
| Grüne Erbsen | 10 kg | von 2019 | | | | Bio-Weizen | 18 kg | von 2019 | | |
| Gelbe Schälerbsen | 10 kg | von 2019 | | | | Bio-Weizen (Neu) | 200 kg | 05/2026 | Kunststoffbehälter, O₂-Absorber, Trockenmittel | lose, luftdicht |
| Berglinsen (1 kg) | 1 Pkg. | MHD 2021 | | **abgelaufen** | | Grüne Erbsen | 10 kg | von 2019 | | |
| Berglinsen (500 g) | 4 Pkg. | MHD 2023 | | **abgelaufen** | | Gelbe Schälerbsen | 10 kg | von 2019 | | |
| Weiße Bohnen | 2 Pkg. | MHD 2022 | | **abgelaufen** | | Berglinsen (1 kg) | 1 Pkg. | MHD 2021 | | **abgelaufen** |
| Sojamehl (6-L-Behälter) | 7 | MHD 2023 | | **abgelaufen** | | Berglinsen (500 g) | 4 Pkg. | MHD 2023 | | **abgelaufen** |
| Sojamehl (1-L-Behälter) | 3 | von 2021 | | **abgelaufen** | | Weiße Bohnen | 2 Pkg. | MHD 2022 | | **abgelaufen** |
| Jodsalz | 25 kg | | | | | Jodsalz | 25 kg | | | |
### Konserven
| Artikel | Menge | MHD | Notizen |
| ------------------------------- | ---------- | -------------- | ------- |
| Kondensmilch gezuckert (Dovgan) | 88 Dosen | MHD prüfen | |
| Corned Beef (Exeter) | 48 Dosen | MHD prüfen | |
| Geschälte Tomaten | 2 × 2,5 kg | **abgelaufen** | |
| Tomatenmark (200 g) | 24 | **abgelaufen** | |
| Sardinen | 5 | **abgelaufen** | |
| Heringsfilet in Tomatensoße | 11 | **abgelaufen** | |
| Thunfisch groß (900 g) | 3 | **abgelaufen** | |
| Thunfisch klein | 9 | **abgelaufen** | |
| Brathering Filet | 2 | **abgelaufen** | |
| Dosenbrot | 6 | **abgelaufen** | |
### Öle & Fette
| Artikel | Menge | MHD | Notizen |
| ----------------------- | ----- | ---- | ---------------------- |
| Olivenöl (750 ml) | 3 | 2022 | **abgelaufen** |
| Avocadoöl (250 ml) | 3 | 2026 | läuft bald ab prüfen |
| Sonnenblumenöl (1 L) | 3 | 2021 | **abgelaufen** |
| Sonnenblumenöl (500 ml) | 1 | 2023 | **abgelaufen** |
### Getränke
| Artikel | Menge | MHD | Notizen |
| ------------------ | ----- | ---- | -------------- |
| Instant-Kaffee | 12 | 2024 | **abgelaufen** |
| Trek'N'Eat Peronin | 8 | 2024 | **abgelaufen** |
### Notfallrationen
| Artikel | Menge | Produktion | MHD | Notizen |
| -------------------------------- | --------------------------- | ---------- | ---------- | -------------------------------------- |
| Conserva-Set (à 2.300 kcal/Tag) | 30 Manntage | | | [conserva.de](https://www.conserva.de) |
| NRG-5 Katadyn (à 2.300 kcal/Tag) | 96 Tagesrationen (4 × 24) | April 2026 | April 2036 | |
| NRG-5 Katadyn (Altbestand) | 19 Tagesrationen (5 verbraucht) | 2019 | ca. 2029 | |
> NRG-5 gesamt: 115 Tagesrationen = 264.500 kcal
--- ---
## Konserven ## Kategorie 3 Medikamente
| Artikel | Menge | MHD | Notizen | | Artikel | Menge | MHD | Notizen |
| --- | --- | --- | --- | | -------- | ---------------------------- | --- | --------------------- |
| Kondensmilch gezuckert (Dovgan) | 88 Dosen | MHD prüfen | | | Vitamine | 3 × 240 + 2 × 120 = 960 Stk. | | 3x240 + 2x120 Tabletten |
| Corned Beef (Exeter) | 48 Dosen | MHD prüfen | |
| Geschälte Tomaten | 2 × 2,5 kg | **abgelaufen** | |
| Tomatenmark (200 g) | 24 | **abgelaufen** | |
| Sardinen | 5 | **abgelaufen** | |
| Heringsfilet in Tomatensoße | 11 | **abgelaufen** | |
| Thunfisch groß (900 g) | 3 | **abgelaufen** | |
| Thunfisch klein | 9 | **abgelaufen** | |
| Brathering Filet | 2 | **abgelaufen** | |
| Dosenbrot | 6 | **abgelaufen** | |
--- ---
## Öle & Fette ## Kategorie 4 Ausrüstung
| Artikel | Menge | MHD | Notizen | | Artikel | Menge | Notizen |
| --- | --- | --- | --- | | ------------------------------ | ----- | ------- |
| Olivenöl (750 ml) | 3 | 2022 | **abgelaufen** | | PMR-Funkgerät (Midland G9 Pro) | 2 | |
| Avocadoöl (250 ml) | 3 | 2026 | läuft bald ab prüfen |
| Sonnenblumenöl (1 L) | 3 | 2021 | **abgelaufen** |
| Sonnenblumenöl (500 ml) | 1 | 2023 | **abgelaufen** |
--- ---
## Getränke & Ergänzung ## Kategorie 5 Hygiene
| Artikel | Menge | MHD | Notizen | | Artikel | Menge | Notizen |
| --- | --- | --- | --- | | ------------------- | ---------- | ------- |
| Instant-Kaffee | 12 | 2024 | **abgelaufen** | | Shampoo Mini | 50 × 20 ml | |
| Trek'N'Eat Peronin | 8 | 2024 | **abgelaufen** | | Ethanol | 30 × 1 L | |
| Vitamine | 3 × 240 + 2 × 120 = 960 Stk. | | | | Isopropanol | 4 × 1 L | |
| Methanol | 1 L | |
| Desinfektionsmittel | 5 × 1 L | |
--- ---
## Notfallrationen ## Kategorie 6 Energie & Licht
| Artikel | Menge | Produktion | MHD | Notizen | | Artikel | Menge | Notizen |
| --- | --- | --- | --- | --- | | --------- | ----- | ------- |
| Conserva-Set (à 2.300 kcal/Tag) | 30 Manntage | | | [conserva.de](https://www.conserva.de) | | Petroleum | 50 L | |
| NRG-5 Katadyn (à 2.300 kcal/Tag) | 96 Tagesrationen (4 × 24) | April 2026 | April 2036 | |
| NRG-5 Katadyn (Altbestand) | 19 Tagesrationen (5 verbraucht) | 2019 | ca. 2029 | |
| **NRG-5 gesamt** | **115 Tagesrationen = 264.500 kcal** | | | |
---
## Hygiene & Desinfektion
| Artikel | Menge | Notizen |
| --- | --- | --- |
| Shampoo Mini | 50 × 20 ml | |
| Ethanol | 30 × 1 L | |
| Isopropanol | 4 × 1 L | |
| Methanol | 1 L | |
| Desinfektionsmittel | 5 × 1 L | |
---
## Brennstoffe
| Artikel | Menge | Notizen |
| --- | --- | --- |
| Petroleum | 50 L | |
---
## Kommunikation & Ausrüstung
| Artikel | Menge | Notizen |
| --- | --- | --- |
| PMR-Funkgerät (Midland G9 Pro) | 2 | |
--- ---
@ -107,4 +107,4 @@
- **Dovgan Kondensmilch & Exeter Corned Beef**: MHD direkt auf der Dose prüfen und nachtragen. - **Dovgan Kondensmilch & Exeter Corned Beef**: MHD direkt auf der Dose prüfen und nachtragen.
- **Avocadoöl**: MHD 2026 zeitnah verbrauchen oder ersetzen. - **Avocadoöl**: MHD 2026 zeitnah verbrauchen oder ersetzen.
- Viele Fisch-/Ölkonserven sind abgelaufen Qualität prüfen. Trockenwaren (Getreide, Hülsenfrüchte) sind in guter Lagerung oft Jahre über MHD nutzbar. - Viele Fisch-/Ölkonserven sind abgelaufen Qualität prüfen. Trockenwaren (Getreide, Hülsenfrüchte) sind in guter Lagerung oft Jahre über MHD nutzbar.
- Weitere Artikel (Medikamente, Wasser, Beleuchtung) können später über die App erfasst werden. - Kategorien 2 (Wasser) und 7 (Dokumente) sind noch leer.