Skip to content

Releases: ADWasHere/Refrax

v0.3.0

Choose a tag to compare

@ADWasHere ADWasHere released this 14 Sep 18:18
Immutable release. Only release title and notes can be modified.

What's Changed

Full Changelog: v0.2.0...v0.3.0

v0.2.0

Choose a tag to compare

@ADWasHere ADWasHere released this 11 Sep 20:50
Immutable release. Only release title and notes can be modified.
fb59fea

What's Changed

Full Changelog: v0.1.0...v0.2.0

v0.1.0

Choose a tag to compare

@ADWasHere ADWasHere released this 12 Jul 16:11
Immutable release. Only release title and notes can be modified.

v0.1.0 — First usable realese

Refrax turns one event-sourced log into multiple standard-conformant projections
(native, NGSI-LD) that stay consistent by construction. No field without a declared
domain meaning and a vocabulary binding can appear in an exposed representation —
the gate enforces that structurally, not by discipline.

This rekease is usable end to end: you declare a schema, ingest events, and read
them back through views and projectors, served from real read models.

What you can do today

  • Ingest events into an append-only log: POST /v1/events (idempotent per eventId).
  • Declare an event type as JSON — its exposable fields, their roles and vocabulary
    URIs — loaded and validated at startup. Anything undeclared is internal by default.
  • Structural leak guarantee: internal payload fields (deviceDbId, userId, …)
    can never appear in a projection, in any format.
  • Views narrow what a consumer sees (data minimisation) and declare queryable axes;
    a view can only shrink the schema, never widen it.
  • Projectors: native and NGSI-LD (with a @context derived from the schema).
    Views and projectors are orthogonal — any view renders in any format.
  • Read side (CQRS): a persisted, incremental consumer maintains reading_latest
    (current state) and reading_series (a TimescaleDB hypertable). Reads are served
    from the read models: /latest, /stream, /series.
  • Disposable & replayable: wipe the read models and rebuild from the log — full or
    per-entity. Ingest is decoupled: the log keeps accepting while the read side lags,
    crashes or rebuilds.

Quick start

docker compose up -d          # TimescaleDB + PostGIS
./mvnw quarkus:dev            # app on :8787

# ingest
curl -X POST http://localhost:8787/v1/events -H 'Content-Type: application/json' -d '{
  "type":"AirQualityReading","eventId":"11111111-1111-1111-1111-111111111111",
  "observedAt":"2026-07-02T10:00:00Z",
  "payload":{"sensorId":"sensor-42","metric":"PM2.5","value":12.3,"unit":"ug/m3","deviceDbId":999}
}'

# read (deviceDbId never appears)
curl 'http://localhost:8787/v1/views/air-quality-full/latest?sensor=sensor-42'
curl 'http://localhost:8787/v1/views/air-quality-full/latest?sensor=sensor-42&format=ngsi-ld'

Requirements

  • JDK 25
  • Docker (for the database, and for the test suite via Dev Services)
  • TimescaleDB + PostGIS (brought up by docker-compose.yml)

Not yet (pre full-version scope)

  • No authentication/authorisation — endpoints are open. Do not expose publicly.
  • Single tenant (tenant_id is fixed); multi-tenancy is not implemented.
  • GDPR enforcement (crypto-shredding) is not built — the seam is kept open (read models never materialise a personalData field in cleartext).
  • PostGIS is enabled but the geo read model / location axis are not built yet.
  • Reads are eventually consistent (projection lag ~seconds).
  • The API and storage layout are unstable and may change without notice.

Feedback and design discussion welcome — the most valuable contribution is to the idea.