Repository navigation
feat: חיפוש בפתקים בוובאפ — שם, תוכן, וסינון לפי צבע - #3408
Conversation
עמוד /notes/search שמחפש בכל הפתקים של המשתמש יחד — לוח, קובץ, וקובץ בריפו. מגיעים אליו מעמוד הקבצים ומהגדרות הלוח. ההתאמה משותפת עם ה-MCP: שני הצרכנים עוברים דרך note_search_filter, ונבדלים רק במה שהם מציגים. $text נבחן ונפסל — מדידה על פתקים אמיתיים בעברית הראתה שהוא מפספס כ-18% מההתאמות שהרג'קס מוצא, כי הוא מתאים טוקנים שלמים ומתעלם מגזירת סיומות. ההדגשה נעשית בצד הלקוח מצמתי DOM ולא ממחרוזות HTML, והשרת אינו שולח היסטים: הוא סופר תווים, מונגו נקודות-קוד ו-JS יחידות UTF-16, וערבוב היחידות האלה הוא הבאג שהפיל את חיפוש הקוד. החיתוך ל-200 תווים הוא $substrCP, לעולם לא $substrBytes. נוסף אינדקס (user_id, updated_at): explain על החיפוש שכבר רץ ב-MCP הראה שמונגו בוחרת ב-updated_desc וסורקת את הפתקים של כל המשתמשים. דגל המוכנוּת קודם ל-v4 בהתאם, והבדיקה נועלת את השניים יחד. סינון הצבע עובר דרך note_color_query — מזהה ורג'קס מעוגן חסר-רישיות בתוך $in — כי במסד 176 פתקים שמורים כ-#FFFFCC בעוד שהפלטה מחזיקה #ffffcc. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PL3goRvy9ze5NrG5z68Awr
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Sorry @amirbiron, you've used your own review budget of 250,000 diff characters for the last 7 days.
You can request another review in 4 days and 12 hours by commenting @sourcery-ai review. Upgrade to get a review now.
|
Warning Review limit reachedNext included review available in 15 minutes. View limit detailsLimit 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. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (19)
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. Comment |
🧯 Dangerous deletes guard reportPolicy: see .cursorrules — dangerous deletions are blocked unless wrapped safely. Summary:
Flagged findings (file:line:snippet): Excluded matches (by path pattern) |
Reviewer's GuideThis PR adds a user-facing Hebrew-aware notes search page and API spanning boards, files, and repository notes, reusing the MCP’s matching filter while adding color filtering, safe previews/highlighting, ranking, limits, and ownership checks; it also introduces a compound performance index, synchronized MCP/webapp initialization, navigation entry points, tests, and documentation. Sequence diagram for webapp notes search with color filteringsequenceDiagram
actor User
participant Page as Notes search page
participant API as GET /api/sticky-notes/search
participant Filter as note_search_filter
participant DB as sticky_notes
User->>Page: Submit query and optional color
Page->>API: Fetch q and color
API->>API: _search_limit
API->>Filter: note_search_filter(user_id, needle, color_id)
Filter-->>API: User, text, and color predicates
API->>DB: aggregate(build_note_search_pipeline)
DB-->>API: Ranked preview results plus sentinel row
API-->>Page: JSON results and truncated flag
Page->>Page: highlightInto
Page-->>User: Render safe highlighted results
Entity relationship diagram for notes search ownership and indexingerDiagram
USER ||--o{ STICKY_NOTE : owns
STICKY_NOTE {
int user_id
string title
string content
string color
datetime updated_at
}
STICKY_NOTE }o--|| NOTE_TARGET : references
NOTE_TARGET {
string target
string file_name
string repo_path
}
STICKY_NOTE }o..o{ SEARCH_INDEX : optimized_by
SEARCH_INDEX {
string user_id_updated_at
}
Flow diagram for note search pipeline and result shapingflowchart TD
Request[Search request] --> Match[$match: shared note_search_filter]
Match --> AddFields[$addFields: title ranking and $substrCP preview]
AddFields --> Project[$project: remove content]
Project --> Sort[$sort: title hits then updated_at]
Sort --> Limit[$limit: requested limit plus sentinel]
Limit --> Unset[$unset ranking helper]
Unset --> Response[Safe result objects with preview only]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
⏱️ Performance report(No performance test durations collected. Mark tests with |
📖 Documentation PreviewThe documentation has been built successfully!
To view locally:
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
✨ תיאור קצר
עמוד
/notes/searchשמחפש בכל הפתקים של המשתמש יחד — לוח, קובץ, וקובץ בריפו. מגיעים אליו מעמוד הקבצים ומהגדרות הלוח. ההתאמה משותפת עם ה-MCP: שני הצרכנים עוברים דרךnote_search_filterונבדלים רק במה שהם מציגים, כך שאותה מילה מחזירה את אותם פתקים בשניהם.📦 שינויים עיקריים
פירוט:
sticky_notes_target— ל-note_search_filterנוסףcolor_idאופציונלי (מצטרף כפרדיקט עצמאי, לא כענף ב-$or); נוספוnote_color_queryו-NOTE_SEARCH_PREVIEW_CHARS.webapp/sticky_notes_api—GET /api/sticky-notes/searchעם@require_authו-@notes_rate_limit, תקרה ל-limit, ו-build_note_search_pipeline.webapp/routes/notes_search.py— בלופרינט חדש לעמוד עצמו (HTML בלבד, בתבניתboards_ui).(user_id, updated_at)— בוובאפ וב-MCP, עם קידום_INDEX_READY_CACHE_KEY.שלוש החלטות שנגזרו ממדידה, לא מהיגיון
$textנבחן ונפסל. אינדקס טקסט הוא הפתרון המתבקש, אבל מדידה על פתקים אמיתיים בעברית הראתה שהוא מפספס כ-18% מההתאמות שהרג'קס מוצא: חיפוש "שימוש" החזיר 2 פתקים מתוך 27. הסיבה מתועדת ולא באג —$textמתאים טוקנים שלמים ומתעלם מגזירת סיומות, ולכן "פתק" אינו מוצא "בפתק". רג'קס תת-מחרוזת מוצא את שניהם. מונגו מתירה אינדקס טקסט אחד לכל אוסף, כלומר זו החלטה שקשה לחזור ממנה — ולכן היא מתועדת ב-docs/dev/sticky_notes_extending.האינדקס
(user_id, updated_at)מתקן בעיה שכבר קיימת. הדוקסטרינג שלnote_search_filterטען ש-user_idכפרדיקט ראשון חוסם את הסריקה למכסת המשתמש "ואינו COLLSCAN".explainעל השאילתה האמיתית הראה שהתוכנית הזוכה בוחרת ב-updated_desc— כלומר החיפוש שרץ היום ב-MCP סורק את הפתקים של כל המשתמשים. הדוקסטרינג תוקן לתאר את מה שנמדד.סינון הצבע צריך את שתי הצורות. במסד 176 פתקים שמורים כ-
#FFFFCCבאותיות גדולות בעוד שהפלטה מחזיקה#ffffcc— כלומר סינון שמשווה למזהה בלבד היה מחזיר אפס, בלי שגיאה.note_color_queryמחזירה$inשל המזהה ורג'קס מעוגן חסר-רישיות. הרג'קס יורד בעריכה אחת אחרי ש-scripts/migrate_note_colors.py --applyרץ בכל הסביבות.עברית, ולמה ההדגשה בצד הלקוח
חיתוך התצוגה המקדימה הוא
$substrCPולעולם לא$substrBytes— אות עברית היא שני בייטים, וחיתוך בבייטים על מספר שנספר בתווים מפיל את השאילתה (Location28657). מאותה סיבה השרת אינו שולח היסטים: הוא סופר תווים, מונגו נקודות-קוד ו-JS יחידות UTF-16. ההתאמה נעשית על 200 התווים שכבר הגיעו.ההדגשה בנויה מצמתי DOM (
createElement+textContent) ולא ממחרוזות HTML, ולכן אין ב-notes_search.jsשוםinnerHTML.🧪 בדיקות
כל בדיקה מומתה. 18 מוטציות בפייתון ו-5 ב-JS, וכל אחת הפילה את הבדיקה שלה: הסרת הדירוג מהמיון, הסרת ה-
$project, הזזתו אחרי ה-$sort, החלפת$substrCPב-$substrBytes, הסרתuser_id, שוויון במקום$in, רג'קס בליi, הסרתre.escape, הסרת$ifNull, הסרת התקרה, הסרת שורת הסנטינל, ו-textContentשהופך ל-innerHTML.שתי מוטציות חשפו חורים בבדיקות שלי עצמי ותוקנו: בדיקת המדידה בבייטים עברה על קוד שבור כי הפתק שנבחר היה קצר מ-200 גם בבייטים — הוחלף בפתק של 150 תווים (270 בייטים), שיושב בין שתי היחידות. ומוטציה שנייה לא הוחלה בכלל כי הדפוס הופיע פעמיים בקובץ.
מדידה בדפדפן (Chromium אמיתי, 1024 ו-390): אין שגיאות דף; הרמז "המילה מופיעה בהמשך הפתק" מופיע בדיוק כשאין התאמה בכותרת ואין בתקציר; מטען
<img onerror>ומרכאות מופיעים כטקסט ולא נוצר מהם אלמנט; עיגולי הפלטה נדגמו בפיקסלים והחזירו בדיוק את גווניNOTE_COLORS; אין גלילה אופקית; הטקסט בתוך ההדגשה 10.57:1 מול רקע ההדגשה.מה שלא נמדד, ונאמר במפורש: ניגודיות ההדגשה מול רקע הכרטיס אינה קבועה כאן. הגרסה הראשונה של הדוח נקבה ב-3.35:1, והמספר הזה היה שגוי — הפיקסל נדגם בפינת הכרטיס, ושם ה-
border-radiusחושף את רקע העמוד, כך שנמדדה הדגשה מול העמוד ולא מול הכרטיס. הוא הוסר ולא הוחלף.בנוסף, התנהגות העמוד בערכות מיובאות נבדקה חלקית בלבד. מה שכן אומת: הטוקנים של ערכה מיובאת חלים על הכרטיס כמצופה (
--card-bgנקרא נכון), וניגודיות הכותרת גבוהה בשלוש הערכות שבשימוש. מה שלא הושלם: ניגודיות שורת התקציר, שנשענת על--text-secondary.[data-theme="custom"] aשב-dark-mode.cssצובע כל<a>ב---primaryומנצח בספציפיות את המחלקה של הכרטיס — אותו דפוס שכבר קיבל וו דריסה ייעודי באוספים ובהצעות החיפוש. אם יידרש, זה תיקון ממוקד בעקבות שימוש ולא חוסם מיזוג.שלוש בדיקות קיימות נפלו על השינוי ותוקנו בשורש — כולן נעלו ספירה או רשימת שמות שמתיישנת. במקום להוסיף שם לרשימה, כל אחת נוסחה מחדש לבטא את החוק עצמו: גרסת המפתח נעולה יחד עם קבוצת האינדקסים שהיא מעידה עליהם; המפרטים ב-MCP נגזרים מהמפרט של הוובאפ במקום להיכתב שוב; והקבוצה הצפויה בבדיקת המקביליות נגזרת מריצה סדרתית.
🧪 בדיקות נדרשות ב‑PR
📝 סוג שינוי
✅ צ'קליסט
rg "#[0-9a-fA-F]{3,6}"עלnotes-search.cssמחזירה ריקdocs/webapp/theming_and_css.rst| המשפט: "Sticky Notes, Reader Modes ו-theme_preview.html נשארים Hardcoded בכוונה לצורכי Preset/Brand"docs/dev/sticky_notes_extending.rst,docs/performance-sticky-notes.rst,docs/database/indexing.rst,docs/webapp/commands-catalog.rst(ממנו נגזרה הדרישה שהמזהים בעמוד לא יהיוglobalSearchInput/searchBtn, כיglobal_search.jsנטען בכל עמוד ומתחבר לכל דף שמכיל את שניהם)🧩 השפעות/סיכונים
הרשאות: העמוד מחזיר את הפתקים של המשתמש בכל שלושת הסוגים, בדיוק כמו
codekeeper_search_notes— שאינו מגודר לאדמין. הפער בין הגייטים של פתקי ריפו ב-MCP ובוובאפ מדווח בנפרד ב-#3407 ולא שונה כאן.אינדקס: נוסף אינדקס אחד לאוסף שכבר נושא אחד-עשר. הבנייה best-effort ואינה מפילה בקשה.
_INDEX_READY_CACHE_KEYקודם ל-v4, ולכן תהליכים שמחזיקים דגלv3חי ייבנו מחדש בפריסה.מיגרציה:
scripts/migrate_note_colors.py --applyלא הורץ כאן, וסינון הצבע עובד גם בלעדיו. הרצתו מיישרת את המסד ומאפשרת לפשט אתnote_color_queryבהמשך.ערכות מיובאות: ראו את סעיף הבדיקות — ייתכן שיידרש וו דריסה לצבע הטקסט בכרטיס, בתבנית שכבר קיימת ב-
collections.cssוב-global_search.css.🔗 קישורים
global_search.js), פתקי ריפו: ה-API בוובאפ פתוח לכל משתמש מחובר, בעוד שב-MCP אותן פעולות מגודרות לאדמין #3407 (גייט פתקי ריפו)🧯 סיכון / החזרה לאחור (Rollback)
השינוי אדיטיבי: אף מסלול קיים לא שינה התנהגות.
note_search_filterקיבל פרמטר עם ברירת מחדל שמשמרת את ההתנהגות הקודמת, ושאר השינויים הם קבצים חדשים או תוספות. Revert מסיר את העמוד ואת נקודות הכניסה; האינדקס נשאר במסד ואינו מזיק (הוא עוזר גם לחיפוש של ה-MCP).🤖 Generated with Claude Code
https://claude.ai/code/session_01PL3goRvy9ze5NrG5z68Awr