Joins NodeTag (key='role') to the node last seen Prometheus metric so
alert rules can target infrastructure nodes only (role="infra").
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add /metrics endpoint with Prometheus gauges for nodes, messages,
advertisements, telemetry, trace paths, events, and members. Include
per-node last_seen timestamps for alerting. Add Alertmanager service
to Docker Compose metrics profile with default blackhole receiver.
Add NodeNotSeen alert rule (48h threshold). Add 1h time window to
all windowed metrics alongside existing 24h/7d/30d windows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nodes, advertisements, and messages pages now auto-refresh on a
configurable interval (WEB_AUTO_REFRESH_SECONDS, default 30s). A
pause/play toggle in the page header lets users control it. Setting
the interval to 0 disables auto-refresh entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Capture e.currentTarget synchronously before async operations
to prevent it from becoming null in async promise handlers.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Only fetch members data when feature is enabled
- Hide member filter when feature is disabled
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Only fetch members data when feature is enabled
- Hide member filter when feature is disabled
- Hide member column when feature is disabled
- Adjust table colspan dynamically based on feature
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enhances the web dashboard's node presentation to match official MeshCore
app behavior and provide better user experience:
- Extract emoji from node names (e.g., "🏠 Home Gateway" uses 🏠 icon)
- Display description tags under node names across all list pages
- Add Member column to show network member associations
- Add copyable public key columns on Nodes and Advertisements pages
- Create reusable renderNodeDisplay() component for consistency
- Improve node detail page layout with larger emoji and inline description
- Document standard node tags (name, description, member_id, etc.)
- Fix documentation: correct Python version requirement and tag examples
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement cache-control middleware to optimize browser caching and reduce
bandwidth usage. Static files are cached for 1 year when accessed with
version parameters, while dynamic content is never cached.
Changes:
- Add CacheControlMiddleware with path-based caching logic
- Register middleware in web app after ProxyHeadersMiddleware
- Add version query parameters to CSS, JS, and app.js references
- Create comprehensive test suite (20 tests) for all cache behaviors
Cache strategy:
- Static files with ?v=X.Y.Z: 1 year (immutable)
- Static files without version: 1 hour (fallback)
- SPA shell HTML: no-cache (dynamic config)
- Health endpoints: no-cache, no-store (always fresh)
- Map data: 5 minutes (location updates)
- Custom pages: 1 hour (stable markdown)
- API proxy: pass-through (backend controls)
All 458 tests passing, 95% middleware coverage.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replaced verbose translation section with concise GitHub alert notification.
- Uses [!IMPORTANT] alert style for better visibility
- Reduced from 16 lines to 4 lines
- Keeps essential information and link to Translation Guide
- More scannable and professional appearance
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed the code-review.yml workflow that automatically runs Claude Code review on pull requests.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The Tags panel title was showing 'nodes.tags' as literal text instead of the translation.
Fixed: node-detail.js line 174 now uses entities.tags
Comprehensive review completed:
- Verified all 115 unique translation keys across all pages
- All keys properly resolve to valid translations in en.json
- All i18n tests passing
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replaced non-existent common.all_nodes key with common.all_entity pattern.
- advertisements.js: Use common.all_entity with entities.nodes
- map.js: Use common.all_entity with entities.nodes
All translation keys now properly resolve across the entire dashboard.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## i18n Refactoring
- Refactor admin translations to use common composable patterns
- Add common patterns: delete_entity_confirm, entity_added_success, move_entity_to_another_node, etc.
- Remove 18 duplicate keys from admin_members and admin_node_tags sections
- Update all admin JavaScript files to use new common patterns with dynamic entity composition
- Fix label consistency: rename first_seen to first_seen_label to match naming convention
## Translation Documentation
- Create comprehensive translation reference guide (languages.md) with 200+ documented keys
- Add translation architecture documentation to AGENTS.md with examples and best practices
- Add "Help Translate" call-to-action section in README with link to translation guide
- Add i18n feature to README features list
## Documentation Audit
- Add undocumented config options: API_KEY, WEB_LOCALE, WEB_DOMAIN to README and .env.example
- Fix outdated CLI syntax: interface --mode receiver → interface receiver
- Update database migration commands to use CLI wrapper (meshcore-hub db) instead of direct alembic
- Add static/locales/ directory to project structure section
- Add i18n configuration (WEB_LOCALE, WEB_THEME) to docker-compose.yml
## Testing
- All 438 tests passing
- All pre-commit checks passing (black, flake8, mypy)
- Added tests for new common translation patterns
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Update admin index page to use entities.members and entities.tags
- Rename admin.node_tags_description to admin.tags_description
- Remove redundant admin.*_title keys in favor of entities
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove page_title section, compose titles dynamically as "{{entity}} - {{network_name}}"
- Add entities section for centralized entity names (nodes, members, tags, etc.)
- Replace specific action translations with composed patterns (add_entity, edit_entity, etc.)
- Create links section for common platform names (github, discord, youtube)
- Remove redundant page-specific title fields, use entity names instead
- Update all page components to use new translation structure
- Keep user-defined strings (network_name) separate from translatable content
This follows i18n best practices by using composition over duplication,
centralizing reusable terms, and making it easier to add new languages.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>