feat(hub): app telemetry analytics dashboard (v0.4.0)

- store/telemetry.go: new app_telemetry + app_log_issues tables with
  SaveAppTelemetry, GetFleetAppSummary (with P95), GetAppTelemetryHistory,
  GetAppCustomerBreakdown, GetCustomerAppSummary, GetAppIssues, prune methods
- api/handler.go: parse and save optional app_telemetry from report body,
  backward-compatible with old controllers
- cmd/hub/main.go: prune app_telemetry (90d) and stale issues (30d)
- web/apps.go: handleApps + handleAppDetail + chart data aggregation helpers
- web/server.go: routes for /apps, /apps/{name}, /static/chart.min.js;
  added memoryColor/accuracyClass/gt template functions
- web/embed.go: embed static/chart.min.js
- web/configs.go: add app telemetry section to handleCustomerUnified
- templates/apps.html: fleet-wide app list with summary cards and sortable table
- templates/app_detail.html: per-app page with Chart.js memory trend,
  customer breakdown, and known issues table
- templates/customer_unified.html: new Alkalmazás telemetria card
- templates/style.css: badge, summary-card, chart, period-selector,
  accuracy-dot, mem-color, data-table styles
- All templates: added Alkalmazások nav link

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-23 10:46:50 +01:00
parent 8bed5ec339
commit a757bee07a
20 changed files with 1323 additions and 2 deletions
+9
View File
@@ -233,6 +233,8 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
var events []store.Event
var eventCounts map[string]int
var appTelemetry []store.CustomerAppSummary
if customer != nil {
history, _ = s.store.GetCustomerHistory(customerID, 24*time.Hour)
notifPrefs, _ = s.store.GetNotificationPrefs(customerID)
@@ -243,6 +245,7 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
}
events, _ = s.store.GetRecentEvents(customerID, 50)
eventCounts, _ = s.store.CountEventsBySeverity(customerID, time.Now().Add(-24*time.Hour))
appTelemetry, _ = s.store.GetCustomerAppSummary(customerID, time.Now().Add(-7*24*time.Hour))
}
type pageData struct {
@@ -277,6 +280,9 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
Events []store.Event
EventCounts map[string]int // severity → count (last 24h)
AppTelemetry []store.CustomerAppSummary
HasAppTelemetry bool
Flash string
ActiveNav string
CSRFField template.HTML
@@ -315,6 +321,9 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
Events: events,
EventCounts: eventCounts,
AppTelemetry: appTelemetry,
HasAppTelemetry: len(appTelemetry) > 0,
Flash: r.URL.Query().Get("flash"),
ActiveNav: "configs",
CSRFField: s.csrfField(r),