147 lines
7.2 KiB
Markdown
147 lines
7.2 KiB
Markdown
# 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 und `fast-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/restore` verschiebt die Daten zurück und korrigiert alle gespeicherten Pfade
|
|
|
|
## Schnellstart
|
|
|
|
```bash
|
|
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:
|
|
|
|
```dotenv
|
|
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:
|
|
|
|
```json
|
|
{
|
|
"ok": true,
|
|
"service": "wegwichtel",
|
|
"instance": "Atlas",
|
|
"socket": "127.0.0.1:47145"
|
|
}
|
|
```
|
|
|
|
## Initialisierungsablauf des Clients
|
|
|
|
1. statischer Initialisierungsbildschirm erscheint ohne Bibliotheksabhängigkeit,
|
|
2. lokale jQuery-Datei wird geladen und auf Version 4.0.0 geprüft,
|
|
3. lokales jQuery UI 1.14.2 samt Base-Theme wird geladen und über `jQuery.ui.version` geprüft,
|
|
4. die Clientmodule werden sequenziell geladen,
|
|
5. `/api/health` prüft Server und SQLite,
|
|
6. der Client lädt die Routenliste,
|
|
7. anschließend wird die Position ermittelt und die Liste auf nahe Routen eingeschränkt,
|
|
8. 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:
|
|
|
|
```text
|
|
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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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
|
|
|
|
```text
|
|
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 `Atlas` erscheint im Startprotokoll, im Initialisierungsbildschirm und in `/api/health`.
|
|
- Für die Geolokalisierung sollte der Client über `http://127.0.0.1:47145` geöffnet werden. Ein frei aufgelöster Hostname wie `http://Atlas:47145` gilt 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
|