Zurück zum Blog
projektsendlybouldernentwicklung

Sendly (Arbeitstitel) — eine App fürs Bouldern, weil die Excel-Tabelle nicht mehr reichte

Punkte für jeden Send, Leaderboards für Halle und Freunde, Routen per Foto anlegen und seit Kurzem ein Trainings-Timer. Was in einem Jahr Nebenbei-Entwicklung entstanden ist — und warum der Name noch nicht feststeht.

Sendly (Arbeitstitel) — eine App fürs Bouldern, weil die Excel-Tabelle nicht mehr reichte

Wir hatten irgendwann angefangen, eine Excel-Tabelle zu erstellen, um uns ein bisschen vergleichen zu können, wer welche Route getoppt hat. Die Excel-Tabelle ist über Jahre gewachsen, war mittel übersichtlich, und Auswertungen, Statistiken und Vergleiche auf „feinerer” Ebene waren so nicht möglich. Am Handy war die Tabelle nicht wirklich gut bedienbar.

Also habe ich angefangen, das als App zu bauen. Seit Mitte Juni läuft sie produktiv, aktuell in Version 0.12. Dieser Post ist die Bestandsaufnahme: was drin ist, warum es so gebaut ist, und was noch fehlt.

Zum Namen

Sendly ist ein Arbeitstitel. Er kommt vom „Send” — Klettersprache für einen durchgestiegenen Boulder — und er hat den Vorteil, dass man ihn tippen kann. Mehr spricht nicht für ihn. Der endgültige Name steht noch aus, und ich gehe fest davon aus, dass er ein anderer wird. Wenn hier also gleich zwanzigmal „Sendly” steht: bitte als Platzhalter lesen.

Die Regeln, um die herum alles gebaut ist

Bevor eine Zeile Code entstand, standen drei Festlegungen. Sie klingen banal, aber sie entscheiden über fast jedes Detail weiter unten.

Ein Punkt pro Send. Egal welcher Grad. Für einen Flash — durchgestiegen im ersten Versuch — gibt es 0,25 Punkte extra. Das war’s. Kein Grad-Multiplikator, keine gewichteten Formeln. Wer schwer klettert, sammelt nicht automatisch mehr Punkte, sondern muss genauso viele Boulder machen wie alle anderen. Das war in der Excel-Tabelle noch anders. Dort gab es für höhere Schwierigkeitsgrade mehr Punkte, was aber teils zu immensen Abständen führte.

Die Schwierigkeitsbewertung gibt keine Punkte. Man kann jeden Send als soft, normal oder hart bewerten — aber das ist reine Meinungsäußerung fürs Vergleichen („fandet ihr die 5 an der Platte auch geschenkt?”). Es fließt bewusst in keine Wertung ein.

Zwei Vergleichsarten, zwei Leaderboards. Aktuell geschraubt zählt nur Sends auf Routen, die gerade hängen — und wird nach dem Umschrauben von selbst wieder eng. Jahresliste zählt alles im Kalenderjahr. Dazu jeweils eine Ansicht für die ganze Halle und eine nur für die eigenen Freunde. Auch das ist direkt aus der Tabelle übernommen.

Leaderboard mit Routen-Matrix
Das Leaderboard als Matrix: eine Zeile pro Route, eine Spalte pro Person. Haken heißt getoppt, Blitz heißt geflasht — und wer eine Route noch nicht geschafft hat, sieht dort seine Versuchszahl stehen.

Was die App heute kann

Routen und die Wand

Jede Route hat eine Farbe, einen Grad, einen Sektor und ein Schraubdatum. Dazu eine fortlaufende Nummer, die sich nie mehr ändert — damit „die 47 ist falsch eingetragen” per WhatsApp eindeutig bleibt, auch wenn zwischendurch Routen gelöscht wurden.

Statt den Sektor aus einer Dropdown-Liste zu suchen, gibt es einen Grundriss der Halle als anklickbare Grafik: Wettkampfwand, Block vorne, Block hinten, Platte, Trainingsbereich. Man tippt auf die Fläche, in der man steht. Derselbe Plan dient in den Statistiken und im Leaderboard als Filter.

Hallenplan mit anklickbaren Sektorflächen
Der Hallenplan als Sektor-Auswahl. Kilter- und Moonboard, Kinderbereich und Eingang sind nur zur Orientierung da und nicht anklickbar.

Abgeschraubt wird nie durch Löschen. Eine Route, die von der Wand kommt, wird auf inaktiv gesetzt — sie verschwindet aus „aktuell geschraubt”, bleibt aber in der Jahresliste und in allen Statistiken erhalten. Löschen gibt es nur für echte Fehleinträge, mit zweistufiger Bestätigung und dem Hinweis, wie viele Sends dabei verloren gehen.

Routenliste mit Farbpunkt, Grad und Sektor
Die Routenliste, wahlweise als kompakte Liste oder als Karten mit Foto-Thumbnail.

Einen Send loggen

Der eigentliche Kernvorgang, und der, der am Handy in der Halle mit einer Hand funktionieren muss. Pro Route gibt es drei Zustände: ein Versuch zählt hoch, ein Top wird gesetzt, ein Flash ist ein Top im ersten Versuch. Alles an derselben Zeile, ohne Formular und ohne Dialog.

Im Hintergrund werden die Sends zu Sessions gebündelt — alles, was an einem Hallentag passiert, gehört zusammen. Das klingt nach einem Implementierungsdetail, ist aber die Grundlage für „wie viele Routen habe ich am 12. Juli geschafft und wie viele Versuche hat das gekostet”.

Routen per Foto anlegen

Das ambitionierteste Feature. Man fotografiert die Wand, und die App legt daraus Routen an: Eine Bilderkennung liest die Farbe der Griffe und den Grad — der steht bei uns als Zahl von 1 bis 8 auf einem kleinen schwarzen Schild neben dem Startgriff. Aus einem Wandfoto entstehen so mehrere vorausgefüllte Routen auf einmal, die man nur noch durchsieht und bestätigt.

Beim Hochladen werden die Fotos serverseitig verkleinert und komprimiert — aus einem 6-MB-Handyfoto wird ein knappes halbes Megabyte. Nebeneffekt: Sämtliche Metadaten fliegen dabei raus, inklusive der GPS-Koordinaten, die moderne Handys in jedes Bild schreiben.

Aus einem Wandfoto erkannte Routen zur Bestätigung
Aus einem Wandfoto erkannte Routen — Farbe und Grad vorausgefüllt, der Rest ist Durchsehen und Bestätigen.

Statistiken

Punkte über die Zeit, Verteilung der Sends über die Grade, Aufstellung pro Session. In der Grad-Verteilung stehen hinter den eigenen Sends grau die offenen Routen — man sieht also nicht nur „ich habe vier Fünfer”, sondern auch „von elf”. Das ändert die Aussage des Diagramms komplett.

Statistik-Seite mit Balkendiagramm nach Grad
Sends pro Grad, dahinter grau, was noch offen ist.

Freunde

Über einen persönlichen Code kann man sich gegenseitig hinzufügen, Anfragen werden bestätigt oder abgelehnt. Der einzige Zweck: das Freundes-Leaderboard füllen und im Vergleich auswählen können, gegen wen man antritt.

Trainings-Tab (neu in 0.12)

Der jüngste größere Brocken, und der erste, der nichts mit der Wand zu tun hat. Man stellt sich eine Trainingseinheit zusammen — Übung, Sätze, Wiederholungen, Pausen — und startet einen Live-Timer im Vollbild, der einen durch die Einheit führt.

Ein paar Dinge daran waren interessanter, als sie klingen:

  • Zwei Arten von Wiederholungen. Gehaltene Wiederholungen (Hangboard, Plank) bekommen einen Countdown. Gezählte Wiederholungen kann keine Maschine erkennen, also zählt der Timer dort hoch und endet erst per Tipp. Nebeneffekt: Das ist automatisch der Modus für ein Training bis zum Muskelversagen — die Anzahl kennt vorher ohnehin niemand, und die tatsächliche Satzdauer wird mitgeschrieben, damit „länger durchgehalten als letzte Woche” überhaupt ablesbar ist.
  • Signaltöne bei 10 Sekunden Restzeit und im 3-2-1-Countdown. Dafür musste die Zeitrechnung des Timers umgebaut werden: Mobile Browser drosseln Timer massiv, sobald das Display aus ist — also genau dann, wenn das Handy in der Tasche liegt und man sich auf die Töne verlässt. Der Timer rechnet jetzt gegen die Wanduhrzeit statt gegen gezählte Ticks. Dazu Vibration parallel zum Ton, weil ein iPhone im Stummmodus schlicht nichts abspielt.
  • Eine Punchcard über Wochentag und Uhrzeit, die zeigt, wann man tatsächlich trainiert. Zweifarbig: Beere für Krafttraining, Blau fürs Bouldern, Violett, wenn beides in dieselbe Stunde fällt. Eine einzelne Zahl pro Feld hätte die eigentliche Frage — „gehe ich abends bouldern oder mache ich Kraft?” — unbeantwortet gelassen.
Trainings-Rhythmus als Punchcard über Wochentag und Uhrzeit
Die Punchcard: Wochentag mal Uhrzeit. Beere ist Krafttraining, Blau ein Hallenbesuch. Das Zeitfenster zieht sich an den Daten auf — eine Einheit um 5:30 würde es nach links erweitern, statt aus dem Raster zu fallen.
Live-Timer im Vollbild während einer Trainingseinheit
Der Live-Timer läuft im Vollbild — bewusst außerhalb der App-Navigation, damit die Bedienfläche nicht unter der Menüleiste liegt.

Unter der Haube

Spring Boot mit PostgreSQL im Backend, React mit Vite im Frontend, alles in Docker. Anmeldung per Token, E-Mail-Bestätigung ist Pflicht — nicht aus Prinzipienreiterei, sondern weil eine offene Registrierung ohne Bestätigung sich früher oder später mit Spam-Accounts füllt. Die App ist als PWA installierbar, weil sie zu 95 % am Handy in der Halle benutzt wird.

Drei Rollen, aufeinander aufbauend: normale Nutzer tracken ihre Sends, Hallenbesitzer legen zusätzlich Routen an und schrauben sie ab, Admins vergeben Rollen. Das brauchte es, sobald mehr als ich selbst Routen eintragen wollte.

Dazu kam zuletzt etwas Infrastruktur für mich selbst: Jeder Pull Request bekommt automatisch eine eigene, vollständig laufende Kopie der App unter einer eigenen Adresse, mit eigener Datenbank. Damit kann ich eine Änderung am Handy ausprobieren, bevor sie in die echte Halle geht.

Was noch fehlt

Ein flexibleres Grading-System. Aktuell hängt einiges an der Zahl-von-1-bis-8-Skala unserer Halle. Für eine zweite Halle mit Farbskala oder Fontainebleau-Graden müsste das lockerer werden.

Datum aus den Foto-Metadaten. Beim Foto-Anlegen könnte das Schraubdatum direkt aus dem Aufnahmedatum kommen, statt getippt zu werden.

Datenbank-Backups. Läuft noch nicht automatisiert. Das ist der Punkt auf dieser Liste, der mir nachts am ehesten einfällt.

Mehrere Hallen. Datenmodell und Oberfläche sind bewusst so gebaut, dass eine zweite Halle nachrüstbar bleibt — Sektoren sind freier Text, die Routennummerierung hat absichtlich keinen globalen Zwang. Gebaut ist es aber nicht, und ich baue es erst, wenn es jemand tatsächlich braucht.

Und ein Name. Siehe oben.

Vorerst tut das Ding genau das, wofür es gedacht war: Die Excel-Tabelle ist zu, und nach dem Umschrauben trägt sich jeder selbst ein.