monorepo/native/desktop/maplefile/internal/app/app_sync.go

148 lines
4.6 KiB
Go

package app
import (
"fmt"
"time"
"go.uber.org/zap"
"codeberg.org/mapleopentech/monorepo/native/desktop/maplefile/internal/service/sync"
)
// SyncStatusData represents the current sync status for the frontend
type SyncStatusData struct {
IsSyncing bool `json:"is_syncing"`
LastSyncTime string `json:"last_sync_time,omitempty"`
LastSyncSuccess bool `json:"last_sync_success"`
LastSyncError string `json:"last_sync_error,omitempty"`
CollectionsSynced bool `json:"collections_synced"`
FilesSynced bool `json:"files_synced"`
FullySynced bool `json:"fully_synced"`
}
// SyncResultData represents the result of a sync operation
type SyncResultData struct {
CollectionsProcessed int `json:"collections_processed"`
CollectionsAdded int `json:"collections_added"`
CollectionsUpdated int `json:"collections_updated"`
CollectionsDeleted int `json:"collections_deleted"`
FilesProcessed int `json:"files_processed"`
FilesAdded int `json:"files_added"`
FilesUpdated int `json:"files_updated"`
FilesDeleted int `json:"files_deleted"`
Errors []string `json:"errors,omitempty"`
}
// GetSyncStatus returns the current sync status
func (a *Application) GetSyncStatus() (*SyncStatusData, error) {
status, err := a.syncService.GetSyncStatus(a.ctx)
if err != nil {
a.logger.Error("Failed to get sync status", zap.Error(err))
return nil, fmt.Errorf("failed to get sync status: %w", err)
}
return &SyncStatusData{
IsSyncing: false,
LastSyncTime: time.Now().Format(time.RFC3339),
LastSyncSuccess: true,
LastSyncError: "",
CollectionsSynced: status.CollectionsSynced,
FilesSynced: status.FilesSynced,
FullySynced: status.FullySynced,
}, nil
}
// TriggerSync triggers a full sync of collections and files
func (a *Application) TriggerSync() error {
a.logger.Info("Manual sync triggered")
// Get current session for email
session, err := a.authService.GetCurrentSession(a.ctx)
if err != nil {
a.logger.Error("Failed to get session for sync", zap.Error(err))
return fmt.Errorf("not authenticated: %w", err)
}
// Get the stored password for decryption
var password string
if a.passwordStore.HasPassword(session.Email) {
password, err = a.passwordStore.GetPassword(session.Email)
if err != nil {
a.logger.Warn("Failed to get stored password, sync will skip decryption", zap.Error(err))
}
} else {
a.logger.Warn("No stored password, sync will skip decryption")
}
input := &sync.SyncInput{
BatchSize: 50,
MaxBatches: 100,
Password: password,
}
result, err := a.syncService.SyncAll(a.ctx, input)
if err != nil {
a.logger.Error("Sync failed", zap.Error(err))
return fmt.Errorf("sync failed: %w", err)
}
a.logger.Info("Sync completed",
zap.Int("collections_added", result.CollectionsAdded),
zap.Int("files_added", result.FilesAdded),
zap.Int("errors", len(result.Errors)))
return nil
}
// TriggerSyncWithResult triggers a full sync and returns the result
func (a *Application) TriggerSyncWithResult() (*SyncResultData, error) {
a.logger.Info("Manual sync with result triggered")
// Get current session for email
session, err := a.authService.GetCurrentSession(a.ctx)
if err != nil {
a.logger.Error("Failed to get session for sync", zap.Error(err))
return nil, fmt.Errorf("not authenticated: %w", err)
}
// Get the stored password for decryption
var password string
if a.passwordStore.HasPassword(session.Email) {
password, err = a.passwordStore.GetPassword(session.Email)
if err != nil {
a.logger.Warn("Failed to get stored password, sync will skip decryption", zap.Error(err))
}
} else {
a.logger.Warn("No stored password, sync will skip decryption")
}
input := &sync.SyncInput{
BatchSize: 50,
MaxBatches: 100,
Password: password,
}
result, err := a.syncService.SyncAll(a.ctx, input)
if err != nil {
a.logger.Error("Sync failed", zap.Error(err))
return nil, fmt.Errorf("sync failed: %w", err)
}
return &SyncResultData{
CollectionsProcessed: result.CollectionsProcessed,
CollectionsAdded: result.CollectionsAdded,
CollectionsUpdated: result.CollectionsUpdated,
CollectionsDeleted: result.CollectionsDeleted,
FilesProcessed: result.FilesProcessed,
FilesAdded: result.FilesAdded,
FilesUpdated: result.FilesUpdated,
FilesDeleted: result.FilesDeleted,
Errors: result.Errors,
}, nil
}
// ResetSync resets all sync state for a fresh sync
func (a *Application) ResetSync() error {
a.logger.Info("Resetting sync state")
return a.syncService.ResetSync(a.ctx)
}