Skip to content

fix(reminders): הבועה מתרעננת גם כשהיא מוצגת — השרת אומר מתי לחזור, next ירד, והסטאב מחיל היטלה - #3444

Merged
amirbiron merged 3 commits into
mainfrom
claude/funny-fermat-7l7dol
Sep 21, 2026
Merged

amirbiron merged 3 commits into
mainfrom
claude/funny-fermat-7l7dol

Conversation

@amirbiron

@amirbiron amirbiron commented Sep 21, 2026 •

Copy link
Copy Markdown
Owner

✨ תיאור קצר

שלב 3 בתוכנית התיקונים שאחרי הסקירה של #3430 (code-review-3430-sticky-reminders.md ב-Ck): WARN-004, WARN-011, YAGNI-001, ואיתם SUGG-001 (מדידה בלבד) ו-SUGG-008. הבועה כבר לא נרדמת לחצי שעה: כשיש תזכורת בשלה השרת אומר ללקוח לחזור לכל היותר בעוד חמש דקות, ומוקדם יותר כשתזכורת נוספת מבשילה — ולכן בועה שנוקתה ממכשיר אחר ומונה שהשתנה נראים תוך דקות. האובייקט next, שאין לו צרכן, ירד יחד עם השאילתה שבנתה אותו, ואיתו הסתירה האפשרית בינו לבין הספירה. והסטאב בטסטים מחיל היטלה כמו מונגו, כך שטסט על היטלה בודק משהו. קומיט אחד, da65a6d, על ענף שאותחל מ-main אחרי מיזוג #3438 (שלב 2).

📦 שינויים עיקריים

  • קוד (Backend) — webapp/sticky_notes_api.py, הנתיב reminders_summary בלבד
  • קוד (Frontend) — ה-IIFE initStickyRemindersIndicator ב-webapp/templates/base.html, בלי CSS
  • בוט טלגרם
  • מסד נתונים/מיגרציות
  • תיעוד (docs/)
  • טסטים (tests/test_sticky_note_reminders.py, tests/test_sticky_reminders_polling_browser.py)
  • DevOps/CI/CD

פירוט:

  • WARN-004 — השרת אומר מתי לחזור גם כשיש בועה. עד היום next_in_seconds חושב רק כשאין תזכורת בשלה, והלקוח, כשיש בועה, החזיר את התקרה: חצי שעה שבה בועה שנוקתה בטלפון נשארה על המסך בדסקטופ, ומונה שהשתנה הראה את המספר הישן. עכשיו השאילתה על התזכורת העתידית הקרובה רצה בשני המצבים, וכשיש בועה התשובה נחתכת ב-BADGE_REFRESH_SECONDS — קבוע חדש במודול, חמש דקות, המרווח הקבוע שהיה כאן לפני הדגימה לפי השרת. הקבוע יושב בשרת ולא בלקוח כדי שללקוח יישאר כלל אחד: "ישן כמה שהשרת אמר, בין הרצפה לתקרה". בלקוח שני הענפים עוברים דרך פונקציה אחת, requestedDelay(j), במקום שני עותקים של אותו חישוב (R6), עם אותה בדיקת טיפוס שכבר הייתה; null עדיין מתורגם לתקרה, ולכן שרת ישן באמצע דיפלוי אינו משנה את ההתנהגות.
  • YAGNI-001 — next ירד. בדקתי בעצמי שאין צרכן: grep על reminders/summary ועל reminders_summary בכל הריפו מוצא רק את ה-IIFE ב-base.html (שקורא ok, has_due, count_due, next_in_seconds ולא next), טסטים ותיעוד; sw.js אינו קורא לנתיב. ירדו: ההיטלה next_projection, ה-find_one הממוין על הבשלות, ההמרה ל-ISO והמפתח בתשובה. עודכנו: test_summary_has_due, _summary ו-_DUE בטסטי הדפדפן, הדוגמה ב-docs/webapp/api-reference.rst, השורה ב-webapp/USER_GUIDE.md, וה-docstring.
  • WARN-011 — הסתירה נעלמת מעצמה. אחרי הסרת next, has_due ו-count_due נגזרים מהספירה בלבד, וה-find_one שנשאר שואל שאלה אחרת — מתי העתידית הקרובה — ולכן שתי התשובות אינן יכולות לשלוח בועה בלי תזכורת מאחוריה. שקלתי אגרגציה יחידה ($match ואז $group) שנותנת צילום עקבי בסיבוב אחד, ודחיתי: היא דורשת מנוע aggregate בסטאב, והרווח מול שני סיבובים מאונדקסים על קומץ מסמכים של משתמש אחד אינו פרופורציונלי (R8). ואין hint: שני האינדקסים המורכבים נוצרים best-effort בתוך except: pass, ואינדקס שחסר היה הופך hint בשם ל-500 על נתיב שכל טאב מחובר דוגם; היום אינדקס חסר הוא רק שאילתה איטית יותר.
  • SUGG-008 — הסטאב מחיל היטלה. _StubColl.find_one ו-find קיבלו projection וזרקו אותו, ולכן כל טסט ראה מסמך מלא היכן שהייצור רואה שדה אחד. פונקציית עזר _project מחילה הכללה (השדות שנקבו ועוד _id, אלא אם _id: 0) והחרגה, כמו במונגו; המיון וה-limit רצים על המסמכים המלאים וההיטלה חלה על היוצא. הראיה שזה משנה משהו: ב-worktree שיניתי את ההיטלה בייצור מ-{'remind_at': 1} ל-{'note_id': 1} — עם הסטאב הישן test_summary_reports_seconds_until_next_reminder עבר (1 passed), ועם החדש הוא נופל (unexpectedly None). כל שאר הקובץ עובר עם הסטאב החדש, כלומר שום נתיב לא קרא שדה מחוץ להיטלה שלו.
  • SUGG-001 — מדידה, לא שינוי (הטבלה למטה).

explain מול הייצור, לפי docs/database/indexing.rst

נמדד דרך ה-MCP של Atlas, קריאה בלבד, executionStats, על code_keeper_bot.note_reminders (MongoDB 8.0.32), עם ה-user_id שלי; התאריך הועבר כ-EJSON ופורש נכון (הגבולות מראים new Date(1789963200000)).

שאילתה תוכנית מנצחת מה קורה לה בקומיט
ספירת הבשלות (count_documents) COUNT ← IXSCAN user_reminders_summary_idx (partial), שני טווחי status, בלי FETCH — מכוסה נשארת כמו שהיא
find_one ממוין על הבשלות (בנה את next) LIMIT ← PROJECTION_SIMPLE ← FETCH בלי פילטר ← SORT_MERGE על user_reminders_summary_idx — שונה מהסקירה, שראתה remind_at_idx עם FETCH על user_id יורדת
find_one ממוין על העתידית (remind_at > now) LIMIT ← PROJECTION_SIMPLE ← FETCH עם פילטר {ack_at, status, user_id} ← IXSCAN remind_at_idx — צורת SUGG-001; התוכניות עם SORT_MERGE על שני האינדקסים המורכבים נדחו נשארת, ורצה עכשיו בשני המצבים

nReturned, totalKeysExamined ו-totalDocsExamined היו 0 בשלוש — למשתמש הזה אין כרגע תזכורת בשלה או עתידית, ולכן הראיה היא צורת התוכנית ולא הזמנים. הבחירה השונה מהסקירה בשאילתה השנייה מאששת את הניתוח שבתוכנית: ל-$in על שני ערכי status האינדקס המורכב מספק את המיון דרך SORT_MERGE, למתכנן יש שני מועמדים, ועל 23 מסמכים ניסוי התוכניות אינו מבחין ביניהם. המלצה להמשך, לא ל-PR הזה: לשאילתה העתידית hint בשם user_reminders_summary_idx, בתנאי שיצירת האינדקס תעבור לאותו מודול ותפסיק להיות שקטה — כי בייצור קיימים שני אינדקסים עם אותו דפוס מפתחות (user_reminders_summary_idx החלקי ו-user_status_time_idx המלא), ולכן hint לפי דפוס היה דו-משמעי. הספירה, שמכוסה, אינה צריכה כלום.

מקורות חיצוניים שקבעו את המימוש

החלטה מקור
סמנטיקת ההיטלה בסטאב (הכללה שומרת _id אלא אם _id: 0; החרגה מסירה) MongoDB Manual, "Project Fields to Return from Query"
find_one(filter, projection, sort=...) pymongo 4.15.3 המותקן, pymongo/synchronous/collection.py — החתימה לא השתנתה, ולכן הסטאב תואם
מה לחפש ב-explain (stage, totalDocsExamined, sortPattern בלי SORT) docs/database/indexing.rst
התאריך ב-explain דרך ה-MCP EJSON {"$date": ...}; אומת מהפלט עצמו — גבולות האינדקס הודפסו כ-new Date(...) ולא כמחרוזת

🧪 בדיקות

  • Unit
  • Integration
  • Manual

כל טסט חדש הורץ על הקוד של היום ונפל עם הערך הישן; כל תיקון עבר בדיקת מוטציה ב-worktree בסקרצ'פאד או על עותק של הסקריפט בזיכרון; הלקוח נמדד ב-Chromium 141 דרך Playwright 1.49.0. ל-CI אין Chromium (docs/testing.rst), ולכן הראיה לטסטי הדפדפן היא הפלט המקומי שכאן.

שרת (unittest, Flask test client, הסטאב):

טסט על הקוד של היום על התיקון
בשלה ואין עתידית next_in_seconds הוא None (None != 300) 300
בשלה ועתידית בעוד שתי דקות None (unexpectedly None) כ-120, פחות מ-300
בשלה ועתידית בעוד 45 דקות None 300 — הריענון גובר
next בתשובה קיים ('next' unexpectedly found) אינו קיים, count_due 1

מוטציות (ב-worktree, עם הקובץ המתוקן): הענף מחזיר None כמו קודם ← שלושת טסטי הבשלה נופלים; בלי ה-min, הקבוע גובר תמיד ← "עתידית בעוד שתי דקות" נופל, שני האחרים עוברים. הקובץ: 25 עברו.

דפדפן: בשלה עם next_in_seconds=300 ← הטיימר [300000] והבועה מוצגת; על הלקוח של היום: [1800000] (assert [1800000] == [300000]). בקרה: מוטציה שמחזירה את הענף ל-return MAX_POLL_MS ← [1800000]. הטסטים הקיימים עם _DUE (בלי next_in_seconds) ממשיכים לצפות לתקרה — זו תאימות לשרת ישן, ולא שינוי בהם.

  • ארבעת הקבצים הישירים (שרת, דפדפן, מקור, השער): 87 עברו. רגרסיה: 37 הקבצים שנוגעים ב-base.html או בסטיקי יחד עם test_browser_suite_is_gated_once — 1325 עברו, 45 דולגו, אפס נפלו.
  • flake8 בבוררי ה-CI החוסמים — נקי. ב-pre-commit (120): טסטי הדפדפן 0; ב-webapp/sticky_notes_api.py 15 ממצאים, אותם 15 בדיוק ב-main, אף אחד בשורות שנגעתי בהן. ל-JS אין לינטר ב-CI. לא הורץ Prettier על התבנית.
  • מה שלא אימתתי, ומראש: ריבוי מכשירים אמיתי — מדומה בשרת דרך שינוי המסד בין דגימות ובדפדפן דרך ה-harness; explain על נתוני הייצור של היום (23 מסמכים, ותוצאות ריקות למשתמש שלי) אינו מנבא את בחירת המתכנן בנפח גדול — וזו הסיבה שלא הוסף hint על סמך המדידה; בניית RTD — פרוזה בעמודים קיימים, בלי כותרות ובלי עוגנים חדשים, ה-check על ה-PR בונה.

🧪 בדיקות נדרשות ב‑PR

  • 🔍 Code Quality & Security
  • Unit Tests (3.11)
  • Unit Tests (3.12)

📝 סוג שינוי

  • fix: תיקון באג
  • test: הוספת/עדכון בדיקות

✅ צ'קליסט

  • בדיקות רצות ועוברות
  • תיעוד עודכן
  • אין סודות/מפתחות בקוד
  • אין מחיקות מסוכנות
  • הודעת הקומיט תואמת Conventional Commits
  • עיינתי במסמכי אתר התיעוד — נתיב: docs/database/indexing.rst | המשפט: "sortPattern: וודאו שהמיון נתמך ע"י האינדקס (ללא SORT נוסף)" — זה מה שנמדד בטבלת ה-explain. וגם: AI-MAP.md בתחילת התכנון, docs/dev/sticky_notes_extending.rst (החוזה של הדגימה — עודכן במשפט אחד), docs/performance-sticky-notes.rst (מי יוצר אינדקסים ומתי — הבסיס להחלטה נגד hint), docs/webapp/api-reference.rst (עודכן), docs/testing.rst. docs/webapp/theming_and_css.rst — לא נקרא, במכוון: אין CSS בשינוי.

תיעוד שעודכן: docs/dev/sticky_notes_extending.rst — משפט אחד בפסקת הדגימה (כשיש בועה השרת עונה לכל היותר חמש דקות), בלי כותרת ובלי עוגן חדש; docs/webapp/api-reference.rst — תיאור הנתיב ודוגמת התשובה בלי next ועם next_in_seconds; webapp/USER_GUIDE.md — השורה על הנתיב; ה-docstring של reminders_summary — החוזה החדש, והמשפט "הלקוח נרדם עד הניווט הבא" (שהיה שגוי, SUGG-012) הוחלף ב"עד התקרה, חצי שעה".

🧩 השפעות/סיכונים

שינויי התנהגות מכוונים: בזמן שבועה מוצגת טאב דוגם לכל היותר כל חמש דקות במקום כל חצי שעה — עד 12 בקשות בשעה לטאב במצב הזה, שנגמר בפעולת משתמש; מגבלת הקצב של הנתיב (300 לדקה למשתמש) רחוקה מזה. השדה next נעלם מתשובת ה-API — אין לו צרכן, וה-api-reference מעודכן. סדר דיפלוי: לקוח ישן מול שרת חדש מתעלם מ-next_in_seconds כשיש בועה ומתנהג כמו היום; לקוח חדש מול שרת ישן מקבל null וחוזר לתקרה — גם הוא כמו היום.

סטיות מהתוכנית שאישרת: אין. שתי החלטות שאפשר לשנות במילה: BADGE_REFRESH_SECONDS = 300, ו-min עם העתידית ולא הקבוע לבדו.

מה שנשאר פתוח לפי התוכנית: שלב 4 (WARN-008, WARN-009, WARN-005); שלב 5 (WARN-001, WARN-010, WARN-012, ה-SUGG-ים, ובהם SUGG-002 — math.ceil ב-seconds_until, שמשפיע גם על הערכים שהשרת מחזיר כאן; SUGG-011 — המדריך למשתמש עדיין אינו מציין את זמני ההמתנה). ההמלצה על hint (למעלה) — לשלב 5 או ל-PR נפרד, יחד עם יצירת האינדקס באותו מודול.

🔗 קישורים

🧯 סיכון / החזרה לאחור (Rollback)

Revert של הקומיט היחיד מחזיר את הכל, כולל השדה next בתשובה. אין מיגרציה, אין שינוי באינדקסים ואין שינוי בסכימה.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YNRfYgfyQFv3Gk9UuXDvFx


Generated by Claude Code

Review in cubic

Summary by Sourcery

Keep sticky reminder indicators synchronized across devices by using server-directed polling even while a reminder bubble is visible.

Bug Fixes:

  • Refresh the sticky-reminder indicator within five minutes when a reminder is displayed, while polling sooner when another reminder is due.
  • Remove the unused next object from the reminders summary API and eliminate the associated inconsistent query.
  • Make the test database stub apply MongoDB-compatible projections so tests validate production field selection.

Enhancements:

  • Consolidate client polling-delay handling around the server-provided next_in_seconds value with backward-compatible fallback behavior.

Documentation:

  • Update the reminders API and extension documentation to describe the revised polling response and removal of next.

Tests:

  • Add backend coverage for refresh timing with due and upcoming reminders, API shape changes, and projection semantics.
  • Add browser coverage confirming that displayed reminders use the server-provided refresh interval.

… שלו, והסטאב מחיל היטלה

שלב 3 בתוכנית התיקונים שאחרי הסקירה של #3430: WARN-004, WARN-011,
YAGNI-001, ואיתם SUGG-001 (מדידה) ו-SUGG-008.

WARN-004: כשיש תזכורת בשלה הלקוח נרדם לתקרה, חצי שעה, ובועה שנוקתה ממכשיר
אחר או מונה שהשתנה חיכו עד אז. עכשיו next_in_seconds מחושב בשני המצבים,
וכשיש בועה הוא נחתך ב-BADGE_REFRESH_SECONDS (חמש דקות, המרווח הקבוע הישן)
או מוקדם יותר כשתזכורת נוספת מבשילה. הלקוח משתמש באותו חישוב בשני הענפים
(requestedDelay), ו-null עדיין מתורגם לתקרה, כך ששרת ישן באמצע דיפלוי
אינו משנה התנהגות.

YAGNI-001: האובייקט next ירד מהתשובה יחד עם ה-find_one וההיטלה שבנו אותו,
כי הצרכן היחיד (base.html) לא קרא אותו מעולם. WARN-011: אחרי ההסרה
has_due ו-count_due נגזרים מהספירה בלבד, וה-find_one שנשאר שואל על
העתיד, ולכן שתי התשובות אינן יכולות לשלוח בועה בלי תזכורת מאחוריה. בלי
aggregate ובלי hint: אינדקס חסר היה הופך hint בשם ל-500 על נתיב שכל טאב
מחובר דוגם.

SUGG-008: הסטאב בטסטים מחיל היטלה כמו מונגו במקום לזרוק אותה. הראיה:
היטלה שבורה בייצור עברה את הסוויטה עם הסטאב הישן ונופלת עם החדש.

SUGG-001: explain לפני ואחרי מול הייצור. הספירה מכוסה על
user_reminders_summary_idx; השאילתה העתידית עדיין בוחרת remind_at_idx עם
FETCH שמסנן user_id, וצורתה אינה משתנה בקומיט הזה. המלצה להמשך בתיאור
ה-PR.

תיעוד: docs/dev/sticky_notes_extending.rst, docs/webapp/api-reference.rst,
webapp/USER_GUIDE.md, וה-docstring של הנתיב (המשפט "נרדם עד הניווט הבא"
הוחלף, חפיפה עם SUGG-012).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YNRfYgfyQFv3Gk9UuXDvFx
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@sourcery-ai

sourcery-ai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer's Guide

The PR changes sticky-reminder polling to use a server-provided refresh deadline in both badge-visible and badge-hidden states, caps visible-badge polling at five minutes, removes the unused next payload and query, makes the test stub honor MongoDB projections, and updates regression tests and documentation accordingly.

Sequence diagram for server-directed sticky reminder polling

sequenceDiagram
    participant Browser
    participant API as reminders_summary
    participant DB as note_reminders

    Browser->>API: GET /reminders/summary
    API->>DB: count_documents(due_filter)
    DB-->>API: count_due
    API->>DB: find_one(upcoming_filter, projection, sort)
    DB-->>API: upcoming remind_at
    alt has_due
        API-->>Browser: has_due, count_due, next_in_seconds = min(300, seconds_until(upcoming))
    else no due reminder
        API-->>Browser: has_due, count_due, next_in_seconds
    end
    Browser->>Browser: requestedDelay(j)
    Browser->>Browser: schedule(delay)
Loading

File-Level Changes

Change Details Files
Update reminder polling so the server schedules the next refresh even while the reminder badge is visible.
  • Added a five-minute badge refresh cap, further reduced when the next future reminder matures sooner.
  • Always query the nearest future reminder and return its delay; centralized client delay handling with legacy-server fallback to the maximum interval.
  • Removed the unused next response object and its due-reminder query.
webapp/sticky_notes_api.py
webapp/templates/base.html
Align the test database stub with MongoDB projection behavior.
  • Implemented inclusion and exclusion projections, including MongoDB’s _id handling.
  • Applied projections after sorting and limiting for both find_one and cursor iteration.
tests/test_sticky_note_reminders.py
Expand regression coverage for the revised API contract and polling behavior.
  • Added backend tests for visible-badge refresh timing, earlier future maturities, the five-minute cap, and removal of next.
  • Added browser coverage proving the client uses the server-provided delay and mutation coverage for the old thirty-minute behavior.
  • Updated fixtures and expectations to remove next.
tests/test_sticky_note_reminders.py
tests/test_sticky_reminders_polling_browser.py
Update documentation to describe the new response fields and polling contract.
  • Documented count_due and next_in_seconds while removing next.
  • Clarified that visible badges refresh within five minutes and retained the legacy fallback behavior.
docs/dev/sticky_notes_extending.rst
docs/webapp/api-reference.rst
webapp/USER_GUIDE.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 22 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 8844a3c4-cd35-4a85-beed-d66740deea2d

📥 Commits

Reviewing files that changed from the base of the PR and between e004530 and 7858495.

📒 Files selected for processing (7)
  • docs/dev/sticky_notes_extending.rst
  • docs/webapp/api-reference.rst
  • tests/test_sticky_note_reminders.py
  • tests/test_sticky_reminders_polling_browser.py
  • webapp/USER_GUIDE.md
  • webapp/sticky_notes_api.py
  • webapp/templates/base.html

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

🧯 Dangerous deletes guard report

Policy: see .cursorrules — dangerous deletions are blocked unless wrapped safely.

Summary:

  • Flagged findings (blocking): 0
    0
  • Excluded matches (not blocking): 15
  • Total matches (all files): 128

Flagged findings (file:line:snippet):
(none)

Excluded matches (by path pattern)
./webapp/static/js/md_preview.bundle.js.map:4:  "sourcesContent": ["// Markdown-it plugin to render GitHub-style task lists; see\n//\n// https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments\n// https://github.com/blog/1825-t … [truncated]
./docs/DOCUMENTATION_GUIDE.md:453:rm -rf _build
./docs/Makefile:24:	rm -rf $(BUILDDIR)
./Dockerfile:42:    rm -rf /var/lib/apt/lists/*
./Dockerfile:121:    rm -rf /var/lib/apt/lists/*
./node_modules/katex/package.json:153:    "build": "rimraf dist/ && mkdirp dist && cp README.md dist && rollup -c --failAfterWarnings && webpack && node update-sri.js package dist/README.md",
./node_modules/katex/src/fonts/Makefile:139:	rm -rf pfa ff otf ttf woff woff2
./node_modules/mermaid/dist/mermaid.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values for tr … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm/chunk-2M32CCKP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence d … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequen … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs:1:var r={name:"mermaid",version:"11.12.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graph … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.core/chunk-KS23V3DP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence  … [truncated]
./node_modules/mermaid/dist/mermaid.min.js:1524:`,"getStyles"),c1e=RQe});var h1e={};dr(h1e,{diagram:()=>NQe});var NQe,f1e=N(()=>{"use strict";$ge();a1e();l1e();u1e();NQe={parser:Fge,db:n1e,renderer:o1e,styles:c1e}});var m1e,g1e=N(()=>{"use  … [truncated]
./node_modules/mermaid/dist/mermaid.min.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values fo … [truncated]
./README.md:842:find . -name "__pycache__" -exec rm -rf {} +

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="tests/test_sticky_note_reminders.py" line_range="60-63" />
<code_context>
     return True


+def _project(doc, projection):
+    """מחיל היטלה כמו מונגו, במקום לזרוק אותה.
+
+    הכללה (``{f: 1}``) שומרת את השדות שנקבו ואת ``_id`` אלא אם ``_id: 0``;
+    החרגה (``{f: 0}``) מסירה את השדות שנקבו. בלי היטלה חוזר המסמך עצמו.
</code_context>
<issue_to_address>
**nitpick (testing):** `_project({'_id': 1})` returns the full document instead of only `_id`: `include` is empty, so the helper falls through to exclusion mode with no excluded fields. The test stub therefore does not implement MongoDB inclusion projection semantics for an `_id`-only projection and can let projection bugs pass.

**Triggers:** When a test exercises an inclusion projection containing only `_id`.

**Suggested fix:** Treat any projection containing inclusion fields, including `_id`, as inclusion mode; return only the requested fields and retain `_id` according to the explicit `_id` projection.

```suggestion
    include = {k for k, v in projection.items() if v}
    if include:
        keep = include | ({'_id'} if projection.get('_id', 1) else set())
        return {k: v for k, v in doc.items() if k in keep}
```
</issue_to_address>

Sourcery assessment

Approved.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread tests/test_sticky_note_reminders.py Outdated
@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

⏱️ Performance report

(No performance test durations collected. Mark tests with @pytest.mark.performance.)

@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

📖 Documentation Preview

The documentation has been built successfully!

To view locally:

  1. Download the artifacts
  2. Extract the zip file
  3. Open index.html in your browser

@codecov

codecov Bot commented Sep 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

claude and others added 2 commits September 21, 2026 04:15
ממצא בסקירה של #3444: היטלה של _id בלבד החזירה בסטאב את המסמך המלא, כי
מצב ההכללה נקבע רק לפי שדות שאינם _id. נמדד מול MongoDB 8.0.32 בייצור:
{_id: 1} מחזיר רק _id; {_id: 1, f: 0} הוא החרגה (_id הוא היוצא מן הכלל
היחיד לאיסור על ערבוב); {_id: 0} מחזיר את כל השאר. התיקון המוצע בסקירה
היה שולח את המקרה השני להכללה, ולכן הכלל ממומש במלואו ולא הקיצור.
טסט יחידה לעוזר עם חמשת המקרים: על הקוד הישן נופל {_id: 1}, ועל הקיצור
המוצע נופל {_id: 1, f: 0}.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YNRfYgfyQFv3Gk9UuXDvFx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants