Files
whetstone_DSL/editor/src/DeploymentPromotionGate.h

76 lines
2.7 KiB
C++

#pragma once
// Step 605: Deployment Promotion Gate
#include <map>
#include <string>
#include <vector>
#include "ScoreClampUtil.h"
#include "ValidationErrorUtil.h"
struct EnvironmentGateState {
std::string environmentId;
int requiredChecks = 0;
int passedChecks = 0;
int manualApprovals = 0;
int blockingIssues = 0;
};
class DeploymentPromotionGate {
public:
bool upsert(const EnvironmentGateState& state, std::string* error) {
if (!error) return false;
error->clear();
if (state.environmentId.empty()) return failWith(error, "environment_id_missing");
if (state.requiredChecks < 0) return failWith(error, "required_checks_invalid");
if (state.passedChecks < 0) return failWith(error, "passed_checks_invalid");
if (state.manualApprovals < 0) return failWith(error, "manual_approvals_invalid");
if (state.blockingIssues < 0) return failWith(error, "blocking_issues_invalid");
if (state.passedChecks > state.requiredChecks) return failWith(error, "passed_checks_exceed_required");
if (states_.count(state.environmentId) == 0) order_.push_back(state.environmentId);
states_[state.environmentId] = state;
return true;
}
bool promotable(const std::string& environmentId, std::string* error) const {
if (!error) return false;
error->clear();
auto it = states_.find(environmentId);
if (it == states_.end()) return failWith(error, "environment_missing");
const auto& state = it->second;
return state.requiredChecks > 0 &&
state.passedChecks == state.requiredChecks &&
state.manualApprovals > 0 &&
state.blockingIssues == 0;
}
int promotionScore(const std::string& environmentId, std::string* error) const {
if (!error) return 0;
error->clear();
auto it = states_.find(environmentId);
if (it == states_.end()) {
failWith(error, "environment_missing");
return 0;
}
const auto& state = it->second;
if (state.requiredChecks == 0) return 0;
int score = (state.passedChecks * 100) / state.requiredChecks;
score += state.manualApprovals * 5;
score -= state.blockingIssues * 20;
return clampToPercent(score);
}
std::vector<std::string> blockedEnvironments() const {
std::vector<std::string> blocked;
for (const auto& id : order_) {
const auto& state = states_.at(id);
if (state.blockingIssues > 0 || state.passedChecks < state.requiredChecks) blocked.push_back(id);
}
return blocked;
}
private:
std::map<std::string, EnvironmentGateState> states_;
std::vector<std::string> order_;
};