Files
radiantwave-legacy/internal/sync/sync.go
T

145 lines
4.1 KiB
Go

package sync
import (
"regexp"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"rhemawavetech.com/rhemawave/internal/db"
"rhemawavetech.com/rhemawave/internal/logger"
"rhemawavetech.com/rhemawave/internal/netreq"
)
var htmlRegex = regexp.MustCompile(`<[^>]*>`)
// SyncProclamations fetches data from the API, cleans it, and updates the local DB.
// It returns the slice of proclamations so the UI can update immediately.
func SyncProclamations(database *gorm.DB) ([]db.Proclamation, error) {
fullURL := "https://portal.radiantwavetech.com/api/v1/proclamations"
logger.Debug("Syncronizing proclamations. URL: %s", fullURL)
proclamations, err := netreq.GetJSON[db.Proclamation](fullURL)
if err != nil {
// If we're offline or API is down, we log it but don't crash.
// The UI can still use whatever is currently in the DB.
logger.Error("Proclamation sync failed, skipping update: %v", err)
return nil, err
}
logger.Debug("Request Granted")
for i := range proclamations {
proclamations[i].Content = htmlRegex.ReplaceAllString(proclamations[i].Content, "")
}
var storedProclamationSettings []db.Proclamation
database.Select("ID", "Selected").Find(&storedProclamationSettings)
// [ID]Selected
stash := make(map[string]bool)
for _, row := range storedProclamationSettings {
stash[row.ID] = row.Selected
}
for i := range proclamations {
proclamations[i].Selected = stash[proclamations[i].ID]
}
err = database.Transaction(func(tx *gorm.DB) error {
ids := make([]string, len(proclamations))
for i, p := range proclamations {
ids[i] = p.ID
}
if len(ids) == 0 {
// API returned nothing → DB should be empty
if err := tx.Where("1 = 1").Delete(&db.Proclamation{}).Error; err != nil {
return err
}
} else {
// Remove anything not in API
if err := tx.Where("id NOT IN ?", ids).Delete(&db.Proclamation{}).Error; err != nil {
return err
}
}
// Upsert (preserve Selected automatically)
if err := tx.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{
"name",
"content",
"solfeggio_frequency_id",
"category_id",
"available",
"price",
}),
}).Create(&proclamations).Error; err != nil {
return err
}
// Return nil as err for this statement, does not exit the function
return nil
})
logger.Debug("Proclamations stored to database")
if err != nil {
logger.Error("Failed to save synced proclamations: %v", err)
return nil, err
}
logger.Info("Successfully synced proclamations: %d", len(proclamations))
return proclamations, nil
}
func SyncCategories(database *gorm.DB) ([]db.ProclamationCategory, error) {
fullURL := "https://portal.radiantwavetech.com/api/v1/categories"
categories, err := netreq.GetJSON[db.ProclamationCategory](fullURL)
if err != nil {
logger.Error("Category sync failed, skipping update: %v", err)
return nil, err
}
err = database.Transaction(func(tx *gorm.DB) error {
if err := tx.Where("1 = 1").Delete(&db.ProclamationCategory{}).Error; err != nil {
return err
}
if err := tx.Save(&categories).Error; err != nil {
return err
}
return nil
})
if err != nil {
logger.Error("failed to sync proclamation categories: %v", err)
return nil, err
}
logger.Info("Successfully synced proclamation categories: %d", len(categories))
return categories, nil
}
func SyncFrequencies(database *gorm.DB) ([]db.SolfeggioFrequency, error) {
fullURL := "https://portal.radiantwavetech.com/api/v1/frequencies"
frequencies, err := netreq.GetJSON[db.SolfeggioFrequency](fullURL)
if err != nil {
logger.Error("Frequency sync failed, skipping update: %v", err)
return nil, err
}
err = database.Transaction(func(tx *gorm.DB) error {
if err := tx.Where("1 = 1").Delete(&db.SolfeggioFrequency{}).Error; err != nil {
return err
}
if err := tx.Save(&frequencies).Error; err != nil {
return err
}
return nil
})
if err != nil {
logger.Error("failed to sync solfeggio frequencies: %v", err)
return nil, err
}
logger.Info("Succesfully synced solfeggio frequencies: %d", len(frequencies))
return frequencies, nil
}