use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use chrono::{DateTime, Utc};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiResponse<T> {
pub data: Option<T>,
pub success: bool,
pub timestamp: DateTime<Utc>,
pub metadata: Option<ResponseMetadata>,
}
impl<T> ApiResponse<T> {
pub fn success(data: T) -> Self {
Self {
data: Some(data),
success: true,
timestamp: Utc::now(),
metadata: None,
}
}
pub fn success_with_metadata(data: T, metadata: ResponseMetadata) -> Self {
Self {
data: Some(data),
success: true,
timestamp: Utc::now(),
metadata: Some(metadata),
}
}
pub fn empty() -> Self {
Self {
data: None,
success: true,
timestamp: Utc::now(),
metadata: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResponseMetadata {
pub total_count: Option<u64>,
pub page: Option<PageInfo>,
pub rate_limit: Option<RateLimitInfo>,
pub request_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PageInfo {
pub page: u32,
pub page_size: u32,
pub total_pages: u32,
pub has_next: bool,
pub has_previous: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RateLimitInfo {
pub remaining: u32,
pub limit: u32,
pub reset_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StoreRequest {
pub data: serde_json::Value,
pub metadata: Option<HashMap<String, serde_json::Value>>,
pub algorithm: Option<String>,
pub key_id: Option<String>,
pub tenant_id: Option<String>,
pub field_encryption: Option<FieldEncryptionConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldEncryptionConfig {
pub fields: HashMap<String, FieldConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldConfig {
pub algorithm: String,
pub key_id: Option<String>,
pub sensitivity: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StoreResponse {
pub id: String,
pub key_id: String,
pub stored_at: DateTime<Utc>,
pub size_bytes: u64,
pub algorithm: String,
pub field_metadata: Option<HashMap<String, FieldEncryptionMetadata>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldEncryptionMetadata {
pub config_id: String,
pub field: String,
pub algorithm: String,
pub key_id: String,
pub key_version: u32,
pub encrypted_at: DateTime<Utc>,
pub nonce: Option<Vec<u8>>,
pub tag: Option<Vec<u8>>,
pub metadata: HashMap<String, String>,
}
pub use fortress_core::field_encryption::FieldEncryptionMetadata as CoreFieldEncryptionMetadata;
impl From<CoreFieldEncryptionMetadata> for FieldEncryptionMetadata {
fn from(core: CoreFieldEncryptionMetadata) -> Self {
Self {
config_id: core.config_id.to_string(),
field: match core.field {
fortress_core::field_encryption::FieldIdentifier::Name(name) => name,
fortress_core::field_encryption::FieldIdentifier::Path(path) => path.join("."),
fortress_core::field_encryption::FieldIdentifier::Indexed { index, .. } => format!("[{}]", index),
},
algorithm: core.algorithm,
key_id: core.key_id.to_string(),
key_version: core.key_version,
encrypted_at: core.encrypted_at,
nonce: core.nonce,
tag: core.tag,
metadata: core.metadata,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RetrieveRequest {
pub id: String,
pub key_id: Option<String>,
pub tenant_id: Option<String>,
pub include_encrypted: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RetrieveResponse {
pub data: serde_json::Value,
pub metadata: Option<HashMap<String, serde_json::Value>>,
pub retrieved_at: DateTime<Utc>,
pub stored_at: DateTime<Utc>,
pub algorithm: String,
pub key_id: String,
pub encrypted_data: Option<String>,
pub field_metadata: Option<HashMap<String, FieldEncryptionMetadata>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeleteRequest {
pub id: String,
pub tenant_id: Option<String>,
pub soft_delete: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeleteResponse {
pub id: String,
pub deleted_at: DateTime<Utc>,
pub soft_delete: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListRequest {
pub tenant_id: Option<String>,
pub pagination: Option<PaginationParams>,
pub filter: Option<FilterParams>,
pub sort: Option<SortParams>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginationParams {
pub page: Option<u32>,
pub page_size: Option<u32>,
pub limit: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FilterParams {
pub metadata: Option<HashMap<String, serde_json::Value>>,
pub algorithm: Option<String>,
pub date_range: Option<DateRange>,
pub key_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DateRange {
pub start: Option<DateTime<Utc>>,
pub end: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SortParams {
pub field: String,
pub direction: SortDirection,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum SortDirection {
Asc,
Desc,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListResponse {
pub items: Vec<DataItem>,
pub total_count: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataItem {
pub id: String,
pub key_id: String,
pub stored_at: DateTime<Utc>,
pub size_bytes: u64,
pub algorithm: String,
pub metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyRequest {
pub algorithm: String,
pub key_size: Option<u32>,
pub metadata: Option<HashMap<String, serde_json::Value>>,
pub tenant_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyResponse {
pub id: String,
pub algorithm: String,
pub key_size: u32,
pub created_at: DateTime<Utc>,
pub metadata: HashMap<String, serde_json::Value>,
pub fingerprint: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthResponse {
pub status: HealthStatus,
pub version: String,
pub uptime: u64,
pub components: HashMap<String, ComponentHealth>,
pub timestamp: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum HealthStatus {
Healthy,
Degraded,
Unhealthy,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComponentHealth {
pub status: HealthStatus,
pub message: Option<String>,
pub response_time_ms: Option<u64>,
pub last_check: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetricsResponse {
pub metrics: HashMap<String, serde_json::Value>,
pub timestamp: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthRequest {
pub username: String,
pub password: String,
pub tenant_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthResponse {
pub access_token: String,
pub token_type: String,
pub expires_in: u64,
pub refresh_token: Option<String>,
pub user: UserInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserInfo {
pub id: String,
pub username: String,
pub email: Option<String>,
pub roles: Vec<String>,
pub tenant_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefreshTokenRequest {
pub refresh_token: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefreshTokenResponse {
pub access_token: String,
pub token_type: String,
pub expires_in: u64,
pub refresh_token: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateDatabaseRequest {
pub name: String,
pub algorithm: String,
pub key_rotation_interval: String,
pub storage_path: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseResponse {
pub name: String,
pub created_at: DateTime<Utc>,
pub algorithm: String,
pub key_rotation_interval: String,
pub tables_count: u32,
pub size_bytes: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListDatabasesResponse {
pub databases: Vec<DatabaseInfo>,
pub total_count: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseInfo {
pub name: String,
pub created_at: DateTime<Utc>,
pub tables_count: u32,
pub size_bytes: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OperationDeleteResponse {
pub deleted: bool,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateTableRequest {
pub name: String,
pub columns: Vec<ColumnDefinition>,
pub encryption: Option<String>,
pub column_encryption: Option<HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ColumnDefinition {
pub name: String,
#[serde(rename = "type")]
pub column_type: String,
pub primary_key: Option<bool>,
pub nullable: Option<bool>,
pub encryption: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TableResponse {
pub name: String,
pub columns: u32,
pub rows: u64,
pub encryption: String,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListTablesResponse {
pub tables: Vec<TableInfo>,
pub total_count: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TableInfo {
pub name: String,
pub columns: u32,
pub rows: u64,
pub encryption: String,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TableSchemaResponse {
pub name: String,
pub columns: Vec<ColumnSchema>,
pub encryption: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ColumnSchema {
pub name: String,
#[serde(rename = "type")]
pub column_type: String,
pub primary_key: bool,
pub nullable: bool,
pub encrypted: bool,
pub encryption_algorithm: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InsertDataRequest {
#[serde(flatten)]
pub data: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InsertResponse {
pub id: String,
pub inserted_at: DateTime<Utc>,
pub rows_affected: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QueryResponse {
pub results: Vec<serde_json::Value>,
pub total_count: u64,
pub execution_time_ms: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BulkInsertRequest {
pub data: Vec<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BulkInsertResponse {
pub inserted_count: u64,
pub inserted_at: DateTime<Utc>,
pub execution_time_ms: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateDataRequest {
#[serde(flatten)]
pub data: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateResponse {
pub id: String,
pub updated_at: DateTime<Utc>,
pub rows_affected: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecuteQueryRequest {
pub sql: String,
pub parameters: Option<Vec<serde_json::Value>>,
pub options: Option<HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RotateKeysResponse {
pub rotation_id: String,
pub status: String,
pub started_at: DateTime<Utc>,
pub completed_at: DateTime<Utc>,
pub rows_rotated: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RotationStatusResponse {
pub rotation_status: String,
pub current_version: u32,
pub previous_version: u32,
pub transition_status: String,
pub started_at: DateTime<Utc>,
pub estimated_completion: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EncryptionMetadataResponse {
pub table_encryption: String,
pub column_encryption: HashMap<String, String>,
pub key_rotation_schedule: HashMap<String, String>,
pub last_rotation: DateTime<Utc>,
pub next_rotation: DateTime<Utc>,
pub zero_downtime_enabled: bool,
pub dual_key_validation: bool,
}
impl Default for PaginationParams {
fn default() -> Self {
Self {
page: Some(1),
page_size: Some(50),
limit: None,
}
}
}
impl Default for SortParams {
fn default() -> Self {
Self {
field: "stored_at".to_string(),
direction: SortDirection::Desc,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StoreDataResponse {
pub id: String,
pub key_id: String,
pub stored_at: DateTime<Utc>,
pub size_bytes: u64,
pub algorithm: String,
pub field_metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RetrieveDataResponse {
pub id: String,
pub data: serde_json::Value,
pub metadata: Option<HashMap<String, serde_json::Value>>,
pub created_at: DateTime<Utc>,
pub last_accessed: Option<DateTime<Utc>>,
pub algorithm: String,
pub key_id: String,
pub field_metadata: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListDataResponse {
pub records: Vec<serde_json::Value>,
pub total_count: u64,
pub page: u32,
pub page_size: u32,
pub total_pages: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComponentStatus {
pub status: String,
pub response_time_ms: u64,
pub error: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorResponse {
pub code: String,
pub message: String,
pub details: Option<HashMap<String, serde_json::Value>>,
pub timestamp: DateTime<Utc>,
pub request_id: String,
}