Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AI-MAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
- `docs/quickstart-contrib.rst` — **Quickstart לתרומה**: דף קצר שמאפשר להתחיל לתרום במהירות ובבטחה.
- `docs/ai-guidelines.rst` — **הנחיות מלאות לסוכני AI**: ההנחיות המלאות לסוכני AI שעובדים בריפו: המגבלות הקריטיות, איך מריצים פקודות, אילו כלי קבצים מאושרים, עקרונות עריכת קוד, ומדיניות הקומיטים וה-Pull Requests.
- `docs/agents/rate-limiting.md` — **🚦 מערכת Rate Limiting לסוכני AI ולווב**: מטרה: להסביר איך מפעילים ומנטרים Rate Limiting בבוט ובווב, עם דגש על Shadow Mode, ניטור וקונפיג.
- `docs/doc-authoring.rst` — **Doc Authoring Guide (Sphinx/RTD)**: כללי כתיבת תיעוד בפרויקט — הצהרת תקציר בראש כל עמוד, הטמעת קוד לפי שם או סימון ולא לפי מספרי שורות, ובנייה ללא אזהרות.
- `docs/doc-authoring.rst` — **Doc Authoring Guide (Sphinx/RTD)**: כללי כתיבת תיעוד בפרויקט — הצהרת תקציר בראש כל עמוד, הטמעת קוד לפי שם או סימון ולא לפי מספרי שורות, ההבחנה בין ספירת מופעים לערך שנאכף, ובנייה ללא אזהרות.
- `docs/style-glossary.rst` — **Style & Naming Glossary**: מילון המונחים והשמות בפרויקט: מיפוי בין מונחים מקבילים, כללי הניסוח, ועוגני התיעוד שמפנים אליהם.
- `docs/versioning-stable-anchors.rst` — **Versioning & Stable Anchors**: מדיניות הגרסאות והעוגנים היציבים בתיעוד: אילו עוגנים מובטחים לא להישבר, איך מתעדים שינוי ב-What's New, ודוגמאות.
- `docs/whats-new.rst` — **What's New**: יומן השינויים של הבוט וה-WebApp לפי תאריך — מה נוסף, מה השתנה ומה תוקן בכל עדכון, עם קישורים ל-Issues הרלוונטיים.
- `docs/architecture.rst` — **ארכיטקטורה**: המערכת מורכבת מבוט Telegram, שכבת שירותים (services), שכבת נתונים (MongoDB) ואפליקציית Web. הזרימה העיקרית: Handlers → Services → Database.
- `docs/architecture/clean-architecture.rst` — **Clean Architecture ב-src**: ארכיטקטורה זו מפרידה בין לוגיקה עסקית, תזמור יישומי ותשתיות כך שניתן לבדוק יחידות קוד בנפרד, להחליף מקורות נתונים בלי לשבור את שאר המערכת ולרוץ גם בסביבות ללא MongoDB.
- `docs/dev/sticky_notes_extending.rst` — **עקרונות להוספת פיצ'ר לסטיקי-נוטס**: המלכודות החוזרות של הפתקים הדביקים: יעד יחיד ב-build_note_target, מכסה fail-closed והפטור-לאדמין שהורג מכסות, flush לפני פעולה הרסנית, אינדקס ממוספר שנבנה לפני שמפילים, נורמליזציה בשני הקצוות, ויתומים בקריאה.
- `docs/dev/sticky_notes_extending.rst` — **עקרונות להוספת פיצ'ר לסטיקי-נוטס**: המלכודות החוזרות של הפתקים הדביקים: יעד יחיד ב-build_note_target, מכסה fail-closed והפטור-לאדמין, flush לפני פעולה הרסנית, אינדקס ממוספר שנבנה לפני שמפילים, נורמליזציה בשני הקצוות, יתומים בקריאה, ועדכון עמוד המשתמש.
- `docs/contributing.rst` — **מדריך תרומה**: לתת מסלול ברור לתרומות קוד, עם דגש על סוכני AI ו-CI.
- `docs/branch-protection-and-pr-rules.rst` — **Branch Protection & PR Rules**: לרכז נהלים ברורים להגנה על ענפים (Branch Protection) ולחוקי PR בפרויקט.

Expand Down
20 changes: 19 additions & 1 deletion docs/dev/sticky_notes_extending.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
עקרונות להוספת פיצ'ר לסטיקי-נוטס
==================================
:summary: המלכודות החוזרות של הפתקים הדביקים: יעד יחיד ב-build_note_target, מכסה fail-closed והפטור-לאדמין שהורג מכסות, flush לפני פעולה הרסנית, אינדקס ממוספר שנבנה לפני שמפילים, נורמליזציה בשני הקצוות, ויתומים בקריאה.
:summary: המלכודות החוזרות של הפתקים הדביקים: יעד יחיד ב-build_note_target, מכסה fail-closed והפטור-לאדמין, flush לפני פעולה הרסנית, אינדקס ממוספר שנבנה לפני שמפילים, נורמליזציה בשני הקצוות, יתומים בקריאה, ועדכון עמוד המשתמש.

הפיצ'ר של הפתקים הדביקים צובר משטחים לאורך זמן — קובץ ב-CodeKeeper ← לוח ← רינדור מארקדאון ← קובץ בריפו ממורר. כל תוספת כזו נוטה לגלות מחדש את אותן מלכודות, כי הן אינן בקוד של פיצ'ר בודד אלא בחוזה המשותף. העמוד הזה מרכז אותן, כדי שהפיצ'ר הבא (או סוכן AI שממש אותו) יקרא אותן פעם אחת במקום לגלות אותן שוב בפרודקשן.

Expand Down Expand Up @@ -72,6 +72,10 @@
-------------------------------------------------------
**טקסט של משתמש או של סוכן לעולם אינו נכתב דרך HTML גולמי.** כל צומת שנושא תוכן כזה נבנה עם ``createElement`` ו-``textContent``, ותכונות של קישור נכתבות עם ``setAttribute`` אחרי אימות סכימה. לכן זריקת ``<script>`` מוצגת כטקסט, ואל תכניסו ספריית מארקדאון שפולטת מחרוזת HTML. תבנית סטטית לגמרי, בלי שום קלט משתמש (למשל שלד מודאל התזכורת), מותרת דרך ``innerHTML`` — הגבול הוא הקלט, לא ה-API. הכלל המוחלט הוא על **טקסט לא-מהימן**, לא על השיטה.

עיגון שורה בפתקי ריפו: למה ``anchored`` אינו זמין
--------------------------------------------------
``anchored`` מחייב עוגן שורה יציב. דפדפן הריפו משתמש ב-CodeMirror, שמרנדר רק את השורות שבתחום הנראה; לכן אין אלמנט DOM יציב שאפשר להיקשר אליו עבור שורה מחוץ למסך. פתקי ריפו תומכים רק ב-``surface`` וב-``screen``. תיאור ההתנהגות למשתמש נמצא ב-:doc:`/user/sticky_notes`.

סדר: ``flush`` לפני כל פעולה הרסנית
-----------------------------------
תור השמירה עובד עם ``debounce``, ולכן עריכה שנעשתה זה עתה עדיין ממתינה בו. כל פעולה שעלולה למחוק את התור — פירוק המנהל בהחלפת יעד, סימון צ'קבוקס שמפעיל כתיבה משלו — חייבת **לרוקן את התור תחילה**. אחרת העריכה האחרונה נעלמת בלי שום סימן. זו תקלת סדר שכבר נתפסה כאן פעמיים (``_flushFor`` לפני ה-toggle; ``destroy`` שמרוקן לפני שהוא מפרק).
Expand All @@ -85,3 +89,17 @@
- **מודל טהור** (יעד, נורמליזציה, מכסה): טסטי יחידה, בלי מסד. כל טסט חדש נבדק במוטציה — ביטול התיקון חייב להפילו.
- **אינדקס ייחודי ופילטר חלקי**: מול מונגו אמיתי בלבד. סטאב מחזיר ``None`` מ-``create_index`` וכל בדיקת כפילות עוברת בו, גם אם האינדקס מעולם לא נוצר.
- **חיווט הלקוח** (הרכבה, שמירה, החלפת יעד): מול דפדפן אמיתי. השוואת מחרוזות אינה מוכיחה שהפתק באמת נשמר ונטען.

התיעוד למשתמש הוא חלק מהפיצ'ר
------------------------------

.. important::
**כל פיצ'ר חדש בפתקים, וכל שינוי בהתנהגות קיימת, מעדכן את** :doc:`/user/sticky_notes` **באותו PR.**

העמוד הזה מתאר **איך** לבנות — מלכודות, חוזים בין שכבות, מה לבדוק ובמה. העמוד למשתמש מתאר **מה קורה** — מה רואים, מה ברירת המחדל, איפה יש מתג ואיפה אין. שינוי בהתנהגות שייך לשם, גם כשהוא נראה קטן.

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

**בלי כפילות בין שני העמודים.** עובדה שכתובה בשניהם מתיישנת באחד מהם, ואז שניהם אומרים דברים שונים על אותו קוד. הכלל הוא הפרדה לפי שאלה: התנהגות נראית נכתבת בעמוד המשתמש בלבד, והנימוק ההנדסי — למה זה בנוי ככה, מה נשבר בלי זה — נכתב כאן בלבד. כשצריך את שניהם, כותבים כל חצי במקומו ומקשרים ביניהם ב-``:doc:``, כפי שעמוד המשתמש כבר עושה בכל מקום שבו הוא נוגע בנימוק הנדסי.

**התיעוד אינו סמכות על הקוד.** אם בזמן העדכון מתגלה שמה שכתוב בעמוד המשתמש כבר אינו נכון — זה ממצא לתקן, לא רקע להתעלם ממנו. פסקת העיגון בפתקי ריפו שרדה כך סבב שלם אחרי שההתנהגות השתנתה תחתיה.
13 changes: 12 additions & 1 deletion docs/doc-authoring.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Doc Authoring Guide (Sphinx/RTD)
================================
:summary: כללי כתיבת תיעוד בפרויקט — הצהרת תקציר בראש כל עמוד, הטמעת קוד לפי שם או סימון ולא לפי מספרי שורות, ובנייה ללא אזהרות.
:summary: כללי כתיבת תיעוד בפרויקט — הצהרת תקציר בראש כל עמוד, הטמעת קוד לפי שם או סימון ולא לפי מספרי שורות, ההבחנה בין ספירת מופעים לערך שנאכף, ובנייה ללא אזהרות.

מטרות
------
Expand All @@ -25,6 +25,17 @@ Doc Authoring Guide (Sphinx/RTD)
- **אל תשאירו כותרת יתומה.** אם ההצהרה מחליפה פסקת פתיחה והסעיף שהכיל אותה נשאר ריק — מחקו גם את הכותרת. סעיף ריק מרונדר בעמוד כשורה ללא גוף.
- **למה הצהרה ולא חילוץ אוטומטי:** הגרסה הקודמת חילצה את פסקת הפרוזה הראשונה, וכדי לעשות זאת מימשה חלקים מ-GFM ומ-RST ביד. ארבעה סבבי ריוויו רצופים מצאו שם מקרי קצה — כולל תקציר שיצא טבלה שלמה ותקציר שיצא ריק. מי שכתב את העמוד יודע מה התקציר.

ספירות בפרוזה: ספירת מופעים לעומת ערך שנאכף
--------------------------------------------
הכלל שלמעלה אוסר ספירה **בתקציר**, אבל הסיבה אינה מוגבלת לשם: כל מספר שנכתב בפרוזה מתיישן באותה שקט. ההבחנה שמכריעה אינה איפה המספר יושב אלא **מי אחראי עליו**.

- **ספירת מופעים — אל תכתבו.** "בשתי ההפניות לעמוד הזה", "28 אייקונים", "שבעה מסלולי API". אף אחד לא שומר על המספר הזה: כל הוספה שוברת אותו, ושום בדיקה לא מתריעה. נסחו בלי כמות — "בכל מקום שבו העמוד נוגע בנימוק הנדסי" נכון גם אחרי התוספת הבאה.
- **ערך שנאכף — כן תעדו.** "20 פתקים לקובץ", "תקרה של 1000 פתקים למשתמש", "עד 500KB לקובץ". המספר הזה חי בקוד ונאכף בו, ולכן הוא אינו נסחף מעצמו — ומי שקורא את התיעוד חייב אותו. שינוי שלו הוא שינוי מוצר שממילא מחייב עדכון תיעוד.

המבחן: **אם המספר יכול להשתנות בלי שאף שורת קוד תשתנה — הוא ספירת מופעים, ואין לכתוב אותו.**

``tests/test_doc_summary_style.py`` אוכף את הכלל על תקצירים בלבד. בפרוזה אין אכיפה אוטומטית, וזה הפער שכבר נתפס כאן: הכלל הזה נוסח אחרי שריוויוור מצא ספירה שגויה בפרוזה של עמוד — בתוך סעיף שכל נושאו דיוק בתיעוד.

הטמעת קוד מהמקור (``literalinclude``)
--------------------------------------
- **אסור** למען לפי מספרי שורות (``:lines:``) — הקוד זז והתיעוד ממשיך להציג את הטווח הישן בלי שום אזהרה. זה דפוס ``line-number-coupling`` (ראו amir-bug-patterns), והוא כבר קרה כאן: בלוק שהצביע על ``main.py:739`` הציג פנימיות של פונקציה אחרת, במרחק 2,900 שורות מהיעד.
Expand Down
8 changes: 5 additions & 3 deletions docs/user/sticky_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,14 @@

עיצוב מארקדאון
~~~~~~~~~~~~~~~
מלבד צ'קבוקסים, הפתק מרנדר תת-קבוצה קלילה של מארקדאון: **מודגש** (``**``), *נטוי* (``*``), ``קוד`` בשורה, קו חוצה (``~~``), כותרות (``#`` עד ``###``), רשימות (``-``/``*``/``1.``), ציטוט (``>``), קו מפריד (``---``), קישורים (``[טקסט](כתובת)``) ובלוקי קוד (שורת גדר של שלושה תווי backtick, מעל התוכן ומתחתיו). כשהעיצוב פעיל, התצוגה נפתחת בדיוק כמו עם צ'קבוקס — כשיש בפתק מבנה מארקדאון כלשהו — ופתק של טקסט רגיל נשאר תיבת עריכה ולא משתנה. (בפתקי לוח העיצוב דלוק כברירת מחדל; בפתקי קבצים כבוי — ראו למטה.)
מלבד צ'קבוקסים, הפתק מרנדר תת-קבוצה קלילה של מארקדאון: **מודגש** (``**``), *נטוי* (``*``), ``קוד`` בשורה, קו חוצה (``~~``), כותרות (``#`` עד ``###``), רשימות (``-``/``*``/``1.``), ציטוט (``>``), קו מפריד (``---``), קישורים (``[טקסט](כתובת)``) ובלוקי קוד (שורת גדר של שלושה תווי backtick, מעל התוכן ומתחתיו). כשהעיצוב פעיל, התצוגה נפתחת בדיוק כמו עם צ'קבוקס — כשיש בפתק מבנה מארקדאון כלשהו — ופתק של טקסט רגיל נשאר תיבת עריכה ולא משתנה. (העיצוב דלוק כברירת מחדל בכל סוגי הפתקים — ראו למטה.)

.. important::
**טקסט של משתמש — או של סוכן דרך** ``codekeeper_create_note`` **— אינו יכול להפוך לתגית.** זריקת ``<script>`` מוצגת כטקסט, וקישורים נפתחים רק בסכימות ``http``/``https``. איך זה נאכף בקוד, ולמה אין כאן ספריית מארקדאון שפולטת HTML — :doc:`/dev/sticky_notes_extending`.

מה **לא** נכנס, ולמה: טבלאות (רחבות מדי לפתק), תמונות (בקשת רשת ומידות בלתי צפויות), ו-HTML גולמי (שובר את חוזה ה-``textContent``). הקו התחתון ``_`` **אינו** נטוי — ``note_id`` ו-``user_id`` נפוצים מדי בכלי שכולו קוד. קישורים נפתחים בלשונית חדשה עם ``rel="noopener noreferrer"``, ורק סכימות ``http``/``https`` — ``javascript:`` ו-``data:`` מרונדרים כטקסט, לא כקישור.

העיצוב **דלוק כברירת מחדל בלוח**, ואפשר לכבות אותו במודאל ההגדרות (גלגל השיניים); ההעדפה נשמרת מקומית לכל לוח, ורק כיבוי מפורש נשמר. כיבוי מציג את התוכן הגולמי כפי שהוקלד. **בפתקים שעל קבצים** ברירת המחדל שמרנית — כבוי — כי אין להם מתג כיבוי, וצ'קבוקסים ממשיכים לעבוד שם כרגיל.
העיצוב **דלוק כברירת מחדל בכל סוגי הפתקים** — בלוח, על קובץ ב-CodeKeeper, ועל קובץ בדפדפן הריפו. **מתג הכיבוי קיים בלוח בלבד**, במודאל ההגדרות (גלגל השיניים); ההעדפה נשמרת מקומית לכל לוח, ורק כיבוי מפורש נשמר, וכיבוי מציג את התוכן הגולמי כפי שהוקלד. בפתקים שעל קבצים אין מתג, אבל גם אין מה לכבות בפתק טקסט רגיל: התצוגה נפתחת רק כשיש בפתק מבנה מארקדאון, ופתק בלי מבנה נשאר תיבת עריכה. צ'קבוקסים עובדים בכל המקרים, בלי תלות בהגדרה.

לוחות דרך MCP
~~~~~~~~~~~~~~~
Expand All @@ -146,7 +146,9 @@

הפתק מזוהה בזוג ``(repo_name, repo_path)``, ולא במזהה יחיד. אין ענף במפתח בכוונה: פתק שנרשם כשהיית על ``main`` מופיע גם כשאתה מסתכל על ענף PR — המלכודת שייכת לקובץ, לא לענף.

**העיגון הוא ברמת קובץ, לא ברמת שורה.** תצוגת הקובץ בדפדפן הריפו היא עורך CodeMirror, שאינו מרנדר שורות שנמצאות מחוץ למסך — אין אלמנט DOM יציב להיצמד אליו. לכן שני מצבי המיקום — ``surface`` (מעוגן למסגרת התצוגה) ו-``screen`` (צמוד לחלון) — מצמידים את הפתק למסגרת הקובץ, והוא **אינו נגלל יחד עם שורות הקוד**. ``anchored`` נדחה כאן מאותה סיבה שהוא נדחה בלוח.
**הפתק נצמד למקום בתוכן, לא לשורה.** שני מצבי המיקום מתנהגים כאן שונה זה מזה: ``surface`` מודד את מיקומו מראשית **התוכן** של הקובץ, ולכן הפתק נגלל יחד עם הקוד ונשאר ליד מה שהוא מדבר עליו — וכשהוא נגלל אל מחוץ לתחום הנראה הוא נעלם מהמסך עד שגוללים אליו בחזרה. ``screen`` הוא ההפך: הפתק צמוד לחלון ונשאר גלוי בכל גלילה. המעבר בין השניים הוא כפתור 📌 שעל הפתק.

מצב ``anchored`` אינו זמין בפתקי ריפו: עורך CodeMirror אינו מרנדר שורות שמחוץ למסך, ולכן אין אלמנט DOM יציב שאפשר להיקשר אליו.

.. note::
דפדפן הריפו פתוח לאדמינים בלבד, ולכן פתקי ריפו הם פיצ'ר אדמין. בפועל: **20 פתקים לקובץ** נאכפים על כולם, אדמין כולל; התקרה הכללית של 1000 פתקים למשתמש אינה נאכפת על אדמין. למה שתי התקרות מתנהגות שונה — :doc:`/dev/sticky_notes_extending`.
Expand Down
Loading
Loading