Zum Inhalt

Betrieb & Deployment

Cron-Jobs

Dokumentation: CRON_SETUP.md Timezone: CRON_TZ=UTC

Aktive Cron-Jobs

CRON_TZ=UTC

# ============================================
# Settlement (täglich 00:00 UTC)
# ============================================
0 0 * * * /root/workspace/lotto-platform/bo-engine/cli/cron-settle.sh

# ============================================
# Hochfrequenz-Worker
# ============================================

# Buy-Intent-Recovery (alle 2 Min)
*/2 * * * * /root/workspace/lotto-platform/bo-engine/cli/cron-recover-intents.sh

# Claim-Recovery (alle 2 Min)
*/2 * * * * /root/workspace/lotto-platform/bo-engine/cli/cron-resolve-pending-claims.sh

# Pot-Sync (alle 15 Min)
*/15 * * * * cd /root/workspace/lotto-platform/bo-engine && npx ts-node workers/updatePotSizes.ts

# Watchdog (alle 5 Min)
*/5 * * * * cd /root/workspace/lotto-platform/bo-engine && npx ts-node --files watchdog/run.ts

# Seed-Refresh Daemon (jede Minute PID-Check)
* * * * * /root/workspace/lotto-platform/bo-engine/cli/cron-refresh-seeds.sh

# ============================================
# Tägliche Worker
# ============================================

# Affiliate-Bonus (2x täglich)
30 0 * * * cd /root/workspace/lotto-platform/bo-engine && npx ts-node --files workers/awardAffiliateBonus.ts
0 12 * * * cd /root/workspace/lotto-platform/bo-engine && npx ts-node --files workers/awardAffiliateBonus.ts

# Re-Engagement-E-Mails (10:00 UTC)
0 10 * * * cd /root/workspace/lotto-platform/bo-engine && npx ts-node --files workers/reEngagementEmail.ts

# ============================================
# Monatliche Worker
# ============================================

# Leaderboard-Bonus (1. des Monats)
0 1 1 * * cd /root/workspace/lotto-platform/bo-engine && npx ts-node --files workers/awardLeaderboardBonus.ts

Logging

Log-Verzeichnisse

bo-engine/logs/
├── settlement/          # Settlement-Pipeline
│   └── settle-YYYY-MM-DD.log
├── recovery/            # Buy-Intent-Recovery
│   └── recover-YYYY-MM-DD.log
├── claim-recovery/      # Claim-Recovery
│   └── claim-recover-YYYY-MM-DD.log
├── seeds/               # Seed-Rotation
│   └── refresh-seeds-YYYY-MM-DD.log
└── bulk-buy/            # Bulk-Buy-Tests
    └── bulk-buy-YYYY-MM-DD.log

Retention

Log-Typ Aufbewahrung
Settlement 30 Tage
Recovery 14 Tage
Claim-Recovery 14 Tage
Seeds 14 Tage

Cron-Wrapper-Pattern

#!/bin/bash
set -e
cd /root/workspace/lotto-platform/bo-engine
LOG="logs/settlement/settle-$(date +%Y-%m-%d).log"
mkdir -p logs/settlement

npx ts-node --files cli/settle.ts >> "$LOG" 2>&1

# Log-Rotation
find logs/settlement -name "*.log" -mtime +30 -delete

Prozess-Management

Daemon: refreshSeeds

Der Seed-Refresh-Worker läuft als Daemon mit PID-Lock:

# cron-refresh-seeds.sh
PID_FILE="logs/refresh-seeds.pid"

# Check ob bereits laufend
if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then
  exit 0
fi

# Starten
npx ts-node --files workers/refreshSeeds.ts &
echo $! > "$PID_FILE"

Neustart: Automatisch via Cron (jede Minute) bei PID-Prüfung.

Kurzlebige Worker

Alle anderen Worker starten als eigenständige Prozesse via Cron und beenden sich nach Abschluss.


Deployment

Voraussetzungen

Komponente Version
Node.js v20 (LTS)
PostgreSQL 16
npm Packages npm install
.env Konfiguriert

Installation

cd /root/workspace/lotto-platform/bo-engine
npm install

# Cron-Jobs installieren
crontab -e  # Einträge aus CRON_SETUP.md einfügen

Datenbank-Setup

# PostgreSQL Container starten
cd /root/workspace/lotto-platform/infra/db
docker compose up -d

# Migrationen ausführen
psql $DATABASE_URL < migrations/001_v2_complete_schema.sql
psql $DATABASE_URL < migrations/020_daily_prize_breakdown.sql
# ... weitere Migrationen

Verifikation

# Settlement-Pipeline testen
npx ts-node --files cli/settle.ts --dayId 20500

# Watchdog manuell ausführen
npx ts-node --files watchdog/run.ts

# Pot-Sizes prüfen
npx ts-node workers/updatePotSizes.ts

Artefakt-Speicherung

Verzeichnisstruktur

bo-engine/artifacts/
├── dayId=20444/
│   ├── inputs.json
│   ├── affiliates.json
│   ├── settlement_result.json
│   ├── winners_merkle.json
│   ├── affiliate_merkle.json
│   ├── commit_bundle.json
│   └── checksums.json
├── dayId=20445/
│   └── ...
└── ...

Speicherbedarf

  • ~440 KB pro Tag
  • ~22 MB für ~50 Tage
  • ~160 MB pro Jahr (geschätzt)

Audit-Integrität

Jede Datei hat einen SHA256-Checksum in checksums.json:

{
  "inputs.json": "a1b2c3...",
  "settlement_result.json": "d4e5f6...",
  "winners_merkle.json": "g7h8i9..."
}

Zusätzlich gespeichert in der settlement_artifacts-Tabelle.


Fehlerbehandlung im Betrieb

Settlement fehlgeschlagen

# 1. Pipeline-Status prüfen
psql $DATABASE_URL -c "SELECT * FROM settlement_pipeline_runs WHERE day_id = 20500"

# 2. Settlement-Run prüfen
psql $DATABASE_URL -c "SELECT * FROM settlement_runs WHERE day_id = 20500"

# 3. Logs prüfen
cat logs/settlement/settle-2026-02-28.log

# 4. Debug-Commit (Simulation)
npx ts-node debug_commit.ts --dayId 20500

# 5. Manuell neu starten
npx ts-node --files cli/settle.ts --dayId 20500

Stuck Buy-Intents

# Status prüfen
psql $DATABASE_URL -c "
  SELECT status, COUNT(*)
  FROM buy_intents
  WHERE created_at > now() - interval '1 hour'
  GROUP BY status
"

# Recovery manuell triggern
npx ts-node --files workers/recoverBuyIntents.ts

Watchdog-Alerts

# Aktive Alerts anzeigen
psql $DATABASE_URL -c "
  SELECT check_id, level, message, alerted_at
  FROM watchdog_alerts
  WHERE resolved_at IS NULL
  ORDER BY alerted_at DESC
"

Cleanup-Tool

Datei: cli/cleanup-settlement.ts (198 Zeilen)

Für die Bereinigung fehlgeschlagener Settlements:

# Dry-Run eines Tages zurücksetzen
npx ts-node --files cli/cleanup-settlement.ts --dayId 20500

# Entfernt:
# - settlement_runs (dry_run Status)
# - settlement_proofs
# - settlement_winner_payouts
# - settlement_affiliate_payouts
# - daily_prize_breakdown
# - settlement_artifacts

Vorsicht

Nur für dry_run-Status verwendbar. Committed Settlements können nicht zurückgesetzt werden.


Infrastruktur-Übersicht

┌──────────────────────────────────────────┐
│  Server (85.215.115.115)                 │
│                                          │
│  ┌────────────────────────────────────┐  │
│  │  Crontab (CRON_TZ=UTC)           │  │
│  │  ├── settle.ts (00:00)            │  │
│  │  ├── recoverBuyIntents (*/2)      │  │
│  │  ├── resolvePendingClaims (*/2)   │  │
│  │  ├── updatePotSizes (*/15)        │  │
│  │  ├── watchdog (*/5)               │  │
│  │  ├── refreshSeeds (Daemon)        │  │
│  │  ├── awardAffiliateBonus (2x/d)   │  │
│  │  ├── reEngagementEmail (10:00)    │  │
│  │  └── awardLeaderboardBonus (1./Mo)│  │
│  └────────────────────────────────────┘  │
│                                          │
│  ┌──────────────┐  ┌──────────────────┐  │
│  │ PostgreSQL   │  │ Node.js v20      │  │
│  │ (Docker)     │  │ (Host)           │  │
│  └──────────────┘  └──────────────────┘  │
│                                          │
│  ── Arbitrum RPC ──────────────────►     │
│  ── Telegram Bot API ──────────────►     │
│  ── Resend E-Mail API ─────────────►     │
└──────────────────────────────────────────┘