# Migrating app settings to another device

## Problem

This is related to simplified database migration UX in the [previous RFC](./2024-02-12-database-migration.md).

Currently, when database is imported after the onboarding is complete, users can configure the app prior to the import.

Some of the settings are particularly important for privacy and security:
- SOCKS proxy settings
- Automatic image etc. downloads
- Link previews

With the new UX, the chat will start automatically, without giving users a chance to configure the app. That means that we have to migrate settings to a new device as well, as part of the archive.

## Solution

There are several possible approaches:
- put settings to the database via the API
- save settings as some file with cross-platform format (e.g. JSON or YAML or properties used on desktop).

The second approach seems much simpler than maintaining the settings in the database.

If we save a file, then there are two options:
- native apps maintain cross-platform schemas for this file, support any JSON and parse it in a safe way (so that even invalid or incorrect JSON - e.g., array instead of object - or invalid types in some properties do not cause the failure of properties that are correct).
- this schema and type will be maintained in the core library, that will be responsible for storing and reading the settings and passing to native UI as correct record of a given type.

The downside of the second approach is that addition of any property that needs to be migrated will have to be done on any change in either of the platforms. The downside of the first approach is that neither app platform will be self-sufficient any more, and not only iOS/Android would have to take into account code, but also each other code.

If we go with the second approach, there will be these types:

```haskell
data AppSettings = AppSettings
  { networkConfig :: NetworkConfig, -- existing type in Haskell and all UIs
    privacyConfig :: PrivacyConfig -- new type, etc.
    -- ... additional properties after the initial release should be added as Maybe, as all extensions
  }

data ArchiveConfig = ArchiveConfig
  { -- existing properties
    archivePath :: FilePath,
    disableCompression :: Maybe Bool,
    parentTempDirectory :: Maybe FilePath,
    -- new property
    appSettings :: AppSettings
    -- for export, these settings will contain the settings passed from the UI and will be saved to JSON file as simplex_v1_settings.json in the archive
    -- for import, these settings will contain the defaults that will be used if some property or subproperty is missing in JSON
  }

-- importArchive :: ChatMonad m => ArchiveConfig -> m [ArchiveError] -- current type
importArchive :: ChatMonad m => ArchiveConfig -> m ArchiveImportResult -- new type

-- | CRArchiveImported {archiveErrors :: [ArchiveError]} -- current type
  | CRArchiveImported {importResult :: ArchiveImportResult} -- new type

data ArchiveImportResult = ArchiveImportResult
  { archiveErrors :: [ArchiveError],
    appSettings :: Maybe AppSettings
  }
```