22b1b069df
Initialize CLAUDE.md schema, index, and log; ingest three architecture sources (system overview, Teltonika ingestion design, official Teltonika data-sending protocols) into 7 entity pages, 8 concept pages, and 3 source pages with wikilink cross-references.
46 lines
2.5 KiB
Markdown
46 lines
2.5 KiB
Markdown
---
|
|
title: Protocol Adapter Pattern
|
|
type: concept
|
|
created: 2026-04-30
|
|
updated: 2026-04-30
|
|
sources: [gps-tracking-architecture, teltonika-ingestion-architecture]
|
|
tags: [architecture, ingestion, vendor-abstraction]
|
|
---
|
|
|
|
# Protocol Adapter Pattern
|
|
|
|
The strategy used by [[tcp-ingestion]] to keep vendor-specific code from leaking into the rest of the system.
|
|
|
|
## The interface
|
|
|
|
- **Input**: a stream of bytes from a TCP socket.
|
|
- **Output**: normalized [[position-record]] values with a stable shape — `device_id`, `timestamp`, `lat`, `lon`, `speed`, `heading`, plus a free-form attribute bag for vendor-specific telemetry.
|
|
|
|
That's the entire boundary contract. Adding a new device vendor (Queclink, Concox, etc.) means writing a new adapter. **Nothing downstream of Ingestion changes** — not [[redis-streams]], not [[processor]], not the schema, not the SPA.
|
|
|
|
This is "the single most important property of [the Ingestion] layer for long-term maintenance."
|
|
|
|
## Layout rules
|
|
|
|
In `tcp-ingestion/`:
|
|
|
|
1. **`src/core/` never imports from `src/adapters/`.** The vendor-agnostic shell (TCP listeners, Redis publishing, configuration, observability) is built without knowing about any vendor.
|
|
2. **Adapters never import from one another.** `adapters/teltonika/` and any future `adapters/queclink/` are independent. Shared utilities (e.g. length-prefix buffer accumulation) live in `core/`.
|
|
3. **Each adapter folder is self-contained.** Lifting [[teltonika]] out into its own service later is a `git mv adapters/teltonika/ ../gps-ingest-teltonika/src/adapter/` plus a copy of `core/`. No untangling required.
|
|
|
|
## The deeper move: model-agnostic via self-description
|
|
|
|
For [[teltonika]] specifically, the adapter is also **model-agnostic** — what matters is the codec ID, not the device model. Fixed fields are codec-defined; model-specific telemetry is carried in an opaque IO bag the parser passes through verbatim. New models work without code changes. See [[teltonika]] and [[codec-dispatch]].
|
|
|
|
This is a property of the protocol, not the pattern, but it pairs well: the adapter pattern isolates vendors; the codec dispatch isolates models within a vendor.
|
|
|
|
## What stays out of adapters
|
|
|
|
Per the Teltonika reference:
|
|
|
|
- **Naming/interpreting telemetry** is a [[processor]] concern, not an adapter concern.
|
|
- **Filtering** is also downstream — adapters produce raw records.
|
|
- **Per-model configuration** lives in the Processor, not the adapter.
|
|
|
|
Adapters do one thing: turn vendor bytes into normalized records.
|