Skip to content

bmmmm/db-wallet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

db-wallet

Ein leichtes, komplett browserbasiertes Getränke-Wallet für Freund:innen vom Hackspace bitcircus101.de in Bonn und der Datenburg e.V. Bonnkein Backend, kein Server. Alle Daten liegen ausschließlich lokal im Browser (localStorage) und lassen sich per Export/Import zwischen Geräten übertragen.

Demo

Schnellstart

  1. index.html öffnen.
  2. Namen für die Nutzer:in eingeben (oder leer lassen für Zufall) → weiter zu wallet.html#<name> (z. B. wallet.html#peter).
  3. Optional: Theme am Seitenende wählen; Auswahl wird gespeichert.
  4. Optional: In wallet.html → Export → „QR-Code (kurz) anzeigen“ (kompakt, minuten-genau, merge-fähig). Tipp: QR-Code antippen → PNG downloaden; der Link unter dem QR ist zum Kopieren markiert.

Funktionen

  • Buchen: Getränke hinzufügen, Tagesstatistik inkl. Diagramm/Log/Raw.
  • Korrigieren: letzte Buchung rückgängig (Löschmarker im Log, syncbar), danach komplette Neuberechnung aus dem Log.
  • Bezahlen: Offene Getränke ausgleichen; Zahlungen sichtbar im Log.
  • Guthaben: Gutschriften aufladen und abbauen wie Vorrat.
  • Historie: Diagramm (inkl. Tages-Drinkcount in [n]), Log mit IDs/Ranges inklusive Löschmarker, Raw-Daten pro Nutzer:in/alle.
  • Statistik: Offen/Guthaben werden ausgeblendet, wenn sie 0 sind.
  • Verwaltung: Einträge bearbeiten/löschen, Nutzer:innen einzeln oder gesammelt löschen.
  • Migration: v1-Wallets können für robusten QR-Export auf v2 migriert werden.
  • Import/Export: Link (auto-merge), kompakter QR-Code oder JSON-Datei; Export enthält auch Theme + Wallet-ID gegen Namens-Kollisionen.

Action Codes (QR)

Action Codes können lokal (wallet-gebunden) oder global (wallet-agnostisch) sein. Der Scope wird beim Erstellen/Bearbeiten gewählt. Beim Scannen erfolgt sofort eine Buchung (ohne Reload):

  • Typ Trinken: bucht ein Drink-Event.
  • Typ Guthaben: bucht eine Gutschrift.

Wichtig:

  • Verwaltung erfolgt inline per Buttons (New action code, Bearbeiten, Löschen).
  • Die Mengenfrage im Inline-Formular passt sich dem Typ an (trinken vs gutschreiben).
  • Pro Code ist der Scope wählbar: 🔒 Lokal (wallet‑gebunden) oder 🌍 Global.
  • Lokale Action Codes sind an eine Wallet gebunden (Ziel-WalletId steckt im QR).
  • Globale Action Codes sind stateless und wirken auf das aktuell geöffnete Wallet.
  • Öffnest du wallet.html#acg:… direkt, wird bei mehreren Wallets eine Auswahl angezeigt; bei genau einem Wallet wird automatisch gebucht.
  • Beim Bearbeiten (Name/Menge/Typ) wird der QR bei Bedarf neu erzeugt; alte Codes werden dann ungültig und werden beim Einlösen strikt abgelehnt.
  • Der Betrag wird aus dem gespeicherten Action Code gelesen (nicht aus manipulierbaren QR-Feldern).
  • QR-Payloads sind schlank gehalten; ältere Payloads bleiben kompatibel.

Globale Action Codes (deterministisch)

Globale Action Codes (#acg:...) sind rein datengetrieben:

  • deterministisch: gleiche Eingaben → gleicher Link
  • keine Speicherung, keine Secrets
  • Validierung: Typ d/g, Menge 1..100
  • wenn kein Wallet geöffnet ist, wird eine Hinweis‑Meldung angezeigt
  • wirkt nur beim Scannen/Öffnen des Links, nicht automatisch

Sync Status (Top-Row)

Die Wallet zeigt einen rein lokalen Sync-Status an, um den Stand zwischen Geräten (z. B. Laptop ↔ Handy) sichtbar zu machen. Es gibt keinen Hintergrund-Sync: Synchronisieren passiert ausschließlich durch Export/Import.

Wie Syncing funktioniert

  • Export/Import (Link/QR/JSON) ist der einzige Weg, Daten zwischen Geräten zu übertragen.
  • Für die Sync-Anzeige zählen ausschließlich Events (nicht Getränkemengen). 1 Event = 1 Schritt auf der Timeline – unabhängig davon, ob ein Event +1 oder +10 enthält.

Wie man die Sync-Zeile liest (Mental Model)

Die ASCII-Timeline basiert auf der Anzahl der Events:

  • ===|: fester Marker für „zuletzt sicher gemeinsam“ (die = wachsen nicht)
  • Zeichen nach |: lokale Divergenz in Event-Schritten (1 Zeichen = 1 Event)
  • Die Anzahl der abweichenden lokalen Events wird zusätzlich separat als Δ angezeigt (kein ΔR).

Beispiele:

  • Sync: ===| → identisch
  • Sync: ===|MMMM → lokal 4 Events weiter
  • Sync: …==|MMMMMMMMMMMMMMMMMMMMMMMM → Divergenz gekürzt (rechts priorisiert)

Ampel-Logik & Reset

  • Grün: Sync aktuell (≤ 5 Tage)
  • Gelb: Sync alt (6–10 Tage)
  • Rot: Sync veraltet (≥ 11 Tage) → Klick führt zur Export-Sektion
  • Button „✅ passt“: manueller Vertrauens-Reset (setzt den Sync-Stand auf „gleich“ auf diesem Gerät, ohne Export/Import).

Geräte-Bewusstsein (pro Wallet, synchronisiert)

Pro Wallet gibt es eine synchronisierte Geräte-Liste (mit deviceKey, Symbol, lastSeenAt), die bei Export/Import mitgesendet und deterministisch gemerged wird:

  • Maximal 6 Geräte pro Wallet (älteste Einträge werden automatisch entfernt).
  • Pro Wallet ist jedes Symbol (L/M/D/K/T/*) eindeutig und wird per Buttons in der Top-Row zugewiesen (keine Texteingabe, keine Prompts).
  • Das lokale Geräte-Symbol zeigt die eigene Device-ID direkt daneben (mobile-tauglich, kein Hover nötig).

Code-Aufteilung (Stage 1)

Ein Teil der UI-Logik wurde aus wallet-ui.js in kleinere Dateien ausgelagert, damit agentic coding / Review einfacher ist:

  • wallet-device-ui.js: Geräte-Symbol-Picker in der Top-Row (inkl. sichtbarer Device-ID)
  • wallet-sync-ui.js: Sync-Status-Zeile (Ampel, Timeline, „✅ passt“)
  • wallet-export-ui.js: Export-UI (Link, QR, JSON, QR-Session-Cache)
  • wallet-history-ui.js: History-Ansicht (Diagramm/Log/Raw, Log-Tools)

Hinweis: wallet.html lädt diese Dateien vor wallet-ui.js.

Architektur (Core vs UI)

Core (Logik/Codec/Storage):

  • wallet-helpers.js, wallet-storage.js, wallet-import-v2.js
  • wallet-summary.js, wallet-sync.js, migration.js
  • action-codes.js (Normalisierung, Merge, Hash encode/decode)
  • hash-router.js (Hash-Parsing)

UI (DOM + Interaktion):

  • index-ui.js, wallet-ui.js
  • wallet-device-ui.js, wallet-history-ui.js, wallet-export-ui.js, wallet-sync-ui.js
  • import-preview.js, theme.js

Tools:

  • self-check.js (Konsole: window.dbWalletSelfCheck.run())

Self-Check

Im Browser (z. B. wallet.html) in der Konsole ausführen:

window.dbWalletSelfCheck.run()

Der Self-Check prüft u. a. Storage-Roundtrip, Import v2, Migration, Hash-Parsing, Summary-Parität, Tombstones/Undo und Action-Code-Payloads.

Datenmodell Hinweise

  • wallet.deviceId (Export/Sync-Metadatum) und wallet.seq (Event-Zähler pro Device-Key) bleiben getrennt; eine Zusammenlegung wäre nicht rückwärtskompatibel.

Dateien

Datei Zweck
index.html Startseite, Nutzer:innenwahl, Import/Export, Theme-Wahl
wallet.html Drinks, Guthaben, Zahlungen, Historie/Raw, Theme-Wahl
index-ui.js UI-Logik der Startseite (Routing, Liste, Import)
wallet-ui.js Wallet-Composer/Entry (DOM-Wiring, Hash-Routing, Module initialisieren)
wallet-device-ui.js Geräte-Symbol-Picker (Top-Row, sichtbare Device-ID)
wallet-sync-ui.js Sync-Status UI (Ampel + ASCII-Timeline + „✅ passt“)
wallet-export-ui.js Export UI (Link/QR/JSON, QR-Session-Cache, PNG-Download)
wallet-helpers.js Helper (Base64URL, gzip, Storage-Safety, Registry)
wallet-storage.js Wallet-Storage/Model (load/save, deviceKey, devices-Liste)
wallet-import-v2.js Import/Export-Codec v2 + Hash-Import (inkl. Action Codes)
wallet-summary.js Berechnung von Total/Offen/Guthaben/Diagramm (pure)
wallet-sync.js Sync-Status Helfer (Ampel + ASCII-Timeline; lokal)
action-codes.js Action Codes UI + Hash-Encoding/Decoding
wallet-history-ui.js History-UI (Diagramm/Log/Raw, Log-Tools)
hash-router.js Hash-Parsing (ac/import/i2/i2u)
self-check.js In-Browser Self-Check (Konsole)
theme.js Theme-Logik (Auswahl + Speicherung)
import-preview.js Import-Auswahl (persist/preview) + Preview-Flow
themes.css Theme-Paletten (CSS-Variablen)
colors.html Vorschau aller 5 Themes mit Farbbalken & UI-Beispielen
colors.css Styles für die Theme-Vorschau
style.css Basis-UI, responsive Layout
qrcodegen.js QR-Code-Generator (Nayuki)
migration.js Migration v1 → v2 (für QR-Export)

Deployment (statisch, „Pages“-Style)

db-wallet ist eine reine Static-Webapp (HTML/CSS/JS) und kann auf vielen Open-Source-freundlichen „Pages“-Diensten deployed werden.

Hosted „Pages“-Dienste (GitHub-Pages-ähnlich)

Self-hosted (Forgejo / Gitea)

Forgejo/Gitea bringen üblicherweise kein integriertes „Pages“-Feature wie GitHub/GitLab mit. Typischer Setup:

  1. Repo in Forgejo (https://forgejo.org/) oder Gitea (https://about.gitea.com/)
  2. CI (Forgejo Actions / Woodpecker / Drone) baut die Static Site (falls nötig)
  3. Deploy auf einen separaten Static Host (z. B. Nginx/Caddy oder S3/MinIO)

Tipp: Wenn du keinen Build brauchst, reicht auch simples Hosting des Repo-Roots als Static-Verzeichnis.

Es sind keine Build-Schritte, keine Server-Komponenten und keine API-Keys notwendig.

Beispiel-URL (GitHub Pages):
https://bmmmm.github.io/db-wallet/

Viel Spaß mit deinem minimalistischen, schnellen Getränke-Wallet 🍹🚀

LLM Notes (for quick repo understanding)

  • File map (core vs UI): Core/codec/storage in wallet-helpers.js, wallet-storage.js, wallet-import-v2.js, wallet-summary.js, wallet-sync.js, migration.js, action-codes.js, hash-router.js. UI in index-ui.js, wallet-ui.js, wallet-device-ui.js, wallet-sync-ui.js, wallet-export-ui.js, wallet-history-ui.js, import-preview.js, theme.js.
  • Invariants: storage prefix db-wallet:, registry key db-wallet:registry, hash formats #<userId>, #import:, #i2:, #i2u:, #ac:, #acg:; event schema {id,t,n?,ts,ref?} with tombstones t:"x" + ref; action code SOFT/HARD limits 6/10; global #acg: deterministic and stateless.
  • Entrypoints & flow: index.htmlindex-ui.js (list/create/import) and wallet.htmlwallet-ui.js (hash classify → load wallet → compute summary → render UI); hash-router.js is the single classifier/parser for hashes.
  • Where to edit: storage/model in wallet-storage.js; summary/tombstones in wallet-summary.js; action-code encode/decode + UI in action-codes.js; hash parsing in hash-router.js; UI wiring in index-ui.js / wallet-ui.js / wallet-history-ui.js.
  • Quick manual checks: open index.html → create/open wallet → add drinks/pay → undo (tombstone) → export/import v2 → local/global action codes → open wallet.html#acg:… with 1+ wallets → window.dbWalletSelfCheck.run().

About

Drink tracking wallet for friends of bitcircus101.de and Datenburg e.V. Bonn.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published