CI / Check (pull_request) Successful in 5m29s
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
Onboarded targets are now the sole persisted entity. The legacy `TrackedRepository` model, the `repositories` collection, the `/repositories` API, the Repositories dashboard page, the one-shot migration, and the `UNIFIED_PIPELINE` transition flag are all removed. Net −1.7k LOC. Agent - New internal `pipeline::repo_view::RepoView` (non-persisted) replaces the `TrackedRepository` model; it's projected from an `OnboardedTarget` + its code artifact by `RepoView::from_target` (the old `repo_view_from_target`), so the scan/PR-review pipeline is byte-for-byte the same behaviour it already ran on the unified path — only the type's origin changed. - `run_scan` always runs the unified `run_target`; the legacy `orchestrator::run` and the `unified_pipeline` flag are gone. `run_pr_review` resolves the target from `onboarded_targets`. - Webhooks (github/gitea/gitlab), the CVE monitor, graph build, chat embeddings, health stats, and the pentest repo lookup all read `onboarded_targets`. - `delete_target` now cascades the full downstream set (findings, sbom, scans, cve, tracker issues, graph, embeddings, DAST targets + pentest sessions and their children) — matching the old repository delete. - `get_ssh_public_key` moved to the health handler; `repositories()` accessor, `repos.rs`, and `migrate/` deleted. Core - `TrackedRepository` removed; `ScanTrigger` stays. `unified_pipeline` config field removed. Dashboard - Repositories page + route deleted; overview / graph / chat / pentest-wizard read onboarded targets; `infrastructure/repositories.rs` trimmed to just the SSH-key fetch. Tests - Legacy repositories-API and migration integration tests removed; tenant isolation, cascade-delete, and stats tests repointed to `/targets` / `onboarded_targets`. `git.rs` gains a `sanitize_repo_dir` unit test. Local: fmt clean; agent/mcp clippy clean; dashboard server+web compile; core + agent lib tests (32) pass; integration tests compile. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
206 lines
7.2 KiB
Rust
206 lines
7.2 KiB
Rust
use axum::routing::{delete, get, patch, post};
|
|
use axum::Router;
|
|
|
|
use crate::api::handlers;
|
|
|
|
pub fn build_router() -> Router {
|
|
Router::new()
|
|
.route("/api/v1/health", get(handlers::health))
|
|
.route("/api/v1/stats/overview", get(handlers::stats_overview))
|
|
.route(
|
|
"/api/v1/settings/ssh-public-key",
|
|
get(handlers::get_ssh_public_key),
|
|
)
|
|
// Unified onboarding targets (#131).
|
|
.route(
|
|
"/api/v1/targets",
|
|
get(handlers::onboarding::list_targets).post(handlers::onboarding::create_target),
|
|
)
|
|
.route(
|
|
"/api/v1/targets/{id}",
|
|
get(handlers::onboarding::get_target)
|
|
.patch(handlers::onboarding::update_target)
|
|
.delete(handlers::onboarding::delete_target),
|
|
)
|
|
.route(
|
|
"/api/v1/targets/{id}/artifacts",
|
|
post(handlers::onboarding::add_artifact),
|
|
)
|
|
.route(
|
|
"/api/v1/targets/{id}/applicable-scans",
|
|
get(handlers::onboarding::applicable_scans_for_target),
|
|
)
|
|
.route(
|
|
"/api/v1/targets/{id}/detect",
|
|
post(handlers::onboarding::detect_target),
|
|
)
|
|
.route(
|
|
"/api/v1/targets/{id}/scan",
|
|
post(handlers::onboarding::trigger_target_scan),
|
|
)
|
|
.route("/api/v1/findings", get(handlers::list_findings))
|
|
.route("/api/v1/findings/{id}", get(handlers::get_finding))
|
|
.route(
|
|
"/api/v1/findings/{id}/status",
|
|
patch(handlers::update_finding_status),
|
|
)
|
|
.route(
|
|
"/api/v1/findings/bulk-status",
|
|
patch(handlers::bulk_update_finding_status),
|
|
)
|
|
.route(
|
|
"/api/v1/findings/{id}/feedback",
|
|
patch(handlers::update_finding_feedback),
|
|
)
|
|
.route("/api/v1/sbom", get(handlers::list_sbom))
|
|
.route("/api/v1/sbom/filters", get(handlers::sbom_filters))
|
|
.route("/api/v1/sbom/export", get(handlers::export_sbom))
|
|
.route("/api/v1/sbom/licenses", get(handlers::license_summary))
|
|
.route("/api/v1/sbom/diff", get(handlers::sbom_diff))
|
|
.route("/api/v1/issues", get(handlers::list_issues))
|
|
.route("/api/v1/scan-runs", get(handlers::list_scan_runs))
|
|
// MCP token management (per-tenant API tokens for the MCP server)
|
|
.route(
|
|
"/api/v1/mcp-tokens",
|
|
get(handlers::mcp_tokens::list_mcp_tokens).post(handlers::mcp_tokens::create_mcp_token),
|
|
)
|
|
.route(
|
|
"/api/v1/mcp-tokens/{id}",
|
|
delete(handlers::mcp_tokens::revoke_mcp_token),
|
|
)
|
|
// Graph API endpoints
|
|
.route("/api/v1/graph/{repo_id}", get(handlers::graph::get_graph))
|
|
.route(
|
|
"/api/v1/graph/{repo_id}/nodes",
|
|
get(handlers::graph::get_nodes),
|
|
)
|
|
.route(
|
|
"/api/v1/graph/{repo_id}/communities",
|
|
get(handlers::graph::get_communities),
|
|
)
|
|
.route(
|
|
"/api/v1/graph/{repo_id}/impact/{finding_id}",
|
|
get(handlers::graph::get_impact),
|
|
)
|
|
.route(
|
|
"/api/v1/graph/{repo_id}/search",
|
|
get(handlers::graph::search_symbols),
|
|
)
|
|
.route(
|
|
"/api/v1/graph/{repo_id}/file-content",
|
|
get(handlers::graph::get_file_content),
|
|
)
|
|
.route(
|
|
"/api/v1/graph/{repo_id}/build",
|
|
post(handlers::graph::trigger_build),
|
|
)
|
|
// DAST API endpoints
|
|
.route("/api/v1/dast/targets", get(handlers::dast::list_targets))
|
|
.route("/api/v1/dast/targets", post(handlers::dast::add_target))
|
|
.route(
|
|
"/api/v1/dast/targets/{id}/scan",
|
|
post(handlers::dast::trigger_scan),
|
|
)
|
|
.route(
|
|
"/api/v1/dast/scan-runs",
|
|
get(handlers::dast::list_scan_runs),
|
|
)
|
|
.route("/api/v1/dast/findings", get(handlers::dast::list_findings))
|
|
.route(
|
|
"/api/v1/dast/findings/{id}",
|
|
get(handlers::dast::get_finding),
|
|
)
|
|
// Chat / RAG API endpoints
|
|
.route("/api/v1/chat/{repo_id}", post(handlers::chat::chat))
|
|
.route(
|
|
"/api/v1/chat/{repo_id}/build-embeddings",
|
|
post(handlers::chat::build_embeddings),
|
|
)
|
|
.route(
|
|
"/api/v1/chat/{repo_id}/status",
|
|
get(handlers::chat::embedding_status),
|
|
)
|
|
// Help chat (documentation-grounded Q&A)
|
|
.route("/api/v1/help/chat", post(handlers::help_chat::help_chat))
|
|
// CVE notification endpoints
|
|
.route(
|
|
"/api/v1/notifications",
|
|
get(handlers::notifications::list_notifications),
|
|
)
|
|
.route(
|
|
"/api/v1/notifications/count",
|
|
get(handlers::notifications::notification_count),
|
|
)
|
|
.route(
|
|
"/api/v1/notifications/read-all",
|
|
post(handlers::notifications::mark_all_read),
|
|
)
|
|
.route(
|
|
"/api/v1/notifications/{id}/read",
|
|
patch(handlers::notifications::mark_read),
|
|
)
|
|
.route(
|
|
"/api/v1/notifications/{id}/dismiss",
|
|
patch(handlers::notifications::dismiss_notification),
|
|
)
|
|
// Pentest API endpoints
|
|
.route(
|
|
"/api/v1/pentest/lookup-repo",
|
|
get(handlers::pentest::lookup_repo),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions",
|
|
get(handlers::pentest::list_sessions).post(handlers::pentest::create_session),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}",
|
|
get(handlers::pentest::get_session),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}/chat",
|
|
post(handlers::pentest::send_message),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}/stop",
|
|
post(handlers::pentest::stop_session),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}/pause",
|
|
post(handlers::pentest::pause_session),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}/resume",
|
|
post(handlers::pentest::resume_session),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}/stream",
|
|
get(handlers::pentest::session_stream),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}/attack-chain",
|
|
get(handlers::pentest::get_attack_chain),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}/messages",
|
|
get(handlers::pentest::get_messages),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}/findings",
|
|
get(handlers::pentest::get_session_findings),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/sessions/{id}/export",
|
|
post(handlers::pentest::export_session_report),
|
|
)
|
|
.route(
|
|
"/api/v1/pentest/stats",
|
|
get(handlers::pentest::pentest_stats),
|
|
)
|
|
// Webhook routes live on the separate webhook server (port 3002,
|
|
// see crate::webhooks::server). The M7.2-C tenant-in-URL form is
|
|
// `/webhook/{tenant_id}/{platform}/{repo_id}` and the handlers
|
|
// expect a (tenant_id, repo_id) path tuple. Anything mounting
|
|
// them here on the API server would mismatch the handler
|
|
// signature, so the routes are not exported.
|
|
}
|