7.2 KiB
Wegwichtel Next
Neuaufbau des früheren schiffsbezogenen Ansagesystems als mobile Lernweg-Anwendung für Schulen. GPX-Strecken werden serverseitig verwaltet; POIs können Bilder und eine Audioansage enthalten. Der Client schlägt anhand der aktuellen Position nahe Routen vor und aktiviert POIs während einer Wanderung über einen GPS-Watcher.
Architektur
- Server: Node.js 22.13+, Express 5,
node:sqlite, Multer undfast-xml-parser - Client: klassisches JavaScript, jQuery 4.0.0 und jQuery UI 1.14.2 mit lokalem Base-Theme
- Medien: getrennte Verzeichnisse für aktive und zum Löschen markierte Strecken
- Löschmodell: Soft Delete in SQLite plus atomisches Verschieben des gesamten Streckenordners in
storage/trash/routes - Wiederherstellung:
POST /api/routes/:id/restoreverschiebt die Daten zurück und korrigiert alle gespeicherten Pfade
Schnellstart
cp .env.example .env
npm install
npm run init-db
npm start
Danach lauscht die Instanz Atlas ausschließlich auf dem lokalen Socket 127.0.0.1:47145 und ist unter http://127.0.0.1:47145 erreichbar. Die offiziellen, exakt versionierten Distributionsdateien sind bereits unter public/vendor enthalten. npm install installiert zusätzlich die Pakete jquery@4.0.0 und jquery-ui@1.14.2 und synchronisiert daraus JavaScript, Base-Theme, Themebilder und Lizenzdateien erneut in das Vendor-Verzeichnis. Der Browser lädt keine Bibliotheken von einem CDN.
Server-Socket und Instanz Atlas
Die Standardwerte stehen in .env.example und werden auch verwendet, wenn keine .env vorhanden ist:
HOST=127.0.0.1
PORT=47145
INSTANCE_NAME=Atlas
HOST ist die tatsächliche Bind-Adresse des Node.js-Servers. INSTANCE_NAME ist eine lesbare Bezeichnung und ändert weder DNS noch die Bind-Adresse. Dadurch verweist die Anwendung auf Atlas, bleibt aber auf den lokalen Loopback-Socket beschränkt. Der Health-Endpunkt meldet beispielsweise:
{
"ok": true,
"service": "wegwichtel",
"instance": "Atlas",
"socket": "127.0.0.1:47145"
}
Initialisierungsablauf des Clients
- statischer Initialisierungsbildschirm erscheint ohne Bibliotheksabhängigkeit,
- lokale jQuery-Datei wird geladen und auf Version 4.0.0 geprüft,
- lokales jQuery UI 1.14.2 samt Base-Theme wird geladen und über
jQuery.ui.versiongeprüft, - die Clientmodule werden sequenziell geladen,
/api/healthprüft Server und SQLite,- der Client lädt die Routenliste,
- anschließend wird die Position ermittelt und die Liste auf nahe Routen eingeschränkt,
- die responsive Routenansicht wird freigeschaltet.
Scheitert ein Schritt, bleibt der Initialisierungsbildschirm mit einer konkreten Fehlermeldung und einem Wiederholungsbutton sichtbar.
Lokale UI-Abhängigkeiten
Im Vendor-Verzeichnis liegen die zur Laufzeit verwendeten Dateien vollständig lokal:
public/vendor/jquery/jquery-4.0.0.min.js
public/vendor/jquery/LICENSE.txt
public/vendor/jquery-ui/jquery-ui-1.14.2.min.js
public/vendor/jquery-ui/jquery-ui-1.14.2.min.css
public/vendor/jquery-ui/images/*.png
Die Anwendung verwendet aus jQuery UI insbesondere die Widgets Button und Controlgroup. Das offizielle vollständige jQuery-UI-Bundle bleibt lokal verfügbar, damit weitere aktuelle Widgets ohne erneuten CDN-Bezug ergänzt werden können. Die frühere jQuery-Mobile-Seitensteuerung wurde durch eine eigene, History-API-basierte Navigation ersetzt.
REST-API
| Methode | Pfad | Zweck |
|---|---|---|
| GET | /api/health |
Server- und SQLite-Selbsttest |
| GET | /api/routes?lat=…&lon=…&radiusKm=25 |
aktive, optional nahe Routen |
| GET | /api/routes/:id |
Route, Trackpunkte, POIs und Medien-URLs |
| GET | /api/routes/:id/pois |
POIs einer Route |
| GET | /api/pois/:id |
einzelner POI samt Bild- und Audio-URLs |
| POST | /api/routes |
neue Route; multipart/form-data, Feld gpx |
| PUT | /api/routes/:id |
Metadaten und optional GPX vollständig ersetzen |
| POST | /api/routes/:id/append |
zusätzliche GPX-Trackpunkte anhängen |
| POST | /api/routes/:id/pois |
POI anlegen; Felder audio und images |
| PUT | /api/pois/:id |
POI ändern und weitere Medien ergänzen |
| DELETE | /api/routes/:id |
Route samt Medien in den Papierkorb verschieben |
| POST | /api/routes/:id/restore |
Route aus dem Papierkorb wiederherstellen |
Route anlegen
curl -X POST http://127.0.0.1:47145/api/routes \
-F 'name=Schulwald-Runde' \
-F 'schoolName=Beispielschule' \
-F 'description=Naturkundlicher Rundweg' \
-F 'gpx=@examples/sample-route.gpx;type=application/gpx+xml'
POI mit Bildern und Audio anlegen
curl -X POST http://127.0.0.1:47145/api/routes/1/pois \
-F 'title=Die alte Eiche' \
-F 'description=Hier wird das Alter der Eiche erklärt.' \
-F 'lat=52.5208' -F 'lon=13.4070' -F 'triggerRadiusM=60' \
-F 'audio=@ansage.mp3;type=audio/mpeg' \
-F 'images=@eiche-1.jpg;type=image/jpeg' \
-F 'images=@eiche-2.jpg;type=image/jpeg'
Dateistruktur
public/ mobiler Client
js/bootstrap-loader.js lädt und prüft lokale Bibliotheken
vendor/ lokale jQuery-/jQuery-UI-Dateien samt Themebildern
src/routes/ REST-Routing
src/services/ GPX-, Geodaten-, Speicher- und Fachlogik
database/schema.sql SQLite-Schema
data/ lokale SQLite-Datei
storage/active/routes/ aktive GPX-, Bild- und Audiodateien
storage/trash/routes/ zum Löschen markierte Strecken
examples/ Beispiel-GPX
test/ Basistests
Technische Hinweise
- Medienpfade werden relativ zu
storage/gespeichert. So bleibt das Projekt verschiebbar. - Dateiverschiebung und Datenbankänderung sind durch eine kompensierende Rückverschiebung gekoppelt: Schlägt die SQL-Transaktion fehl, wird das Verzeichnis an seinen vorherigen Ort zurückbewegt.
- GPX-Erweiterungen ergänzen die Trackpunkte in SQLite. Das Original-GPX bleibt im Skelett unverändert; ein späterer Exportdienst sollte aus den Datenbankpunkten eine konsolidierte GPX-Datei generieren.
- Schreibzugriffe sind noch nicht authentifiziert. Vor einem öffentlichen Einsatz sind Rollen, Login, CSRF-Schutz, Rate-Limits, Dateisignaturprüfung und ein Moderationsworkflow zwingend zu ergänzen.
- Der Server bindet standardmäßig nur an
127.0.0.1; Zugriffe von anderen Geräten sind damit bewusst ausgeschlossen. - Die Instanzbezeichnung
Atlaserscheint im Startprotokoll, im Initialisierungsbildschirm und in/api/health. - Für die Geolokalisierung sollte der Client über
http://127.0.0.1:47145geöffnet werden. Ein frei aufgelöster Hostname wiehttp://Atlas:47145gilt in Browsern ohne HTTPS in der Regel nicht als sicherer Kontext.
Nächste Ausbaustufen
- Administrationsoberfläche zum Zeichnen/Importieren von Routen und Platzieren der POIs
- Benutzer-, Schul- und Projektzuordnung mit Rollenmodell
- Offline-Cache/PWA für Wanderungen ohne Mobilfunkempfang
- Kartenansicht, GPX-Visualisierung und Abweichungswarnung
- Bildunterschriften, Sortierung und gezieltes Entfernen einzelner Medien
- Hintergrundbereinigung des Papierkorbs nach einer konfigurierbaren Aufbewahrungsfrist
- Integritätsjournal für Dateiverschiebungen und Wiederherstellungen