02-custom/

directory
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: MIT

README

02-custom

Demonstrates that a developer can add functionality outside the entlite DSL and still have it compile into typed Go/TS alongside the generated code.

Entities (DSL)

Defined in ent/schema:

  • Sensor — a physical device in the field (code, label, kind, unit, active, firmware, sample_rate_ms, timestamps), plus latest_value with permissions.Virtual: a proto-only field with no column, filled at the API layer from the custom ListSensorsWithLatestReading query below.
  • Reading — a measurement emitted by a sensor (sensor_id, value, quality, flagged, recorded_at).

Custom additions (hand-written)

These files live next to the generated ones. entlite only ever writes the fixed filenames above, so these survive regeneration:

  • contract/sqlc/custom.sql — queries the DSL cannot express: a cross-table LEFT JOIN with a correlated subquery (ListSensorsWithLatestReading, using sqlc.embed), an aggregate (GetSensorReadingStats), and a bulk retention delete (PruneReadingsOlderThan).
  • contract/proto/custom.proto — a hand-written SensorAnalyticsService in the same entlite package that imports schema.proto and reuses the generated Sensor message.

Server

server/server.go implements all three services against the same generated types: SensorService and ReadingService from the DSL, and the hand-written SensorAnalyticsService on top of custom.sql. ListWithLatestReading is where both halves meet — the custom LEFT JOIN returns an embedded sensor row, the generated converter turns it into the same pb.Sensor the CRUD service returns, and the permissions.Virtual latest_value field is filled from the joined reading.

Run

make run   # generates, bundles the frontend, then serves on :8080

Known gap: ReadingService.FilterBySensorIdRecordedAtFlagged fails at runtime. The DSL's filter.Range("recorded_at") emits recorded_at BETWEEN @min AND @max, and sqlc cannot infer the type of a DATETIME placeholder inside BETWEEN, so it drops both bounds from the params struct while the query still binds them. custom.sql works around this by spelling the same range as >= AND <=.

Directories

Path Synopsis
ent

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL