* @brief Restore a previously taken snapshot into ProjectModel and persist it to disk; the * pre-restore snapshot keeps the action reversible. */
| 901 | * pre-restore snapshot keeps the action reversible. |
| 902 | */ |
| 903 | API::CommandResponse API::Handlers::AssistantHandler::restore(const QString& id, |
| 904 | const QJsonObject& params) |
| 905 | { |
| 906 | const auto path = resolveCheckpoint(params); |
| 907 | if (path.isEmpty()) |
| 908 | return CommandResponse::makeError( |
| 909 | id, |
| 910 | ErrorCode::MissingParam, |
| 911 | QStringLiteral("Provide one of: path, timestamp, or label. Use " |
| 912 | "assistant.listCheckpoints to discover available references.")); |
| 913 | |
| 914 | const auto reverse = Misc::BackupManager::instance().snapshot(QStringLiteral("pre-restore")); |
| 915 | |
| 916 | if (!Misc::BackupManager::instance().restore(path)) |
| 917 | return CommandResponse::makeError( |
| 918 | id, |
| 919 | ErrorCode::ExecutionError, |
| 920 | QStringLiteral("Failed to restore checkpoint at %1 (file missing, unreadable, or " |
| 921 | "contained invalid project JSON).") |
| 922 | .arg(path)); |
| 923 | |
| 924 | auto& pm = DataModel::ProjectModel::instance(); |
| 925 | const auto projectPath = pm.jsonFilePath(); |
| 926 | const bool persisted = !projectPath.isEmpty() && pm.apiSaveJsonFile(projectPath); |
| 927 | if (!projectPath.isEmpty() && !persisted) |
| 928 | return CommandResponse::makeError( |
| 929 | id, |
| 930 | ErrorCode::ExecutionError, |
| 931 | QStringLiteral("Restored checkpoint %1 into memory but failed to write it to %2. The " |
| 932 | "project is loaded and modified; revert via %3 or save manually.") |
| 933 | .arg(path, |
| 934 | projectPath, |
| 935 | reverse.isEmpty() ? QStringLiteral("the pre-restore snapshot") : reverse)); |
| 936 | |
| 937 | QJsonObject result; |
| 938 | result[QStringLiteral("restored")] = true; |
| 939 | result[QStringLiteral("path")] = path; |
| 940 | result[QStringLiteral("persisted")] = persisted; |
| 941 | if (!persisted) |
| 942 | result[QStringLiteral("modified")] = true; |
| 943 | |
| 944 | if (!projectPath.isEmpty()) |
| 945 | result[QStringLiteral("projectPath")] = projectPath; |
| 946 | |
| 947 | if (!reverse.isEmpty()) |
| 948 | result[QStringLiteral("reverseSnapshotPath")] = reverse; |
| 949 | |
| 950 | return CommandResponse::makeSuccess(id, result); |
| 951 | } |
| 952 | |
| 953 | /** |
| 954 | * @brief Return the most recent N checkpoints for the current project. |
nothing calls this directly
no test coverage detected