summaryrefslogtreecommitdiff
path: root/server/src/config.rs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-17 14:32:37 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-17 14:32:37 +0800
commit5c0ba37eda80d39e6ceca59bb1d5f4942f858995 (patch)
tree948723f9cedf7ccb0707fa6ee516bd30fe20fd10 /server/src/config.rs
downloadstrategy-lab-5c0ba37eda80d39e6ceca59bb1d5f4942f858995.tar.gz
chore: establish Strategy Lab source baseline (development, not release)
Diffstat (limited to 'server/src/config.rs')
-rw-r--r--server/src/config.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/server/src/config.rs b/server/src/config.rs
new file mode 100644
index 0000000..410cb09
--- /dev/null
+++ b/server/src/config.rs
@@ -0,0 +1,65 @@
+use std::env;
+
+#[derive(Clone, Debug)]
+pub struct Config {
+ pub bind_addr: String,
+ pub canonical_origin: String,
+ pub secure_cookies: bool,
+ pub db_path: String,
+ pub data_dir: String,
+ pub frontend_dir: String,
+ pub worker_image: String,
+ pub fetch_timeout_secs: u64,
+ pub backtest_timeout_secs: u64,
+ pub run_concurrency: usize,
+ pub fetch_concurrency: usize,
+ pub session_hours: i64,
+ pub bootstrap_admin_email: Option<String>,
+ pub bootstrap_admin_password: Option<String>,
+ pub ai_base_url: String,
+ pub ai_model: String,
+ pub ai_daily_request_cap: i64,
+ pub ai_input_token_cap: i64,
+ pub ai_output_token_cap: i64,
+ pub ai_enabled_poc: bool,
+ pub default_run_limit_per_day: i64,
+ pub version: String,
+}
+
+fn envs(k: &str, d: &str) -> String {
+ env::var(k).ok().filter(|v| !v.is_empty()).unwrap_or_else(|| d.to_string())
+}
+
+impl Config {
+ pub fn from_env() -> Self {
+ let canonical_origin = envs("ORIGIN", "");
+ Config {
+ bind_addr: envs("BIND", "127.0.0.1:8787"),
+ canonical_origin: canonical_origin.clone(),
+ secure_cookies: canonical_origin.starts_with("https://"),
+ db_path: envs("DB_PATH", "server-data/strategy-lab.sqlite3"),
+ data_dir: envs("DATA_DIR", "server-data/data"),
+ frontend_dir: envs("FRONTEND_DIR", "frontend/dist"),
+ worker_image: envs("WORKER_IMAGE", "strategy-lab-worker:local"),
+ fetch_timeout_secs: envs("FETCH_TIMEOUT_SECS", "1800").parse().unwrap_or(1800),
+ backtest_timeout_secs: envs("BACKTEST_TIMEOUT_SECS", "1800").parse().unwrap_or(1800),
+ run_concurrency: envs("RUN_CONCURRENCY", "1").parse().unwrap_or(1),
+ fetch_concurrency: envs("FETCH_CONCURRENCY", "2").parse().unwrap_or(2),
+ session_hours: envs("SESSION_HOURS", "336").parse().unwrap_or(336),
+ bootstrap_admin_email: env::var("BOOTSTRAP_ADMIN_EMAIL").ok(),
+ bootstrap_admin_password: env::var("BOOTSTRAP_ADMIN_PASSWORD").ok(),
+ ai_base_url: envs("AI_BASE_URL", "https://opencode.ai/zen/go/v1"),
+ ai_model: envs("AI_MODEL", "glm-5.3-flash"),
+ ai_daily_request_cap: envs("AI_DAILY_REQUEST_CAP", "20").parse().unwrap_or(20),
+ ai_input_token_cap: envs("AI_INPUT_TOKEN_CAP", "8000").parse().unwrap_or(8000),
+ ai_output_token_cap: envs("AI_OUTPUT_TOKEN_CAP", "6000").parse().unwrap_or(6000),
+ ai_enabled_poc: envs("AI_ENABLED_POC", "true") == "true",
+ default_run_limit_per_day: envs("DEFAULT_RUN_LIMIT_PER_DAY", "10").parse().unwrap_or(10),
+ version: envs("APP_VERSION", env!("CARGO_PKG_VERSION")),
+ }
+ }
+}
+
+pub const MAX_CODE_LEN: usize = 256_000;
+pub const MAX_SYMBOLS: usize = 5;
+pub const MAX_RANGE_YEARS: i64 = 15;