{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://getshft.app/schemas/com.shft.config.schema.json",
  "title": "shft Configuration",
  "description": "Configuration profile for the shft Mac-to-Mac migration tool. Targets the user level. Reference: https://getshft.app/docs/configuration-profile.",
  "type": "object",
  "additionalProperties": false,
  "links": [
    {
      "rel": "Full configuration profile reference",
      "href": "https://getshft.app/docs/configuration-profile"
    },
    {
      "rel": "Managed mode (zero-touch deployment)",
      "href": "https://getshft.app/docs/managed-mode"
    },
    {
      "rel": "Logging endpoint schema",
      "href": "https://getshft.app/docs/logging"
    }
  ],
  "properties": {
    "shft.allowedDataCategories": {
      "title": "Allowed data categories",
      "description": "Which data categories users can migrate. If omitted or empty, all categories are available.",
      "property_order": 10,
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "string",
        "enum": [
          "userFiles",
          "applicationData",
          "keychain",
          "systemSettings",
          "browserData"
        ],
        "options": {
          "enum_titles": [
            "User files",
            "Application data & preferences",
            "Keychain",
            "System settings",
            "Browser data"
          ]
        }
      }
    },
    "shft.allowUserOverride": {
      "title": "Allow user override",
      "description": "Whether users can add custom folders beyond the admin-defined categories. When false, users see only the categories listed in 'Allowed data categories'.",
      "property_order": 20,
      "type": "boolean",
      "default": true
    },
    "shft.requireAdminApproval": {
      "title": "Require admin approval",
      "description": "Reserved for future use. When implemented, migrations will require admin approval before starting.",
      "property_order": 30,
      "type": "boolean",
      "default": false
    },
    "shft.maxTransferSizeMB": {
      "title": "Max transfer size (MB)",
      "description": "Maximum total transfer size in megabytes. If the user's selected data exceeds this limit, the Begin Transfer button is disabled. Set to 0 or omit for no limit.",
      "property_order": 40,
      "type": "integer",
      "minimum": 0
    },
    "shft.allowedConnectionTypes": {
      "title": "Allowed connection types",
      "description": "Which connection types are available. If omitted or empty, all types are allowed.",
      "property_order": 50,
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "string",
        "enum": ["wifi", "ethernet", "thunderbolt"],
        "options": {
          "enum_titles": ["Wi-Fi", "Ethernet", "Thunderbolt"]
        }
      }
    },
    "shft.migrationWindowStart": {
      "title": "Migration window — start (HH:mm)",
      "description": "Start time of the allowed migration window in 24-hour format. Pair with 'Migration window — end'. Windows that span midnight are supported (start 22:00, end 06:00).",
      "property_order": 60,
      "type": "string",
      "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
    },
    "shft.migrationWindowEnd": {
      "title": "Migration window — end (HH:mm)",
      "description": "End time of the allowed migration window in 24-hour format. Migrations already in progress are not interrupted when the window closes.",
      "property_order": 70,
      "type": "string",
      "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
    },
    "shft.logMigrationsToEndpoint": {
      "title": "Logging endpoint URL",
      "description": "URL where shft POSTs a JSON migration log after each transfer completes. Omit to keep logs local-only.",
      "property_order": 80,
      "type": "string",
      "format": "uri"
    },
    "shft.brandingName": {
      "title": "Organization name",
      "description": "Organization name displayed on the Welcome screen ('Managed by Acme Corp').",
      "property_order": 90,
      "type": "string"
    },
    "shft.brandingLogoURL": {
      "title": "Organization logo URL",
      "description": "URL to an organization logo image (PNG, JPEG, or SVG) shown on the Welcome screen. Recommended size: 120x80 pixels or smaller.",
      "property_order": 100,
      "type": "string",
      "format": "uri"
    },
    "shft.prefRestoreMode": {
      "title": "Preference restore mode",
      "description": "How migrated app preferences are applied on the destination. 'staged' (recommended) holds prefs in a staging directory until the matching app appears. 'manual' requires the user to apply each bundle from the UI. 'immediate' writes directly to ~/Library/... (legacy).",
      "property_order": 110,
      "type": "string",
      "enum": ["immediate", "staged", "manual"],
      "default": "staged",
      "options": {
        "enum_titles": [
          "Immediate (legacy)",
          "Staged (recommended)",
          "Manual (user applies)"
        ]
      }
    },
    "shft.prefRestoreWindowDays": {
      "title": "Preference restore window (days)",
      "description": "How many days a staged preference bundle is kept before being abandoned.",
      "property_order": 120,
      "type": "integer",
      "minimum": 1,
      "default": 7
    },
    "shft.mdmAppManifestPath": {
      "title": "MDM app manifest — file path",
      "description": "Path to a JSON file describing apps the MDM intends to install on this device. Tilde expansion is supported.",
      "property_order": 130,
      "type": "string"
    },
    "shft.mdmAppManifestJSON": {
      "title": "MDM app manifest — inline JSON",
      "description": "Inline alternative to 'MDM app manifest — file path'. The manifest as a JSON string embedded in the profile. Wins over the file path when both are set.",
      "property_order": 140,
      "type": "string"
    },
    "shft.deploymentMode": {
      "title": "Deployment mode",
      "description": "'Interactive' runs the setup wizard. 'Managed' hides the wizard and drives discovery, pairing, and migration without user interaction. Managed mode requires 'User principal' below.",
      "property_order": 150,
      "type": "string",
      "enum": ["interactive", "managed"],
      "default": "interactive",
      "options": {
        "enum_titles": ["Interactive (wizard)", "Managed (zero-touch)"]
      }
    },
    "shft.deploymentRole": {
      "title": "Deployment role",
      "description": "Which side of the migration this device runs in managed mode.",
      "property_order": 160,
      "type": "string",
      "enum": ["destination", "source"],
      "default": "destination",
      "options": {
        "enum_titles": ["Destination", "Source"]
      }
    },
    "shft.userPrincipal": {
      "title": "User principal",
      "description": "Required when 'Deployment mode' is Managed. Typically the MDM variable $EMAIL, resolved per-device. Used to derive the destination user mapping without prompting.",
      "property_order": 170,
      "type": "string"
    },
    "shft.migrationSource": {
      "title": "Migration source preference",
      "description": "Discovery preference for managed mode. 'Auto' tries Bonjour first, then Thunderbolt.",
      "property_order": 180,
      "type": "string",
      "enum": ["auto", "bonjour", "thunderbolt"],
      "default": "auto",
      "options": {
        "enum_titles": ["Auto", "Bonjour (network)", "Thunderbolt"]
      }
    },
    "shft.migrationCategories": {
      "title": "Migration categories (managed mode)",
      "description": "When set in managed mode, exactly these categories are selected (overriding the wizard's defaults).",
      "property_order": 190,
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "string",
        "enum": [
          "userFiles",
          "applicationData",
          "keychain",
          "systemSettings",
          "browserData"
        ],
        "options": {
          "enum_titles": [
            "User files",
            "Application data & preferences",
            "Keychain",
            "System settings",
            "Browser data"
          ]
        }
      }
    },
    "shft.requireManagedSource": {
      "title": "Require managed source",
      "description": "When true, the destination won't accept pairing with a source that can't prove MDM enrollment. Enforced as a self-check on the destination.",
      "property_order": 200,
      "type": "boolean",
      "default": false
    },
    "shft.telemetryEndpoint": {
      "title": "Telemetry endpoint URL",
      "description": "URL where managed-mode lifecycle events are POSTed (start, awaiting_peer, pairing_complete, complete, failed). Fire-and-forget; failures never block the migration.",
      "property_order": 210,
      "type": "string",
      "format": "uri"
    }
  }
}
