feat(datastore): implement structured personal data layer (ADR 0004, ForwardAuth /family, and OpenClaw protocol)

This commit is contained in:
Moritz Graf
2026-10-06 18:18:27 +02:00
parent 9d890a290f
commit f717a9a2f7
6 changed files with 238 additions and 1 deletions
+33
View File
@@ -7,6 +7,7 @@ spec:
addPrefix:
prefix: /hosting
---
# Public Ingress for hosting.haumdaucher.de (Recipes, Public Assets)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
@@ -16,6 +17,7 @@ metadata:
kubernetes.io/ingress.class: "traefik"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
kubernetes.io/tls-acme: "true"
traefik.ingress.kubernetes.io/router.priority: "10"
traefik.ingress.kubernetes.io/router.middlewares: minio-hosting-add-prefix@kubernetescrd
spec:
ingressClassName: traefik
@@ -34,3 +36,34 @@ spec:
- hosts:
- hosting.haumdaucher.de
secretName: hosting-haumdaucher-de-tls
---
# Protected Ingress for /family (Family Dashboards, Nutrition & Sleep Analytics)
# Protected by Authentik ForwardAuth
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minio-hosting-family
namespace: minio
annotations:
kubernetes.io/ingress.class: "traefik"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
kubernetes.io/tls-acme: "true"
traefik.ingress.kubernetes.io/router.priority: "100"
traefik.ingress.kubernetes.io/router.middlewares: auth-authentik-forwardauth@kubernetescrd,minio-hosting-add-prefix@kubernetescrd
spec:
ingressClassName: traefik
rules:
- host: hosting.haumdaucher.de
http:
paths:
- path: /family
pathType: Prefix
backend:
service:
name: minio
port:
number: 9000
tls:
- hosts:
- hosting.haumdaucher.de
secretName: hosting-haumdaucher-de-tls
Binary file not shown.
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
# ==============================================================================
# setup-garmin-cron.sh
# Declaratively registers the Garmin Connect Nightly Sync in OpenClaw.
# Schedule: Daily at 03:30 Europe/Berlin (cron: 30 3 * * *)
# ==============================================================================
set -euo pipefail
NAMESPACE="${NAMESPACE:-openclaw}"
POD_NAME="${POD_NAME:-openclaw-0}"
CONTAINER_NAME="${CONTAINER_NAME:-openclaw}"
JOB_NAME="garmin-nightly-mirror"
CRON_SCHEDULE="30 3 * * *"
TIMEZONE="Europe/Berlin"
TELEGRAM_GROUP="-1004326921510"
TELEGRAM_TOPIC="20"
echo "=== Registering Garmin Connect Nightly Sync in OpenClaw ($POD_NAME) ==="
# 1. Check if job already exists
EXISTING_ID=$(kubectl exec -n "$NAMESPACE" "$POD_NAME" -c "$CONTAINER_NAME" -- openclaw cron list 2>/dev/null | grep "$JOB_NAME" | awk '{print $1}' || true)
if [ -n "$EXISTING_ID" ]; then
echo "Found existing job with ID $EXISTING_ID. Removing for idempotent recreation..."
kubectl exec -n "$NAMESPACE" "$POD_NAME" -c "$CONTAINER_NAME" -- openclaw cron rm "$EXISTING_ID" || true
fi
# 2. Add the job
echo "Creating automation $JOB_NAME ($CRON_SCHEDULE @ $TIMEZONE)..."
MESSAGE=$(cat << 'EOF'
Führe den nächtlichen Garmin Connect Sync durch.
Vorgehen:
1. Führe den Garmin-Sync-Befehl aus:
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/garmin_sync.py --days 2 --data-dir /home/node/.openclaw/wiki/main/data
2. Aktualisiere die gerenderten Markdown-Ansichten:
PYTHONPATH=/home/node/mop-skills/mop-skills/skills/datastore/scripts uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/render_views.py --data-dir /home/node/.openclaw/wiki/main/data --wiki-dir /home/node/.openclaw/wiki/main
3. Git Commit & Push im Knowledge Wiki:
cd /home/node/.openclaw/wiki/main && git add data/garmin/ entities/nutrition-log/ && git diff --staged --quiet || (git commit -m "chore(garmin): automated nightly mirror [skip ci]" && git push origin main)
4. Finale Antwort:
- Bei Erfolg: Gib exakt 'NO_REPLY' aus (intentional silence, kein Telegram-Spam in der Nacht).
- Nur bei Authentifizierungsfehlern: Informiere kurz via Telegram, dass ein Garmin-Re-Auth nötig ist.
EOF
)
kubectl exec -n "$NAMESPACE" "$POD_NAME" -c "$CONTAINER_NAME" -- openclaw cron add \
--name "$JOB_NAME" \
--description "Nächtlicher deterministischer Spiegel der Garmin Connect Daten (Aktivitäten, Daily Summary, Schlaf) in Git JSONL" \
--cron "$CRON_SCHEDULE" \
--tz "$TIMEZONE" \
--agent "fitness" \
--model "openrouter/deepseek/deepseek-v4.1-flash" \
--session "isolated" \
--channel "telegram" \
--to "$TELEGRAM_GROUP" \
--thread-id "$TELEGRAM_TOPIC" \
--message "$MESSAGE"
echo "=== Automation successfully registered! ==="
kubectl exec -n "$NAMESPACE" "$POD_NAME" -c "$CONTAINER_NAME" -- openclaw cron list | grep "$JOB_NAME" || true