package datastore import ( "context" "time" domain2 "epigas.gitea.cloud/RiskRancher/core/pkg/domain" ) func (s *SQLiteStore) UpdateAppConfig(ctx context.Context, config domain2.AppConfig) error { query := ` INSERT INTO app_config (id, timezone, business_start, business_end, default_extension_days) VALUES (1, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET timezone = excluded.timezone, business_start = excluded.business_start, business_end = excluded.business_end, default_extension_days = excluded.default_extension_days ` _, err := s.DB.ExecContext(ctx, query, config.Timezone, config.BusinessStart, config.BusinessEnd, config.DefaultExtensionDays) return err } func (s *SQLiteStore) GetAppConfig(ctx context.Context) (domain2.AppConfig, error) { var c domain2.AppConfig query := `SELECT timezone, business_start, business_end, default_extension_days, backup_enabled, backup_interval_hours, backup_retention_days FROM app_config WHERE id = 1` err := s.DB.QueryRowContext(ctx, query).Scan( &c.Timezone, &c.BusinessStart, &c.BusinessEnd, &c.DefaultExtensionDays, &c.Backup.Enabled, &c.Backup.IntervalHours, &c.Backup.RetentionDays, ) return c, err } // buildSLAMap creates a fast 2D lookup table: map[Domain][Severity]Policy func (s *SQLiteStore) buildSLAMap(ctx context.Context) (map[string]map[string]domain2.SLAPolicy, error) { policies, err := s.GetSLAPolicies(ctx) if err != nil { return nil, err } slaMap := make(map[string]map[string]domain2.SLAPolicy) for _, p := range policies { if slaMap[p.Domain] == nil { slaMap[p.Domain] = make(map[string]domain2.SLAPolicy) } slaMap[p.Domain][p.Severity] = p } return slaMap, nil } func (s *SQLiteStore) ExportSystemState(ctx context.Context) (domain2.ExportState, error) { var state domain2.ExportState state.Version = "1.1" state.ExportedAt = time.Now().UTC().Format(time.RFC3339) config, err := s.GetAppConfig(ctx) if err == nil { state.AppConfig = config } slas, err := s.GetSLAPolicies(ctx) if err == nil { state.SLAPolicies = slas } users, err := s.GetAllUsers(ctx) if err == nil { for _, u := range users { u.PasswordHash = "" state.Users = append(state.Users, *u) } } adapters, err := s.GetAdapters(ctx) if err == nil { state.Adapters = adapters } query := `SELECT id, domain, source, asset_identifier, title, COALESCE(description, ''), severity, status, dedupe_hash, created_at FROM tickets` rows, err := s.DB.QueryContext(ctx, query) if err != nil { return state, err } defer rows.Close() for rows.Next() { var t domain2.Ticket if err := rows.Scan(&t.ID, &t.Domain, &t.Source, &t.AssetIdentifier, &t.Title, &t.Description, &t.Severity, &t.Status, &t.DedupeHash, &t.CreatedAt); err == nil { state.Tickets = append(state.Tickets, t) } } return state, nil } func (s *SQLiteStore) UpdateBackupPolicy(ctx context.Context, policy domain2.BackupPolicy) error { _, err := s.DB.ExecContext(ctx, ` UPDATE app_config SET backup_enabled = ?, backup_interval_hours = ?, backup_retention_days = ? WHERE id = 1`, policy.Enabled, policy.IntervalHours, policy.RetentionDays) return err } func (s *SQLiteStore) GetSLAPolicies(ctx context.Context) ([]domain2.SLAPolicy, error) { rows, err := s.DB.QueryContext(ctx, "SELECT domain, severity, days_to_remediate, max_extensions, days_to_triage FROM sla_policies ORDER BY domain, severity") if err != nil { return nil, err } defer rows.Close() var policies []domain2.SLAPolicy for rows.Next() { var p domain2.SLAPolicy rows.Scan(&p.Domain, &p.Severity, &p.DaysToRemediate, &p.MaxExtensions, &p.DaysToTriage) policies = append(policies, p) } return policies, nil } func (s *SQLiteStore) UpdateSLAPolicies(ctx context.Context, slas []domain2.SLAPolicy) error { tx, err := s.DB.BeginTx(ctx, nil) if err != nil { return err } defer tx.Rollback() stmt, err := tx.PrepareContext(ctx, ` UPDATE sla_policies SET days_to_triage = ?, days_to_remediate = ?, max_extensions = ? WHERE domain = ? AND severity = ?`) if err != nil { return err } defer stmt.Close() for _, sla := range slas { _, err = stmt.ExecContext(ctx, sla.DaysToTriage, sla.DaysToRemediate, sla.MaxExtensions, sla.Domain, sla.Severity) if err != nil { return err } } return tx.Commit() } func (s *SQLiteStore) GetWranglers(ctx context.Context) ([]domain2.User, error) { query := ` SELECT id, email, full_name, global_role, is_active, created_at FROM users WHERE global_role = 'Wrangler' AND is_active = 1 ORDER BY email ASC ` rows, err := s.DB.QueryContext(ctx, query) if err != nil { return nil, err } defer rows.Close() var wranglers []domain2.User for rows.Next() { var w domain2.User if err := rows.Scan(&w.ID, &w.Email, &w.FullName, &w.GlobalRole, &w.IsActive, &w.CreatedAt); err != nil { return nil, err } wranglers = append(wranglers, w) } return wranglers, nil }