summaryrefslogtreecommitdiff
path: root/server/src/config.rs
blob: 410cb09130e8384b7bc94809743edd7d4ad2f417 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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;