Second half of the envelope fix: ITrackPayload is {name, properties, profileId} — sending
'event' is rejected with 400 "payload/name Invalid input: expected string", which the
module swallows by design. Verified against packages/validation/src/track.validation.ts
and the SDK's track(name, properties) signature.
Two blockers found while wiring OpenPanel for real:
- frontend/Dockerfile declared ARG for VITE_OPENPANEL_URL/CLIENT_ID/SENTRY_DSN but not
VITE_OPENPANEL_SCRIPT_URL, so passing it as a build arg was silently ignored and the
loader compiled out (import.meta.env value undefined).
- backend/app/services/analytics.py posted a flat {type, event, properties} body; the
Track API expects {type, payload:{event, properties, profileId}} (verified against the
SDK source in packages/sdks/sdk). The API answered 400 and the module swallows every
error by design, so all server-side events were being dropped without a trace.
Verified after deploy: the bundle carries the client id + op1.js URL + the queueing shim,
op1.js serves 200, and a track event posted with the real envelope lands in OpenPanel.