mikrormm-dev
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6c3d2aaa35 |
docs: firmware rollouts and backups
Neither area had a page, and both changed materially in v0.24.2/v0.24.3. The firmware page records why the pipeline downloads and verifies before rebooting, and what raising "at once" actually costs: halting becomes less precise, devices reboot together, and the upstream warning is conservative enough that its absence is not proof of safety. The backups page leads with the fact that a backup is /export text rather than a binary blob, since that is what makes preview and diff possible and what limits what a restore can do. It also states plainly that a backup and its Config History snapshot are one artifact, so deleting one removes the other's rollback. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7b994ad935 |
feat(sites): one install, many networks (v0.24.0-beta)
Closes #130. Multi-site, not multi-tenancy: a site is a named collection of devices whose clients, events, topology and dashboards are viewed separately. Sites separate what you see, not who you are — the admin/manage/read-only roles are unchanged and every user sees every site. Per-site permissions would have multiplied the work for a need nobody stated. Two measurements decided the design. Every device-derived table hangs off devices(id) — 25 of 50 tables, 35 foreign keys — so a single site_id column on devices scopes clients, events, topology, backups and the rest transitively. No other table needed one. The frontend has 162 useQuery call sites across 57 files. Threading a site through each would be a large change that leaves a permanent trap: every future query another chance to forget. The site is injected in the existing axios interceptor instead, beside the auth token, so a new query is scoped by default. Only 23 collection routes needed filtering; the 131 per-device routes are already scoped by their device. Existing installs are untouched. Migration creates one "Default Site", adopts every device into it, and a single-site install never meets the concept. An absent X-Site-Id header means unscoped, so existing API tokens and scripts behave exactly as before. Polling stays fleet-wide. Sites are a view over data already gathered, not a change to how it is gathered — a device does not stop being monitored because you are looking elsewhere. Rogue-AP detection scopes the scans but keeps the "these are ours" BSSID set fleet-wide, or your own AP in another site reads as an evil twin. Bulk actions do obey the selector: an operation that silently spanned two customers is the blast radius the wave guards exist to contain. Four rounds of defects came out of testing the UI rather than the API, and the first is the one worth recording. Switching sites called queryClient.clear(), which empties the cache and reviews as correct. It isn't: clear() destroys each query but a *mounted* observer keeps its own reference and last result, so every rendered page went on showing the previous site's data. The QueryClient is now keyed on the site, which remounts the tree against an empty cache. Three tests pin the old behaviour down so the shortcut cannot return. The others: an unscoped fallback path behind the Connected Clients chart; Config Health, TX retries and the activity feed reading fleet-wide; and site_id added to the device list query but none of the other four that build a device payload, so the Site field could not read its own value and appeared to reject every change while the writes were landing. That last one is now structural — DEVICE_BASE_COLUMNS is shared by all five, with a test that fails when a device payload is hand-rolled, and which found two further instances while being written. Frontend tests were never run by CI despite vitest being configured and six suites existing; they now run in both the workflow and ci-preflight. Verified against a live four-device fleet: the migration left every figure identical, an empty site returns zero from every read endpoint, moving a device carries its history with it, and deleting a site with devices is refused. Minor bump rather than patch: sites change the shape of the product rather than adding to it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
98a72e1f7a |
docs: versioned documentation site, and the four pages that were missing (v0.23.28-beta)
Closes #112. Source stays `docs/*.md`, rendered by MkDocs-Material and published to GitHub Pages by Actions. Same repository on purpose: documentation drifts, and co-location is the only thing that reliably prevents it — the pull request that changes behaviour changes the description, and review sees both. A separate repo would double the ceremony and guarantee divergence. The markdown remains readable when browsing the repository, so the site renders those files rather than replacing them. **Versioned from the start**, using mike. Images are published to GHCR and this project ships betas most days, so readers are routinely running something other than the newest build; a single "latest" would confidently describe a release they do not have. Versions follow the product rather than the docs, so the site and the running image carry the same number. **Content came first, and it had to.** The docs were eleven days and sixteen releases stale — SSH keys, bulk commands, the data-cap SMS, poller health and the timezone setting appeared in exactly zero files between them. Publishing that would have given documentation missing five of the most consequential features a polished, authoritative home, and a well-presented wrong answer is worse than an obviously rough one. Four pages now cover them: - cellular.md — signal grading, carrier aggregation, the uplink anchor, observed bands, and the data-cap SMS including why it fires early and how to calibrate the margin - ssh-keys.md — leading with what installing a key costs, because RouterOS disables password SSH for that user and the database becomes load-bearing - commands.md — why waves exist, and why reading output matters when RouterOS reports failure in text rather than an exit code - scaling.md — headroom, why it is insufficient on its own, and every tunable Pull requests build the site with `--strict`, which turns warnings into errors. That is the point of running it there at all, and it earned itself immediately: the first build failed on two links to the project README, which sits outside the docs tree. They are absolute now, so they resolve both in the rendered site and when reading the markdown on GitHub. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |