mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-30 20:39:39 +02:00
Python fp and docs updtes (#58)
* refactor: Update comments for clarity and add expectations.json files for performance metrics * feat: Implement FP guard for JS/TS local-collection receivers to suppress missing ownership checks * feat: Enhance Rust parameter handling to classify local collections and prevent false ownership checks * refactor: Simplify code formatting for better readability in multiple files * refactor: Improve UTF-8 sequence length handling and enhance clarity in loop iteration * feat: Update Java and Python patterns to include new security rules * refactor: Improve comment clarity and consistency across multiple Rust files * refactor: Simplify code formatting for improved readability in integration tests and module files * refactor: Improve comment formatting and enhance clarity in assertions across multiple files
This commit is contained in:
parent
4db0805de6
commit
a438886217
291 changed files with 9485 additions and 3851 deletions
|
|
@ -282,7 +282,7 @@ async fn remove_terminator(
|
|||
// ── Sources / Sinks / Sanitizers (by kind) ───────────────────────────────────
|
||||
|
||||
fn list_by_kind(state: &AppState, target_kind: &str) -> Vec<LabelEntryView> {
|
||||
// Built-in rules live on /api/rules — keep this endpoint focused on the
|
||||
// Built-in rules live on /api/rules, keep this endpoint focused on the
|
||||
// user's own additions in nyx.local.
|
||||
let target_rule_kind = match target_kind {
|
||||
"source" => RuleKind::Source,
|
||||
|
|
|
|||
|
|
@ -306,8 +306,8 @@ async fn get_type_facts(
|
|||
}
|
||||
|
||||
/// GET /api/debug/auth?file=<path>
|
||||
/// Return the file-scoped authorization model — routes, units,
|
||||
/// sensitive operations, and auth checks — for the debug UI.
|
||||
/// Return the file-scoped authorization model, routes, units,
|
||||
/// sensitive operations, and auth checks, for the debug UI.
|
||||
async fn get_auth(
|
||||
State(state): State<AppState>,
|
||||
Query(q): Query<FileQuery>,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ struct TreeEntry {
|
|||
struct SymbolEntry {
|
||||
name: String,
|
||||
/// Legacy display kind (`"function"` / `"method"`) used by existing CSS
|
||||
/// classes in the frontend. Kept for backward-compat — new consumers
|
||||
/// classes in the frontend. Kept for backward-compat, new consumers
|
||||
/// should prefer `func_kind`.
|
||||
kind: String,
|
||||
/// Structural [`crate::symbol::FuncKind`] slug (`"fn"`, `"method"`,
|
||||
|
|
@ -291,7 +291,7 @@ async fn get_symbols(
|
|||
let entries: Vec<SymbolEntry> = symbols
|
||||
.into_iter()
|
||||
.map(|(name, arity, _lang, namespace, container, func_kind)| {
|
||||
// Legacy `kind` field — still used by existing CSS classes
|
||||
// Legacy `kind` field, still used by existing CSS classes
|
||||
// (`symbol-kind-method`, `symbol-kind-function`). Map any
|
||||
// method-like FuncKind onto `"method"` and everything else
|
||||
// onto `"function"` so the rendered icon stays sensible.
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ fn load_latest_findings_internal(state: &AppState) -> LoadedFindings {
|
|||
/// Build (or fetch from cache) the per-scan derived views.
|
||||
///
|
||||
/// Returns clones of `Arc`s so callers can drop the lock immediately and work
|
||||
/// without contention. Triage state is *not* baked into the cached views — it
|
||||
/// without contention. Triage state is *not* baked into the cached views, it
|
||||
/// changes on a different cadence and is overlaid per request.
|
||||
fn cached_for_latest(state: &AppState) -> CachedFindings {
|
||||
let loaded = load_latest_findings_internal(state);
|
||||
|
|
@ -85,7 +85,7 @@ fn cached_for_latest(state: &AppState) -> CachedFindings {
|
|||
}
|
||||
}
|
||||
|
||||
// Slow path: rebuild. Guard against concurrent rebuilds of the same key —
|
||||
// Slow path: rebuild. Guard against concurrent rebuilds of the same key ,
|
||||
// a second writer that finds the cache already populated for our key
|
||||
// simply returns it.
|
||||
let mut guard = state.findings_cache.write();
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ pub fn routes() -> Router<AppState> {
|
|||
.route("/overview/baseline/{scan_id}", post(set_baseline_path))
|
||||
}
|
||||
|
||||
/// GET /api/overview — aggregated dashboard data.
|
||||
/// GET /api/overview, aggregated dashboard data.
|
||||
async fn overview(State(state): State<AppState>) -> Json<OverviewResponse> {
|
||||
// 1. Load latest findings (in-memory → DB fallback)
|
||||
let findings = crate::server::routes::findings::load_latest_findings(&state);
|
||||
|
|
@ -121,7 +121,7 @@ async fn overview(State(state): State<AppState>) -> Json<OverviewResponse> {
|
|||
new_since_last,
|
||||
fixed_since_last,
|
||||
reintroduced: reintroduced_count,
|
||||
// Files-scanned proxy for repo size — used for size-aware
|
||||
// Files-scanned proxy for repo size, used for size-aware
|
||||
// severity dampening in `health::compute`. See
|
||||
// `docs/health-score-audit.md` for calibration data.
|
||||
repo_files: scanner_quality
|
||||
|
|
@ -129,10 +129,10 @@ async fn overview(State(state): State<AppState>) -> Json<OverviewResponse> {
|
|||
.map(|q| q.files_scanned)
|
||||
.filter(|&f| f > 0),
|
||||
backlog: backlog.as_ref(),
|
||||
// Trend is meaningless without ≥2 completed scans —
|
||||
// Trend is meaningless without ≥2 completed scans ,
|
||||
// matches the first-scan check `compare_to_current` uses.
|
||||
has_history: history.scans.len() >= 2,
|
||||
// Suppression-hygiene modifier — populated when the
|
||||
// Suppression-hygiene modifier, populated when the
|
||||
// suppression panel was computable for this scan.
|
||||
blanket_suppression_rate: suppression_hygiene.as_ref().map(|s| s.blanket_rate),
|
||||
},
|
||||
|
|
@ -173,7 +173,7 @@ async fn overview(State(state): State<AppState>) -> Json<OverviewResponse> {
|
|||
})
|
||||
}
|
||||
|
||||
/// GET /api/overview/trends — scan-over-scan finding counts.
|
||||
/// GET /api/overview/trends, scan-over-scan finding counts.
|
||||
async fn overview_trends(State(state): State<AppState>) -> Json<Vec<TrendPoint>> {
|
||||
let mut points = Vec::new();
|
||||
|
||||
|
|
@ -218,7 +218,7 @@ struct BaselineBody {
|
|||
scan_id: String,
|
||||
}
|
||||
|
||||
/// POST /api/overview/baseline { scan_id } — pin a scan as the baseline for drift comparison.
|
||||
/// POST /api/overview/baseline { scan_id }, pin a scan as the baseline for drift comparison.
|
||||
async fn set_baseline(
|
||||
State(state): State<AppState>,
|
||||
Json(body): Json<BaselineBody>,
|
||||
|
|
@ -226,7 +226,7 @@ async fn set_baseline(
|
|||
set_baseline_inner(&state, &body.scan_id)
|
||||
}
|
||||
|
||||
/// POST /api/overview/baseline/:scan_id — convenience path-form for clients without a JSON body.
|
||||
/// POST /api/overview/baseline/:scan_id, convenience path-form for clients without a JSON body.
|
||||
async fn set_baseline_path(
|
||||
State(state): State<AppState>,
|
||||
AxPath(scan_id): AxPath<String>,
|
||||
|
|
@ -248,7 +248,7 @@ fn set_baseline_inner(state: &AppState, scan_id: &str) -> Result<StatusCode, Sta
|
|||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
/// DELETE /api/overview/baseline — clear the pinned baseline.
|
||||
/// DELETE /api/overview/baseline, clear the pinned baseline.
|
||||
async fn clear_baseline(State(state): State<AppState>) -> Result<StatusCode, StatusCode> {
|
||||
let pool = state
|
||||
.db_pool
|
||||
|
|
@ -381,7 +381,7 @@ impl ScanHistory {
|
|||
(new_count, fixed_count, reintroduced)
|
||||
}
|
||||
|
||||
/// Trend slope across the last N totals — 1.0 means strictly improving,
|
||||
/// Trend slope across the last N totals, 1.0 means strictly improving,
|
||||
/// -1.0 strictly regressing, 0.0 unchanged. Returns None with <3 points.
|
||||
fn trend_slope(&self) -> Option<f64> {
|
||||
if self.scans.len() < 3 {
|
||||
|
|
@ -712,7 +712,7 @@ fn compute_cross_file_ratio(findings: &[Diag]) -> f64 {
|
|||
cross as f64 / findings.len() as f64
|
||||
}
|
||||
|
||||
/// Hot sinks are *only* meaningful for taint findings — counting AST rule IDs
|
||||
/// Hot sinks are *only* meaningful for taint findings, counting AST rule IDs
|
||||
/// (e.g. `rs.quality.unwrap`) here just duplicates the Top Rules table. So we
|
||||
/// deliberately require a real Sink-step callee (or a parsable sink snippet)
|
||||
/// and skip everything else. Empty result → frontend hides the card.
|
||||
|
|
@ -751,7 +751,7 @@ fn compute_hot_sinks(findings: &[Diag], limit: usize) -> Vec<HotSink> {
|
|||
rows
|
||||
}
|
||||
|
||||
/// Pull the leading identifier from a sink snippet — a best-effort heuristic
|
||||
/// Pull the leading identifier from a sink snippet, a best-effort heuristic
|
||||
/// for the dashboard's "hot sinks" list.
|
||||
fn extract_callee_from_snippet(s: &str) -> String {
|
||||
let trimmed = s.trim();
|
||||
|
|
@ -932,7 +932,7 @@ fn compute_suppression_hygiene(state: &AppState, findings: &[Diag]) -> Suppressi
|
|||
}
|
||||
|
||||
fn compute_backlog(state: &AppState, findings: &[Diag], history: &ScanHistory) -> BacklogStats {
|
||||
// No useful aging data on the first scan — every fingerprint was first-seen
|
||||
// No useful aging data on the first scan, every fingerprint was first-seen
|
||||
// today by definition. Avoid the misleading "0d / 0d / 0" display.
|
||||
if history.scans.len() <= 1 {
|
||||
return BacklogStats {
|
||||
|
|
@ -1046,7 +1046,7 @@ fn build_posture(
|
|||
current_total: usize,
|
||||
) -> PostureSummary {
|
||||
// First-scan case: no prior data to diff against. Saying "stable / no change"
|
||||
// is misleading — we genuinely don't know yet.
|
||||
// is misleading, we genuinely don't know yet.
|
||||
if history.scans.len() <= 1 {
|
||||
return PostureSummary {
|
||||
trend: "unknown".into(),
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ fn build_rule_list(state: &AppState) -> Vec<RuleInfo> {
|
|||
rules
|
||||
}
|
||||
|
||||
/// GET /api/rules — list all rules with finding counts.
|
||||
/// GET /api/rules, list all rules with finding counts.
|
||||
async fn list_rules(State(state): State<AppState>) -> Json<Vec<RuleListItem>> {
|
||||
let rules = build_rule_list(&state);
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ async fn list_rules(State(state): State<AppState>) -> Json<Vec<RuleListItem>> {
|
|||
Json(items)
|
||||
}
|
||||
|
||||
/// GET /api/rules/:id — full detail for one rule.
|
||||
/// GET /api/rules/:id, full detail for one rule.
|
||||
async fn get_rule(
|
||||
State(state): State<AppState>,
|
||||
Path(id): Path<String>,
|
||||
|
|
@ -140,7 +140,7 @@ async fn get_rule(
|
|||
}))
|
||||
}
|
||||
|
||||
/// POST /api/rules/:id/toggle — enable/disable a rule.
|
||||
/// POST /api/rules/:id/toggle, enable/disable a rule.
|
||||
async fn toggle_rule(
|
||||
State(state): State<AppState>,
|
||||
Path(id): Path<String>,
|
||||
|
|
@ -162,7 +162,7 @@ async fn toggle_rule(
|
|||
Ok(Json(serde_json::json!({ "status": "ok", "rule_id": id })))
|
||||
}
|
||||
|
||||
/// POST /api/rules/clone — clone a built-in rule to custom.
|
||||
/// POST /api/rules/clone, clone a built-in rule to custom.
|
||||
async fn clone_rule(
|
||||
State(state): State<AppState>,
|
||||
Json(body): Json<serde_json::Value>,
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ async fn delete_scan(
|
|||
Json(serde_json::json!({ "error": msg })),
|
||||
));
|
||||
}
|
||||
// "Scan not found" in memory is fine — may be DB-only
|
||||
// "Scan not found" in memory is fine, may be DB-only
|
||||
}
|
||||
|
||||
// Delete from DB (CASCADE handles metrics + logs)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue