Commit Graph
100 Commits
Author SHA1 Message Date
JingleManSweep a471e1a166 Merge pull request #392 from ipnet-mesh/renovate/react-monorepo
chore(deps): update react monorepo to v19.3.0
2026-10-12 18:57:42 +01:00
JingleManSweep 16037e19e6 Merge branch 'main' into renovate/react-monorepo 2026-10-12 18:39:07 +01:00
JingleManSweep adea0bbe1e Merge pull request #393 from ipnet-mesh/renovate/vite-8.x-lockfile
chore(deps): update dependency vite to v8.3.4
2026-10-12 18:38:50 +01:00
JingleManSweep f29160f829 Merge branch 'main' into renovate/vite-8.x-lockfile 2026-10-12 18:06:42 +01:00
JingleManSweep b0886f1c2e Merge pull request #394 from ipnet-mesh/renovate/anomalyco-opencode-2.x
chore(deps): update anomalyco/opencode action to v2
2026-10-12 18:06:25 +01:00
JingleManSweep 4467c0dbb3 Merge branch 'main' into renovate/anomalyco-opencode-2.x 2026-10-12 17:21:35 +01:00
JingleManSweep 0ae075ab6c Merge pull request #395 from ipnet-mesh/renovate/react-i18next-17.x-lockfile
chore(deps): update dependency react-i18next to v17.0.16
2026-10-12 17:21:15 +01:00
JingleManSweep 5074e6ab58 Merge branch 'main' into renovate/react-i18next-17.x-lockfile 2026-10-12 15:50:22 +01:00
JingleManSweep 5e9454d890 Merge pull request #402 from ipnet-mesh/renovate/tanstack-query-monorepo
chore(deps): update dependency @tanstack/react-query to v5.104.2
2026-10-12 15:50:03 +01:00
JingleManSweep 9f7e330d08 Merge branch 'main' into renovate/tanstack-query-monorepo 2026-10-12 15:22:40 +01:00
JingleManSweep 4057ea867e Merge pull request #405 from ipnet-mesh/renovate/vitest-monorepo
chore(deps): update dependency vitest to v5.0.4
2026-10-12 15:22:18 +01:00
JingleManSweep 636c64644f Merge branch 'main' into renovate/tanstack-query-monorepo 2026-10-12 09:50:04 +01:00
JingleManSweep a10229e6d8 Merge pull request #404 from ipnet-mesh/renovate/i18next-26.x-lockfile
chore(deps): update dependency i18next to v26.4.4
2026-10-12 09:49:48 +01:00
JingleManSweep 47bf267f3b Merge branch 'main' into renovate/react-i18next-17.x-lockfile 2026-10-12 08:53:17 +01:00
JingleManSweep 679770ffa8 Merge pull request #403 from ipnet-mesh/renovate/jsdom-30.x-lockfile
chore(deps): update dependency jsdom to v30.1.2
2026-10-12 08:53:00 +01:00
JingleManSweep a17606c81b Merge pull request #401 from ipnet-mesh/renovate/i18next-26.x-lockfile
chore(deps): update dependency i18next to v26.4.3
2026-10-12 00:18:32 +01:00
JingleManSweep d646bbb64a Merge pull request #396 from ipnet-mesh/renovate/testing-library-monorepo
chore(deps): update dependency @testing-library/dom to v10.4.2
2026-10-11 23:33:17 +01:00
JingleManSweep 6c6da618e7 Merge branch 'main' into renovate/testing-library-monorepo 2026-10-11 23:24:58 +01:00
JingleManSweep 2e643f2b4d Merge pull request #397 from ipnet-mesh/renovate/vitest-monorepo
chore(deps): update dependency vitest to v5.0.3
2026-10-11 23:24:44 +01:00
JingleManSweep 72910af686 Merge pull request #399 from ipnet-mesh/renovate/vitejs-plugin-react-6.x-lockfile
chore(deps): update dependency @vitejs/plugin-react to v6.1.2
2026-10-11 23:07:35 +01:00
JingleManSweep a46c6271ad Merge pull request #400 from ipnet-mesh/fix/sqlalchemy-2.1-ci
fix(deps): restore CI under SQLAlchemy 2.1
2026-10-11 23:01:19 +01:00
Louis KingandClaude Opus 5.5 45bcf25fe8 fix(deps): restore CI under SQLAlchemy 2.1
SQLAlchemy 2.1 no longer installs greenlet by default, so the async
engine fails to import (Test, E2E api container), and its sources use
the `untyped-decorator` mypy code that the pinned mypy 1.9 hook rejects
(Lint).

- depend on sqlalchemy[asyncio] so greenlet is installed again
- bump the mirrors-mypy pre-commit hook to v2.4.0
- guard nullable tag values / channel_idx flagged by the newer mypy

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UFsp2i9E98EzovBaurmtEb
2026-10-11 22:53:10 +01:00
JingleManSweep 403a3c7a1c Merge pull request #398 from ipnet-mesh/renovate/react-router-monorepo
chore(deps): update dependency react-router to v8.4.0
2026-10-11 17:28:39 +01:00
JingleManSweep 5e886cfb23 Merge pull request #383 from ipnet-mesh/renovate/daisyui-5.x-lockfile
chore(deps): update dependency daisyui to v5.7.28
2026-09-05 13:43:36 +01:00
JingleManSweep 8e94ad93f8 Merge branch 'main' into renovate/daisyui-5.x-lockfile 2026-09-05 13:41:06 +01:00
JingleManSweep 87b33f824b Merge pull request #384 from ipnet-mesh/renovate/i18next-26.x-lockfile
chore(deps): update dependency i18next to v26.4.2
2026-09-05 13:40:50 +01:00
JingleManSweep f188194f25 Merge pull request #385 from ipnet-mesh/renovate/react-i18next-17.x-lockfile
chore(deps): update dependency react-i18next to v17.0.13
2026-09-05 13:28:46 +01:00
JingleManSweep 3eb83d6544 Merge branch 'main' into renovate/react-i18next-17.x-lockfile 2026-09-05 13:26:18 +01:00
JingleManSweep 45a599b43d Merge pull request #386 from ipnet-mesh/renovate/anomalyco-opencode-1.x
chore(deps): update anomalyco/opencode action to v1.18.29
2026-09-05 13:26:03 +01:00
JingleManSweep da13b9362c Merge pull request #387 from ipnet-mesh/renovate/react-monorepo
chore(deps): update dependency @types/react-dom to v19.2.7
2026-09-05 11:56:46 +01:00
JingleManSweep 3e44c4c77b Merge pull request #388 from ipnet-mesh/renovate/major-vitest-monorepo
chore(deps): update dependency vitest to v5
2026-09-05 11:53:44 +01:00
JingleManSweep b4c5d384a6 Merge pull request #382 from ipnet-mesh/feat/rss-feed-icon-toolbar-links
feat(web): add RSS feed icon links to list toolbars
2026-08-31 10:27:57 +01:00
Louis King 8fb4b4705b feat(web): add RSS feed icon links to list toolbars
- Add IconRss component and feedHref prop to ListToolbar
- Wire feed links on Nodes, Advertisements, and Messages pages
- Messages feed link respects channel filter, defaults to idx 17
- Simplify advert/node feed item bodies, link adverts to packet hashes
- Add unit tests, page tests, and e2e specs for feed link behavior
2026-08-31 10:22:52 +01:00
JingleManSweep f5ae082adb Merge pull request #381 from ipnet-mesh/feat/rss-atom-public-feeds
feat(api): add RSS/Atom feeds for public mesh data
2026-08-30 23:48:43 +01:00
Louis King 1513561df9 feat(api): add RSS/Atom feeds for public mesh data
Four feeds (public messages, node adverts deduped per node, new nodes,
per-community-channel messages), each in RSS 2.0 and Atom, built with
stdlib ElementTree. Feeds are hard-pinned to the logged-out view
(anonymous visibility, spam always filtered, identity headers ignored)
and served at clean public web URLs (/feeds/*) via a shared proxy helper
that forwards If-None-Match + X-Forwarded-* and gates on maintenance
mode. Responses are Redis-cached (ETag/304, public max-age) and
invalidated with messages/adverts/channels mutations. Item/self links
always target the public web endpoint; WEB_PUBLIC_URL pins the canonical
origin. Includes a FEATURE_FEEDS kill switch, SPA autodiscovery <link>
tags, and env/docs updates (v0.21.0 upgrading notes).
2026-08-30 23:44:02 +01:00
JingleManSweep f6a0d9c331 Merge pull request #380 from ipnet-mesh/chore/remove-postgres-transition-shims
chore(db): remove v0.19 Postgres-transition shims (v0.20)
2026-08-30 22:24:32 +01:00
Louis King c643c50378 chore(db): remove v0.19 Postgres-transition shims
Remove the upgrade-compatibility items scheduled for v0.20 in the v0.19
release notes:

- the `meshcore-hub db migrate-to-postgres` command and its
  `common/db_migrate.py` module (with its dedicated tests)
- the `database_backend` settings field and its legacy-backend validator
  (a leftover DATABASE_BACKEND is now silently ignored)
- the `[postgres]` pip extra alias (Dockerfile installs `.` now)

`tests/test_main.py` is rewritten as a minimal CLI smoke test to keep
entry-point coverage. Docs updated: v0.20.0 upgrade section notes the
removals (SQLite deployments must upgrade through v0.19 first), README
and database.md pointers reworded, stale .env.example comment dropped.
2026-08-30 22:20:16 +01:00
JingleManSweep 1948a3d367 Merge pull request #379 from ipnet-mesh/feat/mandatory-redis
feat(api): make Redis a required cache dependency
2026-08-30 21:57:24 +01:00
Louis King 3593d14878 feat(api): make Redis a required cache dependency
Redis becomes mandatory infrastructure (PostgreSQL-parity): the
REDIS_ENABLED flag, NullCache backend, and every conditional caching
code path are removed. /health/ready reports not_ready (503) when
Redis is unreachable and cached endpoints return 503 instead of
silently degrading; invalidation helpers never raise after a
committed write.

The bundled redis container joins the core profile only via
docker-compose.dev.yml (production points REDIS_* at an external
instance, same no-shadowing pattern as postgres), the backend suite
runs against real Redis (test-redis on 127.0.0.1:55433, CI redis:8
service container, per-xdist-worker key prefixes), and operator docs
describe the required-dependency setup (upgrading.md gains the
v0.20.0 section).
2026-08-30 21:51:51 +01:00
JingleManSweep e1f421f7bd Merge pull request #377 from ipnet-mesh/feat/map-node-clustering
feat(web): cluster map markers for large node counts
2026-08-30 13:20:23 +01:00
Louis King d1dd96fb7c test(e2e): make map spec clustering-aware
Marker clustering changed the map DOM contract the spec relied on:
clustered and off-viewport markers are absent, so raw .map-marker counts
undercount and first-marker clicks can hit-test against the sticky
navbar/banners. Count nodes as individual markers plus cluster badge
totals (new data-testid on the badge), zoom into a cluster before the
label and popup interactions so targets sit mid-map, and assert cluster
clicks spread children into individual markers.
2026-08-30 13:11:43 +01:00
Louis King c1024bed04 feat(web): cluster map markers for large node counts
Wrap MapPage node markers in react-leaflet-cluster (leaflet.markercluster)
with spiderfy-at-max-zoom, zoom-to-bounds on click, clustering disabled at
zoom >= 15, and viewport culling so off-screen markers stay out of the DOM.
Cluster bubbles render a plain themed count badge. Marker label HTML is now
only built when the show-labels toggle is on, halving per-marker DOM weight;
hover-to-reveal no longer applies while labels are toggled off.
2026-08-30 13:01:07 +01:00
JingleManSweep bda6370cb0 Merge pull request #376 from ipnet-mesh/test/e2e-ui-regression-coverage
test(e2e): expand Playwright coverage for UI regression protection
2026-08-30 12:39:53 +01:00
JingleManSweep 4a4eb134d0 Merge branch 'main' into test/e2e-ui-regression-coverage 2026-08-30 12:37:54 +01:00
Louis King 47fa9c6749 test(e2e): fix selector and assertion bugs in the new specs
- channels: post-delete card count is 6 (6 seeded + 1 created - 1), not 5
- empty-states/pagination: the empty text renders twice (mobile
  EmptyState + desktop EmptyRow); scope assertions to the table cell
- mobile: list-row is desktop-only; assert the mobile sort select and
  card text instead
- not-found: '/$' is a glob, not a regex; assert the exact URL '/'
- packets-detail: the newest seeded packet is the ce01 message, not an
  advert; assert the event type returned by the API
2026-08-30 12:32:53 +01:00
Louis King ec199e4e2b test(e2e): expand Playwright coverage for UI regression protection
Grow the suite from 41 to 77 specs covering previously untested UI
surfaces: channels admin CRUD with QR codes and keyboard nav, node
detail adoption/tag editing with the role permission matrix, SPA 404
page, sortable tables with URL-synced sort state, pagination with
filter-preserving links, mobile viewport (hamburger nav, mobile cards,
sort select), anonymous/member auth gating, raw packet detail, and
empty states. Route cards now assert history chart, recent-match links
and owner profile links.

Supporting changes: purposeful data-testids on channels/node-detail/
pagination/sort headers (plus aria-sort) and mobile nav; seed_data adds
30 trace_data filler groups for pagination, channels at every
visibility tier incl. one disabled, and a pw-operator profile.
2026-08-30 12:27:48 +01:00
JingleManSweep 18e3eb88de Merge pull request #375 from ipnet-mesh/renovate/major-github-artifact-actions
chore(deps): update actions/download-artifact action to v8
2026-08-30 11:58:17 +01:00
JingleManSweep e67e0ec3ae Merge pull request #374 from ipnet-mesh/chore/ci-summary
ci: add consolidated job summary with test results and artifacts
2026-08-30 11:50:53 +01:00
Louis King 9f9cd67440 ci: add consolidated job summary with test results and artifacts
Add a summary job that runs after all CI jobs (even on failure),
parses the pytest/vitest/Playwright JUnit reports plus coverage.xml,
and renders a consolidated Markdown summary to $GITHUB_STEP_SUMMARY:
job results, test counts, durations, backend coverage, failure
details, and the artifact inventory. Enable a Playwright JUnit
reporter and include it in the playwright-report artifact.
2026-08-30 11:46:12 +01:00
JingleManSweep 8aa451d4b7 Merge pull request #373 from ipnet-mesh/fix/postgres-profile-dev-only
fix(compose): keep bundled postgres out of the core profile in production
2026-08-30 11:24:46 +01:00
Louis King 5a8794f5c9 fix(compose): keep bundled postgres out of the core profile in production
Starting core with docker-compose.prod.yml also started the bundled
postgres container, whose 'postgres' network alias shadowed a shared
instance of the same name on the same Docker network — the live site
silently talked to an empty local database instead of DATABASE_HOST.

- Base file: postgres profiles are now [all, postgres] (core dropped);
  the dev override unions 'core' back in, so the documented dev
  workflow (make up, --profile core) is unchanged
- migrate's postgres dependency is required: false — still health-gated
  when the bundled container is active, skipped when profile-inactive
- prod override documents the behavior; opt in explicitly with
  --profile postgres (or --profile all) for a bundled production DB
- Docs: database.md/deployment.md/configuration.md/README/.env.example
  updated; upgrading.md gains a one-time cleanup runbook (full down to
  remove the previously started hub-postgres container)
2026-08-30 11:22:08 +01:00
JingleManSweep c085e124eb Merge pull request #372 from ipnet-mesh/chore/ci-e2e-and-report-artifacts
Add Playwright e2e job to CI and upload test report artifacts
2026-08-30 11:05:35 +01:00
JingleManSweep 5f621d8036 Merge branch 'main' into chore/ci-e2e-and-report-artifacts 2026-08-30 11:02:56 +01:00
Louis King 3ca379c923 Add Playwright e2e job to CI and upload test report artifacts 2026-08-30 11:02:12 +01:00
JingleManSweep 562e54a2ff Merge pull request #371 from ipnet-mesh/docs/remove-sqlite-support-plan
Remove SQLite support; PostgreSQL is now the only database backend
2026-08-30 10:49:13 +01:00
Louis King 81dcd3dead Remove SQLite support; PostgreSQL is now the only database backend 2026-08-30 10:19:12 +01:00
Louis King 2c805f2ae1 Updates 2026-08-29 23:31:15 +01:00
JingleManSweep e87a002238 Merge pull request #370 from ipnet-mesh/fix/operational-hardening
fix: readiness 503s, maintenance gating, cache invalidation, and webhook/engine hardening
2026-08-29 22:43:25 +01:00
Louis King 3f9669f7e5 fix: readiness 503s, maintenance gating, cache invalidation, and webhook/engine hardening
- /health/ready returns 503 (not 200) when not ready; body no longer leaks
  raw backend error text (api + web tiers)
- SYSTEM_MAINTENANCE now gates the web /api/* proxy (503 MAINTENANCE)
  instead of only hiding the SPA UI
- channel mutations invalidate messages/packets/packet_groups/dashboard
  caches so visibility/key changes apply immediately (was stale up to 1h)
- async DB engine: pool_size/max_overflow/pre_ping matching the sync
  engine (survives Postgres restarts); adispose() awaited from the API
  lifespan (async connections were leaked by the sync dispose)
- webhooks: permanent 4xx (except 408/429) fail fast instead of retrying;
  dispatch queue bounded at 1000 with drop-oldest + warning; shutdown
  logs dropped events; matches_event evaluated once
- SPA: apiGet/apiPostForm redirect to OIDC login on 401; chart date
  labels and route timestamps rendered in UTC/configured timezone
- e2e compose collector healthcheck uses 'meshcore-hub health collector'
  (image has no pgrep)
- docs/upgrading.md: fold unreleased notes into v0.18.0 and document the
  above
2026-08-29 22:40:19 +01:00
JingleManSweep d4cbfb63a4 Merge pull request #369 from ipnet-mesh/fix/correctness-bugs
fix: silent config drops, metrics event-loop stall, and route/decoder bugs
2026-08-29 22:13:04 +01:00
Louis King b23e7bcf15 fix: silent config drops, metrics event-loop stall, and route/decoder bugs
- api CLI single-process path now passes spam_detection_enabled /
  spam_score_threshold to create_app() so the messages hide-filter
  actually runs in the default (Docker) deployment
- OIDC role names (oidc_role_admin/operator/member/test) moved from
  WebSettings to CommonSettings and wired onto API app.state; the API
  tier previously matched hardcoded role names, ignoring customized
  OIDC_ROLE_* config in authz, channel visibility, and tag/adoption
  checks (oidc_roles_claim stays web-only)
- /metrics handler is now sync def so collection runs in the
  threadpool instead of blocking the event loop; hoisted fragile
  in-loop imports
- evaluate_route_history gates max_path_length on the packet's true
  hop count (RawPacket.path_len) instead of the prefix-filtered hop
  list, so history day buckets agree with snapshot evaluation
- reload_keys clears the decode cache: negatively-cached packets for
  a newly added channel key were permanently dropped by the normalizer

Also documents 'sudo npx playwright install-deps chromium' in the
AGENTS.md e2e setup.
2026-08-29 22:08:25 +01:00
JingleManSweep ee6e0c4894 Merge pull request #368 from ipnet-mesh/fix/security-hardening
fix(security): close fail-open defaults, header spoofing, and add CSP
2026-08-29 21:39:28 +01:00
Louis King dca3dcb309 fix(security): close fail-open defaults, header spoofing, and add CSP
- /map/data: resolve viewer OIDC session and apply the endpoint access
  mapping before fetching profiles; serve Cache-Control: private when
  OIDC is enabled (payload varies by viewer)
- /user/profile/me + /user/profile/{id}: trust X-User-Id only with a
  valid API key (new optional_user_identity dependency); closes the
  OIDC subject-identifier leak via forged headers
- OIDC_SESSION_SECRET is now mandatory when OIDC is enabled (hard fail,
  no insecure-dev-secret fallback)
- /metrics denies unauthenticated access when no API read key is set;
  new METRICS_PUBLIC opt-in (Settings, CLI, compose, env factory)
- CORS: unset CORS_ORIGINS keeps wildcard compat but drops
  allow_credentials (invalid combination in browsers) + warns
- Web tier: SecurityHeadersMiddleware (nosniff, X-Frame-Options DENY,
  Referrer-Policy, Permissions-Policy) + nonce-based CSP; nonce applied
  to spa.html inline scripts; WEB_SECURITY_HEADERS kill switch and
  WEB_CSP_EXTRA for custom tile hosts; API emits nosniff

Breaking changes documented in docs/upgrading.md.
2026-08-29 21:32:41 +01:00
JingleManSweep b751cf68b8 Merge pull request #367 from ipnet-mesh/fix/map-data-pagination
fix(web): paginate /map/data node and profile fetches
2026-08-29 13:33:20 +01:00
Louis King 9b6a16d862 fix(web): paginate /map/data node and profile fetches
The map endpoint fetched a single limit=500 page (the API's hard max,
sorted last_seen desc), so networks with more than 500 nodes silently
hid stale/offline nodes from the unfiltered map — including adopted
infrastructure, which still appeared under the adopted_by filter
because that filter narrows the query before the limit applies.

Follow offset/total pagination via a new _fetch_all_pages helper (40
pages / 20k nodes safety cap, partial results on later-page failure)
for both /api/v1/nodes and /api/v1/user/profiles, and report the
API-reported total in debug.total_nodes.
2026-08-29 13:01:16 +01:00
JingleManSweep c9d5e86953 Merge pull request #365 from ipnet-mesh/renovate/anomalyco-opencode-1.x
chore(deps): update anomalyco/opencode action to v1.18.25
2026-08-29 11:39:51 +01:00
JingleManSweep 95e99a2278 Merge pull request #363 from ipnet-mesh/renovate/tanstack-query-monorepo
chore(deps): update dependency @tanstack/react-query to v5.102.8
2026-08-29 11:36:09 +01:00
JingleManSweep 972898cff5 Merge branch 'main' into renovate/tanstack-query-monorepo 2026-08-29 11:33:38 +01:00
JingleManSweep 191ccd07d1 Merge pull request #357 from ipnet-mesh/renovate/leaflet-1.x-lockfile
chore(deps): update dependency @types/leaflet to v1.9.22
2026-08-29 11:33:23 +01:00
JingleManSweep b30f1231ec Merge pull request #355 from ipnet-mesh/renovate/vite-8.x-lockfile
chore(deps): update dependency vite to v8.2.2
2026-08-29 11:30:06 +01:00
JingleManSweep 2dd99f7f92 Merge pull request #364 from hardtofindg/hardtofindg-patch-1
docs: align README Python version
2026-08-29 11:26:30 +01:00
JingleManSweep 18cebeb5ea Merge branch 'main' into hardtofindg-patch-1 2026-08-29 11:19:42 +01:00
JingleManSweep 933ad756f2 Merge pull request #354 from ipnet-mesh/renovate/vitejs-plugin-react-6.x-lockfile
chore(deps): update dependency @vitejs/plugin-react to v6.1.1
2026-08-29 11:17:44 +01:00
JingleManSweep 806b378261 Merge pull request #358 from ipnet-mesh/renovate/testing-library-monorepo
chore(deps): update testing-library monorepo
2026-08-29 11:13:35 +01:00
JingleManSweep 1e871d5c51 Merge pull request #366 from ipnet-mesh/renovate/react-router-monorepo
chore(deps): update dependency react-router to v8.3.1
2026-08-29 11:10:01 +01:00
JingleManSweep b74855ee01 Merge branch 'main' into hardtofindg-patch-1 2026-08-29 11:07:18 +01:00
JingleManSweep 8400fc524f Merge pull request #353 from ipnet-mesh/renovate/jsdom-30.x
chore(deps): update dependency jsdom to v30
2026-08-29 11:06:27 +01:00
JingleManSweep ceb4f2be52 Merge branch 'main' into renovate/jsdom-30.x 2026-08-29 11:03:57 +01:00
JingleManSweep e3bb6752a3 Merge branch 'main' into hardtofindg-patch-1 2026-08-29 11:03:29 +01:00
JingleManSweep 604ff06cb9 Merge pull request #356 from ipnet-mesh/renovate/react-monorepo
chore(deps): update react monorepo to v19.2.18
2026-08-29 11:02:48 +01:00
JingleManSweep 2afffedaf0 Merge branch 'main' into hardtofindg-patch-1 2026-08-29 11:02:00 +01:00
JingleManSweep 1a082edbb8 Merge branch 'main' into renovate/jsdom-30.x 2026-08-29 10:57:18 +01:00
JingleManSweep 08f74f1522 Merge pull request #351 from ipnet-mesh/renovate/daisyui-5.x-lockfile
chore(deps): update dependency daisyui to v5.7.22
2026-08-29 10:57:02 +01:00
JingleManSweep 872cbedd6b Merge pull request #359 from ipnet-mesh/renovate/vitest-monorepo
chore(deps): update dependency vitest to v4.1.11
2026-08-26 00:04:01 +01:00
JingleManSweep e0e9c6e781 Merge branch 'main' into renovate/vitest-monorepo 2026-08-26 00:01:45 +01:00
JingleManSweep fcbd780105 Merge pull request #362 from ipnet-mesh/renovate/react-i18next-17.x-lockfile
chore(deps): update dependency react-i18next to v17.0.12
2026-08-25 23:59:12 +01:00
JingleManSweep df0a34a5c6 Merge branch 'main' into renovate/vitest-monorepo 2026-08-25 23:55:32 +01:00
JingleManSweep 8bbb38e554 Merge pull request #352 from ipnet-mesh/renovate/anomalyco-opencode-1.x
chore(deps): update anomalyco/opencode action to v1.18.23
2026-08-25 23:55:17 +01:00
JingleManSweep de62572dd2 Merge branch 'main' into renovate/vitest-monorepo 2026-08-25 23:52:41 +01:00
JingleManSweep 553b4060e9 Merge pull request #360 from ipnet-mesh/renovate/i18next-26.x-lockfile
chore(deps): update dependency i18next to v26.4.0
2026-08-25 23:51:25 +01:00
JingleManSweep b6e53c6cee Merge pull request #361 from ipnet-mesh/fix/mqtt-zombie-connection-hardening
fix(collector): survive broker dropping MQTT connections without FIN
2026-08-25 23:46:33 +01:00
Louis King 9913ffdecb fix(collector): survive broker dropping MQTT connections without FIN
The meshcore-mqtt-broker destroys subscriber connections (keep-alive
timeout) without sending FIN/RST, leaving a half-open socket that paho
never sees as disconnected: the collector stays "healthy" but silently
stops ingesting forever.

- Enable TCP keepalive (idle 60s / intvl 30s / count 3) on every
  connect, unwrapping paho's _WebsocketWrapper to reach the raw socket;
  kernel now fails zombie sockets so paho reconnects and resubscribes
- Verify SUBACKs via on_subscribe; log broker refusals (0x80) as ERROR
- Resubscribe with the registered QoS instead of paho's QoS 0 default
- Drop the optimistic _mqtt_connected flag; health now reports
  mqtt.is_connected, driven by real CONNACK/disconnect callbacks
2026-08-25 23:39:59 +01:00
JingleManSweep 9c1d3e5210 Merge pull request #349 from ipnet-mesh/renovate/daisyui-5.x-lockfile
chore(deps): update dependency daisyui to v5.7.3
2026-07-25 14:59:06 +01:00
JingleManSweep 10a38502eb Merge pull request #350 from ipnet-mesh/fix/dashboard-packet-retention-window
fix(dashboard): make packet displays retention-aware
2026-07-25 14:54:42 +01:00
Louis King 993ba7b5b6 docs: sync retention/evaluator defaults to #348 values
PR #348 changed several defaults but left a handful of docs, the
docker-compose fallback, example seed files, and code docstrings stale:

- docker-compose.yml: RAW_PACKET_RETENTION_DAYS fallback 7->2 (the
  :-7 override was the most consequential — operators without the env
  var set got 7 days, contradicting the code default and .env.example)
- docs/configuration.md: route-history backfill now references the
  300 s evaluator cadence (was 60 s)
- docs/seeding.md + example/seed/routes.yaml: window_hours 48/24 -> 6
  (matches the new default; both exceeded the 12 h max)
- routes.py docstring: evaluator tick 60 s -> 300 s
- subscriber.py: raw_packet_retention_days signature defaults 7 -> 2
  (overridden at runtime by effective_raw_packet_retention_days, but
  kept consistent with the authoritative config default)
2026-07-25 14:52:06 +01:00
Louis King 7802a00db3 fix(dashboard): make packet displays retention-aware
PR #348 lowered the RAW_PACKET_RETENTION_DAYS default 7->2, but the
dashboard packet count, activity chart, and breakdown chart still
advertised "Last 7 days" — a label that lied once only 2 days of data
remained. Make every raw-packet-derived window track the effective
retention so labels stay honest:

- get_dashboard_stats: packets_7d window = min(7, retention); expose
  packets_window_days on DashboardStats so the UI renders the real window
- packet-activity / packet-breakdown: clamp days = min(days, 90, retention)
  so responses never advertise days whose data has been purged
- Home StatCard + Dashboard chart subtitles: dynamic "Last N days" /
  "Per day (last N days)" via new time.last_n_days / time.per_day_last_n_days
  i18n keys ({{n}} interpolation, matching routes_over_last_n_days)
- ActivitySeries.days made optional (type shared across activity charts);
  PacketBreakdown.days added (backend always serializes it)

Messages/ads 7-day displays are unchanged — those draw on event data
which retains the full 30-day DATA_RETENTION_DAYS window.

Tests: autouse retention fixture (->90) on the three packet test classes
so existing days-handling tests stay valid; added retention-clamp tests
proving the window tracks retention=2 and relaxes to 7 at retention>=7.
2026-07-25 14:39:33 +01:00
JingleManSweep 153ba14ea0 Merge pull request #348 from ipnet-mesh/perf/route-evaluator-remediation
perf(routes): cut evaluator scan cost via window/retention/index/sweep
2026-07-25 13:21:30 +01:00
Louis King c9b247c553 perf(routes): cut evaluator scan cost via window/retention/index/sweep
The route evaluator's fetch_candidate_paths triggered a 10-30s full-table
scan of packet_path_hops per route per sweep, flooding the slow-query
log and blocking route saves on the same scan. EXPLAIN analysis (Merge
Join vs forced Nested Loop, across query rewrites, ANALYZE, CTE
MATERIALIZED) confirmed both candidate plans cost ~10-15s at 6.4M rows;
no SQL rewrite or stats change could avoid the scan. The fix applies
four orthogonal data-volume pressures:

- ROUTE_EVALUATOR_INTERVAL_SECONDS default 60->300 (5x less frequent)
- Remove synchronous _reevaluate_route on POST/PUT; route_result and
  recent_matches now refresh on the next background sweep instead of
  inline (kills save latency)
- Route.window_hours default 48->6, max 12 (bounds the candidate set);
  migration clamps pre-existing routes >12 to 12
- Covering index ix_packet_path_hops_raw_packet_id_position INCLUDE
  (node_hash, packet_hash, event_hash, received_at, observer_node_id)
  so the Merge Join outer scan becomes index-only
- RAW_PACKET_RETENTION_DAYS default 7->2 (hops cascade-delete with raw
  packets; smaller table cuts the dominant outer scan)

Migration a59611449e2a clamps window_hours and rebuilds the index
CONCURRENTLY on PostgreSQL (SQLite is a no-op; no INCLUDE support).

DESTRUCTIVE on upgrade: the retention default change purges ~5 days of
raw packets + cascaded hops on the next cleanup run. See
docs/upgrading.md for the full change notes and the new save/sweep
contract.
2026-07-25 13:15:51 +01:00
JingleManSweep 41dd92e6e7 Merge pull request #347 from ipnet-mesh/fix/pin-playwright-nix
fix(e2e): pin @playwright/test to 1.61.1 to match nixpkgs browsers
2026-07-25 00:22:16 +01:00
Louis King 2634711dd3 fix(e2e): pin @playwright/test to 1.61.1 to match nixpkgs browsers
Playwright browser binaries on this NixOS system are managed by
nixpkgs playwright.browsers (currently 1.61.1, browser revision
1228). Renovate bumped @playwright/test to 1.62.0 (revision 1234)
which has no matching browser binary in the Nix store.

Pin to exact 1.61.1 (no caret) and disable Renovate updates for
this package via renovate.json packageRules.
2026-07-25 00:20:00 +01:00