Documentation
¶
Overview ¶
Package postgres provides PostgreSQL-backed repositories (pgx/v5) and applies migrations via goose. Used when SYNAPSE_DB_DSN is set; otherwise the server falls back to in-memory persistence for dev.
Index ¶
- func AcquireSingletonLock(ctx context.Context, pool *pgxpool.Pool, role string) (*pgxpool.Conn, bool, error)
- func CheckRLSRuntimeRole(ctx context.Context, pool *pgxpool.Pool) error
- func Connect(ctx context.Context, dsn string) (*pgxpool.Pool, error)
- func ConnectPool(ctx context.Context, dsn string, pc PoolConfig) (*pgxpool.Pool, error)
- func GrantRuntimePrivileges(ctx context.Context, adminDSN, runtimeDSN string) error
- func Migrate(ctx context.Context, dsn string) error
- func ValidateMigrationRoleSeparation(migrationDSN, runtimeDSN string) error
- func WithContextTenant(ctx context.Context, pool *pgxpool.Pool, fn func(pgx.Tx) error) error
- func WithGlobalRead(ctx context.Context, pool *pgxpool.Pool, fn func(pgx.Tx) error) error
- func WithGlobalWrite(ctx context.Context, pool *pgxpool.Pool, fn func(pgx.Tx) error) error
- func WithTenant(ctx context.Context, pool *pgxpool.Pool, tenantID string, ...) (err error)
- type AITriageReviewRepository
- func (r *AITriageReviewRepository) Get(ctx context.Context, tenantID, id shared.ID) (aitriagereview.Review, error)
- func (r *AITriageReviewRepository) List(ctx context.Context, tenantID shared.ID, filter ports.AITriageReviewFilter) ([]aitriagereview.Review, error)
- func (r *AITriageReviewRepository) SaveDecision(ctx context.Context, review aitriagereview.Review, expectedVersion int) error
- func (r *AITriageReviewRepository) SaveOwner(ctx context.Context, review aitriagereview.Review, expectedVersion int) error
- func (r *AITriageReviewRepository) UpsertPending(ctx context.Context, review aitriagereview.Review) error
- type AUPStore
- type AdvisoryMaterializer
- func (r *AdvisoryMaterializer) AdvisoryRevisionAt(ctx context.Context, advisoryID string, snapshotAt time.Time) (ports.AdvisoryRevisionRef, error)
- func (r *AdvisoryMaterializer) ByCPE(ctx context.Context, part, vendor, product string) ([]advisory.Advisory, error)
- func (r *AdvisoryMaterializer) ByPackage(ctx context.Context, ecosystem, packageName string) ([]advisory.Advisory, error)
- func (r *AdvisoryMaterializer) CountVulnerabilityAdvisoriesChangedSince(ctx context.Context, since time.Time) (int64, error)
- func (r *AdvisoryMaterializer) CurrentRevision(ctx context.Context, id string) (int64, error)
- func (r *AdvisoryMaterializer) CurrentSourceRecordIDs(ctx context.Context, sourceID string, yield func(string) error) error
- func (r *AdvisoryMaterializer) GetCanonical(ctx context.Context, id string) (advisory.Canonical, error)
- func (r *AdvisoryMaterializer) GetCanonicalAtRevision(ctx context.Context, id string, revision int64) (advisory.Canonical, error)
- func (r *AdvisoryMaterializer) ListAdvisoryRevisions(ctx context.Context, after string, snapshotAt time.Time, limit int) (ports.AdvisoryRevisionPage, error)
- func (r *AdvisoryMaterializer) ListVulnerabilityAdvisories(ctx context.Context, tenantID shared.ID, ...) (vulnerabilityintel.AdvisoryPage, error)
- func (r *AdvisoryMaterializer) ListVulnerabilityAdvisoryRevisions(ctx context.Context, query vulnerabilityintel.AdvisoryRevisionQuery) (vulnerabilityintel.AdvisoryRevisionPage, error)
- func (r *AdvisoryMaterializer) ListVulnerabilitySyncRunRevisions(ctx context.Context, runIDs []shared.ID, limitPerRun int) (map[shared.ID]vulnerabilityintel.AdvisoryRevisionLinkPage, error)
- func (r *AdvisoryMaterializer) MarkAdvisoryEvaluated(ctx context.Context, tenantID shared.ID, advisoryID string, revision int64, ...) error
- func (r *AdvisoryMaterializer) Materialize(ctx context.Context, records []advisory.ObservationRecord) (advisory.MaterializationResult, error)
- func (r *AdvisoryMaterializer) OldestUnevaluatedAdvisory(ctx context.Context, tenantID shared.ID) (*vulnerabilityintel.EvaluationLag, error)
- type AdvisoryRepository
- func (r *AdvisoryRepository) ByCPE(ctx context.Context, part, vendor, product string) ([]advisory.Advisory, error)
- func (r *AdvisoryRepository) ByPackage(ctx context.Context, ecosystem, name string) ([]advisory.Advisory, error)
- func (r *AdvisoryRepository) Upsert(ctx context.Context, a advisory.Advisory) error
- type AgentDecisionStore
- type AgentPlanStore
- type AgentSessionStore
- func (s *AgentSessionStore) AppendMessage(ctx context.Context, sessionID shared.ID, seq int, m agent.Message) error
- func (s *AgentSessionStore) GetSession(ctx context.Context, id shared.ID) (agent.Session, error)
- func (s *AgentSessionStore) ListByEngagement(ctx context.Context, engagementID shared.ID) ([]agent.Session, error)
- func (s *AgentSessionStore) ListResumable(ctx context.Context, staleFor time.Duration, now time.Time, limit int) ([]agent.Session, error)
- func (s *AgentSessionStore) Messages(ctx context.Context, sessionID shared.ID) ([]agent.Message, error)
- func (s *AgentSessionStore) SaveSession(ctx context.Context, e agent.Session) error
- type ApprovalStore
- func (s *ApprovalStore) Consume(ctx context.Context, actionID shared.ID) error
- func (s *ApprovalStore) Decide(ctx context.Context, d agent.ApprovalDecision) error
- func (s *ApprovalStore) EngagementsWithPending(ctx context.Context) ([]shared.ID, error)
- func (s *ApprovalStore) Enqueue(ctx context.Context, a agent.ProposedAction) error
- func (s *ApprovalStore) Get(ctx context.Context, actionID shared.ID) (agent.ProposedAction, agent.ApprovalDecision, error)
- func (s *ApprovalStore) Pending(ctx context.Context, engagementID shared.ID) ([]agent.ProposedAction, error)
- type AssetRepository
- func (r *AssetRepository) AssignEngagementBusinessAsset(ctx context.Context, tenantID, engagementID, assetID shared.ID) error
- func (r *AssetRepository) CreateBusinessAsset(ctx context.Context, a *asset.BusinessAsset) error
- func (r *AssetRepository) GetAssetByKey(ctx context.Context, tenantID shared.ID, kind asset.Kind, key string) (*asset.Asset, error)
- func (r *AssetRepository) GetBusinessAssetByID(ctx context.Context, tenantID, id shared.ID) (*asset.BusinessAsset, error)
- func (r *AssetRepository) GetBusinessAssetByKey(ctx context.Context, tenantID shared.ID, key string) (*asset.BusinessAsset, error)
- func (r *AssetRepository) ListAssets(ctx context.Context, tenantID shared.ID) ([]*asset.Asset, error)
- func (r *AssetRepository) ListBusinessAssetProjects(ctx context.Context, tenantID, assetID shared.ID) ([]asset.ComponentMembership, error)
- func (r *AssetRepository) ListBusinessAssetTechnicalAssets(ctx context.Context, tenantID, assetID shared.ID) ([]asset.ComponentMembership, error)
- func (r *AssetRepository) ListBusinessAssets(ctx context.Context, tenantID shared.ID) ([]*asset.BusinessAsset, error)
- func (r *AssetRepository) ListEdges(ctx context.Context, tenantID shared.ID) ([]*asset.Edge, error)
- func (r *AssetRepository) ListEngagementsByBusinessAsset(ctx context.Context, tenantID, assetID shared.ID) ([]*engagement.Engagement, error)
- func (r *AssetRepository) ReplaceBusinessAssetProjects(ctx context.Context, tenantID, assetID shared.ID, ...) error
- func (r *AssetRepository) ReplaceBusinessAssetTechnicalAssets(ctx context.Context, tenantID, assetID shared.ID, ...) error
- func (r *AssetRepository) UpdateBusinessAsset(ctx context.Context, a *asset.BusinessAsset, expectedVersion int) error
- func (r *AssetRepository) UpsertAsset(ctx context.Context, a *asset.Asset) error
- func (r *AssetRepository) UpsertEdge(ctx context.Context, e *asset.Edge) error
- type AttackPathStore
- type AuditLog
- func (l *AuditLog) List(ctx context.Context, limit int) (out []ports.AuditEntry, err error)
- func (l *AuditLog) Record(ctx context.Context, e ports.AuditEntry) error
- func (l *AuditLog) RecordOnce(ctx context.Context, e ports.AuditEntry) error
- func (l *AuditLog) Verify(ctx context.Context) (audit.Report, error)
- func (l *AuditLog) VerifyGlobal(ctx context.Context) (audit.Report, error)
- type CloudObservationStore
- type CloudRunStore
- func (s *CloudRunStore) EnqueueCloudRun(ctx context.Context, run cloudposture.Run, kind string, payload []byte) error
- func (s *CloudRunStore) GetCloudRun(ctx context.Context, tenantID, id shared.ID) (out cloudposture.Run, err error)
- func (s *CloudRunStore) SaveCloudRun(ctx context.Context, run cloudposture.Run) error
- type CommentRepository
- type ComponentInventoryStore
- type DetectionRecordRepository
- func (r *DetectionRecordRepository) AppendDetection(ctx context.Context, rec detection.Record) error
- func (r *DetectionRecordRepository) ExpireDetections(ctx context.Context, engagementID shared.ID, cutoff time.Time) ([]shared.ID, error)
- func (r *DetectionRecordRepository) HasDetection(ctx context.Context, id shared.ID) (bool, error)
- func (r *DetectionRecordRepository) LastBatchSequence(ctx context.Context, agentID shared.ID) (uint64, error)
- func (r *DetectionRecordRepository) ListDetections(ctx context.Context, engagementID shared.ID) ([]detection.Record, error)
- type EmulationRunRepository
- type EngagementRepository
- func (r *EngagementRepository) Create(ctx context.Context, e *engagement.Engagement) error
- func (r *EngagementRepository) Delete(ctx context.Context, id shared.ID) error
- func (r *EngagementRepository) GetByID(ctx context.Context, id shared.ID) (out *engagement.Engagement, err error)
- func (r *EngagementRepository) GetByIDInTenant(ctx context.Context, tenantID, id shared.ID) (out *engagement.Engagement, err error)
- func (r *EngagementRepository) GetByProjectID(ctx context.Context, tenantID, projectID shared.ID) (out *engagement.Engagement, err error)
- func (r *EngagementRepository) List(ctx context.Context, tenantID shared.ID) (out []*engagement.Engagement, err error)
- func (r *EngagementRepository) ListProjectEngagements(ctx context.Context, tenantID shared.ID) (out []*engagement.Engagement, err error)
- func (r *EngagementRepository) ListPromotionReconciliationScopes(ctx context.Context) ([]ports.PromotionReconciliationScope, error)
- func (r *EngagementRepository) ListReconciliationEngagements(ctx context.Context, tenantID, after shared.ID, snapshotAt time.Time, ...) (ports.ReconciliationEngagementPage, error)
- func (r *EngagementRepository) ListTenantIDs(ctx context.Context) ([]shared.ID, error)
- func (r *EngagementRepository) ProjectContexts(ctx context.Context, tenantID shared.ID, projectIDs []shared.ID) (out map[shared.ID]*engagement.Engagement, err error)
- func (r *EngagementRepository) Update(ctx context.Context, e *engagement.Engagement) error
- type EvidenceStore
- func (r *EvidenceStore) Append(ctx context.Context, items []evidence.Evidence) error
- func (r *EvidenceStore) Head(ctx context.Context, engagementID shared.ID) (string, error)
- func (r *EvidenceStore) ListByEngagement(ctx context.Context, engagementID shared.ID) (out []evidence.Evidence, err error)
- func (r *EvidenceStore) LookupSealedForFinding(ctx context.Context, engagementID, findingID shared.ID, kind string) (evidence.Evidence, bool, error)
- type ExploitationChainRepository
- type FindingRepository
- func (r *FindingRepository) ClaimFindingProjection(ctx context.Context, tenantID, engagementID, judgmentID shared.ID, ...) error
- func (r *FindingRepository) GetByEngagementAndID(ctx context.Context, engagementID, findingID shared.ID) (finding.Finding, error)
- func (r *FindingRepository) ListByEngagement(ctx context.Context, engagementID shared.ID) (out []finding.Finding, err error)
- func (r *FindingRepository) ListPublishableByEngagement(ctx context.Context, engagementID shared.ID) ([]finding.Finding, error)
- func (r *FindingRepository) SetAssignee(ctx context.Context, engagementID, findingID shared.ID, assignee string, ...) (out finding.Finding, err error)
- func (r *FindingRepository) SetEvidenceScore(ctx context.Context, engagementID, findingID shared.ID, ...) (out finding.Finding, err error)
- func (r *FindingRepository) UpdateStatus(ctx context.Context, engagementID, findingID shared.ID, status finding.Status, ...) (out finding.Finding, err error)
- func (r *FindingRepository) Upsert(ctx context.Context, findings []finding.Finding) error
- type FleetAgentRepository
- func (r *FleetAgentRepository) ConsumeEnrolToken(ctx context.Context, tenantID shared.ID, hash string, now time.Time) (*fleetagent.EnrolToken, error)
- func (r *FleetAgentRepository) CreateAgent(ctx context.Context, a *fleetagent.Agent) error
- func (r *FleetAgentRepository) CreateEnrolToken(ctx context.Context, t *fleetagent.EnrolToken) error
- func (r *FleetAgentRepository) Decommission(ctx context.Context, tenantID, id shared.ID, now time.Time) error
- func (r *FleetAgentRepository) GetAgent(ctx context.Context, tenantID, id shared.ID) (*fleetagent.Agent, error)
- func (r *FleetAgentRepository) Heartbeat(ctx context.Context, tenantID, id shared.ID, ...) error
- func (r *FleetAgentRepository) ListAgents(ctx context.Context, tenantID shared.ID) ([]*fleetagent.Agent, error)
- func (r *FleetAgentRepository) Revoke(ctx context.Context, tenantID, id, by shared.ID, reason string, now time.Time) error
- func (r *FleetAgentRepository) SetFingerprint(ctx context.Context, tenantID, id shared.ID, fingerprint string, now time.Time) error
- type FleetRolloutRepository
- type ImportedFindingRepository
- func (r *ImportedFindingRepository) ExistsDigest(ctx context.Context, tenantID, engagementID shared.ID, digest string) (bool, error)
- func (r *ImportedFindingRepository) ListByEngagement(ctx context.Context, tenantID, engagementID shared.ID) ([]importedfinding.ImportedFinding, error)
- func (r *ImportedFindingRepository) Save(ctx context.Context, tenantID shared.ID, ...) (int, int, error)
- type ImportedSBOMStore
- type JobQueue
- func (q *JobQueue) Claim(ctx context.Context, visibility time.Duration, kinds ...string) (*ports.QueuedJob, error)
- func (q *JobQueue) Complete(ctx context.Context, id string) error
- func (q *JobQueue) Deadletter(ctx context.Context, id string) error
- func (q *JobQueue) Depth(ctx context.Context, kinds ...string) (count int, err error)
- func (q *JobQueue) Enqueue(ctx context.Context, kind string, payload []byte) (string, error)
- func (q *JobQueue) Fail(ctx context.Context, id string, retryIn time.Duration) error
- func (q *JobQueue) Heartbeat(ctx context.Context, id string, extend time.Duration) error
- func (q *JobQueue) JobStatus(ctx context.Context, id string) (status ports.JobStatus, err error)
- func (q *JobQueue) Stats(ctx context.Context, kinds ...string) (stats ports.JobStats, err error)
- type JudgmentRepository
- func (r *JudgmentRepository) AcknowledgeJudgmentAudit(ctx context.Context, kind ports.JudgmentAuditKind, judgmentID shared.ID, ...) error
- func (r *JudgmentRepository) ListByEngagement(ctx context.Context, engagementID shared.ID) ([]judgment.Judgment, error)
- func (r *JudgmentRepository) ListBySubject(ctx context.Context, engagementID, subjectID shared.ID) ([]judgment.Judgment, error)
- func (r *JudgmentRepository) ListPendingJudgmentAudits(ctx context.Context, engagementID shared.ID) (out []ports.PendingJudgmentAudit, err error)
- func (r *JudgmentRepository) Save(ctx context.Context, j judgment.Judgment) error
- func (r *JudgmentRepository) SaveWithProposalAudit(ctx context.Context, j judgment.Judgment, entry ports.AuditEntry) error
- func (r *JudgmentRepository) SetScoreState(ctx context.Context, engagementID, id shared.ID, score int, ...) (judgment.Judgment, error)
- func (r *JudgmentRepository) SetVerdictState(ctx context.Context, engagementID, id shared.ID, score int, ...) (judgment.Judgment, error)
- func (r *JudgmentRepository) SetVerdictStateWithAudit(ctx context.Context, engagementID, id shared.ID, score int, ...) (out judgment.Judgment, err error)
- type LeaderStore
- type LeaseRunLock
- type PoolConfig
- type ProjectAnalysisStore
- func (r *ProjectAnalysisStore) AttachSourceWithAudit(ctx context.Context, tenantID, projectID, analysisID shared.ID, ...) error
- func (r *ProjectAnalysisStore) CurrentAnalysisHotspotSummary(ctx context.Context, tenantID, projectID, analysisID shared.ID, ...) (hotspot.Summary, error)
- func (r *ProjectAnalysisStore) CurrentFindingStatuses(ctx context.Context, tenantID, projectID shared.ID, keys []string) (map[string]string, error)
- func (r *ProjectAnalysisStore) Get(ctx context.Context, tenantID, projectID, analysisID shared.ID) (projectanalysis.Analysis, error)
- func (r *ProjectAnalysisStore) GetHotspot(ctx context.Context, tenantID, projectID, hotspotID shared.ID) (hotspot.Hotspot, error)
- func (r *ProjectAnalysisStore) GetIssue(ctx context.Context, tenantID, projectID, issueID shared.ID) (issue.Issue, error)
- func (r *ProjectAnalysisStore) HotspotHistory(ctx context.Context, tenantID, projectID, hotspotID shared.ID) ([]hotspot.ReviewEvent, error)
- func (r *ProjectAnalysisStore) IssueHistory(ctx context.Context, tenantID, projectID, issueID shared.ID) ([]issue.ReviewEvent, error)
- func (r *ProjectAnalysisStore) LatestForProjects(ctx context.Context, tenantID shared.ID, projectIDs []shared.ID) (map[shared.ID]projectanalysis.Analysis, error)
- func (r *ProjectAnalysisStore) LatestWithResult(ctx context.Context, tenantID, projectID shared.ID) (projectanalysis.Analysis, []byte, error)
- func (r *ProjectAnalysisStore) List(ctx context.Context, tenantID, projectID shared.ID, limit int, ...) ([]projectanalysis.Analysis, bool, error)
- func (r *ProjectAnalysisStore) ListAnalysisHotspots(ctx context.Context, tenantID, projectID, analysisID shared.ID, ...) (hotspot.Page, hotspot.Summary, error)
- func (r *ProjectAnalysisStore) ListHotspots(ctx context.Context, tenantID, projectID shared.ID, filter hotspot.ListFilter) (hotspot.Page, error)
- func (r *ProjectAnalysisStore) ListIssues(ctx context.Context, tenantID, projectID shared.ID, filter issue.ListFilter) (issue.Page, error)
- func (r *ProjectAnalysisStore) ResolvedIssueKeys(ctx context.Context, tenantID, projectID shared.ID) (map[string]bool, error)
- func (r *ProjectAnalysisStore) Save(ctx context.Context, analysis projectanalysis.Analysis) error
- func (r *ProjectAnalysisStore) SaveWithResult(ctx context.Context, analysis projectanalysis.Analysis, result []byte) error
- func (r *ProjectAnalysisStore) SaveWithResultAndHotspots(ctx context.Context, analysis projectanalysis.Analysis, result []byte, ...) error
- func (r *ProjectAnalysisStore) SaveWithResultAndProjections(ctx context.Context, analysis projectanalysis.Analysis, result []byte, ...) error
- func (r *ProjectAnalysisStore) TransitionHotspot(ctx context.Context, cmd hotspot.TransitionCommand) (hotspot.Hotspot, hotspot.ReviewEvent, error)
- func (r *ProjectAnalysisStore) TransitionIssue(ctx context.Context, cmd issue.TransitionCommand) (issue.Issue, issue.ReviewEvent, error)
- type ProjectRepository
- func (r *ProjectRepository) AssignProfile(ctx context.Context, tenantID shared.ID, ...) error
- func (r *ProjectRepository) CountByGate(ctx context.Context, tenantID shared.ID, gateID string) (int, error)
- func (r *ProjectRepository) Create(ctx context.Context, p *project.Project) error
- func (r *ProjectRepository) DeleteByKey(ctx context.Context, tenantID shared.ID, key string) error
- func (r *ProjectRepository) GetByID(ctx context.Context, tenantID, projectID shared.ID) (*project.Project, error)
- func (r *ProjectRepository) GetByKey(ctx context.Context, tenantID shared.ID, key string) (*project.Project, error)
- func (r *ProjectRepository) List(ctx context.Context, tenantID shared.ID) ([]*project.Project, error)
- func (r *ProjectRepository) UpdateGate(ctx context.Context, tenantID shared.ID, key, gateID string) error
- type PromotionStore
- func (r *PromotionStore) Apply(ctx context.Context, engagementID, findingID shared.ID, ...) (out finding.Finding, err error)
- func (r *PromotionStore) FindByJudgment(ctx context.Context, engagementID, findingID, judgmentID shared.ID) (evt promotion.PromotionEvent, ok bool, err error)
- func (r *PromotionStore) LatestByFinding(ctx context.Context, engagementID, findingID shared.ID) (evt promotion.PromotionEvent, ok bool, err error)
- func (r *PromotionStore) ListByFinding(ctx context.Context, engagementID, findingID shared.ID) (out []promotion.PromotionEvent, err error)
- func (r *PromotionStore) ListPendingAudits(ctx context.Context, engagementID shared.ID) (out []promotion.PromotionEvent, err error)
- func (r *PromotionStore) MarkAuditComplete(ctx context.Context, eventID shared.ID) error
- type PurpleRepository
- func (r *PurpleRepository) ListByEngagement(ctx context.Context, engagementID shared.ID) ([]pcdom.Coverage, error)
- func (r *PurpleRepository) ListByRun(ctx context.Context, runID shared.ID) ([]pcdom.Coverage, error)
- func (r *PurpleRepository) SaveCoverage(ctx context.Context, records []pcdom.Coverage) error
- type QualityGateMutator
- func (m *QualityGateMutator) AssignProjectGate(ctx context.Context, tenantID shared.ID, projectKey, gateID string, ...) error
- func (m *QualityGateMutator) CreateGate(ctx context.Context, tenantID shared.ID, gate qualitygate.Gate, ...) error
- func (m *QualityGateMutator) CreateProjectWithGate(ctx context.Context, p *project.Project) error
- func (m *QualityGateMutator) DeleteGate(ctx context.Context, tenantID shared.ID, key string, audit ports.AuditEntry) error
- func (m *QualityGateMutator) UpdateGate(ctx context.Context, tenantID shared.ID, gate qualitygate.Gate, ...) error
- type QualityGateStore
- func (s *QualityGateStore) Create(ctx context.Context, tenantID shared.ID, gate qualitygate.Gate) error
- func (s *QualityGateStore) Delete(ctx context.Context, tenantID shared.ID, key string) error
- func (s *QualityGateStore) DeleteIfUnassigned(ctx context.Context, tenantID shared.ID, key string) error
- func (s *QualityGateStore) Get(ctx context.Context, tenantID shared.ID, key string) (qualitygate.Gate, error)
- func (s *QualityGateStore) List(ctx context.Context, tenantID shared.ID) ([]qualitygate.Gate, error)
- func (s *QualityGateStore) Update(ctx context.Context, tenantID shared.ID, gate qualitygate.Gate) error
- type QualityProfileStore
- func (s *QualityProfileStore) Create(ctx context.Context, tenantID shared.ID, profile qualityprofile.Profile) error
- func (s *QualityProfileStore) Delete(ctx context.Context, tenantID shared.ID, key string) error
- func (s *QualityProfileStore) Get(ctx context.Context, tenantID shared.ID, key string) (qualityprofile.Profile, error)
- func (s *QualityProfileStore) List(ctx context.Context, tenantID shared.ID) ([]qualityprofile.Profile, error)
- func (s *QualityProfileStore) Update(ctx context.Context, tenantID shared.ID, profile qualityprofile.Profile) error
- type ReconRunStore
- func (r *ReconRunStore) Get(ctx context.Context, id shared.ID) (recon.Run, error)
- func (r *ReconRunStore) ListByEngagement(ctx context.Context, engagementID shared.ID) ([]recon.Run, error)
- func (r *ReconRunStore) ListStaleRunning(ctx context.Context, olderThan time.Time, limit int) ([]recon.Run, error)
- func (r *ReconRunStore) Save(ctx context.Context, run recon.Run) error
- type ResponseRepository
- type RetestRepository
- type RunLock
- type SLAStore
- func (s *SLAStore) ActivePolicy(ctx context.Context, tenantID shared.ID) (sla.Policy, error)
- func (s *SLAStore) AssessmentHistory(ctx context.Context, tenantID, engagementID, findingID shared.ID) ([]sla.Assessment, error)
- func (s *SLAStore) Current(ctx context.Context, tenantID, engagementID, findingID shared.ID) (sla.Current, error)
- func (s *SLAStore) LifecycleEvents(ctx context.Context, tenantID, engagementID, findingID shared.ID) ([]sla.LifecycleEvent, error)
- func (s *SLAStore) ListCurrent(ctx context.Context, tenantID, engagementID shared.ID) ([]sla.Current, error)
- func (s *SLAStore) PolicyHistory(ctx context.Context, tenantID shared.ID) ([]sla.Policy, error)
- func (s *SLAStore) PutPolicy(ctx context.Context, policy sla.Policy, activate bool) (bool, error)
- func (s *SLAStore) SaveTransition(ctx context.Context, next sla.Lifecycle, event sla.LifecycleEvent) error
- func (s *SLAStore) UpsertAssessment(ctx context.Context, assessment sla.Assessment) (sla.AssessmentUpsertResult, error)
- type ScanJobStore
- func (r *ScanJobStore) CreateRunning(ctx context.Context, j ports.ScanJob) error
- func (r *ScanJobStore) GetJob(ctx context.Context, id string) (ports.ScanJob, error)
- func (r *ScanJobStore) LatestForEngagement(ctx context.Context, engagementID shared.ID) (ports.ScanJob, error)
- func (r *ScanJobStore) LatestForEngagements(ctx context.Context, engagementIDs []shared.ID) (map[shared.ID]ports.ScanJob, error)
- func (r *ScanJobStore) ListStaleRunning(ctx context.Context, olderThan time.Time, limit int) ([]ports.ScanJob, error)
- func (r *ScanJobStore) Save(ctx context.Context, j ports.ScanJob) error
- type ScanRepository
- type ScanResultStore
- type ScanRunStore
- type ScannedImageStore
- type SyncRunStore
- func (s *SyncRunStore) Advance(ctx context.Context, id shared.ID, expectedCheckpoint, nextCheckpoint []byte, ...) (vulnerabilitysync.Run, error)
- func (s *SyncRunStore) Finish(ctx context.Context, id shared.ID, state vulnerabilitysync.State, ...) (vulnerabilitysync.Run, error)
- func (s *SyncRunStore) Get(ctx context.Context, id shared.ID) (vulnerabilitysync.Run, error)
- func (s *SyncRunStore) GetByDurableJobID(ctx context.Context, jobID string) (vulnerabilitysync.Run, error)
- func (s *SyncRunStore) GetVulnerabilitySyncRun(ctx context.Context, tenantID, id shared.ID) (vulnerabilityintel.SyncRunItem, error)
- func (s *SyncRunStore) LatestForSource(ctx context.Context, sourceID shared.ID, states []vulnerabilitysync.State) (vulnerabilitysync.Run, error)
- func (s *SyncRunStore) LatestSuccessfulVulnerabilitySync(ctx context.Context, tenantID shared.ID) (*time.Time, error)
- func (s *SyncRunStore) ListStale(ctx context.Context, olderThan time.Time, limit int) ([]vulnerabilitysync.Run, error)
- func (s *SyncRunStore) ListVulnerabilitySyncRuns(ctx context.Context, query vulnerabilityintel.SyncRunQuery) (vulnerabilityintel.SyncRunPage, error)
- func (s *SyncRunStore) MarkRunning(ctx context.Context, id shared.ID) error
- func (s *SyncRunStore) RecoverStale(ctx context.Context, staleRunID shared.ID, staleBefore time.Time, ...) (vulnerabilitysync.Run, bool, error)
- func (s *SyncRunStore) Start(ctx context.Context, request ports.SyncRunStart) (vulnerabilitysync.Run, bool, error)
- func (s *SyncRunStore) Supersede(ctx context.Context, id shared.ID) error
- type TelemetryRepository
- func (r *TelemetryRepository) Footprint(ctx context.Context) (ports.TelemetryFootprint, error)
- func (r *TelemetryRepository) Ingest(ctx context.Context, batch ports.TelemetryBatch) error
- func (r *TelemetryRepository) LastSequence(ctx context.Context, hostID shared.ID, class detection.Class) (uint64, error)
- func (r *TelemetryRepository) Query(ctx context.Context, q ports.HuntQuery) (ports.HuntResult, error)
- func (r *TelemetryRepository) RetentionSweep(ctx context.Context, now time.Time) (ports.SweepReport, error)
- type TenantTransactionRunner
- type ThreatModelRepository
- type TimestampStore
- func (s *TimestampStore) Get(ctx context.Context, chain string, eng shared.ID, head string) (*ports.TimestampToken, error)
- func (s *TimestampStore) LatestHead(ctx context.Context, chain string, eng shared.ID) (string, bool, error)
- func (s *TimestampStore) Put(ctx context.Context, chain string, eng shared.ID, head string, ...) error
- type UserRepository
- func (r *UserRepository) Create(ctx context.Context, u *user.User) error
- func (r *UserRepository) GetByAPIKeyHash(ctx context.Context, hash string) (*user.User, error)
- func (r *UserRepository) GetByID(ctx context.Context, id shared.ID) (*user.User, error)
- func (r *UserRepository) List(ctx context.Context) ([]*user.User, error)
- func (r *UserRepository) Upsert(ctx context.Context, u *user.User) error
- type VulnerabilityActionStore
- func (s *VulnerabilityActionStore) AcknowledgeAction(ctx context.Context, tenantID, actionID shared.ID, actor string, at time.Time) (vulnerabilityaction.Action, error)
- func (s *VulnerabilityActionStore) ClaimOutbox(ctx context.Context, tenantID shared.ID, now, lockedUntil time.Time, limit int) ([]vulnerabilityaction.OutboxEvent, error)
- func (s *VulnerabilityActionStore) CompleteOutbox(ctx context.Context, tenantID, eventID shared.ID, at time.Time) error
- func (s *VulnerabilityActionStore) CountPendingVulnerabilityActions(ctx context.Context, tenantID shared.ID) (int64, error)
- func (s *VulnerabilityActionStore) GetAction(ctx context.Context, tenantID, actionID shared.ID) (vulnerabilityaction.Action, error)
- func (s *VulnerabilityActionStore) ListActions(ctx context.Context, query vulnerabilityaction.ActionQuery) (vulnerabilityaction.ActionPage, error)
- func (s *VulnerabilityActionStore) ListVulnerabilityTransitions(ctx context.Context, query vulnerabilityintel.TransitionQuery) (vulnerabilityintel.TransitionPage, error)
- func (s *VulnerabilityActionStore) RecordChange(ctx context.Context, change vulnerabilityaction.Change) (bool, error)
- func (s *VulnerabilityActionStore) ResolveAction(ctx context.Context, tenantID, actionID shared.ID, actor string, at time.Time) (vulnerabilityaction.Action, error)
- func (s *VulnerabilityActionStore) RetryOutbox(ctx context.Context, tenantID, eventID shared.ID, at, availableAt time.Time, ...) error
- func (s *VulnerabilityActionStore) SummarizeVulnerabilityActions(ctx context.Context, tenantID shared.ID, advisoryIDs []string) (map[string]vulnerabilityintel.AdvisoryActionSummary, error)
- type VulnerabilityOccurrenceStore
- func (s *VulnerabilityOccurrenceStore) CountActiveVulnerabilityOccurrences(ctx context.Context, tenantID shared.ID, advisoryID string) (int64, error)
- func (s *VulnerabilityOccurrenceStore) Get(ctx context.Context, tenantID, engagementID shared.ID, ...) (vulnerabilityoccurrence.Occurrence, error)
- func (s *VulnerabilityOccurrenceStore) ListByEngagement(ctx context.Context, tenantID, engagementID shared.ID, ...) ([]vulnerabilityoccurrence.Occurrence, error)
- func (s *VulnerabilityOccurrenceStore) ListEvents(ctx context.Context, tenantID, occurrenceID shared.ID) ([]vulnerabilityoccurrence.Event, error)
- func (s *VulnerabilityOccurrenceStore) ListUnreconciled(ctx context.Context, tenantID, runID shared.ID, advisoryID string, ...) (ports.VulnerabilityOccurrenceReconciliationPage, error)
- func (s *VulnerabilityOccurrenceStore) ListVulnerabilityOccurrences(ctx context.Context, query vulnerabilityintel.OccurrenceQuery) (vulnerabilityintel.OccurrencePage, error)
- func (s *VulnerabilityOccurrenceStore) SummarizeVulnerabilityOccurrences(ctx context.Context, tenantID shared.ID, advisoryIDs []string, ...) (map[string]vulnerabilityintel.AdvisoryOccurrenceSummary, error)
- func (s *VulnerabilityOccurrenceStore) Upsert(ctx context.Context, occurrence vulnerabilityoccurrence.Occurrence) (vulnerabilityoccurrence.UpsertResult, error)
- type VulnerabilityReconcileRunStore
- func (s *VulnerabilityReconcileRunStore) Advance(ctx context.Context, id shared.ID, expectedCheckpoint, nextCheckpoint []byte, ...) (vulnerabilityreconcile.Run, error)
- func (s *VulnerabilityReconcileRunStore) Finish(ctx context.Context, id shared.ID, state vulnerabilityreconcile.State, ...) (vulnerabilityreconcile.Run, error)
- func (s *VulnerabilityReconcileRunStore) Get(ctx context.Context, id shared.ID) (vulnerabilityreconcile.Run, error)
- func (s *VulnerabilityReconcileRunStore) GetByDurableJobID(ctx context.Context, jobID string) (vulnerabilityreconcile.Run, error)
- func (s *VulnerabilityReconcileRunStore) HasReconciliationMatch(ctx context.Context, tenantID, runID, engagementID shared.ID, ...) (bool, error)
- func (s *VulnerabilityReconcileRunStore) ListReconciliationDiffs(ctx context.Context, query vulnerabilityreconcile.DiffQuery) (vulnerabilityreconcile.DiffPage, error)
- func (s *VulnerabilityReconcileRunStore) MarkRunning(ctx context.Context, id shared.ID) error
- func (s *VulnerabilityReconcileRunStore) RecordReconciliationDiff(ctx context.Context, diff vulnerabilityreconcile.Diff) (bool, error)
- func (s *VulnerabilityReconcileRunStore) Start(ctx context.Context, request ports.VulnerabilityReconcileStart) (vulnerabilityreconcile.Run, bool, error)
- func (s *VulnerabilityReconcileRunStore) SummarizeReconciliationDiffs(ctx context.Context, tenantID, runID shared.ID) (vulnerabilityreconcile.Counts, error)
- type VulnerabilityRiskAssessmentStore
- func (s *VulnerabilityRiskAssessmentStore) CountOpenHighCriticalVulnerabilityExposure(ctx context.Context, tenantID shared.ID) (int64, error)
- func (s *VulnerabilityRiskAssessmentStore) Current(ctx context.Context, tenantID, occurrenceID shared.ID) (vulnerabilityrisk.Assessment, error)
- func (s *VulnerabilityRiskAssessmentStore) History(ctx context.Context, tenantID, occurrenceID shared.ID) ([]vulnerabilityrisk.Assessment, error)
- func (s *VulnerabilityRiskAssessmentStore) ListVulnerabilityAssessments(ctx context.Context, query vulnerabilityintel.AssessmentQuery) (vulnerabilityintel.AssessmentPage, error)
- func (s *VulnerabilityRiskAssessmentStore) SummarizeVulnerabilityRisk(ctx context.Context, tenantID shared.ID, advisoryIDs []string) (map[string]vulnerabilityintel.AdvisoryRiskSummary, error)
- func (s *VulnerabilityRiskAssessmentStore) Upsert(ctx context.Context, assessment vulnerabilityrisk.Assessment) (vulnerabilityrisk.Result, error)
- type VulnerabilitySourceStore
- func (s *VulnerabilitySourceStore) Archive(ctx context.Context, id shared.ID, expectedVersion int) error
- func (s *VulnerabilitySourceStore) Create(ctx context.Context, source vulnerabilitysource.Source) error
- func (s *VulnerabilitySourceStore) Get(ctx context.Context, id shared.ID) (vulnerabilitysource.Source, error)
- func (s *VulnerabilitySourceStore) List(ctx context.Context, includeArchived bool) ([]vulnerabilitysource.Source, error)
- func (s *VulnerabilitySourceStore) SetEnabled(ctx context.Context, id shared.ID, enabled bool, expectedVersion int) (vulnerabilitysource.Source, error)
- func (s *VulnerabilitySourceStore) Update(ctx context.Context, source vulnerabilitysource.Source, expectedVersion int) error
- type WorkOrderRepository
- func (r *WorkOrderRepository) CancelForAgent(ctx context.Context, tenantID, agentID shared.ID, reason string, now time.Time) (int, error)
- func (r *WorkOrderRepository) Claim(ctx context.Context, tenantID, agentID shared.ID, max int, now time.Time) ([]*workorder.WorkOrder, error)
- func (r *WorkOrderRepository) GetByID(ctx context.Context, tenantID, id shared.ID) (*workorder.WorkOrder, error)
- func (r *WorkOrderRepository) Issue(ctx context.Context, wo *workorder.WorkOrder) (*workorder.WorkOrder, error)
- func (r *WorkOrderRepository) ListByTenant(ctx context.Context, tenantID shared.ID) ([]*workorder.WorkOrder, error)
- func (r *WorkOrderRepository) Transition(ctx context.Context, tenantID, id shared.ID, to workorder.State, reason string, ...) error
- type WriteupDraftRepository
- func (r *WriteupDraftRepository) Get(ctx context.Context, engagementID, id shared.ID) (out writeupdraft.Draft, err error)
- func (r *WriteupDraftRepository) ListByEngagement(ctx context.Context, engagementID shared.ID) (out []writeupdraft.Draft, err error)
- func (r *WriteupDraftRepository) Save(ctx context.Context, d writeupdraft.Draft) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AcquireSingletonLock ¶
func AcquireSingletonLock(ctx context.Context, pool *pgxpool.Pool, role string) (*pgxpool.Conn, bool, error)
AcquireSingletonLock takes a session-level advisory lock (keyed by role) on a DEDICATED connection the caller holds for the whole process lifetime – releasing it drops the lock. A second instance OF THE SAME ROLE gets ok=false so it can fail fast (the repos still ignore tenant_id, so two same-role writers would race). Returns the held connection (retain it; Release at shutdown), whether the lock was obtained, and any error.
func CheckRLSRuntimeRole ¶ added in v0.1.8
CheckRLSRuntimeRole reports whether the role the pool connects as can actually be constrained by Row Level Security. RLS is bypassed entirely by SUPERUSER and BYPASSRLS roles regardless of FORCE ROW LEVEL SECURITY, so if the runtime role holds either attribute the whole tenant isolation guarantee is silently a no-op. It returns a non-nil error naming the offending attribute when the role would bypass RLS.
This is intended to gate multi-tenant enablement (fail-closed): the caller that turns on RLS-protected tables must refuse to serve if this returns an error. It is exported and separate so that path can enforce it at startup, while single-tenant deployments that connect as a superuser and use no RLS-protected table are not forced to change their role.
func ConnectPool ¶
ConnectPool opens a sized pgx pool and verifies connectivity.
func GrantRuntimePrivileges ¶ added in v0.1.8
GrantRuntimePrivileges grants the runtime role the DML privileges required by the application after migrations have completed under the separate owner credential.
func Migrate ¶
Migrate applies all pending goose migrations (idempotent; tracked in goose_db_version).
func ValidateMigrationRoleSeparation ¶ added in v0.1.8
ValidateMigrationRoleSeparation ensures migrations cannot run as the runtime role.
func WithContextTenant ¶ added in v0.1.8
WithContextTenant runs fn under the immutable tenant previously bound to ctx.
func WithGlobalRead ¶ added in v0.1.8
func WithGlobalWrite ¶ added in v0.1.8
func WithTenant ¶ added in v0.1.8
func WithTenant(ctx context.Context, pool *pgxpool.Pool, tenantID string, fn func(pgx.Tx) error) (err error)
WithTenant runs fn inside a transaction whose `app.current_tenant` session variable is set to tenantID for the life of that transaction only. Stores of Row-Level-Security-protected tables (see migration 0057 and its synapse_enable_tenant_rls procedure) MUST route reads and writes through this helper: the policy denies every row when the tenant resolves to NULL, so a query that runs outside WithTenant sees nothing rather than leaking across tenants. The setting is applied with set_config(..., is_local => true), which is transaction-scoped.
Fail-closed semantics: an empty tenantID resolves (via synapse_current_tenant's NULLIF) to NULL and therefore matches no row. Under RLS the empty string is DENY, not the default tenant, so callers of RLS-protected tables must pass a non-empty tenant id. This closes the placeholder-GUC reset hazard: app.current_tenant reverts to the empty string (not "unset") after a transaction, and mapping the empty string to NULL means a connection reused outside WithTenant still denies rather than exposing default-tenant rows.
Types ¶
type AITriageReviewRepository ¶ added in v0.1.8
type AITriageReviewRepository struct {
// contains filtered or unexported fields
}
func NewAITriageReviewRepository ¶ added in v0.1.8
func NewAITriageReviewRepository(pool *pgxpool.Pool) *AITriageReviewRepository
func (*AITriageReviewRepository) Get ¶ added in v0.1.8
func (r *AITriageReviewRepository) Get(ctx context.Context, tenantID, id shared.ID) (aitriagereview.Review, error)
func (*AITriageReviewRepository) List ¶ added in v0.1.8
func (r *AITriageReviewRepository) List(ctx context.Context, tenantID shared.ID, filter ports.AITriageReviewFilter) ([]aitriagereview.Review, error)
func (*AITriageReviewRepository) SaveDecision ¶ added in v0.1.8
func (r *AITriageReviewRepository) SaveDecision(ctx context.Context, review aitriagereview.Review, expectedVersion int) error
func (*AITriageReviewRepository) SaveOwner ¶ added in v0.1.8
func (r *AITriageReviewRepository) SaveOwner(ctx context.Context, review aitriagereview.Review, expectedVersion int) error
func (*AITriageReviewRepository) UpsertPending ¶ added in v0.1.8
func (r *AITriageReviewRepository) UpsertPending(ctx context.Context, review aitriagereview.Review) error
type AUPStore ¶
type AUPStore struct {
// contains filtered or unexported fields
}
AUPStore persists Acceptable-Use-Policy acceptances to PostgreSQL.
func NewAUPStore ¶
NewAUPStore returns an AUP store backed by the given pool.
func (*AUPStore) Save ¶
Save records an acceptance, idempotent per (actor, version) – this keeps per-actor history (the file dev sink keeps one record per version; both gate identically via Accepted's EXISTS-by-version). RBAC is enforced at the API edge. Should actor identifiers ever become attacker- influenced (e.g. a future external OIDC subject), key idempotency on a UNIQUE(actor, policy_version) constraint instead of a concatenated id.
type AdvisoryMaterializer ¶ added in v0.1.8
type AdvisoryMaterializer struct {
// contains filtered or unexported fields
}
func NewAdvisoryMaterializer ¶ added in v0.1.8
func NewAdvisoryMaterializer(pool *pgxpool.Pool) *AdvisoryMaterializer
func (*AdvisoryMaterializer) AdvisoryRevisionAt ¶ added in v0.1.8
func (r *AdvisoryMaterializer) AdvisoryRevisionAt(ctx context.Context, advisoryID string, snapshotAt time.Time) (ports.AdvisoryRevisionRef, error)
func (*AdvisoryMaterializer) CountVulnerabilityAdvisoriesChangedSince ¶ added in v0.1.8
func (*AdvisoryMaterializer) CurrentRevision ¶ added in v0.1.8
func (*AdvisoryMaterializer) CurrentSourceRecordIDs ¶ added in v0.1.8
func (*AdvisoryMaterializer) GetCanonical ¶ added in v0.1.8
func (*AdvisoryMaterializer) GetCanonicalAtRevision ¶ added in v0.1.8
func (*AdvisoryMaterializer) ListAdvisoryRevisions ¶ added in v0.1.8
func (r *AdvisoryMaterializer) ListAdvisoryRevisions(ctx context.Context, after string, snapshotAt time.Time, limit int) (ports.AdvisoryRevisionPage, error)
func (*AdvisoryMaterializer) ListVulnerabilityAdvisories ¶ added in v0.1.8
func (r *AdvisoryMaterializer) ListVulnerabilityAdvisories(ctx context.Context, tenantID shared.ID, query vulnerabilityintel.AdvisoryQuery) (vulnerabilityintel.AdvisoryPage, error)
func (*AdvisoryMaterializer) ListVulnerabilityAdvisoryRevisions ¶ added in v0.1.8
func (r *AdvisoryMaterializer) ListVulnerabilityAdvisoryRevisions(ctx context.Context, query vulnerabilityintel.AdvisoryRevisionQuery) (vulnerabilityintel.AdvisoryRevisionPage, error)
func (*AdvisoryMaterializer) ListVulnerabilitySyncRunRevisions ¶ added in v0.1.8
func (r *AdvisoryMaterializer) ListVulnerabilitySyncRunRevisions(ctx context.Context, runIDs []shared.ID, limitPerRun int) (map[shared.ID]vulnerabilityintel.AdvisoryRevisionLinkPage, error)
func (*AdvisoryMaterializer) MarkAdvisoryEvaluated ¶ added in v0.1.8
func (*AdvisoryMaterializer) Materialize ¶ added in v0.1.8
func (r *AdvisoryMaterializer) Materialize(ctx context.Context, records []advisory.ObservationRecord) (advisory.MaterializationResult, error)
func (*AdvisoryMaterializer) OldestUnevaluatedAdvisory ¶ added in v0.1.8
func (r *AdvisoryMaterializer) OldestUnevaluatedAdvisory(ctx context.Context, tenantID shared.ID) (*vulnerabilityintel.EvaluationLag, error)
type AdvisoryRepository ¶
type AdvisoryRepository struct {
// contains filtered or unexported fields
}
AdvisoryRepository persists the OWNED normalized-advisory store to PostgreSQL. It is GLOBAL reference data (NOT tenant-scoped): the full advisory is a JSONB blob in `advisories`, with one `advisory_affects` row per affected (ecosystem, package) for the indexed ByPackage lookup.
func NewAdvisoryRepository ¶
func NewAdvisoryRepository(pool *pgxpool.Pool) *AdvisoryRepository
NewAdvisoryRepository returns a repository backed by the given pool.
func (*AdvisoryRepository) ByPackage ¶
func (r *AdvisoryRepository) ByPackage(ctx context.Context, ecosystem, name string) ([]advisory.Advisory, error)
ByPackage returns the advisories that affect (ecosystem, name), decoded from their JSONB blobs. The caller runs advisory.Match to decide which actually hit the component's version. Deterministic id order.
func (*AdvisoryRepository) Upsert ¶
Upsert inserts or replaces an advisory by id and rebuilds its (ecosystem, package) index rows, in one transaction. Idempotent – advisories are re-syncable reference data (a re-ingest REPLACES in place), not an append-only ledger. The affected (ecosystem, package) keys must be ingester-normalized per the ports.AdvisoryStore KEY CONTRACT. The full domain advisory round-trips through the JSONB `data` blob.
type AgentDecisionStore ¶
type AgentDecisionStore struct {
// contains filtered or unexported fields
}
AgentDecisionStore is the durable ports.DecisionStore on PostgreSQL (migration 0032). seq is a monotonic per-session counter (MAX+1). Idempotency is enforced by partial unique indexes – one row per (session_id, action_id) for steps and one stop per session – so a redelivered drive that re-records a decision is a no-op (ON CONFLICT DO NOTHING), never a forked log. Decisions are written by a single driver under the session run lock, so the MAX+1 read/insert pair is race-free.
func NewAgentDecisionStore ¶
func NewAgentDecisionStore(pool *pgxpool.Pool) *AgentDecisionStore
NewAgentDecisionStore returns a Postgres-backed decision store.
func (*AgentDecisionStore) AppendDecision ¶
func (s *AgentDecisionStore) AppendDecision(ctx context.Context, d agent.AgentDecision) error
func (*AgentDecisionStore) ListBySession ¶
func (s *AgentDecisionStore) ListBySession(ctx context.Context, sessionID shared.ID) ([]agent.AgentDecision, error)
type AgentPlanStore ¶
type AgentPlanStore struct {
// contains filtered or unexported fields
}
AgentPlanStore is the durable ports.PlanStore on PostgreSQL (migration 0031). One plan per session (session_id UNIQUE → CreatePlan on a redelivery hits a unique violation → ErrConflict, preventing a forked second plan). SavePlan is a guarded UPDATE (… WHERE revision=$expected) that bumps the revision, so a node claim is an atomic compare-and-swap; a lost CAS (0 rows) returns ErrConflict.
func NewAgentPlanStore ¶
func NewAgentPlanStore(pool *pgxpool.Pool) *AgentPlanStore
NewAgentPlanStore returns a Postgres-backed plan store.
func (*AgentPlanStore) CreatePlan ¶
func (*AgentPlanStore) GetBySession ¶
type AgentSessionStore ¶
type AgentSessionStore struct {
// contains filtered or unexported fields
}
AgentSessionStore is the durable ports.AgentSessionStore on PostgreSQL: agent_sessions + agent_messages (migration 0027). The (session_id, seq) primary key is the transcript fork-guard – a duplicate seq is a unique violation → ErrConflict.
func NewAgentSessionStore ¶
func NewAgentSessionStore(pool *pgxpool.Pool) *AgentSessionStore
NewAgentSessionStore returns a Postgres-backed agent session store.
func (*AgentSessionStore) AppendMessage ¶
func (*AgentSessionStore) GetSession ¶
func (*AgentSessionStore) ListByEngagement ¶
func (*AgentSessionStore) ListResumable ¶
func (*AgentSessionStore) SaveSession ¶
type ApprovalStore ¶
type ApprovalStore struct {
// contains filtered or unexported fields
}
ApprovalStore is the durable ports.ApprovalStore on PostgreSQL: the HITL approval queue (migration 0028). Decide is a guarded UPDATE (… WHERE decision_state= 'pending') so the first decision wins; a second hits 0 rows and returns ErrConflict.
func NewApprovalStore ¶
func NewApprovalStore(pool *pgxpool.Pool) *ApprovalStore
NewApprovalStore returns a Postgres-backed approval store.
func (*ApprovalStore) Decide ¶
func (s *ApprovalStore) Decide(ctx context.Context, d agent.ApprovalDecision) error
func (*ApprovalStore) EngagementsWithPending ¶
func (*ApprovalStore) Enqueue ¶
func (s *ApprovalStore) Enqueue(ctx context.Context, a agent.ProposedAction) error
func (*ApprovalStore) Get ¶
func (s *ApprovalStore) Get(ctx context.Context, actionID shared.ID) (agent.ProposedAction, agent.ApprovalDecision, error)
func (*ApprovalStore) Pending ¶
func (s *ApprovalStore) Pending(ctx context.Context, engagementID shared.ID) ([]agent.ProposedAction, error)
type AssetRepository ¶ added in v0.1.8
type AssetRepository struct {
// contains filtered or unexported fields
}
AssetRepository is the Postgres-backed fleet asset model. It is the first store to route every operation through WithTenant, so the Row Level Security policies on fleet_assets, fleet_asset_edges and fleet_business_services (migration 0058, using the 0057 procedure) enforce tenant isolation at the database. A query that bypassed WithTenant would resolve the tenant to NULL and see nothing.
func NewAssetRepository ¶ added in v0.1.8
func NewAssetRepository(pool *pgxpool.Pool) *AssetRepository
NewAssetRepository constructs the Postgres asset repository.
func (*AssetRepository) AssignEngagementBusinessAsset ¶ added in v0.1.8
func (*AssetRepository) CreateBusinessAsset ¶ added in v0.1.8
func (r *AssetRepository) CreateBusinessAsset(ctx context.Context, a *asset.BusinessAsset) error
func (*AssetRepository) GetAssetByKey ¶ added in v0.1.8
func (r *AssetRepository) GetAssetByKey(ctx context.Context, tenantID shared.ID, kind asset.Kind, key string) (*asset.Asset, error)
GetAssetByKey returns the asset for (tenantID, kind, key) or shared.ErrNotFound.
func (*AssetRepository) GetBusinessAssetByID ¶ added in v0.1.8
func (r *AssetRepository) GetBusinessAssetByID(ctx context.Context, tenantID, id shared.ID) (*asset.BusinessAsset, error)
func (*AssetRepository) GetBusinessAssetByKey ¶ added in v0.1.8
func (r *AssetRepository) GetBusinessAssetByKey(ctx context.Context, tenantID shared.ID, key string) (*asset.BusinessAsset, error)
func (*AssetRepository) ListAssets ¶ added in v0.1.8
func (r *AssetRepository) ListAssets(ctx context.Context, tenantID shared.ID) ([]*asset.Asset, error)
ListAssets returns the tenant's assets ordered by (kind, key).
func (*AssetRepository) ListBusinessAssetProjects ¶ added in v0.1.8
func (r *AssetRepository) ListBusinessAssetProjects(ctx context.Context, tenantID, assetID shared.ID) ([]asset.ComponentMembership, error)
func (*AssetRepository) ListBusinessAssetTechnicalAssets ¶ added in v0.1.8
func (r *AssetRepository) ListBusinessAssetTechnicalAssets(ctx context.Context, tenantID, assetID shared.ID) ([]asset.ComponentMembership, error)
func (*AssetRepository) ListBusinessAssets ¶ added in v0.1.8
func (r *AssetRepository) ListBusinessAssets(ctx context.Context, tenantID shared.ID) ([]*asset.BusinessAsset, error)
func (*AssetRepository) ListEdges ¶ added in v0.1.8
ListEdges returns the tenant's edges ordered by (from, to, kind, provenance).
func (*AssetRepository) ListEngagementsByBusinessAsset ¶ added in v0.1.8
func (r *AssetRepository) ListEngagementsByBusinessAsset(ctx context.Context, tenantID, assetID shared.ID) ([]*engagement.Engagement, error)
func (*AssetRepository) ReplaceBusinessAssetProjects ¶ added in v0.1.8
func (r *AssetRepository) ReplaceBusinessAssetProjects(ctx context.Context, tenantID, assetID shared.ID, links []asset.ComponentMembership) error
func (*AssetRepository) ReplaceBusinessAssetTechnicalAssets ¶ added in v0.1.8
func (r *AssetRepository) ReplaceBusinessAssetTechnicalAssets(ctx context.Context, tenantID, assetID shared.ID, links []asset.ComponentMembership) error
func (*AssetRepository) UpdateBusinessAsset ¶ added in v0.1.8
func (r *AssetRepository) UpdateBusinessAsset(ctx context.Context, a *asset.BusinessAsset, expectedVersion int) error
func (*AssetRepository) UpsertAsset ¶ added in v0.1.8
UpsertAsset inserts or updates by the (tenant_id, kind, key) natural key, preserving the id and created_at of an existing row so re-observation does not churn identity.
func (*AssetRepository) UpsertEdge ¶ added in v0.1.8
UpsertEdge inserts the edge idempotently by its full natural key.
type AttackPathStore ¶ added in v0.1.8
type AttackPathStore struct {
// contains filtered or unexported fields
}
AttackPathStore persists derived asset-to-finding links behind PostgreSQL RLS.
func NewAttackPathStore ¶ added in v0.1.8
func NewAttackPathStore(pool *pgxpool.Pool) *AttackPathStore
func (*AttackPathStore) ListBindings ¶ added in v0.1.8
func (s *AttackPathStore) ListBindings(ctx context.Context, tenantID shared.ID) ([]attackpath.Binding, error)
func (*AttackPathStore) ReplaceBindings ¶ added in v0.1.8
func (s *AttackPathStore) ReplaceBindings(ctx context.Context, tenantID, engagementID, producer shared.ID, bindings []attackpath.Binding) error
type AuditLog ¶
type AuditLog struct {
// contains filtered or unexported fields
}
AuditLog is an append-only, attributable audit log on PostgreSQL.
func NewAuditLog ¶
NewAuditLog returns an audit log backed by the given pool.
func (*AuditLog) List ¶
List returns the calling tenant's most recent audit entries (newest first), capped at limit.
func (*AuditLog) RecordOnce ¶ added in v0.1.8
Record appends an immutable audit entry (INSERT only – never update or delete), chaining it to the previous row. A transaction-scoped advisory lock serializes the read-head/insert so concurrent writers cannot fork the chain. The fork-guard unique index (migration 0033) is defense-in-depth on top of the lock: if the lock is ever bypassed, a concurrent append yields a 23505 unique violation – Record then re-reads the advanced head and re-chains (bounded), parity with the evidence store, rather than surfacing an opaque error. On the normal locked path the conflict is unreachable and the loop runs once. RecordOnce implements ports.IdempotentAuditLogger. Entries with a deterministic metadata idempotency_key are recovered without adding a second chain link.
func (*AuditLog) Verify ¶
Verify examines only the calling tenant's rows. The historical audit chain is global, so omitted links make a tenant-only result unavailable rather than falsely claiming a complete integrity check. Server maintenance code may use VerifyGlobal.
func (*AuditLog) VerifyGlobal ¶ added in v0.1.8
VerifyGlobal re-derives the complete, globally linked audit chain. It deliberately bypasses tenant visibility and must only be called by server-side maintenance code, never by a tenant HTTP endpoint.
type CloudObservationStore ¶ added in v0.1.8
type CloudObservationStore struct {
// contains filtered or unexported fields
}
CloudObservationStore atomically replaces producer ownership only after a complete target snapshot.
func NewCloudObservationStore ¶ added in v0.1.8
func NewCloudObservationStore(pool *pgxpool.Pool) *CloudObservationStore
type CloudRunStore ¶ added in v0.1.8
type CloudRunStore struct {
// contains filtered or unexported fields
}
CloudRunStore persists the tenant-scoped CSPM lifecycle under RLS.
func NewCloudRunStore ¶ added in v0.1.8
func NewCloudRunStore(pool *pgxpool.Pool) *CloudRunStore
func (*CloudRunStore) EnqueueCloudRun ¶ added in v0.1.8
func (s *CloudRunStore) EnqueueCloudRun(ctx context.Context, run cloudposture.Run, kind string, payload []byte) error
func (*CloudRunStore) GetCloudRun ¶ added in v0.1.8
func (s *CloudRunStore) GetCloudRun(ctx context.Context, tenantID, id shared.ID) (out cloudposture.Run, err error)
func (*CloudRunStore) SaveCloudRun ¶ added in v0.1.8
func (s *CloudRunStore) SaveCloudRun(ctx context.Context, run cloudposture.Run) error
type CommentRepository ¶
type CommentRepository struct {
// contains filtered or unexported fields
}
CommentRepository persists the per-finding comment thread to PostgreSQL.
func NewCommentRepository ¶
func NewCommentRepository(pool *pgxpool.Pool) *CommentRepository
NewCommentRepository returns a repository backed by the given pool.
func (*CommentRepository) Add ¶
Add inserts a comment (append-only; comments are not edited or deleted in app code).
func (*CommentRepository) ListByEngagementFinding ¶
func (r *CommentRepository) ListByEngagementFinding(ctx context.Context, engagementID, findingID shared.ID) (out []finding.Comment, err error)
ListByEngagementFinding returns a finding's comments oldest-first, scoped to the engagement (no cross-engagement read).
type ComponentInventoryStore ¶ added in v0.1.8
type ComponentInventoryStore struct {
// contains filtered or unexported fields
}
func NewComponentInventoryStore ¶ added in v0.1.8
func NewComponentInventoryStore(pool *pgxpool.Pool) *ComponentInventoryStore
func (*ComponentInventoryStore) ListCurrentComponents ¶ added in v0.1.8
func (s *ComponentInventoryStore) ListCurrentComponents(ctx context.Context, query sbom.ComponentQuery) (sbom.ComponentPage, error)
type DetectionRecordRepository ¶ added in v0.1.8
type DetectionRecordRepository struct {
// contains filtered or unexported fields
}
DetectionRecordRepository persists the detection-ledger projection (migration 0074), tenant-scoped via WithTenant so RLS isolates one tenant's detections from another's. The evidence-chain link each row references is the permanent ledger; these rows are the queryable, retention-bounded projection.
func NewDetectionRecordRepository ¶ added in v0.1.8
func NewDetectionRecordRepository(pool *pgxpool.Pool) *DetectionRecordRepository
NewDetectionRecordRepository constructs the repository.
func (*DetectionRecordRepository) AppendDetection ¶ added in v0.1.8
func (r *DetectionRecordRepository) AppendDetection(ctx context.Context, rec detection.Record) error
AppendDetection stores one projection row, idempotent on (tenant_id, id): a row is immutable once written (provenance), so a re-delivery of the same detection does not overwrite it.
func (*DetectionRecordRepository) ExpireDetections ¶ added in v0.1.8
func (r *DetectionRecordRepository) ExpireDetections(ctx context.Context, engagementID shared.ID, cutoff time.Time) ([]shared.ID, error)
ExpireDetections deletes the engagement's records whose expiry has elapsed at cutoff and returns their ids for auditing. Rows with a NULL expires_at are never removed. Deleting a projection row leaves its evidence-chain link intact — the ledger is permanent, only the queryable projection ages out.
func (*DetectionRecordRepository) HasDetection ¶ added in v0.1.8
HasDetection reports whether a record with this id already exists in the ctx tenant.
func (*DetectionRecordRepository) LastBatchSequence ¶ added in v0.1.8
func (r *DetectionRecordRepository) LastBatchSequence(ctx context.Context, agentID shared.ID) (uint64, error)
LastBatchSequence returns the highest batch sequence for an agent in the ctx tenant (0 = none yet).
func (*DetectionRecordRepository) ListDetections ¶ added in v0.1.8
func (r *DetectionRecordRepository) ListDetections(ctx context.Context, engagementID shared.ID) ([]detection.Record, error)
ListDetections returns the non-expired records for an engagement, oldest first, tenant-scoped by RLS.
type EmulationRunRepository ¶ added in v0.1.8
type EmulationRunRepository struct {
// contains filtered or unexported fields
}
EmulationRunRepository persists emulation runs and coverage (migration 0073), tenant-scoped via WithTenant so RLS isolates one tenant's coverage from another's.
func NewEmulationRunRepository ¶ added in v0.1.8
func NewEmulationRunRepository(pool *pgxpool.Pool) *EmulationRunRepository
NewEmulationRunRepository constructs the repository.
type EngagementRepository ¶
type EngagementRepository struct {
// contains filtered or unexported fields
}
EngagementRepository persists engagements and their scope to PostgreSQL.
func NewEngagementRepository ¶
func NewEngagementRepository(pool *pgxpool.Pool) *EngagementRepository
NewEngagementRepository returns a repository backed by the given pool.
func (*EngagementRepository) Create ¶
func (r *EngagementRepository) Create(ctx context.Context, e *engagement.Engagement) error
Create inserts the engagement and its scope targets in one transaction.
func (*EngagementRepository) Delete ¶
Delete removes an engagement; ON DELETE CASCADE drops its scope, findings, comments, evidence, recon runs, and retests. Idempotent (no error if absent). Used to roll back a partially-materialized import.
func (*EngagementRepository) GetByID ¶
func (r *EngagementRepository) GetByID(ctx context.Context, id shared.ID) (out *engagement.Engagement, err error)
GetByID returns the engagement with its full scope WITHOUT a tenant predicate. It is the INTERNAL execution-gate read (see ports.EngagementRepository.GetByID): the scope/window/RoE guard and the worker/agent execution paths, which act on an engagement a queued/authorized run already belongs to. User-facing access uses GetByIDInTenant (below), which adds the tenant predicate that blocks cross-tenant reads.
func (*EngagementRepository) GetByIDInTenant ¶
func (r *EngagementRepository) GetByIDInTenant(ctx context.Context, tenantID, id shared.ID) (out *engagement.Engagement, err error)
GetByIDInTenant loads an engagement scoped to tenantID. Empty input normalizes to the non-empty default tenant and never becomes a wildcard; cross-tenant access returns ErrNotFound.
func (*EngagementRepository) GetByProjectID ¶
func (r *EngagementRepository) GetByProjectID(ctx context.Context, tenantID, projectID shared.ID) (out *engagement.Engagement, err error)
func (*EngagementRepository) List ¶
func (r *EngagementRepository) List(ctx context.Context, tenantID shared.ID) (out []*engagement.Engagement, err error)
List returns the tenant's engagements, each with its scope loaded (consistent with the in-memory repository; the UI and the scope gate both rely on scope).
func (*EngagementRepository) ListProjectEngagements ¶ added in v0.1.8
func (r *EngagementRepository) ListProjectEngagements(ctx context.Context, tenantID shared.ID) (out []*engagement.Engagement, err error)
ListProjectEngagements returns the tenant's hidden Project analysis contexts for operational aggregation. Normal engagement lists remain unchanged and continue to hide these rows.
func (*EngagementRepository) ListPromotionReconciliationScopes ¶ added in v0.1.8
func (r *EngagementRepository) ListPromotionReconciliationScopes(ctx context.Context) ([]ports.PromotionReconciliationScope, error)
ListPromotionReconciliationScopes returns every non-project tenant and engagement pair for process-local recovery. Each engagement query remains RLS-scoped.
func (*EngagementRepository) ListReconciliationEngagements ¶ added in v0.1.8
func (*EngagementRepository) ListTenantIDs ¶ added in v0.1.8
func (*EngagementRepository) ProjectContexts ¶
func (r *EngagementRepository) ProjectContexts(ctx context.Context, tenantID shared.ID, projectIDs []shared.ID) (out map[shared.ID]*engagement.Engagement, err error)
Update persists an existing engagement aggregate: the engagement row and its full scope target set, replaced atomically in one transaction (E1 scope CRUD + lifecycle). Returns shared.ErrNotFound if the engagement does not exist. Unlike Create's deterministic scope PKs, the replace path uses generated IDs.
func (*EngagementRepository) Update ¶
func (r *EngagementRepository) Update(ctx context.Context, e *engagement.Engagement) error
type EvidenceStore ¶
type EvidenceStore struct {
// contains filtered or unexported fields
}
EvidenceStore persists the per-engagement hash-chained evidence ledger.
func NewEvidenceStore ¶
func NewEvidenceStore(pool *pgxpool.Pool) *EvidenceStore
NewEvidenceStore returns a store backed by the given pool.
func (*EvidenceStore) Append ¶
Append inserts sealed evidence items in order, in one transaction (append-only).
func (*EvidenceStore) Head ¶
Head returns the most recent sealed hash for an engagement ("" if the chain is empty). A real query error is returned (NOT swallowed as "empty") so the caller never forks the append-only chain on a transient DB failure.
func (*EvidenceStore) ListByEngagement ¶
func (r *EvidenceStore) ListByEngagement(ctx context.Context, engagementID shared.ID) (out []evidence.Evidence, err error)
ListByEngagement returns the engagement's evidence in chain order (oldest first).
func (*EvidenceStore) LookupSealedForFinding ¶ added in v0.1.8
func (r *EvidenceStore) LookupSealedForFinding(ctx context.Context, engagementID, findingID shared.ID, kind string) (evidence.Evidence, bool, error)
LookupSealedForFinding returns the most recent sealed evidence link of the given kind for the specified finding, or (zero, false, nil) if none exists.
type ExploitationChainRepository ¶ added in v0.1.8
type ExploitationChainRepository struct {
// contains filtered or unexported fields
}
ExploitationChainRepository persists attack chains and their steps (migration 0072). Every method runs through WithTenant so Row Level Security isolates one tenant's chains from another's.
func NewExploitationChainRepository ¶ added in v0.1.8
func NewExploitationChainRepository(pool *pgxpool.Pool) *ExploitationChainRepository
NewExploitationChainRepository constructs the repository.
func (*ExploitationChainRepository) SaveChain ¶ added in v0.1.8
SaveChain upserts the chain and replaces its steps atomically. The whole chain — cursor, state, and every step's state and evidence — is written in one transaction, so a halt or a crash cannot leave the persisted chain disagreeing with itself about which steps still owe cleanup.
type FindingRepository ¶
type FindingRepository struct {
// contains filtered or unexported fields
}
FindingRepository persists findings to PostgreSQL, deduped per engagement.
func NewFindingRepository ¶
func NewFindingRepository(pool *pgxpool.Pool) *FindingRepository
NewFindingRepository returns a repository backed by the given pool.
func (*FindingRepository) ClaimFindingProjection ¶ added in v0.1.8
func (r *FindingRepository) ClaimFindingProjection(ctx context.Context, tenantID, engagementID, judgmentID shared.ID, mode ports.FindingProjectionMode) error
ClaimFindingProjection atomically reserves the SAST or legacy runtime DAST projection mode for a judgment.
func (*FindingRepository) GetByEngagementAndID ¶ added in v0.1.8
func (r *FindingRepository) GetByEngagementAndID(ctx context.Context, engagementID, findingID shared.ID) (finding.Finding, error)
GetByEngagementAndID loads a single finding by engagement and finding ID. Returns shared.ErrNotFound if no such finding exists in the engagement.
func (*FindingRepository) ListByEngagement ¶
func (r *FindingRepository) ListByEngagement(ctx context.Context, engagementID shared.ID) (out []finding.Finding, err error)
ListByEngagement returns the engagement's findings, highest risk first (CISA KEV, then EPSS x CVSS, then severity).
func (*FindingRepository) ListPublishableByEngagement ¶
func (r *FindingRepository) ListPublishableByEngagement(ctx context.Context, engagementID shared.ID) ([]finding.Finding, error)
ListPublishableByEngagement returns only the engagement's findings that clear the evidence gate. It reuses ListByEngagement and the single domain rule finding.Publishable, so the publishability policy lives in exactly one place (the domain) rather than being re-encoded in SQL.
func (*FindingRepository) SetAssignee ¶
func (r *FindingRepository) SetAssignee(ctx context.Context, engagementID, findingID shared.ID, assignee string, expectedVersion int) (out finding.Finding, err error)
SetAssignee sets the assignee with the same optimistic-concurrency guard.
func (*FindingRepository) SetEvidenceScore ¶
func (r *FindingRepository) SetEvidenceScore(ctx context.Context, engagementID, findingID shared.ID, score, expectedVersion int) (out finding.Finding, err error)
SetEvidenceScore sets a finding's evidence score with the same optimistic-concurrency guard as UpdateStatus (the adversarial-verdict path): the row is updated only if version matches, then version is bumped. Note the Upsert ON CONFLICT set deliberately omits evidence_score, so this is the only path that moves it for an already-stored finding.
func (*FindingRepository) UpdateStatus ¶
func (r *FindingRepository) UpdateStatus(ctx context.Context, engagementID, findingID shared.ID, status finding.Status, expectedVersion int) (out finding.Finding, err error)
UpdateStatus sets the triage status with optimistic concurrency: the row is updated only if version matches expectedVersion, then version is bumped. On a miss it distinguishes ErrConflict (exists, version moved) from ErrNotFound.
type FleetAgentRepository ¶ added in v0.1.8
type FleetAgentRepository struct {
// contains filtered or unexported fields
}
FleetAgentRepository is the Postgres-backed fleet agent identity store. Every method runs through WithTenant so Row Level Security (migration 0060 via the 0057 procedure) isolates by tenant. The auth lookup is tenant-scoped because the agent credential carries a non-secret tenant prefix.
func NewFleetAgentRepository ¶ added in v0.1.8
func NewFleetAgentRepository(pool *pgxpool.Pool) *FleetAgentRepository
NewFleetAgentRepository constructs the Postgres fleet agent repository.
func (*FleetAgentRepository) ConsumeEnrolToken ¶ added in v0.1.8
func (r *FleetAgentRepository) ConsumeEnrolToken(ctx context.Context, tenantID shared.ID, hash string, now time.Time) (*fleetagent.EnrolToken, error)
ConsumeEnrolToken atomically marks a usable token used and returns it; shared.ErrNotFound if no unused, unexpired token with that hash exists for the tenant.
func (*FleetAgentRepository) CreateAgent ¶ added in v0.1.8
func (r *FleetAgentRepository) CreateAgent(ctx context.Context, a *fleetagent.Agent) error
func (*FleetAgentRepository) CreateEnrolToken ¶ added in v0.1.8
func (r *FleetAgentRepository) CreateEnrolToken(ctx context.Context, t *fleetagent.EnrolToken) error
func (*FleetAgentRepository) Decommission ¶ added in v0.1.8
func (r *FleetAgentRepository) Decommission(ctx context.Context, tenantID, id shared.ID, now time.Time) error
Decommission marks the agent decommissioned on its own report (#412). It is an idempotent no-op on a REVOKED agent: an operator revocation is the stronger terminal state and a self-report must not overwrite it (the CASE leaves a revoked row untouched but still matches it, so only a truly missing agent yields ErrNotFound — matching the memory store's contract).
func (*FleetAgentRepository) GetAgent ¶ added in v0.1.8
func (r *FleetAgentRepository) GetAgent(ctx context.Context, tenantID, id shared.ID) (*fleetagent.Agent, error)
func (*FleetAgentRepository) ListAgents ¶ added in v0.1.8
func (r *FleetAgentRepository) ListAgents(ctx context.Context, tenantID shared.ID) ([]*fleetagent.Agent, error)
type FleetRolloutRepository ¶ added in v0.1.8
type FleetRolloutRepository struct {
// contains filtered or unexported fields
}
FleetRolloutRepository persists operator update-rollout plans (migration 0065).
Durability is the point: a plan held only in memory stops offering updates the moment the control plane restarts, and says nothing about why. Every method runs through WithTenant, so Row Level Security isolates by tenant — one tenant must never be able to read, still less move, another tenant's fleet.
func NewFleetRolloutRepository ¶ added in v0.1.8
func NewFleetRolloutRepository(pool *pgxpool.Pool) *FleetRolloutRepository
NewFleetRolloutRepository constructs the Postgres rollout repository.
func (*FleetRolloutRepository) Get ¶ added in v0.1.8
func (r *FleetRolloutRepository) Get(ctx context.Context, tenantID shared.ID, channel string) (*fleetrollout.Plan, error)
Get returns the plan for a channel, or shared.ErrNotFound when none is configured.
"No row" is a legitimate resting state, not an error condition: it means no rollout is in progress and therefore no agent is offered anything.
func (*FleetRolloutRepository) Put ¶ added in v0.1.8
func (r *FleetRolloutRepository) Put(ctx context.Context, plan *fleetrollout.Plan) error
Put upserts the plan for (tenant, channel).
It is an upsert rather than an insert-or-update decision at the call site because a plan is a single current STATE, not a history: "the fleet is moving to 1.4.0, canary first" replaces whatever came before it. The audit log is what carries the history of who decided what.
created_at is preserved on conflict so the plan keeps the moment the rollout began, while updated_at moves with each operator action.
type ImportedFindingRepository ¶ added in v0.1.8
type ImportedFindingRepository struct {
// contains filtered or unexported fields
}
ImportedFindingRepository persists third-party findings (migration 0064) to PostgreSQL.
Durability is not incidental here: the ingest writes an append-only audit entry claiming that N external results entered an engagement, and that claim is only true if the rows survive a restart. Every method runs through WithTenant so Row Level Security isolates by tenant.
func NewImportedFindingRepository ¶ added in v0.1.8
func NewImportedFindingRepository(pool *pgxpool.Pool) *ImportedFindingRepository
NewImportedFindingRepository constructs the Postgres imported-finding repository.
func (*ImportedFindingRepository) ExistsDigest ¶ added in v0.1.8
func (r *ImportedFindingRepository) ExistsDigest(ctx context.Context, tenantID, engagementID shared.ID, digest string) (bool, error)
ExistsDigest reports whether this tenant's engagement already ingested a document with this digest.
func (*ImportedFindingRepository) ListByEngagement ¶ added in v0.1.8
func (r *ImportedFindingRepository) ListByEngagement(ctx context.Context, tenantID, engagementID shared.ID) ([]importedfinding.ImportedFinding, error)
ListByEngagement returns the engagement's imported findings in a deterministic order.
func (*ImportedFindingRepository) Save ¶ added in v0.1.8
func (r *ImportedFindingRepository) Save(ctx context.Context, tenantID shared.ID, findings []importedfinding.ImportedFinding) (int, int, error)
Save persists a batch ATOMICALLY: one transaction, so a failure anywhere leaves no partially ingested report and no recorded digest that would make a retry look like a clean deduplicated ingest.
Each row is inserted with ON CONFLICT DO NOTHING against the idempotency index, so re-posting the same document is a no-op rather than a duplicate, and the accepted/deduplicated split the caller reports is the database's own answer rather than a guess.
type ImportedSBOMStore ¶
type ImportedSBOMStore struct {
// contains filtered or unexported fields
}
ImportedSBOMStore persists the active imported SBOM per engagement.
func NewImportedSBOMStore ¶
func NewImportedSBOMStore(pool *pgxpool.Pool) *ImportedSBOMStore
NewImportedSBOMStore returns a Postgres-backed imported-SBOM store.
func (*ImportedSBOMStore) LatestByEngagement ¶
func (s *ImportedSBOMStore) LatestByEngagement(ctx context.Context, tenantID, engagementID shared.ID) (importedsbom.Record, error)
LatestByEngagement returns the active imported SBOM for a tenant-scoped engagement.
func (*ImportedSBOMStore) SaveActive ¶
func (s *ImportedSBOMStore) SaveActive(ctx context.Context, record importedsbom.Record) error
SaveActive upserts the active imported SBOM for an engagement.
type JobQueue ¶
type JobQueue struct {
// contains filtered or unexported fields
}
JobQueue is the durable PostgreSQL queue with tenant-bound at-least-once delivery.
func NewJobQueue ¶
func NewJobQueue(pool *pgxpool.Pool, ids ports.IDGenerator) *JobQueue
type JudgmentRepository ¶
type JudgmentRepository struct {
// contains filtered or unexported fields
}
JudgmentRepository persists AI judgments to PostgreSQL, engagement-scoped. All operations route through WithContextTenant so tenant isolation is enforced at the database level. Save validates that the engagement belongs to the context tenant before writing.
func NewJudgmentRepository ¶
func NewJudgmentRepository(pool *pgxpool.Pool) *JudgmentRepository
NewJudgmentRepository returns a repository backed by the given pool.
func (*JudgmentRepository) AcknowledgeJudgmentAudit ¶ added in v0.1.8
func (r *JudgmentRepository) AcknowledgeJudgmentAudit(ctx context.Context, kind ports.JudgmentAuditKind, judgmentID shared.ID, version int) error
func (*JudgmentRepository) ListByEngagement ¶
func (r *JudgmentRepository) ListByEngagement(ctx context.Context, engagementID shared.ID) ([]judgment.Judgment, error)
ListByEngagement returns the engagement's judgments, oldest first (deterministic order). RLS scopes the query to the context tenant.
func (*JudgmentRepository) ListBySubject ¶
func (r *JudgmentRepository) ListBySubject(ctx context.Context, engagementID, subjectID shared.ID) ([]judgment.Judgment, error)
ListBySubject returns the engagement's judgments about a given subject id, oldest first. RLS scopes the query to the context tenant.
func (*JudgmentRepository) ListPendingJudgmentAudits ¶ added in v0.1.8
func (r *JudgmentRepository) ListPendingJudgmentAudits(ctx context.Context, engagementID shared.ID) (out []ports.PendingJudgmentAudit, err error)
func (*JudgmentRepository) Save ¶
Save inserts a proposed judgment (idempotent by id; never clobbers an existing row – score/state move only via SetScoreState). The typed claim is stored as its fail-closed discriminated envelope (JSONB). The tenant_id is resolved from context, and the engagement is validated to belong to that tenant before the insert.
func (*JudgmentRepository) SaveWithProposalAudit ¶ added in v0.1.8
func (r *JudgmentRepository) SaveWithProposalAudit(ctx context.Context, j judgment.Judgment, entry ports.AuditEntry) error
SaveWithProposalAudit persists a proposal with its immutable pending audit entry.
func (*JudgmentRepository) SetScoreState ¶
func (r *JudgmentRepository) SetScoreState(ctx context.Context, engagementID, id shared.ID, score int, state judgment.State, expectedVersion int) (judgment.Judgment, error)
SetScoreState moves a judgment's evidence score + state under optimistic concurrency (the verify/accept path): the row updates only if version matches expectedVersion, then version is bumped. This is the ONLY path that moves a stored judgment's score/state, and it is deliberately off the broad ports.JudgmentStore interface (a read-only consumer cannot reach it). On a miss it distinguishes ErrConflict (exists, version moved) from ErrNotFound. RLS scopes the operation to the context tenant.
func (*JudgmentRepository) SetVerdictState ¶ added in v0.1.8
func (r *JudgmentRepository) SetVerdictState(ctx context.Context, engagementID, id shared.ID, score int, state judgment.State, verifiedBy, verdictRationale string, expectedVersion int) (judgment.Judgment, error)
SetVerdictState persists a verdict's sealed verifier and rationale with its score transition.
func (*JudgmentRepository) SetVerdictStateWithAudit ¶ added in v0.1.8
func (r *JudgmentRepository) SetVerdictStateWithAudit(ctx context.Context, engagementID, id shared.ID, score int, state judgment.State, verifiedBy, rationale string, expectedVersion int, entry ports.AuditEntry) (out judgment.Judgment, err error)
SetVerdictStateWithAudit commits the verdict and immutable pending audit entry atomically.
type LeaderStore ¶ added in v0.1.8
type LeaderStore struct {
// contains filtered or unexported fields
}
LeaderStore is the Postgres fenced-lease implementation of leader election. It is global control-plane state (no tenant scoping, no RLS; see migration 0061).
func NewLeaderStore ¶ added in v0.1.8
func NewLeaderStore(pool *pgxpool.Pool) *LeaderStore
NewLeaderStore constructs the Postgres leader store.
func (*LeaderStore) Acquire ¶ added in v0.1.8
func (s *LeaderStore) Acquire(ctx context.Context, resource, holder string, term time.Duration, now time.Time) (bool, int64, error)
Acquire atomically takes or renews leadership in a single upsert: it takes the lease when the row is absent, already held by holder (renewal), or expired (takeover, which bumps the fence), and otherwise leaves a live foreign lease untouched. held is true iff holder owns it afterwards.
func (*LeaderStore) Resign ¶ added in v0.1.8
Resign releases the lease if held by holder. It EXPIRES the lease (clears the holder and sets the term to now) rather than deleting the row, so the fence survives: a graceful handover keeps the fence monotonic (the next acquirer takes over an expired row and bumps it), which a fresh INSERT with fence=1 would not. A challenger sees the expired row immediately and can take over without waiting out the term.
type LeaseRunLock ¶
type LeaseRunLock struct {
// contains filtered or unexported fields
}
LeaseRunLock implements ports.RunLocker via a jobs_run_lock ROW lease instead of a session advisory lock. Unlike RunLock it does NOT hold a pooled connection for the duration of the run – each operation borrows a connection transiently – so N concurrent runs cannot starve the pool (the ≤8-default-pool hazard the hostile review flagged). A background renewer extends the lease while the run is live; a crash lets the lease expire so another worker can reclaim it. Used for RECON; the agent SESSION lock stays the advisory RunLock (it must not expire mid-LLM-loop). owner is a per-process id so renew/release are owner-scoped.
func NewLeaseRunLock ¶
NewLeaseRunLock returns a row-lease run locker. lease is the claim TTL (set it comfortably above the longest run, e.g. ReconTimeout + a minute); the renewer ticks at lease/4 so several renews fall inside one TTL.
func (*LeaseRunLock) TryLock ¶
TryLock claims the lease (see TryLockLeased) and discards the lease-loss context – for callers that don't observe lease loss (e.g. the stale-run sweeper's liveness probe).
func (*LeaseRunLock) TryLockLeased ¶
func (l *LeaseRunLock) TryLockLeased(ctx context.Context, runID string) (context.Context, func(), bool, error)
TryLockLeased claims the lease for runID if it is free or expired. On success it starts a renewer and returns: a leaseCtx cancelled when the lease is LOST (so the caller aborts the in-flight run), plus a release that stops the renewer, cancels leaseCtx, and deletes the owner's row. A claim held by a live owner returns ok=false (the at-least-once queue retries).
type PoolConfig ¶
type PoolConfig struct {
MaxConns int32
MinConns int32
MaxConnLifetime time.Duration
MaxConnIdleTime time.Duration
HealthCheckPeriod time.Duration
}
PoolConfig sizes the pgx connection pool. Zero values get sane defaults. Sizing the pool explicitly (the default pgx cap is max(4, NumCPU) ≈ 8) is required now that the durable agent path holds a connection-bearing advisory lock per active run – an unsized pool would starve HTTP handlers at low-tens concurrency.
type ProjectAnalysisStore ¶
type ProjectAnalysisStore struct {
// contains filtered or unexported fields
}
ProjectAnalysisStore persists immutable Project analysis snapshots.
func NewProjectAnalysisStore ¶
func NewProjectAnalysisStore(pool *pgxpool.Pool) *ProjectAnalysisStore
func (*ProjectAnalysisStore) AttachSourceWithAudit ¶ added in v0.1.8
func (r *ProjectAnalysisStore) AttachSourceWithAudit(ctx context.Context, tenantID, projectID, analysisID shared.ID, capture projectanalysis.SourceCapture, audit ports.AuditEntry) error
func (*ProjectAnalysisStore) CurrentAnalysisHotspotSummary ¶
func (*ProjectAnalysisStore) CurrentFindingStatuses ¶ added in v0.1.8
func (*ProjectAnalysisStore) Get ¶
func (r *ProjectAnalysisStore) Get(ctx context.Context, tenantID, projectID, analysisID shared.ID) (projectanalysis.Analysis, error)
func (*ProjectAnalysisStore) GetHotspot ¶
func (*ProjectAnalysisStore) HotspotHistory ¶
func (r *ProjectAnalysisStore) HotspotHistory(ctx context.Context, tenantID, projectID, hotspotID shared.ID) ([]hotspot.ReviewEvent, error)
func (*ProjectAnalysisStore) IssueHistory ¶
func (r *ProjectAnalysisStore) IssueHistory(ctx context.Context, tenantID, projectID, issueID shared.ID) ([]issue.ReviewEvent, error)
func (*ProjectAnalysisStore) LatestForProjects ¶
func (*ProjectAnalysisStore) LatestWithResult ¶
func (r *ProjectAnalysisStore) LatestWithResult(ctx context.Context, tenantID, projectID shared.ID) (projectanalysis.Analysis, []byte, error)
func (*ProjectAnalysisStore) ListAnalysisHotspots ¶
func (*ProjectAnalysisStore) ListHotspots ¶
func (r *ProjectAnalysisStore) ListHotspots(ctx context.Context, tenantID, projectID shared.ID, filter hotspot.ListFilter) (hotspot.Page, error)
func (*ProjectAnalysisStore) ListIssues ¶
func (r *ProjectAnalysisStore) ListIssues(ctx context.Context, tenantID, projectID shared.ID, filter issue.ListFilter) (issue.Page, error)
func (*ProjectAnalysisStore) ResolvedIssueKeys ¶
func (*ProjectAnalysisStore) Save ¶
func (r *ProjectAnalysisStore) Save(ctx context.Context, analysis projectanalysis.Analysis) error
func (*ProjectAnalysisStore) SaveWithResult ¶
func (r *ProjectAnalysisStore) SaveWithResult(ctx context.Context, analysis projectanalysis.Analysis, result []byte) error
func (*ProjectAnalysisStore) SaveWithResultAndHotspots ¶
func (r *ProjectAnalysisStore) SaveWithResultAndHotspots(ctx context.Context, analysis projectanalysis.Analysis, result []byte, candidates []hotspot.Candidate) error
SaveWithResultAndHotspots commits the immutable analysis and its Security Hotspot projection in one PostgreSQL transaction. It delegates to SaveWithResultAndProjections with no issue projection, so both write paths share the same single-transaction body: a projection write failure rolls the analysis back, and the scan worker cannot publish a successful analysis without its projections.
func (*ProjectAnalysisStore) SaveWithResultAndProjections ¶
func (r *ProjectAnalysisStore) SaveWithResultAndProjections(ctx context.Context, analysis projectanalysis.Analysis, result []byte, hotspots []hotspot.Candidate, issues []issue.Candidate) error
SaveWithResultAndProjections commits the immutable analysis, its Security Hotspot projection, and its code-quality issue projection in a single PostgreSQL transaction. A projection write failure rolls the analysis back, so the scan worker cannot publish a successful analysis without both projections.
func (*ProjectAnalysisStore) TransitionHotspot ¶
func (r *ProjectAnalysisStore) TransitionHotspot(ctx context.Context, cmd hotspot.TransitionCommand) (hotspot.Hotspot, hotspot.ReviewEvent, error)
func (*ProjectAnalysisStore) TransitionIssue ¶
func (r *ProjectAnalysisStore) TransitionIssue(ctx context.Context, cmd issue.TransitionCommand) (issue.Issue, issue.ReviewEvent, error)
type ProjectRepository ¶
type ProjectRepository struct {
// contains filtered or unexported fields
}
func NewProjectRepository ¶
func NewProjectRepository(pool *pgxpool.Pool) *ProjectRepository
func (*ProjectRepository) AssignProfile ¶
func (r *ProjectRepository) AssignProfile(ctx context.Context, tenantID shared.ID, projectKey, language, profileKey string) error
AssignProfile sets or clears the quality profile for a language in the project's JSONB default_profile_by_lang map, atomically at the column level (no read-modify-write race).
func (*ProjectRepository) CountByGate ¶
func (*ProjectRepository) DeleteByKey ¶
func (*ProjectRepository) UpdateGate ¶
type PromotionStore ¶ added in v0.1.8
type PromotionStore struct {
// contains filtered or unexported fields
}
PromotionStore persists promotion lifecycle events to PostgreSQL. Every operation runs inside a single RLS-scoped transaction via WithContextTenant so tenant isolation is enforced at the database level.
Apply atomically:
- Acquires sorted advisory transaction locks on (judgment, fingerprint) to serialize concurrent idempotency checks (prevents deadlocks).
- Checks judgment-level idempotency (tenant+judgmentID).
- Checks fingerprint-level idempotency (tenant+fingerprint).
- Locks the finding FOR UPDATE, verifies CAS (priority + version).
- Binds command metadata to CAS state.
- Validates exact reversal for corroborating_signal_loss.
- Constructs and validates the PromotionEvent.
- Mutates the finding (priority + version) for escalating/de-escalating effects.
- Appends the event to the append-only table.
func NewPromotionStore ¶ added in v0.1.8
func NewPromotionStore(pool *pgxpool.Pool) (*PromotionStore, error)
NewPromotionStore returns a repository backed by the given pool.
func (*PromotionStore) Apply ¶ added in v0.1.8
func (r *PromotionStore) Apply(ctx context.Context, engagementID, findingID shared.ID, cmd ports.PromotionCommand) (out finding.Finding, err error)
Apply constructs a PromotionEvent from the command, persists it, and atomically moves the finding's priority. Returns the existing event on exact replay (same judgmentID), or shared.ErrConflict on semantic conflicts.
func (*PromotionStore) FindByJudgment ¶ added in v0.1.8
func (r *PromotionStore) FindByJudgment(ctx context.Context, engagementID, findingID, judgmentID shared.ID) (evt promotion.PromotionEvent, ok bool, err error)
FindByJudgment returns an event scoped to its tenant, engagement, and finding.
func (*PromotionStore) LatestByFinding ¶ added in v0.1.8
func (r *PromotionStore) LatestByFinding(ctx context.Context, engagementID, findingID shared.ID) (evt promotion.PromotionEvent, ok bool, err error)
LatestByFinding returns the most recent promotion event for a finding, or (zero, false) if none exist.
func (*PromotionStore) ListByFinding ¶ added in v0.1.8
func (r *PromotionStore) ListByFinding(ctx context.Context, engagementID, findingID shared.ID) (out []promotion.PromotionEvent, err error)
ListByFinding returns all promotion events for a finding, oldest first.
func (*PromotionStore) ListPendingAudits ¶ added in v0.1.8
func (r *PromotionStore) ListPendingAudits(ctx context.Context, engagementID shared.ID) (out []promotion.PromotionEvent, err error)
ListPendingAudits returns applied events whose required audit record has not been acknowledged. The status row is created atomically with each event.
func (*PromotionStore) MarkAuditComplete ¶ added in v0.1.8
MarkAuditComplete acknowledges an event's required audit record. Repeating the acknowledgement is idempotent.
type PurpleRepository ¶ added in v0.1.8
type PurpleRepository struct {
// contains filtered or unexported fields
}
PurpleRepository persists purple-team coverage (migration 0077), tenant-scoped via WithTenant/RLS so one tenant's coverage is never visible to another.
func NewPurpleRepository ¶ added in v0.1.8
func NewPurpleRepository(pool *pgxpool.Pool) *PurpleRepository
NewPurpleRepository constructs the repository.
func (*PurpleRepository) ListByEngagement ¶ added in v0.1.8
func (r *PurpleRepository) ListByEngagement(ctx context.Context, engagementID shared.ID) ([]pcdom.Coverage, error)
ListByEngagement returns all coverage for an engagement in the ctx tenant, oldest first, so a trend across runs is queryable.
func (*PurpleRepository) ListByRun ¶ added in v0.1.8
func (r *PurpleRepository) ListByRun(ctx context.Context, runID shared.ID) ([]pcdom.Coverage, error)
ListByRun returns one run's coverage in the ctx tenant, ordered by technique.
func (*PurpleRepository) SaveCoverage ¶ added in v0.1.8
SaveCoverage upserts a run's coverage under the authenticated tenant, keyed (run, technique), in one transaction so a re-computation of a run is atomic.
type QualityGateMutator ¶
type QualityGateMutator struct {
// contains filtered or unexported fields
}
QualityGateMutator commits managed-gate writes and their audit records together.
func NewQualityGateMutator ¶
func NewQualityGateMutator(pool *pgxpool.Pool) *QualityGateMutator
func (*QualityGateMutator) AssignProjectGate ¶
func (m *QualityGateMutator) AssignProjectGate(ctx context.Context, tenantID shared.ID, projectKey, gateID string, audit ports.AuditEntry) error
func (*QualityGateMutator) CreateGate ¶
func (m *QualityGateMutator) CreateGate(ctx context.Context, tenantID shared.ID, gate qualitygate.Gate, audit ports.AuditEntry) error
func (*QualityGateMutator) CreateProjectWithGate ¶
func (*QualityGateMutator) DeleteGate ¶
func (m *QualityGateMutator) DeleteGate(ctx context.Context, tenantID shared.ID, key string, audit ports.AuditEntry) error
func (*QualityGateMutator) UpdateGate ¶
func (m *QualityGateMutator) UpdateGate(ctx context.Context, tenantID shared.ID, gate qualitygate.Gate, audit ports.AuditEntry) error
type QualityGateStore ¶
type QualityGateStore struct {
// contains filtered or unexported fields
}
QualityGateStore persists tenant-scoped custom quality gates.
func NewQualityGateStore ¶
func NewQualityGateStore(pool *pgxpool.Pool) *QualityGateStore
func (*QualityGateStore) Create ¶
func (s *QualityGateStore) Create(ctx context.Context, tenantID shared.ID, gate qualitygate.Gate) error
func (*QualityGateStore) DeleteIfUnassigned ¶
func (*QualityGateStore) Get ¶
func (s *QualityGateStore) Get(ctx context.Context, tenantID shared.ID, key string) (qualitygate.Gate, error)
func (*QualityGateStore) List ¶
func (s *QualityGateStore) List(ctx context.Context, tenantID shared.ID) ([]qualitygate.Gate, error)
func (*QualityGateStore) Update ¶
func (s *QualityGateStore) Update(ctx context.Context, tenantID shared.ID, gate qualitygate.Gate) error
type QualityProfileStore ¶
type QualityProfileStore struct {
// contains filtered or unexported fields
}
QualityProfileStore persists tenant-scoped custom quality profiles. Built-in profiles are generated from the rule catalog and never stored here.
func NewQualityProfileStore ¶
func NewQualityProfileStore(pool *pgxpool.Pool) *QualityProfileStore
func (*QualityProfileStore) Create ¶
func (s *QualityProfileStore) Create(ctx context.Context, tenantID shared.ID, profile qualityprofile.Profile) error
func (*QualityProfileStore) Get ¶
func (s *QualityProfileStore) Get(ctx context.Context, tenantID shared.ID, key string) (qualityprofile.Profile, error)
func (*QualityProfileStore) List ¶
func (s *QualityProfileStore) List(ctx context.Context, tenantID shared.ID) ([]qualityprofile.Profile, error)
func (*QualityProfileStore) Update ¶
func (s *QualityProfileStore) Update(ctx context.Context, tenantID shared.ID, profile qualityprofile.Profile) error
type ReconRunStore ¶
type ReconRunStore struct {
// contains filtered or unexported fields
}
ReconRunStore persists recon-run records.
func NewReconRunStore ¶
func NewReconRunStore(pool *pgxpool.Pool) *ReconRunStore
NewReconRunStore returns a store backed by the given pool.
func (*ReconRunStore) ListByEngagement ¶
func (r *ReconRunStore) ListByEngagement(ctx context.Context, engagementID shared.ID) ([]recon.Run, error)
ListByEngagement returns an engagement's runs, newest first.
type ResponseRepository ¶ added in v0.1.8
type ResponseRepository struct {
// contains filtered or unexported fields
}
ResponseRepository persists governed response actions (migration 0076), tenant-scoped via WithTenant/RLS so one tenant's actions are never visible to another.
func NewResponseRepository ¶ added in v0.1.8
func NewResponseRepository(pool *pgxpool.Pool) *ResponseRepository
NewResponseRepository constructs the repository.
func (*ResponseRepository) Get ¶ added in v0.1.8
Get returns the record for an id in the ctx tenant.
func (*ResponseRepository) ListByState ¶ added in v0.1.8
func (r *ResponseRepository) ListByState(ctx context.Context, state rdom.State) ([]rdom.Record, error)
ListByState returns the ctx tenant's records in a state, deterministically ordered by id.
type RetestRepository ¶
type RetestRepository struct {
// contains filtered or unexported fields
}
RetestRepository persists the per-finding retest history to PostgreSQL.
func NewRetestRepository ¶
func NewRetestRepository(pool *pgxpool.Pool) *RetestRepository
NewRetestRepository returns a repository backed by the given pool.
func (*RetestRepository) Add ¶
Add inserts a retest (append-only; retests are not edited or deleted in app code).
func (*RetestRepository) ListByEngagementFinding ¶
func (r *RetestRepository) ListByEngagementFinding(ctx context.Context, engagementID, findingID shared.ID) (out []finding.Retest, err error)
ListByEngagementFinding returns a finding's retests oldest-first, scoped to the engagement (no cross-engagement read).
type RunLock ¶
type RunLock struct {
// contains filtered or unexported fields
}
RunLock implements ports.RunLocker with a PostgreSQL session advisory lock keyed by the run id (F9). The lock is held on a dedicated pooled connection for the duration of the execution and released (with the connection) afterwards – so across the API + the worker, at most one delivery of a given run executes at a time. A redelivery that finds the lock held gets ok=false and skips, preventing a duplicate live scan.
func NewRunLock ¶
NewRunLock returns a Postgres-backed run locker.
type SLAStore ¶ added in v0.1.8
type SLAStore struct {
// contains filtered or unexported fields
}
SLAStore is the PostgreSQL adapter for versioned SLA policy, immutable assessments, and the human remediation lifecycle. Every operation is routed through WithTenant so RLS remains the final isolation boundary even when an application-level predicate regresses.
func NewSLAStore ¶ added in v0.1.8
func (*SLAStore) ActivePolicy ¶ added in v0.1.8
func (*SLAStore) AssessmentHistory ¶ added in v0.1.8
func (*SLAStore) LifecycleEvents ¶ added in v0.1.8
func (*SLAStore) ListCurrent ¶ added in v0.1.8
func (*SLAStore) PolicyHistory ¶ added in v0.1.8
func (*SLAStore) SaveTransition ¶ added in v0.1.8
func (*SLAStore) UpsertAssessment ¶ added in v0.1.8
func (s *SLAStore) UpsertAssessment(ctx context.Context, assessment sla.Assessment) (sla.AssessmentUpsertResult, error)
type ScanJobStore ¶
type ScanJobStore struct {
// contains filtered or unexported fields
}
ScanJobStore persists asynchronous scan-job status.
func NewScanJobStore ¶
func NewScanJobStore(pool *pgxpool.Pool) *ScanJobStore
NewScanJobStore returns a store backed by the given pool.
func (*ScanJobStore) CreateRunning ¶
func (*ScanJobStore) LatestForEngagement ¶
func (*ScanJobStore) LatestForEngagements ¶
func (r *ScanJobStore) LatestForEngagements(ctx context.Context, engagementIDs []shared.ID) (map[shared.ID]ports.ScanJob, error)
LatestForEngagement returns the engagement's most recent scan job, or ErrNotFound.
type ScanRepository ¶
type ScanRepository struct {
// contains filtered or unexported fields
}
ScanRepository persists SCA scans (SBOM + components + vulnerabilities).
func NewScanRepository ¶
func NewScanRepository(pool *pgxpool.Pool) *ScanRepository
NewScanRepository returns a repository backed by the given pool.
func (*ScanRepository) SaveScan ¶
func (r *ScanRepository) SaveScan(ctx context.Context, engagementID shared.ID, doc *sbom.SBOM, vulns []vulnerability.Vulnerability, snap ports.ScanSnapshot) (int, error)
SaveScan stores the SBOM, its components, and the vulnerabilities found against them in one transaction – a new immutable snapshot per scan. It returns the number of vulns that could not be linked to a component in this SBOM (skipped, never orphaned); the caller surfaces a non-zero count on the audit log so a dropped advisory is never invisible on a chain-of-custody tool.
type ScanResultStore ¶
type ScanResultStore struct {
// contains filtered or unexported fields
}
ScanResultStore caches the latest full scan result (JSON) per engagement.
func NewScanResultStore ¶
func NewScanResultStore(pool *pgxpool.Pool) *ScanResultStore
NewScanResultStore returns a store backed by the given pool.
func (*ScanResultStore) LatestResult ¶
LatestResult returns the engagement's cached scan result, or shared.ErrNotFound.
func (*ScanResultStore) SaveResult ¶
func (r *ScanResultStore) SaveResult(ctx context.Context, engagementID shared.ID, result []byte) error
SaveResult upserts the engagement's latest scan result JSON.
type ScanRunStore ¶
type ScanRunStore struct {
// contains filtered or unexported fields
}
ScanRunStore persists scan-run manifests + finding keys.
func NewScanRunStore ¶
func NewScanRunStore(pool *pgxpool.Pool) *ScanRunStore
NewScanRunStore returns a store backed by the given pool.
type ScannedImageStore ¶ added in v0.1.8
type ScannedImageStore struct {
// contains filtered or unexported fields
}
ScannedImageStore is the Postgres-backed scanned-image digest index (#446). Every operation routes through WithTenant so the Row Level Security policy on scanned_image (migration 0063) enforces tenant isolation at the database — a query that bypassed WithTenant would resolve the tenant to NULL and see nothing.
func NewScannedImageStore ¶ added in v0.1.8
func NewScannedImageStore(pool *pgxpool.Pool) *ScannedImageStore
NewScannedImageStore constructs the Postgres scanned-image store.
func (*ScannedImageStore) MarkScanned ¶ added in v0.1.8
func (s *ScannedImageStore) MarkScanned(ctx context.Context, tenantID shared.ID, digest string, at time.Time) error
MarkScanned records digest as scanned for the tenant. Idempotent by (tenant, digest): a repeat keeps the earliest first_scanned_at.
func (*ScannedImageStore) ScannedDigests ¶ added in v0.1.8
func (s *ScannedImageStore) ScannedDigests(ctx context.Context, tenantID shared.ID) (map[string]bool, error)
ScannedDigests returns the set of scanned digests for the tenant.
type SyncRunStore ¶ added in v0.1.8
type SyncRunStore struct {
// contains filtered or unexported fields
}
func NewSyncRunStore ¶ added in v0.1.8
func NewSyncRunStore(pool *pgxpool.Pool, ids ports.IDGenerator) *SyncRunStore
func (*SyncRunStore) Advance ¶ added in v0.1.8
func (s *SyncRunStore) Advance(ctx context.Context, id shared.ID, expectedCheckpoint, nextCheckpoint []byte, counts vulnerabilitysync.Counts, errors []string) (vulnerabilitysync.Run, error)
func (*SyncRunStore) Finish ¶ added in v0.1.8
func (s *SyncRunStore) Finish(ctx context.Context, id shared.ID, state vulnerabilitysync.State, counts vulnerabilitysync.Counts, samples []string) (vulnerabilitysync.Run, error)
func (*SyncRunStore) Get ¶ added in v0.1.8
func (s *SyncRunStore) Get(ctx context.Context, id shared.ID) (vulnerabilitysync.Run, error)
func (*SyncRunStore) GetByDurableJobID ¶ added in v0.1.8
func (s *SyncRunStore) GetByDurableJobID(ctx context.Context, jobID string) (vulnerabilitysync.Run, error)
func (*SyncRunStore) GetVulnerabilitySyncRun ¶ added in v0.1.8
func (s *SyncRunStore) GetVulnerabilitySyncRun(ctx context.Context, tenantID, id shared.ID) (vulnerabilityintel.SyncRunItem, error)
func (*SyncRunStore) LatestForSource ¶ added in v0.1.8
func (s *SyncRunStore) LatestForSource(ctx context.Context, sourceID shared.ID, states []vulnerabilitysync.State) (vulnerabilitysync.Run, error)
func (*SyncRunStore) LatestSuccessfulVulnerabilitySync ¶ added in v0.1.8
func (*SyncRunStore) ListStale ¶ added in v0.1.8
func (s *SyncRunStore) ListStale(ctx context.Context, olderThan time.Time, limit int) ([]vulnerabilitysync.Run, error)
func (*SyncRunStore) ListVulnerabilitySyncRuns ¶ added in v0.1.8
func (s *SyncRunStore) ListVulnerabilitySyncRuns(ctx context.Context, query vulnerabilityintel.SyncRunQuery) (vulnerabilityintel.SyncRunPage, error)
func (*SyncRunStore) MarkRunning ¶ added in v0.1.8
func (*SyncRunStore) RecoverStale ¶ added in v0.1.8
func (s *SyncRunStore) RecoverStale(ctx context.Context, staleRunID shared.ID, staleBefore time.Time, request ports.SyncRunStart) (vulnerabilitysync.Run, bool, error)
func (*SyncRunStore) Start ¶ added in v0.1.8
func (s *SyncRunStore) Start(ctx context.Context, request ports.SyncRunStart) (vulnerabilitysync.Run, bool, error)
type TelemetryRepository ¶ added in v0.1.8
type TelemetryRepository struct {
// contains filtered or unexported fields
}
TelemetryRepository is the CE columnar-tier store (migration 0075) behind ports.TelemetryStore, tenant-scoped via WithTenant/RLS. It is reached only through the port and appears in no domain type.
func NewTelemetryRepository ¶ added in v0.1.8
func NewTelemetryRepository(pool *pgxpool.Pool, hot, warm time.Duration) *TelemetryRepository
NewTelemetryRepository constructs the store with the hot/warm tier boundaries (ADR 0001 config).
func (*TelemetryRepository) Footprint ¶ added in v0.1.8
func (r *TelemetryRepository) Footprint(ctx context.Context) (ports.TelemetryFootprint, error)
Footprint reports the GLOBAL store size — an operator spend metric across all tenants, not a per-tenant figure. Both numbers are global and coherent: an estimated row count from the planner statistics (pg_class.reltuples) paired with the real on-disk size (pg_total_relation_size). These are catalog reads, unaffected by RLS, and carry only counts/bytes — never tenant data — so a global scope leaks nothing. reltuples is an estimate (refreshed by ANALYZE/autovacuum), which is the right shape for "predict spend, don't discover it".
func (*TelemetryRepository) Ingest ¶ added in v0.1.8
func (r *TelemetryRepository) Ingest(ctx context.Context, batch ports.TelemetryBatch) error
Ingest bulk-inserts the batch's events, idempotent on (tenant, host, class, seq, idx).
func (*TelemetryRepository) LastSequence ¶ added in v0.1.8
func (r *TelemetryRepository) LastSequence(ctx context.Context, hostID shared.ID, class detection.Class) (uint64, error)
LastSequence returns the highest stored seq for a (host, class) in the ctx tenant.
func (*TelemetryRepository) Query ¶ added in v0.1.8
func (r *TelemetryRepository) Query(ctx context.Context, q ports.HuntQuery) (ports.HuntResult, error)
Query runs a retro-hunt over a window and reports completeness honestly (sampled + sequence gaps).
func (*TelemetryRepository) RetentionSweep ¶ added in v0.1.8
func (r *TelemetryRepository) RetentionSweep(ctx context.Context, now time.Time) (ports.SweepReport, error)
RetentionSweep down-samples the warm window (drops 1-in-2 by idx for reduced resolution) and expires the past-warm window, for the ctx tenant. Returns the counts so the caller can audit the expiry.
type TenantTransactionRunner ¶ added in v0.1.8
type TenantTransactionRunner struct {
// contains filtered or unexported fields
}
func NewTenantTransactionRunner ¶ added in v0.1.8
func NewTenantTransactionRunner(pool *pgxpool.Pool) *TenantTransactionRunner
type ThreatModelRepository ¶
type ThreatModelRepository struct {
// contains filtered or unexported fields
}
ThreatModelRepository persists the architecture-input threat model per engagement to PostgreSQL: one row per engagement, the validated domain model stored as a JSONB blob. Tenant-scoped customer data (tenant_id recorded for the row-scoping sweep); reads are engagement-scoped (the tenant gate runs upstream at the child route).
func NewThreatModelRepository ¶
func NewThreatModelRepository(pool *pgxpool.Pool) *ThreatModelRepository
NewThreatModelRepository returns a repository backed by the given pool.
func (*ThreatModelRepository) Get ¶
func (r *ThreatModelRepository) Get(ctx context.Context, engagementID shared.ID) (threatmodel.Model, bool, error)
Get decodes the engagement's model from its JSONB blob; ok=false when none has been ingested.
func (*ThreatModelRepository) Save ¶
func (r *ThreatModelRepository) Save(ctx context.Context, engagementID, tenantID shared.ID, m threatmodel.Model) error
Save upserts the engagement's model (the usecase has already bounded size + validated it), bumping version on each re-ingest. The model round-trips through the JSONB `data` blob.
type TimestampStore ¶
type TimestampStore struct {
// contains filtered or unexported fields
}
TimestampStore persists external RFC-3161 tokens for chain heads on PostgreSQL, out-of-band from the report. One token per (chain, engagement, head).
func NewTimestampStore ¶
func NewTimestampStore(pool *pgxpool.Pool) *TimestampStore
NewTimestampStore returns a timestamp store backed by the given pool.
func (*TimestampStore) Get ¶
func (s *TimestampStore) Get(ctx context.Context, chain string, eng shared.ID, head string) (*ports.TimestampToken, error)
Get returns the stored token for a head, or nil if it is not yet anchored.
type UserRepository ¶
type UserRepository struct {
// contains filtered or unexported fields
}
UserRepository persists operator identities to PostgreSQL.
func NewUserRepository ¶
func NewUserRepository(pool *pgxpool.Pool) *UserRepository
NewUserRepository returns a repository backed by the given pool.
func (*UserRepository) GetByAPIKeyHash ¶
type VulnerabilityActionStore ¶ added in v0.1.8
type VulnerabilityActionStore struct {
// contains filtered or unexported fields
}
func NewVulnerabilityActionStore ¶ added in v0.1.8
func NewVulnerabilityActionStore(pool *pgxpool.Pool) *VulnerabilityActionStore
func (*VulnerabilityActionStore) AcknowledgeAction ¶ added in v0.1.8
func (*VulnerabilityActionStore) ClaimOutbox ¶ added in v0.1.8
func (s *VulnerabilityActionStore) ClaimOutbox(ctx context.Context, tenantID shared.ID, now, lockedUntil time.Time, limit int) ([]vulnerabilityaction.OutboxEvent, error)
func (*VulnerabilityActionStore) CompleteOutbox ¶ added in v0.1.8
func (*VulnerabilityActionStore) CountPendingVulnerabilityActions ¶ added in v0.1.8
func (*VulnerabilityActionStore) GetAction ¶ added in v0.1.8
func (s *VulnerabilityActionStore) GetAction(ctx context.Context, tenantID, actionID shared.ID) (vulnerabilityaction.Action, error)
func (*VulnerabilityActionStore) ListActions ¶ added in v0.1.8
func (s *VulnerabilityActionStore) ListActions(ctx context.Context, query vulnerabilityaction.ActionQuery) (vulnerabilityaction.ActionPage, error)
func (*VulnerabilityActionStore) ListVulnerabilityTransitions ¶ added in v0.1.8
func (s *VulnerabilityActionStore) ListVulnerabilityTransitions(ctx context.Context, query vulnerabilityintel.TransitionQuery) (vulnerabilityintel.TransitionPage, error)
func (*VulnerabilityActionStore) RecordChange ¶ added in v0.1.8
func (s *VulnerabilityActionStore) RecordChange(ctx context.Context, change vulnerabilityaction.Change) (bool, error)
func (*VulnerabilityActionStore) ResolveAction ¶ added in v0.1.8
func (*VulnerabilityActionStore) RetryOutbox ¶ added in v0.1.8
func (*VulnerabilityActionStore) SummarizeVulnerabilityActions ¶ added in v0.1.8
func (s *VulnerabilityActionStore) SummarizeVulnerabilityActions(ctx context.Context, tenantID shared.ID, advisoryIDs []string) (map[string]vulnerabilityintel.AdvisoryActionSummary, error)
type VulnerabilityOccurrenceStore ¶ added in v0.1.8
type VulnerabilityOccurrenceStore struct {
// contains filtered or unexported fields
}
func NewVulnerabilityOccurrenceStore ¶ added in v0.1.8
func NewVulnerabilityOccurrenceStore(pool *pgxpool.Pool) *VulnerabilityOccurrenceStore
func (*VulnerabilityOccurrenceStore) CountActiveVulnerabilityOccurrences ¶ added in v0.1.8
func (*VulnerabilityOccurrenceStore) Get ¶ added in v0.1.8
func (s *VulnerabilityOccurrenceStore) Get(ctx context.Context, tenantID, engagementID shared.ID, advisoryID, componentFingerprint string) (vulnerabilityoccurrence.Occurrence, error)
func (*VulnerabilityOccurrenceStore) ListByEngagement ¶ added in v0.1.8
func (s *VulnerabilityOccurrenceStore) ListByEngagement(ctx context.Context, tenantID, engagementID shared.ID, states []vulnerabilityoccurrence.State) ([]vulnerabilityoccurrence.Occurrence, error)
func (*VulnerabilityOccurrenceStore) ListEvents ¶ added in v0.1.8
func (s *VulnerabilityOccurrenceStore) ListEvents(ctx context.Context, tenantID, occurrenceID shared.ID) ([]vulnerabilityoccurrence.Event, error)
func (*VulnerabilityOccurrenceStore) ListUnreconciled ¶ added in v0.1.8
func (*VulnerabilityOccurrenceStore) ListVulnerabilityOccurrences ¶ added in v0.1.8
func (s *VulnerabilityOccurrenceStore) ListVulnerabilityOccurrences(ctx context.Context, query vulnerabilityintel.OccurrenceQuery) (vulnerabilityintel.OccurrencePage, error)
func (*VulnerabilityOccurrenceStore) SummarizeVulnerabilityOccurrences ¶ added in v0.1.8
func (s *VulnerabilityOccurrenceStore) SummarizeVulnerabilityOccurrences(ctx context.Context, tenantID shared.ID, advisoryIDs []string, affectedAsset string, states []vulnerabilityoccurrence.State) (map[string]vulnerabilityintel.AdvisoryOccurrenceSummary, error)
func (*VulnerabilityOccurrenceStore) Upsert ¶ added in v0.1.8
func (s *VulnerabilityOccurrenceStore) Upsert(ctx context.Context, occurrence vulnerabilityoccurrence.Occurrence) (vulnerabilityoccurrence.UpsertResult, error)
type VulnerabilityReconcileRunStore ¶ added in v0.1.8
type VulnerabilityReconcileRunStore struct {
// contains filtered or unexported fields
}
func NewVulnerabilityReconcileRunStore ¶ added in v0.1.8
func NewVulnerabilityReconcileRunStore(pool *pgxpool.Pool, ids ports.IDGenerator) *VulnerabilityReconcileRunStore
func (*VulnerabilityReconcileRunStore) Advance ¶ added in v0.1.8
func (s *VulnerabilityReconcileRunStore) Advance(ctx context.Context, id shared.ID, expectedCheckpoint, nextCheckpoint []byte, counts vulnerabilityreconcile.Counts, samples []string) (vulnerabilityreconcile.Run, error)
func (*VulnerabilityReconcileRunStore) Finish ¶ added in v0.1.8
func (s *VulnerabilityReconcileRunStore) Finish(ctx context.Context, id shared.ID, state vulnerabilityreconcile.State, counts vulnerabilityreconcile.Counts, samples []string) (vulnerabilityreconcile.Run, error)
func (*VulnerabilityReconcileRunStore) Get ¶ added in v0.1.8
func (s *VulnerabilityReconcileRunStore) Get(ctx context.Context, id shared.ID) (vulnerabilityreconcile.Run, error)
func (*VulnerabilityReconcileRunStore) GetByDurableJobID ¶ added in v0.1.8
func (s *VulnerabilityReconcileRunStore) GetByDurableJobID(ctx context.Context, jobID string) (vulnerabilityreconcile.Run, error)
func (*VulnerabilityReconcileRunStore) HasReconciliationMatch ¶ added in v0.1.8
func (*VulnerabilityReconcileRunStore) ListReconciliationDiffs ¶ added in v0.1.8
func (s *VulnerabilityReconcileRunStore) ListReconciliationDiffs(ctx context.Context, query vulnerabilityreconcile.DiffQuery) (vulnerabilityreconcile.DiffPage, error)
func (*VulnerabilityReconcileRunStore) MarkRunning ¶ added in v0.1.8
func (*VulnerabilityReconcileRunStore) RecordReconciliationDiff ¶ added in v0.1.8
func (s *VulnerabilityReconcileRunStore) RecordReconciliationDiff(ctx context.Context, diff vulnerabilityreconcile.Diff) (bool, error)
func (*VulnerabilityReconcileRunStore) Start ¶ added in v0.1.8
func (s *VulnerabilityReconcileRunStore) Start(ctx context.Context, request ports.VulnerabilityReconcileStart) (vulnerabilityreconcile.Run, bool, error)
func (*VulnerabilityReconcileRunStore) SummarizeReconciliationDiffs ¶ added in v0.1.8
func (s *VulnerabilityReconcileRunStore) SummarizeReconciliationDiffs(ctx context.Context, tenantID, runID shared.ID) (vulnerabilityreconcile.Counts, error)
type VulnerabilityRiskAssessmentStore ¶ added in v0.1.8
type VulnerabilityRiskAssessmentStore struct {
// contains filtered or unexported fields
}
func NewVulnerabilityRiskAssessmentStore ¶ added in v0.1.8
func NewVulnerabilityRiskAssessmentStore(pool *pgxpool.Pool) *VulnerabilityRiskAssessmentStore
func (*VulnerabilityRiskAssessmentStore) CountOpenHighCriticalVulnerabilityExposure ¶ added in v0.1.8
func (*VulnerabilityRiskAssessmentStore) Current ¶ added in v0.1.8
func (s *VulnerabilityRiskAssessmentStore) Current(ctx context.Context, tenantID, occurrenceID shared.ID) (vulnerabilityrisk.Assessment, error)
func (*VulnerabilityRiskAssessmentStore) History ¶ added in v0.1.8
func (s *VulnerabilityRiskAssessmentStore) History(ctx context.Context, tenantID, occurrenceID shared.ID) ([]vulnerabilityrisk.Assessment, error)
func (*VulnerabilityRiskAssessmentStore) ListVulnerabilityAssessments ¶ added in v0.1.8
func (s *VulnerabilityRiskAssessmentStore) ListVulnerabilityAssessments(ctx context.Context, query vulnerabilityintel.AssessmentQuery) (vulnerabilityintel.AssessmentPage, error)
func (*VulnerabilityRiskAssessmentStore) SummarizeVulnerabilityRisk ¶ added in v0.1.8
func (s *VulnerabilityRiskAssessmentStore) SummarizeVulnerabilityRisk(ctx context.Context, tenantID shared.ID, advisoryIDs []string) (map[string]vulnerabilityintel.AdvisoryRiskSummary, error)
func (*VulnerabilityRiskAssessmentStore) Upsert ¶ added in v0.1.8
func (s *VulnerabilityRiskAssessmentStore) Upsert(ctx context.Context, assessment vulnerabilityrisk.Assessment) (vulnerabilityrisk.Result, error)
type VulnerabilitySourceStore ¶ added in v0.1.8
type VulnerabilitySourceStore struct {
// contains filtered or unexported fields
}
func NewVulnerabilitySourceStore ¶ added in v0.1.8
func NewVulnerabilitySourceStore(pool *pgxpool.Pool) *VulnerabilitySourceStore
func (*VulnerabilitySourceStore) Create ¶ added in v0.1.8
func (s *VulnerabilitySourceStore) Create(ctx context.Context, source vulnerabilitysource.Source) error
func (*VulnerabilitySourceStore) Get ¶ added in v0.1.8
func (s *VulnerabilitySourceStore) Get(ctx context.Context, id shared.ID) (vulnerabilitysource.Source, error)
func (*VulnerabilitySourceStore) List ¶ added in v0.1.8
func (s *VulnerabilitySourceStore) List(ctx context.Context, includeArchived bool) ([]vulnerabilitysource.Source, error)
func (*VulnerabilitySourceStore) SetEnabled ¶ added in v0.1.8
func (s *VulnerabilitySourceStore) SetEnabled(ctx context.Context, id shared.ID, enabled bool, expectedVersion int) (vulnerabilitysource.Source, error)
func (*VulnerabilitySourceStore) Update ¶ added in v0.1.8
func (s *VulnerabilitySourceStore) Update(ctx context.Context, source vulnerabilitysource.Source, expectedVersion int) error
type WorkOrderRepository ¶ added in v0.1.8
type WorkOrderRepository struct {
// contains filtered or unexported fields
}
WorkOrderRepository is the Postgres-backed fleet work order store. Every method runs through WithTenant so Row Level Security (migration 0059 via the 0057 procedure) isolates by tenant.
func NewWorkOrderRepository ¶ added in v0.1.8
func NewWorkOrderRepository(pool *pgxpool.Pool) *WorkOrderRepository
NewWorkOrderRepository constructs the Postgres work order repository.
func (*WorkOrderRepository) CancelForAgent ¶ added in v0.1.8
func (r *WorkOrderRepository) CancelForAgent(ctx context.Context, tenantID, agentID shared.ID, reason string, now time.Time) (int, error)
CancelForAgent cancels every live order addressed to agentID (used on agent revocation).
func (*WorkOrderRepository) Claim ¶ added in v0.1.8
func (r *WorkOrderRepository) Claim(ctx context.Context, tenantID, agentID shared.ID, max int, now time.Time) ([]*workorder.WorkOrder, error)
Claim atomically moves up to max unexpired issued orders addressed to agentID into claimed and returns them, using FOR UPDATE SKIP LOCKED so concurrent claimers never double-claim.
func (*WorkOrderRepository) GetByID ¶ added in v0.1.8
func (r *WorkOrderRepository) GetByID(ctx context.Context, tenantID, id shared.ID) (*workorder.WorkOrder, error)
GetByID returns the order for (tenantID, id) or shared.ErrNotFound.
func (*WorkOrderRepository) Issue ¶ added in v0.1.8
func (r *WorkOrderRepository) Issue(ctx context.Context, wo *workorder.WorkOrder) (*workorder.WorkOrder, error)
Issue inserts wo. It is idempotent by (tenant, idempotency key): a duplicate returns the existing order. A second LIVE order for the same (tenant, asset, capability, time bucket) returns shared.ErrConflict (the partial unique index).
func (*WorkOrderRepository) ListByTenant ¶ added in v0.1.8
func (r *WorkOrderRepository) ListByTenant(ctx context.Context, tenantID shared.ID) ([]*workorder.WorkOrder, error)
ListByTenant returns every work order for the tenant, ordered deterministically. Read-only, used by the coverage projection (#413); routed through WithTenant so RLS scopes it to the tenant.
func (*WorkOrderRepository) Transition ¶ added in v0.1.8
func (r *WorkOrderRepository) Transition(ctx context.Context, tenantID, id shared.ID, to workorder.State, reason string, expected workorder.State, now time.Time) error
Transition applies to with an optimistic expected-state check. It returns shared.ErrConflict when no row matched (the state changed concurrently or the order does not exist under this tenant).
type WriteupDraftRepository ¶
type WriteupDraftRepository struct {
// contains filtered or unexported fields
}
WriteupDraftRepository persists AI-proposed, human-gated finding write-up drafts to PostgreSQL, engagement-scoped.
func NewWriteupDraftRepository ¶
func NewWriteupDraftRepository(pool *pgxpool.Pool) *WriteupDraftRepository
NewWriteupDraftRepository returns a repository backed by the given pool.
func (*WriteupDraftRepository) Get ¶
func (r *WriteupDraftRepository) Get(ctx context.Context, engagementID, id shared.ID) (out writeupdraft.Draft, err error)
Get returns the engagement's draft by id, or shared.ErrNotFound.
func (*WriteupDraftRepository) ListByEngagement ¶
func (r *WriteupDraftRepository) ListByEngagement(ctx context.Context, engagementID shared.ID) (out []writeupdraft.Draft, err error)
ListByEngagement returns the engagement's drafts, oldest first (deterministic order).
func (*WriteupDraftRepository) Save ¶
func (r *WriteupDraftRepository) Save(ctx context.Context, d writeupdraft.Draft) error
Save upserts a draft by id. Unlike a Judgment (insert-only), a Draft is mutable working data, so on conflict the mutable fields (text, state, decided_by, updated_at) are replaced; the immutable fields (engagement_id, finding_id, proposed_by, created_at) are never moved. tenant_id is written as the empty-string default tenant (mirrors judgments/findings); reads are tenant-isolated via the engagement gate, and the column is present so the P5/E22 row-scoping sweep covers it.
Source Files
¶
- advisory_materializer.go
- advisory_repo.go
- agent_decision_store.go
- agent_plan_store.go
- agent_session_store.go
- aitriage_review_repo.go
- approval_store.go
- asset_repo.go
- attack_path_store.go
- aup_audit.go
- cloud_observation_store.go
- cloud_run_store.go
- comment_repo.go
- component_inventory_store.go
- db.go
- detection_record_repo.go
- emulation_run_repo.go
- engagement_repo.go
- evidence_repo.go
- exploitation_chain_repo.go
- finding_repo.go
- fleetagent_repo.go
- fleetrollout_repo.go
- imported_sbom_store.go
- importedfinding_repo.go
- jobqueue.go
- judgment_repo.go
- leader_store.go
- project_analysis_source.go
- project_analysis_store.go
- project_hotspot_store.go
- project_issue_store.go
- project_repo.go
- promotion_store.go
- purple_repo.go
- quality_gate_mutator.go
- quality_gate_store.go
- quality_profile_store.go
- recon_run_repo.go
- response_repo.go
- retest_repo.go
- runlock.go
- runlock_lease.go
- scan_job_repo.go
- scan_repo.go
- scan_result_repo.go
- scan_run_repo.go
- scanned_image_store.go
- sla_store.go
- sync_run_store.go
- telemetry_repo.go
- tenant.go
- threat_model_repo.go
- timestamp_store.go
- user_repo.go
- vulnerability_action_store.go
- vulnerability_occurrence_store.go
- vulnerability_reconcile_run_store.go
- vulnerability_risk_assessment_store.go
- vulnerability_source_store.go
- workorder_repo.go
- writeupdraft_repo.go