use clap::Parser;
use std::path::PathBuf;
pub const DEFAULT_METADATA_REDACT_KEYS: &str = "maintainer_email,author_email,contact_*";
#[derive(Parser, Debug)]
#[command(name = "ceres-server")]
#[command(author, version, about = "REST API server for Ceres semantic search")]
pub struct ServerConfig {
#[arg(long, env = "DATABASE_URL")]
pub database_url: String,
#[arg(long, env = "EMBEDDING_PROVIDER", default_value = "gemini")]
pub embedding_provider: String,
#[arg(long, env = "GEMINI_API_KEY")]
pub gemini_api_key: Option<String>,
#[arg(long, env = "OPENAI_API_KEY")]
pub openai_api_key: Option<String>,
#[arg(long, env = "EMBEDDING_MODEL")]
pub embedding_model: Option<String>,
#[arg(long, env = "OLLAMA_ENDPOINT")]
pub ollama_endpoint: Option<String>,
#[arg(short, long, env = "PORT", default_value = "3000")]
pub port: u16,
#[arg(long, env = "HOST", default_value = "0.0.0.0")]
pub host: String,
#[arg(long, env = "PORTALS_CONFIG")]
pub portals_config: Option<PathBuf>,
#[arg(long, env = "CORS_ALLOWED_ORIGINS", default_value = "*")]
pub cors_origins: String,
#[arg(long, env = "RATE_LIMIT_RPS", default_value = "10")]
pub rate_limit_rps: u32,
#[arg(long, env = "RATE_LIMIT_BURST", default_value = "30")]
pub rate_limit_burst: u32,
#[arg(long, env = "DB_MAX_CONNECTIONS", default_value = "10")]
pub max_connections: u32,
#[arg(long, env = "CERES_ADMIN_TOKEN")]
pub admin_token: Option<String>,
#[arg(
long,
env = "CERES_METADATA_REDACT_KEYS",
default_value = DEFAULT_METADATA_REDACT_KEYS
)]
pub metadata_redact_keys: String,
}
#[cfg(test)]
mod tests {
use clap::Parser;
use super::ServerConfig;
#[test]
fn metadata_redact_keys_can_be_overridden_from_cli() {
let config = ServerConfig::try_parse_from([
"ceres-server",
"--database-url",
"postgresql://localhost/ceres",
"--metadata-redact-keys",
"secret,private_*",
])
.expect("parse server configuration");
assert_eq!(config.metadata_redact_keys, "secret,private_*");
}
}