writekit/internal/server/sync.go

114 lines
2.6 KiB
Go
Raw Permalink Normal View History

2026-01-09 00:16:46 +02:00
package server
import (
"context"
"log"
"time"
"github.com/writekitapp/writekit/internal/tenant"
)
func (s *Server) StartAnalyticsSync() {
if !s.cloudflare.IsConfigured() {
return
}
go s.runAnalyticsSync()
}
func (s *Server) runAnalyticsSync() {
ticker := time.NewTicker(24 * time.Hour)
defer ticker.Stop()
s.syncYesterdayAnalytics()
for range ticker.C {
s.syncYesterdayAnalytics()
}
}
func (s *Server) syncYesterdayAnalytics() {
ctx := context.Background()
yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
tenants, err := s.database.ListTenants(ctx)
if err != nil {
log.Printf("analytics sync: list tenants: %v", err)
return
}
for _, t := range tenants {
s.syncTenantAnalytics(ctx, t.ID, t.Subdomain, yesterday)
}
demos, err := s.database.ListActiveDemos(ctx)
if err != nil {
log.Printf("analytics sync: list demos: %v", err)
return
}
for _, d := range demos {
s.syncTenantAnalytics(ctx, d.ID, d.Subdomain, yesterday)
}
}
func (s *Server) syncTenantAnalytics(ctx context.Context, tenantID, subdomain, date string) {
hostname := subdomain + "." + s.domain
tenantDB, err := s.tenantPool.Get(tenantID)
if err != nil {
log.Printf("analytics sync: get tenant db %s: %v", tenantID, err)
return
}
q := tenant.NewQueries(tenantDB)
has, err := q.HasArchivedDate(ctx, date)
if err != nil {
log.Printf("analytics sync: check archived %s: %v", tenantID, err)
return
}
if has {
return
}
cfData, err := s.cloudflare.GetAnalytics(ctx, 1, hostname)
if err != nil {
log.Printf("analytics sync: fetch cf data %s: %v", tenantID, err)
return
}
if cfData == nil || len(cfData.Daily) == 0 {
return
}
day := cfData.Daily[0]
archived := &tenant.ArchivedDay{
Date: day.Date,
Requests: day.Requests,
PageViews: day.PageViews,
UniqueVisitors: day.Visitors,
Bandwidth: day.Bandwidth,
}
for _, b := range cfData.Browsers {
archived.Browsers = append(archived.Browsers, tenant.NamedStat{Name: b.Name, Count: b.Count})
}
for _, o := range cfData.OS {
archived.OS = append(archived.OS, tenant.NamedStat{Name: o.Name, Count: o.Count})
}
for _, d := range cfData.Devices {
archived.Devices = append(archived.Devices, tenant.NamedStat{Name: d.Name, Count: d.Count})
}
for _, c := range cfData.Countries {
archived.Countries = append(archived.Countries, tenant.NamedStat{Name: c.Name, Count: c.Count})
}
for _, p := range cfData.Paths {
archived.Paths = append(archived.Paths, tenant.PageStats{Path: p.Path, Views: p.Requests})
}
if err := q.SaveDailyAnalytics(ctx, archived); err != nil {
log.Printf("analytics sync: save archived %s: %v", tenantID, err)
}
}