feat(billing): implement tenant subscription entitlements system (milestones 0-6)
Some checks failed
ci / ui (push) Failing after 28s
ci / rust (push) Failing after 2m40s
images / build-and-push (push) Failing after 19s

This commit is contained in:
2026-03-30 18:41:23 +03:00
parent 5992044b7e
commit 2595e7f1c5
63 changed files with 8448 additions and 321 deletions

View File

@@ -11,7 +11,7 @@ fn repo_root() -> PathBuf {
#[test]
fn docker_compose_files_parse_and_include_required_services() {
let root = repo_root();
let compose = fs::read_to_string(root.join("observability/docker-compose.yml")).unwrap();
let compose = fs::read_to_string(root.join("docker-compose.yml")).unwrap();
let v: serde_yaml::Value = serde_yaml::from_str(&compose).unwrap();
let services = v
@@ -19,7 +19,15 @@ fn docker_compose_files_parse_and_include_required_services() {
.and_then(|x| x.as_mapping())
.expect("missing services");
for required in ["grafana", "victoria-metrics", "vmagent", "loki", "tempo"] {
// Core + optional observability services are all declared in one compose file.
for required in [
"grafana",
"victoria-metrics",
"vmagent",
"loki",
"tempo",
"mailhog",
] {
assert!(
services.contains_key(serde_yaml::Value::String(required.to_string())),
"missing service {required}"
@@ -28,17 +36,19 @@ fn docker_compose_files_parse_and_include_required_services() {
}
#[tokio::test]
#[ignore]
async fn docker_compose_config_validation_is_gated_and_fast() {
let enabled = std::env::var("CONTROL_TEST_DOCKER").ok();
assert_eq!(enabled.as_deref(), Some("1"));
if enabled.as_deref() != Some("1") {
eprintln!("skipping: set CONTROL_TEST_DOCKER=1 to enable docker compose validation");
return;
}
let root = repo_root();
let compose = root.join("observability/docker-compose.yml");
let compose = root.join("docker-compose.yml");
let cmd = tokio::process::Command::new("docker")
.args(["compose", "-f"])
.arg(compose)
.arg(&compose)
.args(["config"])
.output();
@@ -52,4 +62,22 @@ async fn docker_compose_config_validation_is_gated_and_fast() {
"docker compose config failed: {}",
String::from_utf8_lossy(&out.stderr)
);
// Validate full-stack profile wiring too.
let cmd = tokio::process::Command::new("docker")
.args(["compose", "-f"])
.arg(&compose)
.args(["--profile", "observability", "config"])
.output();
let out = tokio::time::timeout(Duration::from_secs(10), cmd)
.await
.expect("docker compose config (observability profile) timed out")
.expect("failed to run docker compose config (observability profile)");
assert!(
out.status.success(),
"docker compose config (observability profile) failed: {}",
String::from_utf8_lossy(&out.stderr)
);
}