Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ testutils = ["mockall"]
[dependencies]
url = { version = "2", features = ["serde"] }
# Web framework
axum = { version = "0.7", features = ["macros"] }
axum = { version = "0.7", features = ["macros", "ws"] }
tower = { version = "0.5", features = ["full", "util"] }
tower-http = { version = "0.5", features = ["cors", "trace", "compression-gzip", "request-id"] }

Expand Down Expand Up @@ -60,7 +60,7 @@ futures-util = { version = "0.3", default-features = false, features = ["std"] }

# External Integrations
utoipa = { version = "5.0", features = ["axum_extras", "chrono", "uuid"] }
utoipa-swagger-ui = { version = "8.0", features = ["axum"] }
utoipa-swagger-ui = { version = "8.0", features = ["axum", "vendored"] }
apalis = { version = "0.6" }
apalis-redis = "0.6"
rust_decimal = { version = "1.35", features = ["serde"] }
Expand Down
84 changes: 84 additions & 0 deletions backend/migrations/20260601000000_contract_services.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
-- Backend contract service tables for storage optimization, versioning,
-- deployment automation, and test result storage.

CREATE TABLE IF NOT EXISTS contract_storage_optimizations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contract_id TEXT NOT NULL,
target_network TEXT NOT NULL,
storage_entries_estimate BIGINT NOT NULL,
estimated_rent_savings_percent DOUBLE PRECISION NOT NULL,
ttl_strategy TEXT NOT NULL,
recommendations JSONB NOT NULL DEFAULT '[]',
generated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_contract_storage_optimizations_contract_id
ON contract_storage_optimizations (contract_id);

CREATE TABLE IF NOT EXISTS contract_versions (
id TEXT PRIMARY KEY,
contract_id TEXT NOT NULL,
version TEXT NOT NULL,
source_hash TEXT NOT NULL,
wasm_hash TEXT,
changelog TEXT,
created_by TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT uq_contract_versions_contract_version UNIQUE (contract_id, version)
);

CREATE INDEX IF NOT EXISTS idx_contract_versions_contract_id
ON contract_versions (contract_id);

CREATE TABLE IF NOT EXISTS contract_deployments (
id TEXT PRIMARY KEY,
contract_id TEXT NOT NULL,
version TEXT NOT NULL,
network TEXT NOT NULL,
deployer TEXT NOT NULL,
wasm_hash TEXT NOT NULL,
status TEXT NOT NULL CHECK (status IN ('planned', 'queued', 'running', 'succeeded', 'failed')),
transaction_envelope TEXT,
steps JSONB NOT NULL DEFAULT '[]',
checks JSONB NOT NULL DEFAULT '[]',
dry_run BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_contract_deployments_contract_id
ON contract_deployments (contract_id);
CREATE INDEX IF NOT EXISTS idx_contract_deployments_network_status
ON contract_deployments (network, status);

CREATE TABLE IF NOT EXISTS contract_test_runs (
id TEXT PRIMARY KEY,
contract_id TEXT NOT NULL,
build_id TEXT,
status TEXT NOT NULL CHECK (status IN ('passed', 'failed', 'error', 'running')),
total_tests BIGINT NOT NULL,
passed_tests BIGINT NOT NULL,
failed_tests BIGINT NOT NULL,
skipped_tests BIGINT NOT NULL,
duration_ms BIGINT,
metadata JSONB NOT NULL DEFAULT '{}',
completed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_contract_test_runs_contract_id
ON contract_test_runs (contract_id);
CREATE INDEX IF NOT EXISTS idx_contract_test_runs_status
ON contract_test_runs (status);

CREATE TABLE IF NOT EXISTS contract_test_cases (
id TEXT PRIMARY KEY,
test_run_id TEXT NOT NULL REFERENCES contract_test_runs(id) ON DELETE CASCADE,
name TEXT NOT NULL,
status TEXT NOT NULL CHECK (status IN ('passed', 'failed', 'skipped', 'running')),
duration_ms BIGINT,
gas_used BIGINT,
error_message TEXT,
stack_trace TEXT
);

CREATE INDEX IF NOT EXISTS idx_contract_test_cases_run_id
ON contract_test_cases (test_run_id);
86 changes: 86 additions & 0 deletions backend/scripts/init-db.sql
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,92 @@ CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs(status);
CREATE INDEX IF NOT EXISTS idx_jobs_job_type ON jobs(job_type);
CREATE INDEX IF NOT EXISTS idx_jobs_scheduled_at ON jobs(scheduled_at);

-- Contract storage optimization reports
CREATE TABLE IF NOT EXISTS contract_storage_optimizations (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
contract_id TEXT NOT NULL,
target_network TEXT NOT NULL,
storage_entries_estimate BIGINT NOT NULL,
estimated_rent_savings_percent DOUBLE PRECISION NOT NULL,
ttl_strategy TEXT NOT NULL,
recommendations JSONB NOT NULL DEFAULT '[]',
generated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_contract_storage_optimizations_contract_id
ON contract_storage_optimizations (contract_id);

-- Contract versions and artifact hashes
CREATE TABLE IF NOT EXISTS contract_versions (
id TEXT PRIMARY KEY,
contract_id TEXT NOT NULL,
version TEXT NOT NULL,
source_hash TEXT NOT NULL,
wasm_hash TEXT,
changelog TEXT,
created_by TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT uq_contract_versions_contract_version UNIQUE (contract_id, version)
);

CREATE INDEX IF NOT EXISTS idx_contract_versions_contract_id
ON contract_versions (contract_id);

-- Deployment automation jobs
CREATE TABLE IF NOT EXISTS contract_deployments (
id TEXT PRIMARY KEY,
contract_id TEXT NOT NULL,
version TEXT NOT NULL,
network TEXT NOT NULL,
deployer TEXT NOT NULL,
wasm_hash TEXT NOT NULL,
status TEXT NOT NULL CHECK (status IN ('planned', 'queued', 'running', 'succeeded', 'failed')),
transaction_envelope TEXT,
steps JSONB NOT NULL DEFAULT '[]',
checks JSONB NOT NULL DEFAULT '[]',
dry_run BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_contract_deployments_contract_id
ON contract_deployments (contract_id);
CREATE INDEX IF NOT EXISTS idx_contract_deployments_network_status
ON contract_deployments (network, status);

-- Stored contract test results
CREATE TABLE IF NOT EXISTS contract_test_runs (
id TEXT PRIMARY KEY,
contract_id TEXT NOT NULL,
build_id TEXT,
status TEXT NOT NULL CHECK (status IN ('passed', 'failed', 'error', 'running')),
total_tests BIGINT NOT NULL,
passed_tests BIGINT NOT NULL,
failed_tests BIGINT NOT NULL,
skipped_tests BIGINT NOT NULL,
duration_ms BIGINT,
metadata JSONB NOT NULL DEFAULT '{}',
completed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_contract_test_runs_contract_id
ON contract_test_runs (contract_id);
CREATE INDEX IF NOT EXISTS idx_contract_test_runs_status
ON contract_test_runs (status);

CREATE TABLE IF NOT EXISTS contract_test_cases (
id TEXT PRIMARY KEY,
test_run_id TEXT NOT NULL REFERENCES contract_test_runs(id) ON DELETE CASCADE,
name TEXT NOT NULL,
status TEXT NOT NULL CHECK (status IN ('passed', 'failed', 'skipped', 'running')),
duration_ms BIGINT,
gas_used BIGINT,
error_message TEXT,
stack_trace TEXT
);

CREATE INDEX IF NOT EXISTS idx_contract_test_cases_run_id
ON contract_test_cases (test_run_id);

-- ---------------------------------------------------------------------------
-- Functions: Auto-update updated_at timestamp
-- ---------------------------------------------------------------------------
Expand Down
10 changes: 5 additions & 5 deletions backend/src/api/handlers/admin.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::api::contracts::ApiResponse;
use crate::api::handlers::profiling::AppState;
use crate::error::AppError;
use crate::services::contract_call_logger::{ContractCallLog, ContractCallLogger};
use axum::{extract::State, response::IntoResponse, Json};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use crate::error::AppError;
use crate::api::handlers::profiling::AppState;
use crate::api::contracts::ApiResponse;
use crate::services::contract_call_logger::{ContractCallLogger, ContractCallLog};
use std::sync::Arc;

// Global static for maintenance mode (mock implementation)
pub static MAINTENANCE_MODE: AtomicBool = AtomicBool::new(false);
Expand Down
Loading
Loading