Two faults found while checking whether today's live bills had landed. They had — 17 of them, complete — but both of these were sitting in the same data. **Health existed only over MQTT.** The consumer subscribes to the health topic and has done since startup, but a terminal on the HTTP route has no way to reach it. Today's terminal was on HTTP, so it reported nothing and the board showed "online 0 of 1" while the till was demonstrably alive and selling. POST /pos/health now takes the same payload the broker carries, into the same Redis record, so the board cannot tell the two routes apart and does not need to. It answers 202 and swallows failures: a till that cannot say how it is must still sell. **terminalid was empty on 16 of 17 bills.** The consumer backfills a missing terminal code from the topic, but onto the batch, while the row was built from the order — the two never met, and importPosOrder was not handed the batch's value at all. Over HTTP there was no topic to fall back on either. So the invoice numbers read INV-2608-T5EDD-000NN while the column they should have matched was blank, and `byterminal` on the sales summary grouped almost everything under "". The bill's own terminal now wins with the batch's as the fallback, trimmed, so whitespace is not mistaken for a code. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
43 lines
1.7 KiB
Go
43 lines
1.7 KiB
Go
package routes
|
|
|
|
import (
|
|
"nearle/facade"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
// Routes for the Nearle POS terminal.
|
|
//
|
|
// The paths are fixed by the till, which appends `/orders`, `/customers` and
|
|
// `/catalogue` to whatever base URL a shop enters in Settings. Set that base to
|
|
// this group — `https://your-host/live/api/v1/pos` — and the three line up.
|
|
//
|
|
// Kept in their own group rather than folded into the order routes because a
|
|
// terminal authenticates as a device, not as a signed-in user, and because
|
|
// these answer with a bare ack rather than the web app's response envelope.
|
|
func RegisterPosRoutes(api fiber.Router, f *facade.Facade) {
|
|
|
|
pos := api.Group("/v1/pos")
|
|
|
|
pos.Post("/orders", f.PosController.IngestOrders)
|
|
pos.Post("/customers", f.PosController.IngestCustomers)
|
|
pos.Get("/catalogue", f.PosController.Catalogue)
|
|
|
|
// The 30-second heartbeat, for tills on the HTTP route. The broker carries
|
|
// the same payload for tills on MQTT; both land in the same Redis record,
|
|
// so the fleet board cannot tell them apart and does not need to.
|
|
pos.Post("/health", f.PosController.IngestHealth)
|
|
|
|
// Counter sales, read back out. The ingest above only ever writes; without
|
|
// these a committed bill is unreachable from every screen in the product.
|
|
pos.Get("/sales", f.PosController.GetSales)
|
|
pos.Get("/sales/detail", f.PosController.GetSaleDetail)
|
|
pos.Get("/sales/summary", f.PosController.GetSalesSummary)
|
|
|
|
// Terminal presence, read from Redis. What the rider app's POS board and a
|
|
// support call both hit — the tills themselves publish health over the
|
|
// broker rather than posting it here.
|
|
pos.Get("/health/terminal", f.PosController.TerminalHealth)
|
|
pos.Get("/health/location", f.PosController.LocationHealth)
|
|
}
|