add telemetry system with analytics and crash reporting (M08)

This commit is contained in:
2026-01-18 21:53:06 +01:00
parent fbcb5c9543
commit a5aa3cc9d7
6 changed files with 1484 additions and 3 deletions

View File

@@ -13,6 +13,7 @@ import (
"github.com/omixlab/mosis-portal/internal/config"
"github.com/omixlab/mosis-portal/internal/database"
"github.com/omixlab/mosis-portal/internal/storage"
"github.com/omixlab/mosis-portal/internal/telemetry"
"github.com/omixlab/mosis-portal/internal/web"
)
@@ -32,6 +33,13 @@ func NewRouter(cfg *config.Config, db *database.DB) http.Handler {
log.Fatalf("Failed to initialize storage: %v", err)
}
// Initialize telemetry service
telemetryDB := cfg.StoragePath + "/telemetry.db"
telemetrySvc, err := telemetry.New(telemetryDB)
if err != nil {
log.Fatalf("Failed to initialize telemetry service: %v", err)
}
// Initialize auth components
jwtManager := auth.NewJWTManager(cfg.JWTSecret)
oauthManager := auth.NewOAuthManager(
@@ -44,6 +52,7 @@ func NewRouter(cfg *config.Config, db *database.DB) http.Handler {
appHandler := handlers.NewAppHandler(db, store)
storeHandler := handlers.NewStoreHandler(db, store)
adminHandler := handlers.NewAdminHandler(db, store)
telemetryHandler := handlers.NewTelemetryHandler(db, telemetrySvc)
// Health check
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
@@ -95,6 +104,19 @@ func NewRouter(cfg *config.Config, db *database.DB) http.Handler {
// Package upload
r.Post("/{versionID}/upload", appHandler.UploadPackage)
})
// Analytics
r.Route("/{appID}/analytics", func(r chi.Router) {
r.Get("/overview", telemetryHandler.GetAnalyticsOverview)
r.Get("/events", telemetryHandler.GetAnalyticsEvents)
})
// Crashes
r.Route("/{appID}/crashes", func(r chi.Router) {
r.Get("/", telemetryHandler.GetCrashes)
r.Get("/{crashID}", telemetryHandler.GetCrash)
r.Patch("/{crashID}", telemetryHandler.UpdateCrashStatus)
})
})
// API Keys
@@ -121,10 +143,10 @@ func NewRouter(cfg *config.Config, db *database.DB) http.Handler {
r.Get("/apps/{packageID}/versions/{versionCode}/download", storeHandler.DownloadVersion)
})
// Telemetry (API key auth preferred, but can work without for initial setup)
// Telemetry endpoints (public - devices send events here)
r.Route("/telemetry", func(r chi.Router) {
r.Post("/events", handlers.NotImplemented)
r.Post("/crash", handlers.NotImplemented)
r.Post("/events", telemetryHandler.RecordEvents)
r.Post("/crash", telemetryHandler.RecordCrash)
})
})
@@ -145,6 +167,7 @@ func NewRouter(cfg *config.Config, db *database.DB) http.Handler {
log.Printf("Warning: Failed to initialize web handler: %v", err)
} else {
webHandler.SetStorage(store)
webHandler.SetTelemetry(telemetrySvc)
sessionMW := web.NewSessionMiddleware(db, cfg.JWTSecret)
// Public web pages
@@ -163,6 +186,8 @@ func NewRouter(cfg *config.Config, db *database.DB) http.Handler {
r.Get("/dashboard", webHandler.Dashboard)
r.Get("/apps/new", webHandler.AppNew)
r.Get("/apps/{appID}", webHandler.AppDetail)
r.Get("/apps/{appID}/analytics", webHandler.AppAnalytics)
r.Get("/apps/{appID}/crashes", webHandler.AppCrashes)
// htmx partials
r.Get("/partials/apps", webHandler.AppListPartial)