client_logs.tester: mark our own sessions, not the family's
Telling a real report from one of our test runs was impossible. Three no_first_frame rows from a development emulator sat in a production log dump and were only spotted because an emulator decoder name happened to be visible in a field logged for something unrelated. Third time this silent drop has cost us — hidden profiles.pinHash, then client_logs.flavor, now this. A field the client sends does not exist until a migration declares it, and PocketBase says nothing. Caught only because the added field was read back off a measured session. NOT deployed. The reader (amber-app/tools/reports.py) works without this column by recognising an emulator in `device` and a test address from the resolved account, so nothing is blocked on the redeploy.
This commit is contained in:
parent
8d3cefa3f5
commit
447cb85346
1 changed files with 51 additions and 0 deletions
51
pb_migrations/1789500000_client_logs_tester.js
Normal file
51
pb_migrations/1789500000_client_logs_tester.js
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
/// <reference path="../pb_data/types.d.ts" />
|
||||||
|
|
||||||
|
// Add `tester` to client_logs: was this session OURS, or a real viewer's?
|
||||||
|
//
|
||||||
|
// WHY THIS MIGRATION EXISTS: telling our own test runs from the family's sessions
|
||||||
|
// was impossible. Three `no_first_frame` rows from a development emulator sat in
|
||||||
|
// the middle of a production log dump for an evening, and the only reason they
|
||||||
|
// were not read as a family member's television was that an emulator decoder name
|
||||||
|
// (`c2.goldfish.hevc.decoder`) happened to be visible in a field logged for an
|
||||||
|
// entirely unrelated reason. That is luck, not a method, and a wrong attribution
|
||||||
|
// here sends someone chasing a bug that nobody has.
|
||||||
|
//
|
||||||
|
// THIS IS THE THIRD TIME the same silent drop has cost us: hidden `profiles.pinHash`
|
||||||
|
// PATCHes, then `client_logs.flavor` (see the migration beside this one), now this.
|
||||||
|
// PocketBase drops an unknown key in a create payload with no error, no warning and
|
||||||
|
// HTTP 200. **A field the client sends does not exist until a migration declares
|
||||||
|
// it.** It was caught this time only because the added field was read back off a
|
||||||
|
// measured session instead of being assumed to have arrived — `tester: None` on a
|
||||||
|
// row whose build definitely sends it.
|
||||||
|
//
|
||||||
|
// Not folded into `meta`: this is a dimension of every record regardless of event
|
||||||
|
// type, exactly like `platform`, `flavor` and `device` beside it, and the query it
|
||||||
|
// exists for is "hide our own rows", which should not have to reach into a blob.
|
||||||
|
//
|
||||||
|
// The reader (`amber-app/tools/reports.py`) deliberately does NOT depend on this
|
||||||
|
// column — it also recognises an emulator from `device` and a test address from the
|
||||||
|
// resolved account, so it stays correct before this deploys and if a future client
|
||||||
|
// omits the field. Belt and braces on purpose, because the column is exactly the
|
||||||
|
// kind of thing that silently goes missing.
|
||||||
|
|
||||||
|
migrate(
|
||||||
|
(app) => {
|
||||||
|
const logs = app.findCollectionByNameOrId("client_logs")
|
||||||
|
logs.fields.add(
|
||||||
|
new BoolField({
|
||||||
|
name: "tester",
|
||||||
|
// Not required. A bool field in PocketBase defaults to false, which is the
|
||||||
|
// correct reading for every historical row: they came from the family's
|
||||||
|
// devices. Rejecting a record for a missing dimension would trade a whole
|
||||||
|
// diagnostic away for a label.
|
||||||
|
required: false,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
app.save(logs)
|
||||||
|
},
|
||||||
|
(app) => {
|
||||||
|
const logs = app.findCollectionByNameOrId("client_logs")
|
||||||
|
logs.fields.removeByName("tester")
|
||||||
|
app.save(logs)
|
||||||
|
},
|
||||||
|
)
|
||||||
Loading…
Reference in a new issue