fix: address follow-up PR review findings (FU2-QUAL-001/002/003)
FU2-QUAL-001 (MEDIUM): Unconditionally restore sys.modules in finally block - Changed conditional restoration to unconditional to ensure broken modules from failed exec_module() calls don't persist in sys.modules FU2-QUAL-002 (MEDIUM): Remove test dependencies from production requirements - Removed pytest>=8.0.0 and pytest-cov>=5.0.0 from apps/backend/requirements.txt - Test dependencies already exist in tests/requirements-test.txt FU2-QUAL-003 (LOW): Add pagination to GitLab notes API call - Added pagination loop to fetch all issue notes before filtering - Prevents selected notes from being silently dropped when they're beyond the default 20-item page limit
This commit is contained in:
@@ -31,9 +31,5 @@ google-generativeai>=0.8.0
|
||||
# Pydantic for structured output schemas
|
||||
pydantic>=2.0.0
|
||||
|
||||
# Testing
|
||||
pytest>=8.0.0
|
||||
pytest-cov>=5.0.0
|
||||
|
||||
# Error tracking (optional - requires SENTRY_DSN environment variable)
|
||||
sentry-sdk>=2.0.0
|
||||
|
||||
@@ -109,14 +109,33 @@ export function registerInvestigateIssue(
|
||||
`/projects/${encodedProject}/issues/${issueIid}`
|
||||
) as GitLabAPIIssue;
|
||||
|
||||
// Fetch notes if any selected
|
||||
// Fetch notes if any selected (with pagination to get all notes)
|
||||
let filteredNotes: Array<{ body: string; author: { username: string } }> = [];
|
||||
if (selectedNoteIds && selectedNoteIds.length > 0) {
|
||||
const allNotes = await gitlabFetch(
|
||||
config.token,
|
||||
config.instanceUrl,
|
||||
`/projects/${encodedProject}/issues/${issueIid}/notes`
|
||||
) as Array<{ id: number; body: string; author: { username: string } }>;
|
||||
// Fetch all notes with pagination (GitLab defaults to 20 per page)
|
||||
const allNotes: Array<{ id: number; body: string; author: { username: string } }> = [];
|
||||
let page = 1;
|
||||
const perPage = 100;
|
||||
let hasMore = true;
|
||||
|
||||
while (hasMore) {
|
||||
const notesPage = await gitlabFetch(
|
||||
config.token,
|
||||
config.instanceUrl,
|
||||
`/projects/${encodedProject}/issues/${issueIid}/notes?page=${page}&per_page=${perPage}`
|
||||
) as Array<{ id: number; body: string; author: { username: string } }>;
|
||||
|
||||
if (notesPage.length === 0) {
|
||||
hasMore = false;
|
||||
} else {
|
||||
allNotes.push(...notesPage);
|
||||
if (notesPage.length < perPage) {
|
||||
hasMore = false;
|
||||
} else {
|
||||
page++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter notes based on selection
|
||||
filteredNotes = allNotes.filter(note => selectedNoteIds.includes(note.id));
|
||||
|
||||
@@ -2594,7 +2594,6 @@ class TestBuildCommandsModuleImport:
|
||||
finally:
|
||||
# Always restore original state, even if an exception occurred
|
||||
sys.path[:] = original_path
|
||||
# Restore saved modules (if they still exist in sys.modules, skip to avoid conflicts)
|
||||
# Unconditionally restore saved modules (overwrite to ensure clean state after failures)
|
||||
for mod_name, mod_obj in original_modules.items():
|
||||
if mod_name not in sys.modules:
|
||||
sys.modules[mod_name] = mod_obj
|
||||
sys.modules[mod_name] = mod_obj
|
||||
|
||||
Reference in New Issue
Block a user