Skip to content

v1.2.0 New Features , UI Updates and More

Choose a tag to compare

@Digitalcheffe Digitalcheffe released this 10 Apr 04:45
· 27 commits to main since this release
Immutable release. Only release title and notes can be modified.
922a98f

N.O.R.A — v1.2.0 Release Notes


🆕 New Features

API Polling Engine (AP-01 → AP-04)

A full end-to-end API polling system that lets NORA actively query your apps instead of waiting for webhooks.

  • Digest Registry — new database table (digest_registry) with a startup reconciler that reads all app profiles and upserts their digest categories and widgets. Entries can be toggled active/inactive; active entries cannot be deleted. A new Digest Registry tab in Settings exposes the registry with a filter-by-profile dropdown and a SlidePanel detail drawer.
  • App Profile Schema extensions — profiles now support an api_polling block (list of endpoints with path, name, label, target, value_type) and a digest.widgets section with source: api | webhook. Validation runs at load time with log-and-skip on failure — no startup crashes.
  • API Poller scannerRunAPIPolling registered as a GlobalDiscoveryJob (hourly cadence). Supports four auth types, count/string/boolean/list value types, JSONPath and length targets. Snapshots written to a new app_metric_snapshots table (UNIQUE(app_id, metric_name)).
  • App Detail metric cards — the App Detail page now renders per-category digest stats as individual metric cards, sourced from both webhook events and API poll snapshots. Cards appear even when the app has zero events yet.
  • API URL field — apps can now store a separate internal api_url distinct from the public base_url. The poller uses api_url when present, falls back to base_url. Add App and App Settings UI both expose the field.

Relationship Graph & Infrastructure Topology

  • component_links table — canonical parent-child relationship store covering all entity types (Proxmox → VM, VM → Docker Engine → Container → App → Monitor). Backfilled from all previous inline FK columns on first startup.
  • /relationships page — app-centric table showing each app's infra link chain; + Link dropdown to create a new relationship; Unlink to remove one. All writes go through the component_links API (GET/POST/DELETE /api/v1/links).
  • Network Topology page — interactive ReactFlow graph showing all four entity tiers (infra, containers, apps, monitors) as distinct styled nodes. Color-coded edges per tier (blue → teal → violet → green). Tree layout replaces flat BFS — parents are centered above children. Topology replaced the embedded map tab on the Infrastructure page.
  • Auto-linking — containers are automatically linked to apps when a discovered container's image matches the app's registered image field. Traefik route → app links are synced automatically when discovery resolves a route to an app via container cross-reference.

Container Management

  • Infrastructure Containers tab — all discovered containers from every Docker Engine and Portainer endpoint in one flat table (/infrastructure?view=containers). Columns: status dot, name, source badge (Docker / Portainer), truncated image, update status, last seen, linked app, settings gear.
  • Container detail panel — SlidePanel to inspect a container: ports, networks, volumes, labels, restart policy, Docker-native created timestamp. On-demand only, no continuous polling.
  • Portainer + Docker Engine detail pages — replaced the inline container card grids with stat cards (running/stopped/images/volumes/networks/dangling images/unused volumes) and a link through to the Containers tab. Inline app linking removed from both pages; now managed exclusively via the Relationships page.
  • Container enrichment fieldsports, labels, volumes, networks, restart_policy, docker_created_at now fully populated by the Docker and Portainer scanners and returned by the API (previously collected in DB but silently dropped from the response struct).

SlidePanel Shared Drawer Component

All modal-backdrop overlays replaced with a unified SlidePanel component — right-side panel on desktop (480px), bottom sheet on mobile. Features: React portal, focus trap, Escape key, body scroll lock, 200ms entry / 150ms exit animation. Migrated across: Add/Edit Infra Component, Add Check, Edit Check, App Settings, Add App wizard (3-step), Event detail expand. All dropdowns (templates, apps, Traefik integrations) now sort alphabetically.


Instance & Tech Stack Info

Settings Instance tab overhauled:

  • Displays NORA version, Go runtime version, live SQLite version (queried at runtime)
  • Tech Stack card — Backend dependencies read from the compiled binary via debug.ReadBuildInfo() (SQLite, chi, jwt, webpush-go, gosnmp, Docker SDK, sqlx). Frontend deps imported from package.json at build time (React, React Router, Vite, TypeScript). Always reflects what's actually running — no manual updates.
  • GitHub repo and Wiki links in-panel.
  • Settings tabs reordered: Apps → Notifications → Notify Rules → Digest Registry → Jobs → Users → Instance.

🏗️ Infrastructure & Schema Improvements

Database Sprawl Cleanup (Migrations 043–049)

Seven migrations eliminated redundant tables that had been accumulating since earlier refactors:

Migration What happened
043 Drop legacy traefik_routes table
044 Drop traefik_services; services now derived from discovered_routes
045 Drop infrastructure_integrations, traefik_certs, traefik_component_certs; strip ssl_source/integration_id from monitor_checks
046 Drop traefik_overview; add traefik_meta column to infra components
047 Consolidate snmp_meta / synology_meta / traefik_meta → single meta column
048 Migrate docker_engines rows into infrastructure_components (same IDs, all links preserved), drop table; topology rewritten to treat Docker Engines as uniform infra nodes
049 Add servers_json column to discovered_routes (JSON map of backend server URLs → UP|DOWN)

Proxmox VM Type System

  • Dropped bare_metal, lxc, and virtual_host component types; added vm_linux, vm_windows, vm_other.
  • LXC containers removed entirely from the Proxmox scanner.
  • VM OS type (ostype from Proxmox API) now determines the component type at discovery time (Linux variants → vm_linux, Windows variants → vm_windows, unknown → vm_other).

Route Data Enrichment

Eleven previously missing fields now returned by route list endpoints (GET /routes, GET /infrastructure/{id}/routes): router_status, provider, entry_points, has_tls_resolver, cert_resolver_name, service_status, service_type, servers_total, servers_up, servers_down, servers_json.

Stale BackendService Field Removed

BackendService field removed from DiscoveredRoute struct, routeSelectCols, and all test fixtures. It was superseded by ServiceName in an earlier migration but was still being SELECTed on every route query.


🐛 Bug Fixes

Issue Fix
Traefik discovery source_type Events from Traefik discovery were logged as "physical_host". Fixed to "traefik", consistent with every other scanner.
Portainer "Discover Now" button ScanOneComponent had no portainer_api case — hit default and returned an error. Added the case, wired to PortainerEnrichmentWorker. Portainer discovery now also upserts containers to discovered_containers instead of just counting them.
Portainer metrics source_type Portainer container metrics were written with source_type = "portainer_container" which violated the DB CHECK constraint. Fixed to "docker_container".
Monitor check auto-filling app template URL The monitor: block in app profiles was auto-creating and overwriting user URL checks on every save/startup via SyncAllProfileChecks. Removed the entire monitor sync system — monitor checks are now fully user-managed. The monitor: block stripped from all 25 app profiles.
API Poller — taint/security (CodeQL) API key was string-concatenated into rawURL, creating a CodeQL taint path to log call sites. Fixed by building requests with clean URLs and setting the key via q.Encode(). All error log calls now log entry.Path instead of the full URL.
Secure cookie breaking HTTP dev environments Secure: true on session cookies silently dropped cookies on plain-HTTP dev setups. Replaced with isSecureRequest(r) helper (checks r.TLS != nil or X-Forwarded-Proto: https) on all three cookie writes (Login, Logout, TOTP Verify).
SSL monitor check Cleaned up SSL check result parsing and days-remaining display.
Proxmox detail page Proxmox detail page not rendering correctly — fixed as part of the VM type system and detail page refactor.
Traefik chain walker Chain walker was following parent links through Traefik nodes into VMs/Proxmox. Added early-break on parentType == "traefik" and "traefik_route". Manual Traefik links with no discovered routes now inject a synthetic ManualLink: true entry so Traefik still appears in the chain.

🎨 UI / Dashboard

Dashboard Rework

  • New section order: Summary Bar → Events → Monitor Checks → Apps → Infrastructure
  • Events + Monitor Checks side-by-side in a shared 2-column row; each a 2×2 grid at matched heights. Event cards redesigned to match check rollup structure (type label → big count → event count; no icon). Both card sets use identical padding and top-border accent stripe so rows align pixel-perfectly.
  • Unified app cards — Apps and Services split removed. New compact card: icon left, name + status dot, last event text, optional checks X/Y pill. Backend computes checks_up/checks_total per app from enabled linked monitor checks.
  • Sparklines removed from Summary Bar cards.
  • Responsive: summary bar 2-column on mobile, events + checks stack vertically, app cards in 2-column grid.

Infrastructure Page

  • Container list gains column headers on desktop.
  • Image update indicator changed from amber dot → "Update" amber pill.
  • Navigate button redesigned as a pill with accent border, solid hover fill and glow.

Digest Report (Email)

  • Per-app enrichment: linked monitor checks, Traefik routes (parsed via routeDomain() helper), container counts pre-computed per app section.
  • Compact one-row-per-app summary table replaces expanded per-app widget blocks.
  • Infrastructure and container sections use consistent column-header table layout in both HTML and plain-text templates.

📦 Migrations Summary

# Description
031 digest_registry table
032 profile_source column on digest_registry
033 app_metric_snapshots table
034 Component type system rebuild (add vm_linux/vm_windows/vm_other, remove bare_metal/lxc/virtual_host)
035 component_links table + backfill from inline FK columns
036 Drop old inline FK columns (parent_id, docker_engine_id, host_component_id)
037 learned_containers / discovered_containers enrichment fields
038 first_seen_at on traefik_services
041 Backfill traefik → route, route → app, monitor → app into component_links
043–049 Database sprawl cleanup (see table above)
051 Container env vars