The app has been sending `flavor` since yesterday's change and PocketBase was throwing it away. An unknown key in a create payload is dropped with no error, no warning and HTTP 200 -- the same silent-drop behaviour already documented for hidden fields in amber-app/CLAUDE.md. So the dashboard's "Podle varianty" row read `neznámá` for every record while the client believed it was reporting the variant, and the only way to notice was to query the stored rows and find the field absent. Found by verifying instead of assuming: a real play/exit on the TV produced two session_summary rows, both with flavor empty, on a build that definitely sends it. Not folded into `meta`, though that needs no migration and the dashboard already falls back to reading it there. The variant is a first-class dimension of every record, exactly like platform and appVersion beside it, and burying it in json would make the one query it exists for -- group errors by variant -- awkward for nothing. Additive and nullable so existing rows stay valid. Validated on a clean local boot of the pinned PocketBase against the real migrations directory: health 200, no errors, and client_logs now reports the field.
44 lines
1.9 KiB
JavaScript
44 lines
1.9 KiB
JavaScript
/// <reference path="../pb_data/types.d.ts" />
|
|
|
|
// Add `flavor` to client_logs: which build variant a device runs, clean or adult.
|
|
//
|
|
// WHY THIS MIGRATION EXISTS: the app was already sending the field and PocketBase
|
|
// was silently throwing it away. An unknown key in a create payload is simply
|
|
// dropped — no error, no warning, HTTP 200 — which is the same silent-drop
|
|
// behaviour already documented for hidden fields in amber-app/CLAUDE.md. So the
|
|
// status dashboard's "Podle varianty" row read `neznámá` for every record while the
|
|
// client believed it was reporting the variant, and the only way to notice was to
|
|
// query the stored rows and find the field missing.
|
|
//
|
|
// Not folded into `meta`, though that would have needed no migration and the
|
|
// dashboard already falls back to reading it there: the variant is a first-class
|
|
// dimension of every record, exactly like `platform` and `appVersion` beside it,
|
|
// and burying it in a json blob would make the one query it exists for — group the
|
|
// errors by variant — awkward for no benefit.
|
|
//
|
|
// Additive and nullable, so existing rows stay valid and simply have no variant.
|
|
// Fourteen days from now the retention cron will have aged all of them out and the
|
|
// column will be populated for everything.
|
|
|
|
migrate(
|
|
(app) => {
|
|
const logs = app.findCollectionByNameOrId("client_logs")
|
|
logs.fields.add(
|
|
new TextField({
|
|
name: "flavor",
|
|
// "clean" | "adult". Not required: every row written before the app build
|
|
// that sends it, and any future client that omits it, must still be
|
|
// accepted — losing a diagnostic record over a missing dimension would be
|
|
// a worse trade than not knowing the variant.
|
|
required: false,
|
|
max: 20,
|
|
}),
|
|
)
|
|
app.save(logs)
|
|
},
|
|
(app) => {
|
|
const logs = app.findCollectionByNameOrId("client_logs")
|
|
logs.fields.removeByName("flavor")
|
|
app.save(logs)
|
|
},
|
|
)
|