amber-backend/pb_migrations/1790000000_client_logs_gitsha.js
Claude 449b1e75e0 Dashboard: read the reports, and create accounts without the admin UI
Two views on status.html, and one migration.

Hlášení: one incident per card rather than a table row, because a report
carries fifteen numbers and the job is to read one incident, not scan a
column. The reporter's address is resolved from the `user` relation in the
browser — the app never writes identity onto telemetry rows. The box is
named. Our own test sessions are HIDDEN by default, since the question
this view answers is what the family experienced; `tester` OR an emulator
tell OR a test address, so it stays right for rows written before the
column existed. Day-range filter, and every field says "neměří se" rather
than 0 when that player does not send it — a different claim from zero,
and the TV sends everything while mpv sends part.

Správa: create an account and flip clean/18+. Registration stays CLOSED —
`users.createRule` is still null and this is a plain POST with the
superuser token the page has held since it was written, so it grants
nothing that was not already available in the PocketBase admin UI. The
password field is deliberately visible: you are making it for someone
else and have to read it out.

client_logs.gitSha: which BUILD wrote a row, not which version. Fourth
outing for the silent-drop lesson, and written alongside the client change
rather than discovered after.

Verified against real data before deploying, by splicing production rows
into the shipped page as fixtures and driving it in a browser: seven
reports render with the right reporter and box, the day filter and the
test toggle both work, prefs persist, and the create form's guard fires.
That caught a JS syntax error (a Czech quote closed with an ASCII one
inside a double-quoted string, which would have taken the whole dashboard
down — PocketBase serves this file with no build step) and a missing space
that rendered "ďáblashlédnuto".
2026-08-08 23:29:51 +02:00

42 lines
1.7 KiB
JavaScript

/// <reference path="../pb_data/types.d.ts" />
// Add `gitSha` to client_logs: which BUILD wrote this row, not which version.
//
// WHY THIS MIGRATION EXISTS: `1.1.7+18` was built and installed at least four
// times in one evening with materially different code in it. Two telemetry fields
// were broken in the earlier builds — `lastLoadError` recorded a single obfuscated
// letter and throughput reported -1 — and nothing in the stored rows could tell
// those builds apart from the fixed one. So a real measurement from a real
// television had to be discarded as "probably the old build", which is exactly the
// kind of ambiguity a diagnostic pipeline must not have.
//
// A version number records an intent to release. The sha records the artifact.
//
// Fourth time the silent-drop lesson applies (hidden `profiles.pinHash`,
// `client_logs.flavor`, `client_logs.tester`, now this): PocketBase discards an
// undeclared key in a create payload with no error and HTTP 200, so a field the
// client sends does not exist until a migration declares it. Written at the same
// time as the client change rather than discovered afterwards.
//
// Not required, and empty in an ad-hoc local build. An absent sha honestly says
// "unknown"; the release scripts pass `--dart-define=GIT_SHA=$(git rev-parse
// --short HEAD)` so every published artifact carries one.
migrate(
(app) => {
const logs = app.findCollectionByNameOrId("client_logs")
logs.fields.add(
new TextField({
name: "gitSha",
required: false,
max: 20,
}),
)
app.save(logs)
},
(app) => {
const logs = app.findCollectionByNameOrId("client_logs")
logs.fields.removeByName("gitSha")
app.save(logs)
},
)