initial commit
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user