-
Notifications
You must be signed in to change notification settings - Fork 0
fix: resolve 8 Claude-identified bugs (null guards, UTC, fp precision, cascade deletes) #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -252,9 +252,17 @@ def delete_student(student_id: str) -> bool: | |
| True if the student was deleted, False if not found | ||
| """ | ||
| conn = sqlite3.connect(DB_FILE) | ||
| conn.execute("PRAGMA foreign_keys = ON") | ||
| cursor = conn.cursor() | ||
|
|
||
| try: | ||
| # Delete packets first — their FK cascade removes daily_lessons, | ||
| # worksheet_artifacts, and packet_feedback automatically. | ||
| # weekly_packets may not exist in minimal test DBs, so ignore if absent. | ||
| try: | ||
| cursor.execute("DELETE FROM weekly_packets WHERE student_id = ?", (student_id,)) | ||
| except sqlite3.OperationalError: | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM] This
If the goal is to handle missing tables in tests, consider either: except sqlite3.OperationalError as e:
if "no such table" not in str(e):
raiseor better, fix the test fixtures to always call |
||
| pass | ||
| cursor.execute( | ||
| "DELETE FROM student_profiles WHERE student_id = ?", | ||
| (student_id,), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,12 +15,17 @@ | |
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def _get_grade_level(student_id: str) -> int: | ||
| """Return grade_level from the student's most recent weekly packet, or 0.""" | ||
| def _get_grade_level(student_id: str, metadata_fallback: dict | None = None) -> int: | ||
| """Return grade_level from the student's most recent weekly packet. | ||
|
|
||
| Falls back to metadata_fallback["grade_level"] if no packets exist, then to 1. | ||
| """ | ||
| packets, _ = list_weekly_packets(student_id, limit=1, offset=0) | ||
| if packets: | ||
| return packets[0].get("grade_level", 0) | ||
| return 0 | ||
| if metadata_fallback: | ||
| return int(metadata_fallback.get("grade_level", 1)) | ||
| return 1 | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [LOW] The fallback sentinel changed from The |
||
|
|
||
|
|
||
| def generate_trio_for_student(student_id: str) -> None: | ||
|
|
@@ -30,7 +35,7 @@ def generate_trio_for_student(student_id: str) -> None: | |
| name = metadata.get("name", student_id) | ||
|
|
||
| try: | ||
| grade_level = _get_grade_level(student_id) | ||
| grade_level = _get_grade_level(student_id, metadata_fallback=metadata) | ||
| subjects = pick_subjects(student_id) | ||
|
|
||
| with ThreadPoolExecutor(max_workers=3) as executor: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[CRITICAL — regression]
PRAGMA foreign_keys = ONactivates the FK constraint fromingest_standards.py'spacket_feedbackschema:This has no
ON DELETE CASCADEand theweekly_packetsdelete above does not cascade topacket_feedback(because in the actual live DB,packet_feedbackhas an FK tostudent_profiles, not toweekly_packets). So the sequence is:DELETE FROM weekly_packets WHERE student_id = ?— orphanspacket_feedbackrows (no cascade)DELETE FROM student_profiles WHERE student_id = ?— raisessqlite3.IntegrityError: FOREIGN KEY constraint failedbecausepacket_feedbackrows still reference thisstudent_idAny student who has ever submitted feedback is now undeletable after this PR. The endpoint returns 500 instead of 204.
Suggestion: rather than enabling PRAGMA here, explicitly delete
packet_feedbackrows before deletingstudent_profiles(similar to howweekly_packetsis already handled), or remove the conflicting FK fromingest_standards.pyand rely solely onpacket_store.py's schema.