diff --git a/crates/flowscope-cli/src/server/api.rs b/crates/flowscope-cli/src/server/api.rs index 2e937f42..568d6fab 100644 --- a/crates/flowscope-cli/src/server/api.rs +++ b/crates/flowscope-cli/src/server/api.rs @@ -48,6 +48,8 @@ struct AnalyzeRequest { #[serde(default)] enable_column_lineage: Option, #[serde(default)] + enable_linting: Option, + #[serde(default)] template_mode: Option, } @@ -134,10 +136,19 @@ async fn analyze( let schema = state.schema.read().await.clone(); // Build analysis options from request - let options = if payload.hide_ctes.is_some() || payload.enable_column_lineage.is_some() { + let options = if payload.hide_ctes.is_some() + || payload.enable_column_lineage.is_some() + || payload.enable_linting.is_some() + { Some(flowscope_core::AnalysisOptions { hide_ctes: payload.hide_ctes, enable_column_lineage: payload.enable_column_lineage, + lint: payload + .enable_linting + .map(|enabled| flowscope_core::LintConfig { + enabled, + ..Default::default() + }), ..Default::default() }) } else { diff --git a/crates/flowscope-cli/tests/serve_api.rs b/crates/flowscope-cli/tests/serve_api.rs index 9374114e..c3195217 100644 --- a/crates/flowscope-cli/tests/serve_api.rs +++ b/crates/flowscope-cli/tests/serve_api.rs @@ -157,6 +157,82 @@ async fn analyze_with_join() { assert!(!json["statements"].as_array().unwrap().is_empty()); } +#[tokio::test] +async fn analyze_enables_linting_for_file_payload_when_requested() { + let state = test_state(default_config(), vec![]); + let app = build_router(state, 3000); + + let (status, json) = post_json( + &app, + "/api/analyze", + json!({ + "sql": "", + "files": [{ + "name": "query.sql", + "content": "SELECT 1 UNION SELECT 2" + }], + "enable_linting": true + }), + ) + .await; + + assert_eq!(status, StatusCode::OK); + assert!(json["issues"] + .as_array() + .unwrap() + .iter() + .any(|issue| issue["code"] == "LINT_AM_002")); +} + +#[tokio::test] +async fn analyze_keeps_linting_disabled_when_requested() { + let state = test_state(default_config(), vec![]); + let app = build_router(state, 3000); + + let (status, json) = post_json( + &app, + "/api/analyze", + json!({ + "sql": "SELECT 1 UNION SELECT 2", + "enable_linting": false + }), + ) + .await; + + assert_eq!(status, StatusCode::OK); + assert!(!json["issues"] + .as_array() + .unwrap() + .iter() + .any(|issue| issue["code"] + .as_str() + .is_some_and(|code| code.starts_with("LINT_")))); +} + +#[tokio::test] +async fn analyze_does_not_enable_linting_when_omitted() { + let state = test_state(default_config(), vec![]); + let app = build_router(state, 3000); + + let (status, json) = post_json( + &app, + "/api/analyze", + json!({ + "sql": "SELECT 1 UNION SELECT 2" + }), + ) + .await; + + assert_eq!(status, StatusCode::OK); + assert!(!json["issues"] + .as_array() + .unwrap() + .iter() + .any(|issue| issue["code"] + .as_str() + .is_some_and(|code| code.starts_with("LINT_")))); +} + // === Completion endpoint tests === #[tokio::test]