//! `RepoView` — an internal, non-persisted view of a code target for the scan //! pipeline. //! //! It replaces the old persisted `TrackedRepository` model. The pipeline //! (SAST → SBOM → CVE → triage → issues → DAST, and PR review) only ever needs a //! flat bundle of git + issue-tracker + auth fields; those are projected from an //! [`OnboardedTarget`] and its code [`Artifact`] by [`RepoView::from_target`]. //! Nothing here is written to Mongo — onboarded targets are the sole persisted //! entity. use compliance_core::models::{Artifact, OnboardedTarget, TrackerType}; /// A flat, pipeline-facing view of a code target. Built from an onboarded /// target; never persisted. #[derive(Debug, Clone)] pub struct RepoView { /// The onboarded target's id (used as `repo_id` across findings/sbom/etc.). pub id: Option, pub name: String, pub git_url: String, pub default_branch: String, pub local_path: Option, pub scan_schedule: Option, pub webhook_enabled: bool, pub webhook_secret: Option, pub tracker_type: Option, pub tracker_owner: Option, pub tracker_repo: Option, pub tracker_token: Option, pub auth_token: Option, pub auth_username: Option, pub last_scanned_commit: Option, pub findings_count: u32, } impl RepoView { /// Project an onboarded target + its code artifact into a pipeline view. pub fn from_target(target: &OnboardedTarget, code: &Artifact) -> Self { let mut view = Self { id: target.id, name: target.name.clone(), git_url: code.source_ref.clone(), default_branch: "main".to_string(), local_path: None, scan_schedule: target.scan_schedule.clone(), webhook_enabled: target.webhook_enabled, webhook_secret: target.webhook_secret.clone(), tracker_type: None, tracker_owner: None, tracker_repo: None, tracker_token: None, auth_token: None, auth_username: None, last_scanned_commit: None, findings_count: target.findings_count, }; if let Some(git) = &code.git { view.default_branch = git.default_branch.clone(); view.last_scanned_commit = git.last_scanned_commit.clone(); view.local_path = git.local_path.clone(); } if let Some(auth) = &code.auth { view.auth_token = auth.secret.clone(); view.auth_username = auth.username.clone(); } if let Some(it) = &target.scan_config.issue_tracker { view.tracker_type = it.tracker_type.clone(); view.tracker_owner = it.owner.clone(); view.tracker_repo = it.repo.clone(); view.tracker_token = it.token.clone(); } view } }