Skip to content

P1: SettingsManager manual property mapping is a bug factory and should use an immutable record #555

Description

@QQSHI13

Problem

SettingsManager is a mutable god object with ~100 public properties. Every load/save cycle requires manual mapping in three places: the property declaration, the Load() method, and ToSettingsData(). This is extremely error-prone — it is easy to add a property and forget to persist it, causing silent data loss.

Additionally, Load() parses JSON twice: once via JsonDocument for legacy credential migration, then again via SettingsData.FromJson.

Impact

  • Adding a new setting requires manual edits in 3+ locations.
  • Silent bugs where the UI shows a setting but it never round-trips to disk (or vice versa).
  • Legacy migration logic is mixed with active persistence logic.

Suggested fix

  1. Make SettingsData the single source of truth — an immutable record with init-only properties.
  2. Have SettingsManager hold a private SettingsData _data field and expose accessors that delegate to it:
    public string GatewayUrl
    {
        get => _data.GatewayUrl;
        set => _data = _data with { GatewayUrl = value };
    }
  3. Replace the giant manual Load() / ToSettingsData() copy blocks with a single JsonSerializer.Deserialize<SettingsData>(json) call, using fallback defaults (data ?? SettingsData.Default).
  4. Use a custom JsonConverter for DPAPI-protected secrets so encryption is transparent to the model.

Files

  • src/OpenClaw.Tray.WinUI/Services/SettingsManager.cs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions