feat: schedule in the operator's timezone, and make Top Talkers searchable (v0.23.21-beta)

Closes #117.

**Scheduled work ran on the container's clock.** cronMatchesNow used Date's own
accessors, which read the process timezone — UTC in the shipped image. A backup
set for 02:00 therefore fired at 02:00 UTC wherever the operator was: seven hours
early on the US west coast, and on the wrong day entirely for anyone far enough
east. The settings page said "server time", which was accurate and precisely the
problem. Reported by a user managing devices across regions, who described it as
a configuration gap; it is a correctness bug.

There is now an app_timezone setting, chosen from the zones the runtime knows
and offered alongside the browser's own as a one-click default. Schedules are
evaluated in it, and the page states the zone and the current time in it, so a
wrong setting is obvious immediately rather than at 2am three days later.

The matching logic moved to utils/cron.ts with 13 tests, because the bug was
invisible where it lived: it only manifests when the process zone and the
operator's differ, which never happens in a developer's own shell. The tests
pin the cases that matter — the same instant matching in exactly one of three
zones, a job on the 2nd UTC still being the 1st in Los Angeles, day-of-week
resolved locally, and daylight saving handled by Intl rather than by a fixed
offset. Zone handling goes through Intl for that last reason; offset arithmetic
would be wrong twice a year.

An unknown zone falls back to UTC rather than throwing, so a bad value cannot
stop every schedule in the product.

**Top Talkers was ten rows with no way to look anything up**, which is unusable
on a network of any size — you could see the loudest ten and nothing else. It
now filters on name, IP, MAC or vendor, and ranks 10, 25 or 50. Filtering is
client-side because the rows are already present; asking the server per keystroke
would be slower and no more accurate. Requested in the discussion thread, where
the backend already served everything needed and only the UI was missing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2GT-Rich
2026-09-02 08:18:08 -07:00
co-authored by Claude Opus 5
parent dd71271473
commit 7d02bedc5f
10 changed files with 307 additions and 57 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mikrotik-manager-backend",
"version": "0.23.20-beta",
"version": "0.23.21-beta",
"description": "Mikrotik Network Management Platform - Backend API",
"main": "dist/index.js",
"scripts": {