#pragma once #include #include #include namespace smartbotic::storage { // How long a workflow's data is kept: its own documents, the files it stores, // and its execution records, so a run's history and the files that history // points at go together rather than one outliving the other. // // Settings shape, on both a project and a workflow: // // "retention": { "ttlSeconds": 604800 } // // **Absent is not the same as zero.** Absent (or null) on a workflow means // inherit the project's; an explicit 0 means keep for ever, which is a choice // somebody made and must not be re-read as "unset". A plain // value("ttlSeconds", 0) collapses the two, so nothing reads it that way. inline constexpr const char* kRetentionKey = "retention"; inline constexpr const char* kTtlSecondsKey = "ttlSeconds"; inline std::optional declaredTtlSeconds(const nlohmann::json& settings) { if (!settings.is_object() || !settings.contains(kRetentionKey)) return std::nullopt; const auto& retention = settings[kRetentionKey]; if (!retention.is_object() || !retention.contains(kTtlSecondsKey)) return std::nullopt; const auto& ttl = retention[kTtlSecondsKey]; if (!ttl.is_number_integer()) return std::nullopt; // null, or a string somebody typed const auto seconds = ttl.get(); return seconds < 0 ? std::nullopt : std::optional{seconds}; } struct Retention { int64_t ttl_seconds = 0; // 0 = keep for ever bool inherited = false; // true when it came from the project [[nodiscard]] bool keepsForever() const { return ttl_seconds == 0; } [[nodiscard]] int64_t ttlMs() const { return ttl_seconds * 1000; } }; // Nothing at all is a third answer, distinct from "keep for ever": an // installation from before retention existed has made no choice, and each // caller applies its own historical default rather than having one invented // here. Executions have always aged out after a week; documents never have. // Collapsing those into a single "0" would either start deleting documents // nobody agreed to lose or stop executions ageing out at all. inline std::optional declaredRetention(const nlohmann::json& workflow_settings, const nlohmann::json& project_settings) { if (const auto own = declaredTtlSeconds(workflow_settings)) { return Retention{*own, false}; } if (const auto from_project = declaredTtlSeconds(project_settings)) { return Retention{*from_project, true}; } return std::nullopt; } } // namespace smartbotic::storage