673 lines
23 KiB
Markdown
673 lines
23 KiB
Markdown
Pamietnik ist eine Journal App (Android + Webapp + Go Server)
|
||
|
||
1. Zielbild
|
||
Die Applikation besteht aus folgenden Komponenten
|
||
|
||
- Backend in go programmiert mit Postgres DB und REST API
|
||
- Webapp, eine simple im schlichten design umgesetzte Web App
|
||
- Android app loggt Standortdaten im Background, cached offline, und lädt per HTTP backend
|
||
|
||
Fuer Nutzung ist ein Account und Login notwendig.
|
||
|
||
Das Backend soll basierend auf Logdaten Vorschläge für bestimmte Standorte machen (z. B. wenn man sich länger an einem Ort aufhält). Die Standortinformationen (Reverse-Geocoding/Place-Info) sollen über eine kostenlose API bezogen werden.
|
||
|
||
Es möglich sein, manuell Punkte hinzuzufügen (ohne GPS).
|
||
|
||
2. Festlegungen (Decisions)
|
||
DEC-CLIENT-01: Android (Kotlin), UI mit Jetpack Compose.
|
||
|
||
DEC-CLIENT-LANG-01: Android wird in Kotlin implementiert (Android „Kotlin-first").
|
||
|
||
DEC-LOC-01: Standortlogging im Background ist erforderlich.
|
||
|
||
DEC-API-01: Server-Schnittstelle ist HTTP/REST (MQTT verworfen).
|
||
|
||
DEC-DOC-01: Alle wesentlichen Inhalte werden in Markdown gepflegt; Diagramme in Mermaid.
|
||
|
||
DEC-DB-01: Android lokal/offline: SQLite (über Room); Backend: PostgreSQL.
|
||
|
||
DEC-WEB-01: Server bietet Website mit Login; Anzeige der Trackpoints pro Tag.
|
||
|
||
DEC-AUTH-01: Für die Website wird Session-basierte Auth (Session Cookie) bevorzugt; JWT ist optional für spätere Erweiterungen (z. B. API-first/SSO).
|
||
|
||
DEC-MAP-01: Für Kartenanzeige wird OpenStreetMap-Datenbasis genutzt, mit MapLibre als SDK/Renderer (Android) bzw. Web-Kartenbibliothek nach Wahl; Tile-Quelle wird konfigurierbar gehalten.
|
||
|
||
DEC-GEO-01: Für Reverse-Geocoding (kostenlos) wird initial Nominatim (OSM) eingeplant, aber nur mit striktem Caching/Rate-Limiting und „Provider austauschbar"-Design.
|
||
|
||
DEC-OPENAPI-01: Die Backend-HTTP-Schnittstelle wird als OpenAPI-Dokument gepflegt (OpenAPI 3.1, YAML oder JSON).
|
||
|
||
3. Produktanforderungen (PRD Requirements)
|
||
3.1 Background-Logging & Permissions
|
||
REQ-LOC-01: Die App MUSS Standort im Vordergrund und im Hintergrund erfassen können.
|
||
|
||
REQ-LOC-02: Manifest & Runtime: COARSE (und optional FINE) MUSS deklariert und zur Laufzeit angefragt werden; die App MUSS mit „approximate" funktionieren.
|
||
|
||
REQ-LOC-03: Background-Location: Für Hintergrundzugriff MUSS Background-Location berücksichtigt und korrekt angefordert werden (wenn Background-Logging aktiviert ist).
|
||
|
||
REQ-LOC-04: Falls Tracking als Foreground Service umgesetzt wird, MUSS beim Service der Location-Typ gesetzt werden (foregroundServiceType="location").
|
||
|
||
3.2 Offline-First, Upload bevorzugt
|
||
REQ-SYNC-01: Trackpoints MÜSSEN zuerst lokal persistiert werden (keine rein RAM-basierte Queue).
|
||
|
||
REQ-SYNC-02: Upload ist bevorzugter Weg; bei Server-Nichterreichbarkeit MUSS gecached werden und später automatisch nachgesendet werden (Retry).
|
||
|
||
REQ-SYNC-03: Hintergrund-Upload SOLL über WorkManager erfolgen, mit Constraints „Network connected" und Retry/Backoff.
|
||
|
||
REQ-SYNC-04: Retries dürfen keine Duplikate erzeugen; es MUSS eine Idempotenz-Strategie geben (event_id).
|
||
|
||
3.3 Manuelle Punkte
|
||
REQ-MAN-01: Die App MUSS es erlauben, manuell einen Punkt hinzuzufügen (mindestens: lat, lon, timestamp; optional: Name/Notiz).
|
||
|
||
REQ-MAN-02: Manuelle Punkte MÜSSEN lokal in SQLite/Room gespeichert werden, genauso wie GPS-Punkte.
|
||
|
||
REQ-MAN-03: Manuelle Punkte MÜSSEN in den Upload-Flow (Queue) integriert sein und zum Server hochgeladen werden (inkl. event_id).
|
||
|
||
REQ-MAN-04: Manuelle Punkte MÜSSEN validiert werden (z. B. Pflichtfelder, Wertebereich) und bei Fehlern im UI eine verständliche Fehlermeldung anzeigen; Validierung kann „as the user types" erfolgen.
|
||
|
||
REQ-MAN-05: Der Nutzer SOLL optional „aktuellen Zeitpunkt" und/oder „aktuelle Position" als Vorschlag übernehmen können, aber die Eingabe bleibt manuell editierbar.
|
||
|
||
3.4 Export (sekundär)
|
||
REQ-EXP-01: Nutzer MUSS Logs/Trips in eine Datei exportieren können.
|
||
|
||
REQ-EXP-02: Export MUSS über Storage Access Framework erfolgen (z. B. ACTION_CREATE_DOCUMENT; Nutzer wählt Speicherort, App schreibt in URI).
|
||
|
||
3.5 Server Website
|
||
REQ-WEB-01: Der Server MUSS eine Website bereitstellen, die nur nach Login zugänglich ist (Auth erforderlich).
|
||
|
||
REQ-WEB-02: Nach Login MUSS die Website pro Tag die gespeicherten Punkte anzeigen können (z. B. Tagesliste + Detailansicht eines Tages).
|
||
|
||
REQ-WEB-03: Die Website MUSS die Daten nutzerspezifisch anzeigen (ein Nutzer sieht nur seine eigenen Daten / Devices/Trips innerhalb seiner Berechtigung).
|
||
|
||
REQ-WEB-04: Die Website SOLL eine Kartenansicht bieten (zusätzlich zur Liste), um Punkte/Stops pro Tag visuell darzustellen.
|
||
|
||
3.6 Security / Auth
|
||
REQ-AUTH-01: Passwörter DÜRFEN nicht im Klartext gespeichert werden; Password Hashing MUSS sicher erfolgen (Argon2id bevorzugt).
|
||
|
||
REQ-AUTH-02: Session-basierte Auth (Cookie) ist erlaubt; Sessions SOLLEN serverseitig verwaltet werden, damit Sessions invalidierbar sind (Logout/Expire).
|
||
|
||
REQ-AUTH-03: Auth muss auch für Web-Query-Endpoints gelten (Tagesliste/Tagesdetail sind geschützt).
|
||
|
||
3.7 Vorschläge/Stops
|
||
REQ-SUG-01: Das Backend MUSS aus Trackpoints „Stops" erkennen können (Aufenthalte an ungefähr gleicher Position über eine Mindestdauer).
|
||
|
||
REQ-SUG-02: Das Backend MUSS aus Stops „Vorschläge" ableiten können.
|
||
|
||
REQ-SUG-03: Stops/Vorschläge MÜSSEN pro Nutzer/Device/Trip zuordenbar sein und in der Website pro Tag sichtbar sein (Liste + Karte).
|
||
|
||
3.8 Kostenlose Standortinfo-API
|
||
REQ-GEO-01: Reverse-Geocoding/Place-Info MUSS über einen kostenlosen Dienst erfolgen (initial Nominatim), mit Caching und klaren Limits/Retry-Strategie.
|
||
|
||
REQ-GEO-02: Geocoding-Provider MUSS austauschbar sein (z. B. via Server-Config/Proxy), ohne App-Update.
|
||
|
||
REQ-GEO-03: Bulk/periodische Reverse-Geocoding Requests SOLLEN vermieden werden; Geocoding wird bevorzugt ereignisbasiert (z. B. pro erkanntem Stop) und gecached.
|
||
|
||
3.9 Karten-Dienst
|
||
REQ-MAP-01: Kartenanzeige SOLL auf OpenStreetMap-Daten basieren; Rendering/SDK via MapLibre (Android) oder äquivalente Open-Source Web-Kartenkomponente.
|
||
|
||
REQ-MAP-02: Tile-Quelle MUSS konfigurierbar sein (später Self-hosting oder Provider-Wechsel möglich).
|
||
|
||
3.10 OpenAPI
|
||
REQ-OPENAPI-01: Die Backend-HTTP-Schnittstelle MUSS im OpenAPI-Format dokumentiert werden (OAS 3.1).
|
||
|
||
REQ-OPENAPI-02: Das OpenAPI-Dokument MUSS als YAML oder JSON im Repository versioniert werden (Entry-Point: openapi.yaml oder openapi.json).
|
||
|
||
REQ-OPENAPI-03: Das OpenAPI-Dokument MUSS alle implementierten Endpoints, Schemas (Request/Response), Fehlerformate und Security-Schemes enthalten.
|
||
|
||
REQ-OPENAPI-04: Cookie-basierte Auth für Web-Endpoints SOLL im OpenAPI über type: apiKey, in: cookie beschrieben werden (CookieAuth).
|
||
|
||
3.11 Google Play / Transparenz
|
||
REQ-PRIV-01: Bei Standortzugriff im Hintergrund MUSS eine klare In-App-Erklärung/Disclosure vorhanden sein; Background-Location ist zu begründen und sauber zu deklarieren.
|
||
|
||
3.13 Hashtags
|
||
REQ-TAG-01: Trackpoints und manuelle Punkte MÜSSEN mit einem oder mehreren Hashtags versehen werden können (z. B. `#restaurant`, `#aussicht`, `#hotel`).
|
||
|
||
REQ-TAG-02: Hashtags MÜSSEN lokal in SQLite/Room gespeichert und beim Upload zum Server übertragen werden (als Teil des Trackpoint-Schemas, Feld `tags: string[]`).
|
||
|
||
REQ-TAG-03: Der Server MUSS Hashtags persistieren und pro Trackpoint/Stop abfragbar machen.
|
||
|
||
REQ-TAG-04: Die Webapp MUSS eine Filteransicht bieten, die alle Trackpoints eines Tages oder Trips nach einem oder mehreren Hashtags filtert.
|
||
|
||
REQ-TAG-05: Hashtags SOLLEN bei der Eingabe in der App als Vorschläge angezeigt werden (aus bereits verwendeten Tags des Nutzers).
|
||
|
||
REQ-TAG-06: Die Webapp SOLL eine Tag-Übersicht bieten, die alle verwendeten Hashtags des Nutzers mit Häufigkeit auflistet.
|
||
|
||
3.12 Dokumentationsstil
|
||
REQ-DOC-STYLE-01: Alle wesentlichen Anforderungen, Architekturentscheidungen, API-Contracts, Testanforderungen und Tasks MÜSSEN in diesem Markdown gepflegt werden.
|
||
|
||
REQ-DOC-STYLE-02: Im Chat wird nur minimal kommentiert; Details stehen im Markdown.
|
||
|
||
REQ-DOC-STYLE-03: Änderungen erfolgen als fortlaufende Updates dieses Dokuments.
|
||
|
||
4. Architektur-Dokumentation (arc42-orientiert)
|
||
Die Architekturdokumentation MUSS Kontextsicht, Bausteinsicht, Laufzeitsicht und Verteilungssicht enthalten.
|
||
Alle Diagramme MÜSSEN Mermaid sein.
|
||
Architektur wird zuerst erstellt und abgestimmt, bevor Implementierung beginnt.
|
||
|
||
4.1 Kontextsicht
|
||
Fachlicher Kontext (Kommunikationspartner)
|
||
Benutzer mobil (startet/stopt Trips, sieht Status, exportiert, fügt manuell Punkte hinzu).
|
||
|
||
Benutzer web (loggt sich ein, sieht pro Tag Punkte/Stops/Vorschläge).
|
||
|
||
Android OS / Location Services (liefert Standortupdates).
|
||
|
||
Webserver (nimmt Trackpoints entgegen, berechnet Stops, stellt Website bereit).
|
||
|
||
Geocoding-Dienst (liefert Adress-/Place-Infos).
|
||
|
||
Dateisystem via SAF (Export-Ziel).
|
||
|
||
Technischer Kontext (Schnittstellen)
|
||
Android → Server: HTTPS/REST (JSON oder Protobuf, Entscheidung offen).
|
||
|
||
Browser → Server: HTTPS (Web UI, Login, Views).
|
||
|
||
Server → Geocoding: HTTPS (Reverse-Geocoding; Provider austauschbar, gecached).
|
||
|
||
Android → SAF: ACTION_CREATE_DOCUMENT und Schreiben in content:// URI.
|
||
|
||
text
|
||
flowchart LR
|
||
UserM[User Mobile] -->|Start/Stop Trip, Export, Manual point| App[Android App]
|
||
OS[Android Location Services] -->|Location updates| App
|
||
App -->|HTTPS REST: trackpoints| API[Go REST API]
|
||
API --> DB[(PostgreSQL)]
|
||
API -->|HTTPS reverse-geocode cached| GEO[Geocoding Provider]
|
||
UserW[User Web] -->|HTTPS| Web[Go Web UI]
|
||
Web --> API
|
||
App -->|SAF create document| SAF[Android Storage Access Framework]
|
||
SAF --> File[(Exported file)]
|
||
4.2 Bausteinsicht
|
||
Bausteine (initial):
|
||
|
||
Android App: UI (Compose), Domain/Use-Cases, Background Location Logging, Manuelle Punkt-Eingabe, Lokale DB + Upload-Queue, Upload Worker, Export, Map View (optional).
|
||
|
||
Go Server: REST Router/Handler, Validation, Idempotenz/Dedupe, Persistenz, Observability.
|
||
|
||
Go Web UI: Login, Tagesübersicht, Tagesdetail (Punktliste + Karte), Vorschläge.
|
||
|
||
Suggestion Engine: Stop Detection + Reverse-Geocoding + Vorschlagslogik.
|
||
|
||
Geocoding Adapter: Provider/Proxy + Cache/RateLimit.
|
||
|
||
text
|
||
flowchart TB
|
||
subgraph Mobile[Android App]
|
||
UI[Compose UI]
|
||
Domain[Domain / Use-Cases]
|
||
Loc[Background Location Logging]
|
||
Manual[Manual Point Entry + Validation]
|
||
Store[(SQLite/Room: Local DB + Upload Queue)]
|
||
Worker[Upload Worker]
|
||
Export[Export SAF]
|
||
UI --> Domain
|
||
Domain --> Loc
|
||
Domain --> Manual
|
||
Loc --> Store
|
||
Manual --> Store
|
||
Store --> Worker
|
||
Domain --> Export
|
||
end
|
||
|
||
subgraph Server[Go Server]
|
||
API[HTTP REST API]
|
||
Val[Validation]
|
||
Idem[Idempotency/Dedupe]
|
||
Auth[Auth users sessions]
|
||
Web[Web UI login day view map]
|
||
Suggest[Stop Detection + Suggestions]
|
||
Geo[Geocoding Adapter + Cache]
|
||
SDB[(PostgreSQL)]
|
||
API --> Val --> Idem --> SDB
|
||
API --> Suggest --> SDB
|
||
Suggest --> Geo
|
||
Geo -->|HTTPS| Provider[Geocoding Provider]
|
||
Web --> Auth
|
||
Web --> API
|
||
Auth --> SDB
|
||
end
|
||
|
||
Worker -->|HTTPS Batch Upload| API
|
||
4.3 Laufzeitsicht (Szenarien)
|
||
Szenarien:
|
||
|
||
R1: Trip starten → Background-Logging → Trackpoints in lokale DB.
|
||
|
||
R2: Offline → Queue wächst → Online → Batch Upload → Ack → Queue markiert als sent.
|
||
|
||
R3: Retry/Duplicate → gleiche event_id erneut → Server erkennt Duplicate → kein doppelter Insert.
|
||
|
||
R4: Export → Nutzer wählt Datei → App schreibt Export.
|
||
|
||
R5: Web Login → Tagesübersicht → Tagesdetail (Punktliste + Karte).
|
||
|
||
R6: Stop erkannt → Reverse-Geocoding (cached) → Vorschlag wird gespeichert → Web zeigt Vorschlag.
|
||
|
||
R7: Nutzer fügt Punkt manuell hinzu → Validierung → SQLite/Room persistiert → Queue pending → später Upload.
|
||
|
||
text
|
||
sequenceDiagram
|
||
participant U as User
|
||
participant A as Android App
|
||
participant L as Location Services
|
||
participant D as Local DB Queue
|
||
|
||
U->>A: Start Trip
|
||
A->>L: Request location updates
|
||
L-->>A: Location update trackpoint
|
||
A->>D: Persist trackpoint pending
|
||
text
|
||
sequenceDiagram
|
||
participant A as Android App
|
||
participant W as WorkManager Worker
|
||
participant D as Local DB Queue
|
||
participant S as Go REST API
|
||
|
||
W->>D: Fetch pending batch
|
||
W->>S: POST /v1/trackpoints:batch
|
||
alt Server unreachable timeout
|
||
S--xW: Network error
|
||
W->>D: Keep pending; schedule retry
|
||
else Success
|
||
S-->>W: Ack accepted_ids rejected[]
|
||
W->>D: Mark accepted as sent; keep rejected with reason
|
||
end
|
||
text
|
||
sequenceDiagram
|
||
participant B as Browser
|
||
participant W as Go Web UI
|
||
participant A as Auth sessions
|
||
participant API as Go REST API
|
||
participant DB as PostgreSQL
|
||
|
||
B->>W: GET /login
|
||
B->>W: POST /login username + password
|
||
W->>A: Verify credentials + create session
|
||
A->>DB: Load user + verify hash
|
||
A-->>W: Session created
|
||
W-->>B: Set-Cookie session + redirect
|
||
|
||
B->>W: GET /days
|
||
W->>API: GET /v1/days auth
|
||
API->>DB: Query days group filter by date
|
||
API-->>W: days[]
|
||
W-->>B: Render days view
|
||
|
||
B->>W: GET /days/yyyy-mm-dd
|
||
W->>API: GET /v1/trackpoints?date=YYYY-MM-DD
|
||
API->>DB: Query trackpoints for date
|
||
API-->>W: trackpoints[]
|
||
W-->>B: Render day detail
|
||
text
|
||
sequenceDiagram
|
||
participant W as WorkManager Worker
|
||
participant S as Go REST API
|
||
participant DB as PostgreSQL
|
||
participant SE as Suggestion Engine
|
||
participant G as Geocoding Adapter Cache
|
||
participant P as Geocoding Provider
|
||
|
||
W->>S: POST /v1/trackpoints:batch
|
||
S->>DB: Persist trackpoints
|
||
S->>SE: Trigger stop detection async
|
||
SE->>DB: Read recent points
|
||
SE->>G: Reverse-geocode stop if not cached
|
||
alt Cache hit
|
||
G-->>SE: Place info cached
|
||
else Cache miss
|
||
G->>P: HTTPS reverse-geocode
|
||
P-->>G: Place info
|
||
G-->>SE: Place info
|
||
end
|
||
SE->>DB: Persist stop + suggestion
|
||
text
|
||
sequenceDiagram
|
||
participant U as User
|
||
participant A as Android App
|
||
participant V as Validation ViewModel
|
||
participant D as SQLite Room Queue
|
||
participant W as Upload Worker
|
||
participant S as Go REST API
|
||
|
||
U->>A: Add manual point lat/lon/time/note
|
||
A->>V: Update fields as user types
|
||
V-->>A: Show validation errors or OK
|
||
A->>D: Persist trackpoint source=manual pending
|
||
W->>D: Fetch pending batch
|
||
W->>S: POST /v1/trackpoints:batch
|
||
S-->>W: Ack
|
||
W->>D: Mark sent
|
||
4.4 Verteilungssicht
|
||
text
|
||
flowchart LR
|
||
Phone[Android Device] -->|Internet HTTPS| Edge[Reverse Proxy LB optional]
|
||
Browser[Web Browser] -->|Internet HTTPS| Edge
|
||
Edge --> API[Go API Service REST + Web UI]
|
||
API --> DB[(PostgreSQL)]
|
||
API --> GEO[Geocoding Adapter Proxy + Cache]
|
||
GEO -->|HTTPS| Provider[Geocoding Provider]
|
||
5. HTTP API (REST) — Vertrag (Draft)
|
||
5.1 Ziele
|
||
Single-Point ingest und Batch ingest.
|
||
|
||
Idempotenz über event_id (mind. unique pro device).
|
||
|
||
Klare Acks für Queue-Weiterdrehen.
|
||
|
||
Web UI benötigt Tagesaggregation und Tagesdetail.
|
||
|
||
Vorschläge/Stops müssen abfragbar sein.
|
||
|
||
5.2 Endpoints (Vorschlag)
|
||
Ingest:
|
||
|
||
POST /v1/trackpoints (single)
|
||
|
||
POST /v1/trackpoints:batch (batch)
|
||
|
||
GET /healthz
|
||
|
||
GET /readyz
|
||
|
||
Web/Query:
|
||
|
||
GET /v1/days?from=YYYY-MM-DD&to=YYYY-MM-DD
|
||
|
||
GET /v1/trackpoints?date=YYYY-MM-DD
|
||
|
||
GET /v1/stops?date=YYYY-MM-DD
|
||
|
||
GET /v1/suggestions?date=YYYY-MM-DD
|
||
|
||
GET /v1/tags (alle Tags des Nutzers mit Häufigkeit)
|
||
|
||
GET /v1/trackpoints?tag=restaurant (Filter nach Hashtag)
|
||
|
||
Web UI Routes (serverseitig gerendert):
|
||
|
||
GET /login
|
||
|
||
POST /login
|
||
|
||
POST /logout
|
||
|
||
GET /days
|
||
|
||
GET /days/{yyyy-mm-dd}
|
||
|
||
5.3 Datenmodell (Draft)
|
||
Trackpoint:
|
||
|
||
event_id (string, client-generated; UUID empfohlen)
|
||
|
||
device_id (string)
|
||
|
||
trip_id (string)
|
||
|
||
timestamp (RFC3339 oder epochMillis, offen)
|
||
|
||
lat, lon (float)
|
||
|
||
source: "gps" | "manual" (optional; Default: gps)
|
||
|
||
note (string, optional; nur bei manuellen Punkten)
|
||
|
||
tags (string[], optional; Hashtags ohne #-Präfix, z. B. ["restaurant", "aussicht"])
|
||
|
||
optional: accuracy_m, speed_mps, bearing_deg, altitude_m
|
||
|
||
Stop:
|
||
|
||
stop_id
|
||
|
||
device_id, trip_id
|
||
|
||
start_ts, end_ts
|
||
|
||
center_lat, center_lon
|
||
|
||
duration_s
|
||
|
||
place_label (optional, aus reverse-geocode)
|
||
|
||
place_details (optional JSON)
|
||
|
||
Suggestion:
|
||
|
||
suggestion_id
|
||
|
||
stop_id
|
||
|
||
type (z. B. "highlight", "name_place", "add_note")
|
||
|
||
title/text
|
||
|
||
created_at
|
||
|
||
dismissed_at (optional)
|
||
|
||
Batch response:
|
||
|
||
server_time
|
||
|
||
accepted_ids (string[])
|
||
|
||
rejected (array of {event_id, code, message})
|
||
|
||
Day summary:
|
||
|
||
date (YYYY-MM-DD)
|
||
|
||
count (int)
|
||
|
||
first_ts, last_ts (optional)
|
||
|
||
5.4 Idempotenz-Regel
|
||
Unique Key: (device_id, event_id)
|
||
|
||
Duplicate: Server antwortet erfolgreich (z. B. 200) und behandelt es als „already processed".
|
||
|
||
5.5 Auth (Draft)
|
||
Website-Zugriff MUSS Login erfordern (Session Cookie).
|
||
|
||
API-Calls für Web UI müssen Auth prüfen (Session).
|
||
|
||
Android Upload Auth ist separat zu entscheiden (API-Key vs Bearer/JWT).
|
||
|
||
6. Auth: Session Cookie vs JWT
|
||
Session Cookie (session-basiert, stateful)
|
||
Vorteile:
|
||
|
||
Browser sendet Cookies automatisch mit; serverseitige Sessions sind gut kontrollierbar.
|
||
|
||
Sofortiger Widerruf möglich (Logout = Session löschen).
|
||
|
||
Nachteile:
|
||
|
||
Server muss Session-State speichern und über Instanzen verfügbar machen (z. B. Postgres/Redis).
|
||
|
||
JWT (token-basiert, stateless)
|
||
Vorteile:
|
||
|
||
Stateless pro Request; skaliert oft leichter für reine APIs/mehrere Services.
|
||
|
||
Gut für API-first/SSO/Verteilung.
|
||
|
||
Nachteile:
|
||
|
||
Widerruf/Revocation, Rotation und Lebensdauer-Management erhöhen Komplexität.
|
||
|
||
Empfehlung für RALPH
|
||
Website: Session Cookie.
|
||
|
||
JWT optional später, falls API-first/SSO nötig wird.
|
||
|
||
7. Testing (Requirements)
|
||
7.1 Use-Case Coverage
|
||
Alle wichtigen Use Cases (R1–R7, plus Duplicate/Retry und Validierungsfehler) MÜSSEN automatisiert getestet werden.
|
||
|
||
7.2 Android Unit Tests
|
||
REQ-TEST-A01: Lokale JVM-Unit-Tests für Domain/Queue/Serializer/Retry-Entscheidungen.
|
||
|
||
REQ-TEST-A02: Unit Tests für Validierungslogik manueller Punkte.
|
||
|
||
7.3 Android Integration/Instrumentation (WorkManager)
|
||
REQ-TEST-A03: Integrationstests für Worker/Constraints/Delays mit WorkManager-Testunterstützung.
|
||
|
||
7.4 Go Unit & HTTP Handler Tests
|
||
REQ-TEST-S01: Go Unit Tests via testing (go test ./...).
|
||
|
||
REQ-TEST-S02: REST Handler Tests (inkl. /v1/days, /v1/trackpoints?date=…, /v1/stops, /v1/suggestions) mit net/http/httptest.
|
||
|
||
7.5 System-/Integrationstests (App ↔ Server)
|
||
REQ-TEST-I01: Integrationstest: Pending Queue → Batch Upload → Ack → Mark sent.
|
||
|
||
REQ-TEST-I02: Offline→Online-Wechsel: zuerst Fehler, später Erfolg.
|
||
|
||
REQ-TEST-I03: Duplicate event_id: gleicher Batch zweimal → keine Duplikate.
|
||
|
||
REQ-TEST-I04: Manual point → Queue → Upload → Ack (End-to-End).
|
||
|
||
7.6 Web UI Tests
|
||
REQ-TEST-W01: Login-Flow muss getestet werden (gültig/ungültig, Session created, Zugriffsschutz).
|
||
|
||
REQ-TEST-W02: Tagesansicht muss getestet werden (korrekte Tage, korrekte Punkte/Stops/Vorschläge pro Tag, AuthZ).
|
||
|
||
7.7 Geocoding/RateLimit Tests
|
||
REQ-TEST-GEO-01: Tests müssen sicherstellen, dass Reverse-Geocoding gecached wird und keine Bulk/periodischen Calls entstehen.
|
||
|
||
REQ-TEST-GEO-02: Provider-Wechsel muss testbar sein (Config umstellen → anderer Endpoint, ohne App-Update).
|
||
|
||
8. Backlog (Tasks)
|
||
8.1 Reihenfolge (wichtig)
|
||
T000: Architektur in diesem Dokument finalisieren (Kontext, Bausteine, Laufzeit, Verteilung) und abnehmen, bevor Implementierung startet.
|
||
|
||
T000e: Architektur-Review/Abnahme-Checkpoint (Issue/PR), erst danach Implementierungs-Tasks starten.
|
||
|
||
8.2 Android (Client)
|
||
T001: Compose-Projekt anlegen (Kotlin, minSdk festlegen).
|
||
|
||
T001a: Kotlin-Standards festlegen (Coroutines-Usage, KTX/Extensions, Code Style).
|
||
|
||
T004: Permissions im Manifest + Runtime-Flow (COARSE/FINE + Background).
|
||
|
||
T006: Background-Tracking Architektur (Provider/Manager/Service falls nötig).
|
||
|
||
T033: Android Persistenz: Room-Setup (Entities/DAOs/Migrations) auf SQLite-Basis.
|
||
|
||
T008: Lokale DB + Upload-Queue (pending/sent/failed, retryCount).
|
||
|
||
T012: Upload-Worker (Constraints Network connected, Retry/Backoff).
|
||
|
||
T018: Export via SAF ACTION_CREATE_DOCUMENT + Schreiben in URI.
|
||
|
||
T060: App-Kartenansicht (Track/Stops lokal anzeigen), SDK nach DEC-MAP-01 (optional).
|
||
|
||
T080: UI Screen/Flow „Manuellen Punkt hinzufügen" (lat/lon, timestamp, note optional).
|
||
|
||
T081: Eingabevalidierung in Compose (as the user types) + Fehlermeldungen.
|
||
|
||
T082: Persistenz: Manual-Point als Trackpoint in Room speichern, inkl. source=manual.
|
||
|
||
T083: Upload: Manual-Points in Batch/Single Upload einbeziehen (idempotent über event_id).
|
||
|
||
T084: Tests: Unit Tests für Validierung + Mapping; Integrationstest: Manual point → Queue → Upload → Ack.
|
||
|
||
Hashtags (Android):
|
||
|
||
T085: Room-Schema erweitern: tags-Feld (String-Array) in Trackpoint-Entity + Migration.
|
||
|
||
T086: UI: Hashtag-Eingabe in Compose (manueller Punkt + GPS-Punkt nachträglich taggen), Vorschläge aus vorhandenen Tags.
|
||
|
||
T087: Upload: tags-Feld in Batch-Payload einbeziehen.
|
||
|
||
8.3 Server (Go, HTTP + Web UI)
|
||
API / Persistenz:
|
||
|
||
T024: REST API finalisieren (Single + Batch, Fehlerformat, Limits).
|
||
|
||
T027: Persistenz: Postgres Schema + Migrationen + Indizes + Retention.
|
||
|
||
T028: Server-Idempotenz (unique event_id pro device).
|
||
|
||
T029: Observability (Logs/Metrics), Health/Ready.
|
||
|
||
T030: E2E lokal: docker compose (API + Postgres) + Minimal-Client zum Senden.
|
||
|
||
Auth / Website:
|
||
|
||
T050: User-/Auth-Konzept festlegen (User, Devices, Ownership, Session-Lifetime).
|
||
|
||
T051: Passwort-Hashing implementieren (Argon2id bevorzugt).
|
||
|
||
T052: Session-Management implementieren (Session-Store in Postgres, Cookie setzen, Logout/Invalidate).
|
||
|
||
T053: Web UI: Login-Seite (GET/POST), Zugriffsschutz (Middleware).
|
||
|
||
T054: Web UI: Tagesübersicht (GET /days) + Tagesdetail (GET /days/{date}) inkl. Karte.
|
||
|
||
T055: API: GET /v1/days und GET /v1/trackpoints?date=YYYY-MM-DD (Auth required).
|
||
|
||
T061: Stop Detection implementieren (Parameter: minDuration, radiusMeters; konfigurierbar).
|
||
|
||
T062: Suggestions implementieren (aus Stops ableiten; Storage + API).
|
||
|
||
T063: Geocoding Adapter + Cache + RateLimit + Provider-Wechsel implementieren.
|
||
|
||
T064: Web UI: Stops/Vorschläge pro Tag anzeigen (Liste + Karte).
|
||
|
||
OpenAPI:
|
||
|
||
T070: OpenAPI-Dokument anlegen (openapi.yaml als OAS 3.1) und im Repo versionieren.
|
||
|
||
T071: OpenAPI vollständig halten: alle Endpoints/Schemas/Responses/Errors/Security abbilden, inkl. CookieAuth für Web-API.
|
||
|
||
T072: OpenAPI in CI validieren (Spec-Validation) und Änderungen nur via PR.
|
||
|
||
Hashtags (Server + Webapp):
|
||
|
||
T073: DB-Schema: tags-Spalte (text[]) in trackpoints-Tabelle + Migration + Index (GIN für Array-Suche).
|
||
|
||
T074: API: tags in Ingest-Endpoints annehmen und speichern; GET /v1/tags (Häufigkeit) und GET /v1/trackpoints?tag=... implementieren.
|
||
|
||
T075: Webapp: Tag-Filter in Tagesdetail; Tag-Übersicht (/tags); Tags bei Trackpoints anzeigen.
|
||
|
||
T076: OpenAPI: tags-Feld in Trackpoint-Schema + neue Endpoints dokumentieren.
|
||
|
||
8.4 Tests
|
||
T040: Use-Case-Matrix (Use Case → Testart).
|
||
|
||
T041: Android Unit Tests (Queue/Serializer/Retry/Validation).
|
||
|
||
T042: Android WorkManager Integrationstests.
|
||
|
||
T043: Go Unit Tests (testing).
|
||
|
||
T044: Go HTTP Handler Tests (httptest).
|
||
|
||
T045: Integrationstests (E2E ingest + Ack + Dedupe).
|
||
|
||
T057: Web Login Tests (happy path + invalid creds + session required).
|
||
|
||
T058: Web Tagesansicht Tests (korrekte Tage, korrekte Punkte pro Tag, AuthZ).
|
||
|
||
T065: Stop/Suggestion Tests (synthetische Trackpoints → erwartete Stops/Vorschläge).
|
||
|
||
T066: Geocoding Cache/RateLimit Tests (keine Bulk Calls; Provider switch).
|
||
|
||
9. Offene Entscheidungen (Checklist)
|
||
timestamp Format: epochMillis vs RFC3339.
|
||
|
||
Android Upload Auth: X-API-Key vs Bearer/JWT (Web bleibt Session Cookie).
|
||
|
||
Payload: JSON vs Protobuf über HTTP.
|
||
|
||
Batch limits (max items, max bytes).
|
||
|
||
Server Retention-Policy (wie lange Trackpoints gespeichert werden).
|
||
|
||
Stop-Detection Parameter (min Dauer, Radius).
|
||
|
||
Karten-Tile-Provider (konkreter Anbieter/Hosting; muss austauschbar bleiben).
|
||
|
||
Geocoding Provider (konkret: Nominatim public vs self-hosted Nominatim vs alternative freie Provider); Nutzung muss Policy-konform sein. |