ספריית סניפטים (Web) ====================== מה זה? ------ "ספריית סניפטים" היא גלריית קטעי קוד קצרים עם הדגשת תחביר, חיפוש וסינון. הספרייה מציגה גם סניפטים שהוגשו ע"י משתמשים (לאחר אישור אדמין), וגם סניפטים מובנים (Curated) שמסופקים כחלק מהמערכת. מאפייני UI ----------- - רשימה מתקפלת: כל פריט מוצג ככותרת נפתחת (``
``/````). לחיצה פותחת את הקוד. - הדגשת תחביר: Highlight.js נטען דינמית ומדגיש קוד בעת פתיחת הפריט. - קרדיט מחבר: מוצג "נוסף על ידי @username" (אם קיים) לצד השפה של הסניפט. API – JSON ----------- נתיב: ``GET /api/snippets`` פרמטרים: - ``q`` – חיפוש חופשי בכותרת/תיאור/קוד (אופציונלי) - ``language`` – סינון לפי שפה (אופציונלי) - ``page`` – עמוד (ברירת מחדל: 1) - ``per_page`` – גודל עמוד (ברירת מחדל: 30, מקסימום: 60) תגובה (דוגמה): .. code-block:: json { "ok": true, "items": [ { "title": "זמן יחסי בעברית (TimeUtils.format_relative_time)", "description": "פורמט זמן יחסי בעברית (לפני X דקות/אתמול).", "code": "...", "language": "python", "username": "CodeBot", "approved_at": "2025-11-10T13:37:00+00:00" } ], "page": 1, "per_page": 30, "total": 42 } OpenAPI (תקציר) ~~~~~~~~~~~~~~~~ .. code-block:: yaml get: summary: List public snippets (approved + curated) parameters: - in: query name: q schema: { type: string } - in: query name: language schema: { type: string } - in: query name: page schema: { type: integer, default: 1, minimum: 1 } - in: query name: per_page schema: { type: integer, default: 30, minimum: 1, maximum: 60 } responses: '200': { description: Snippets page } '500': { description: Internal error } JSON Schema (Response) ~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: json { "type": "object", "properties": { "ok": { "type": "boolean" }, "items": { "type": "array", "items": { "type": "object", "properties": { "title": { "type": "string" }, "description": { "type": "string" }, "code": { "type": "string" }, "language": { "type": "string" }, "username": { "type": "string", "nullable": true }, "approved_at": { "type": "string", "format": "date-time", "nullable": true } } } }, "page": { "type": "integer" }, "per_page": { "type": "integer" }, "total": { "type": "integer" } } } הערות: - בעמוד הראשון ייתכנו סניפטים "מובנים" (curated) בנוסף לפריטי DB – המערך מאוחד ללא כפילויות לפי כותרת. - השדה ``username`` (אם קיים) מוצג ב-UI עבור קרדיט. כללי דפדוף/ספירה ~~~~~~~~~~~~~~~~~~ - איחוד Curated+DB מתבצע רק ל־page=1; בעמודים הבאים יוחזר DB בלבד. - ``total`` כולל גם את כמות ה‑curated התואמים (גם אם אינם בעמוד המבוקש). - ``per_page`` נחתך ל־[1..60]. שגיאות ~~~~~~~ - 200 עם ``ok: true`` בהצלחה. - 500 עם ``{"ok": false, "error": "internal_error"}`` במקרה חריג. דוגמאות cURL ~~~~~~~~~~~~~ .. code-block:: bash # עמוד ראשון, 30 פריטים curl -sS \ 'https://example.com/api/snippets?page=1&per_page=30' \ -H 'Accept: application/json' .. code-block:: bash # סינון לפי שפה וחיפוש חופשי curl -sS \ 'https://example.com/api/snippets?language=python&q=markdown' \ -H 'Accept: application/json' .. code-block:: bash # ללא תוצאות – חוזר items=[] ו-total=0 curl -sS 'https://example.com/api/snippets?q=__no_such__' -H 'Accept: application/json' הגשות, אישור וניהול (אדמין) --------------------------- - תור ממתינים: ``/admin/snippets/pending`` – צפייה בהגשות ממתינות. - צפייה בפריט: ``/admin/snippets/view?id=`` – מציג קוד מלא + כפתורי "✏️ ערוך" ו"🗑️ מחק". - עריכה: ``/admin/snippets/edit?id=`` (GET/POST) – עדכון כותרת/תיאור/שפה/קוד. - מחיקה: ``POST /admin/snippets/delete?id=``. ייבוא מסמך (אדמין) ------------------- מאפשר להוסיף בבת־אחת אוסף סניפטים ממסמך Markdown (גם קישור GitHub/Gist) – נוח במיוחד במובייל/טאבלט. היכן? - כפתור **"📥 ייבוא מסמך"** מופיע למנהלים בראש עמוד הספרייה: ``/snippets``. - עמוד הייבוא: ``GET/POST /admin/snippets/import`` (נגיש רק למזהים שב‑``ADMIN_USER_IDS``). קלטים - **URL**: הדביקו קישור לקובץ ב‑GitHub/Gist או כל קובץ Markdown ציבורי. המערכת ממירה אוטומטית ל‑Raw. - **תוכן מלא**: הדביקו את כל ה‑Markdown ישירות לטקסט־בוקס. כללי פירוס - כותרות פריטים מזוהות מתוך ``##``/``###``. - השורה שמתחילה ב‑``**למה זה שימושי:**`` או ``**מטרה:**`` הופכת ל‑description. - קטעי קוד מזוהים ע"י גדרות ```lang ...```. זיהוי שפה: ``py→python``, ``js→javascript``, ``ts→typescript``, ``sh/shell→bash``, ``yml→yaml`` ועוד. - הגנה בסיסית מתוכן חריג: חיתוך קוד חריג באורכו (כ~150K תווים) כדי למנוע עומס UI. אפשרויות - **Dry‑run**: הרצה ללא כתיבה ל‑DB – מציגה סיכום כמה פריטים זוהו. - **אישור אוטומטי**: ברירת מחדל דולקת – לאחר יצירה יאושרו אוטומטית. מדיניות כפילויות - מניעת כפילות לפי כותרת (case‑insensitive). פריטים עם אותה כותרת ייסומנו כ‑"דילוג" (skipped). שגיאות שכיחות - "לא התקבל תוכן או URL" – יש להזין לפחות אחד. - "לא נמצאו סניפטים במסמך" – המסמך אינו כולל כותרות/גדרות קוד בפורמט הנתמך. - "שגיאה בטעינת ה‑URL" – קישור לא נגיש או לא נתמך. אבטחה - אין להדביק סודות/טוקנים. לוגים מסננים ערכים רגישים, אך האחריות לתוכן המיובא עליכם. - הרשאה מוגבלת למנהלים בלבד (ENV ``ADMIN_USER_IDS``). הגשה דרך הבוט -------------- - תפריט ראשי > "אוסף הקהילה" > "ספריית סניפטים" > "הוסף סניפט משלך". - מסך פתיחה מציע שני מצבים: "🧩 קוד רגיל" ו"✍️ קוד ארוך". - "קוד ארוך": ניתן לשלוח את הקוד במספר הודעות ולסיים ב־``/done`` (לאחר מכן ממשיכים כרגיל לבחירת כותרת/תיאור/שפה). - ביטול: ``❌ ביטול`` או לחיצה על כל כפתור אחר – תבטל ותנקה מצב איסוף. UI בבוט – הסרות ושיפורים ------------------------ - מתפריט "📚 הצג את כל הקבצים שלי" הוסרו קיצורי "אוסף הקהילה"/"הוסף מוצר משלך" (נמצאים כבר בתפריט הראשי). - שמות כפתורים עודכנו: "ספריית סניפטים (web 🌐)" ו"ממשקי משתמשים (web 🌐)". גרסה משודרגת – מה חדש ----------------------- - איחוד Curated+DB ב‑page=1 עם סינון כפילויות יציב לפי כותרת. - הגבלת ``per_page`` ל‑[1..60] ומדיניות ``total`` עקבית הכוללת Curated תואמים. - הדגשת תחביר Deferred: הטעינה מתבצעת רק בעת פתיחת פריט (ביצועים טובים יותר). - תפריטי אדמין ברורים יותר: צפייה/עריכה/מחיקה והפרדה בין "ממתינים" לבין "מאושרים". מדריך קצר לסוכני AI --------------------- - הצגת רשימה מסוננת: השתמש/י ב‑API ``GET /api/snippets`` עם ``q``/``language`` והצע/י למשתמש לפתוח פריט רלוונטי. - שליחת סניפט (Web): נווט/י ל‑``/snippets/submit`` ומלא/י: כותרת*, תיאור, שפה*, קוד*; אשר/י שליחה והמתן/י לחיווי "תודה". - שליחת סניפט (בוט): תפריט ראשי > "ספריית סניפטים (web 🌐)" > "הוסף סניפט משלך"; במצב "קוד ארוך" סיים/י ב‑``/done``. - טיפול בשגיאה: הצג/י למשתמש את טקסט השגיאה הקצר, הצע/י ערך תקין והגש/י מחדש.