API Endpoint /vehicles/:id/timeseries #4

Open
opened 2026-08-27 21:26:32 +02:00 by erdbruegger · 1 comment
Owner

Der "/vehicles/:id/timeseries" Endpoint sollte etwas aufgebohrt werden:

  • Zusätzlich zu der :id sollte auch die vin als Parameter akzeptiert werden
  • Per Default sollten nur die letzten 50-100 Einträge zurück gegeben werden
  • Zusätzliche query-parameter ermöglichen schäfere selektieren, bspw. filter über "kategorie" oder datum, limit, etc
Der "/vehicles/:id/timeseries" Endpoint sollte etwas aufgebohrt werden: - Zusätzlich zu der :id sollte auch die vin als Parameter akzeptiert werden - Per Default sollten nur die letzten 50-100 Einträge zurück gegeben werden - Zusätzliche query-parameter ermöglichen schäfere selektieren, bspw. filter über "kategorie" oder datum, limit, etc
Collaborator

Umgesetzt in 46f55e6 (release) — CI grün, deployt, live verifiziert.

1. VIN statt ID im Pfad

:id ist bei /vehicles/:id/timeseries und /vehicles/:id/latest jetzt die Fahrzeug-ID oder die VIN:

curl "$BASE/vehicles/1/timeseries"                  # wie bisher
curl "$BASE/vehicles/LMWHP1S89N1000000/timeseries"  # neu
curl "$BASE/vehicles/lmwhp1s89n1000000/latest"      # VIN case-insensitiv

Reine Ziffernfolgen werden zuerst als ID probiert und danach noch als VIN — eine rein numerische VIN ist unüblich, aber nichts im Schema verbietet sie, und so bleibt beides erreichbar. Ist weder ID noch VIN bekannt, kommt ein 404 {"error":"vehicle not found"} statt wie bisher eine stille leere Liste. Der Pfad wird als Bind-Parameter aufgelöst; ein VIN-Segment mit SQL darin landet nur in einem erfolglosen Lookup.

2. Default nur noch die letzten ~100 Einträge

War Teil von #1 und ist bereits live: limit hat den Default 100 (vorher 5000) und die Sortierung steht auf ts desc, du bekommst also ohne Parameter die 100 jüngsten Einträge. Dazu offset zum Blättern; die Gesamttrefferzahl steht im Header X-Total-Count.

3. Schärfer selektieren

Ebenfalls aus #1: from/to fürs Zeitfenster, f_<spalte> je Spalte (>80, >=80, <80, 10..50, leer, Teilstring bei Textspalten), sort + dir, every fürs Downsampling.

Für „Kategorie" habe ich als sinnvollste Auslegung die drei einordnenden Spalten ergänzt — sag Bescheid, falls du etwas anderes gemeint hast:

Filter Beispiel
f_source f_source=inx — nur Records aus dem .inx-Recorder (vs. cache_data)
f_charge_state f_charge_state=2
f_status f_status=1

Die Quelle ist jetzt auch eine eigene Spalte in der Dashboard-Tabelle, damit der Filter dort erreichbar ist.

Verifikation (echte Postgres-Instanz mit Produktivschema, 200 Zeilen)

  • ID, VIN in Groß- und in Kleinschreibung liefern alle dasselbe Fahrzeug (X-Total-Count: 200).
  • Unbekannte VIN und unbekannte ID → 404 bei timeseries und latest.
  • f_source=inx → 100 von 200, f_source=cache_data → 100, f_charge_state=2 → 67 — passt exakt zu den Testdaten.
  • Ohne limit kommen 100 Zeilen zurück.
  • VIN-Segment mit '; DROP TABLE telemetry; -- → 404, Tabelle danach unverändert bei 200 Zeilen.
  • Selbsttests grün, Live: /health ok, beide Routen weiterhin 401 ohne Token, Sandbox-Doku und Dashboard auf neuem Stand. Testdatenbank wieder entfernt.

Punkt 2 und der Großteil von Punkt 3 waren durch #1 schon abgedeckt; neu dazugekommen sind hier die VIN-Auflösung, das 404 und die Kategorie-Filter.

**Umgesetzt** in `46f55e6` (release) — CI grün, deployt, live verifiziert. ### 1. VIN statt ID im Pfad `:id` ist bei **`/vehicles/:id/timeseries`** und **`/vehicles/:id/latest`** jetzt die Fahrzeug-ID *oder* die VIN: ```bash curl "$BASE/vehicles/1/timeseries" # wie bisher curl "$BASE/vehicles/LMWHP1S89N1000000/timeseries" # neu curl "$BASE/vehicles/lmwhp1s89n1000000/latest" # VIN case-insensitiv ``` Reine Ziffernfolgen werden zuerst als ID probiert und danach *noch* als VIN — eine rein numerische VIN ist unüblich, aber nichts im Schema verbietet sie, und so bleibt beides erreichbar. Ist weder ID noch VIN bekannt, kommt ein **404 `{"error":"vehicle not found"}`** statt wie bisher eine stille leere Liste. Der Pfad wird als Bind-Parameter aufgelöst; ein VIN-Segment mit SQL darin landet nur in einem erfolglosen Lookup. ### 2. Default nur noch die letzten ~100 Einträge War Teil von #1 und ist bereits live: `limit` hat den **Default 100** (vorher 5000) und die Sortierung steht auf `ts desc`, du bekommst also ohne Parameter die 100 jüngsten Einträge. Dazu `offset` zum Blättern; die Gesamttrefferzahl steht im Header `X-Total-Count`. ### 3. Schärfer selektieren Ebenfalls aus #1: `from`/`to` fürs Zeitfenster, `f_<spalte>` je Spalte (`>80`, `>=80`, `<80`, `10..50`, `leer`, Teilstring bei Textspalten), `sort` + `dir`, `every` fürs Downsampling. Für „Kategorie" habe ich als sinnvollste Auslegung die drei einordnenden Spalten ergänzt — sag Bescheid, falls du etwas anderes gemeint hast: | Filter | Beispiel | |---|---| | `f_source` | `f_source=inx` — nur Records aus dem .inx-Recorder (vs. `cache_data`) | | `f_charge_state` | `f_charge_state=2` | | `f_status` | `f_status=1` | Die **Quelle** ist jetzt auch eine eigene Spalte in der Dashboard-Tabelle, damit der Filter dort erreichbar ist. ### Verifikation (echte Postgres-Instanz mit Produktivschema, 200 Zeilen) - ID, VIN in Groß- und in Kleinschreibung liefern alle dasselbe Fahrzeug (`X-Total-Count: 200`). - Unbekannte VIN und unbekannte ID → **404** bei `timeseries` *und* `latest`. - `f_source=inx` → 100 von 200, `f_source=cache_data` → 100, `f_charge_state=2` → 67 — passt exakt zu den Testdaten. - Ohne `limit` kommen 100 Zeilen zurück. - VIN-Segment mit `'; DROP TABLE telemetry; --` → 404, Tabelle danach unverändert bei 200 Zeilen. - Selbsttests grün, Live: `/health` ok, beide Routen weiterhin **401** ohne Token, Sandbox-Doku und Dashboard auf neuem Stand. Testdatenbank wieder entfernt. Punkt 2 und der Großteil von Punkt 3 waren durch #1 schon abgedeckt; neu dazugekommen sind hier die VIN-Auflösung, das 404 und die Kategorie-Filter.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
aiways/Backend#4
No description provided.