fix: scope posture endpoints to latest completed scan#145
Merged
Conversation
total_findings > 0 skips any scan where 0 issues were found. So after you fix all misconfigs and run a clean scan, the dashboard ignores it and keeps showing the old dirty scan. status = 'completed' picks the latest scan that finished successfully, whether it found 0 things or 100 things.
all confirmed passing locally. Zero real DB or Azure calls pure mock.
| """Tests proving that a clean (zero-finding) completed scan is shown by posture | ||
| endpoints instead of falling back to stale data from an older scan.""" | ||
|
|
||
| from unittest.mock import MagicMock, patch, call |
| endpoints instead of falling back to stale data from an older scan.""" | ||
|
|
||
| from unittest.mock import MagicMock, patch, call | ||
| import pytest |
| from unittest.mock import MagicMock, patch, call | ||
| import pytest | ||
|
|
||
| from api.models.finding import DatabaseManager, FRAMEWORK_FILE_MAP |
ritiksah141
requested changes
Jun 17, 2026
ritiksah141
left a comment
Collaborator
There was a problem hiding this comment.
CI is failing and beside that logic sounds good to me.
Collaborator
Author
|
@ritiksah141 already working on it . |
ritiksah141
approved these changes
Jun 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
Closes #139
Every dashboard endpoint was selecting the "latest scan" with this filter:
That silently skips any scan where zero findings were returned. So if your
team remediates everything and runs a clean scan the dashboard ignores it
and keeps showing the old dirty scan score stays low, compliance shows
Fails, resources and drift describe old posture. For a CSPM tool this is a
correctness bug, not a UI issue.
Root cause
Two separate problems:
All five query locations used "total_findings > 0" to find the latest
scan, excluding clean scans entirely.
get_compliance_score()had no scan scope at all it ran"SELECT DISTINCT rule_id FROM finding" across the entire findings
table. A rule that fired once months ago would permanently show as FAIL
until that row was manually deleted from the database.
Fix
Replace "total_findings > 0" with "status = 'completed" at every
location. A completed scan is the correct selector for "latest real scan"
it includes clean scans (0 findings) and excludes pending, running, and
failed scans.
Scope "get_compliance_score()" to the latest completed scan so only
Current findings affect compliance status.
Files changed
api/models/finding.pyget_findings(),get_score(),get_cve_summary(), andget_compliance_score()— 4 SQL queries updatedapi/routes/resources.pyapi/routes/drift.pyapi/routes/prioritization.pydocs/architecture.mdtotal_findings > 0behavior, corrected drift descriptiontests/test_clean_scan.py.github/workflows/ci.ymlDATABASE_URLenv block, addedtest_clean_scan.pyto regression stepBehaviour after this fix
Tests
New file
tests/test_clean_scan.py— 8 tests, no real database or Azurecredentials required (pure mocks).
test_get_findings_uses_completed_status_not_total_findings— asserts the SQL no longer containstotal_findingstest_get_findings_clean_scan_returns_empty_list— clean scan returns []test_get_score_uses_completed_status— asserts corrected SQLtest_get_score_is_100_after_clean_scan— score = 100 with no findingstest_get_score_does_not_include_old_scan_findings— old HIGH findings do not deduct pointstest_get_compliance_score_scopes_to_latest_scan— asserts compliance query is now scopedtest_get_compliance_score_all_pass_after_clean_scan— all controls PASS after clean scantest_get_compliance_score_remediated_rule_shows_pass— remediated rule correctly shows PASSAll 8 pass locally.
Acceptance criteria checklist
GET /api/findingsreturns empty list when latest scan has zero findingsGET /api/scorereturns 100 for a latest clean scanGET /api/compliance/<framework>marks controls PASS/FAIL using the latest scan onlyReviewers
API and Backend: Safid + Ritik (as listed in the issue)