ספריית סניפטים (Web)

summary:

גלריית קטעי קוד קצרים עם הדגשת תחביר, מאפייני ה-UI, והפעולות שאפשר לבצע עליה.

מאפייני UI

  • רשימה מתקפלת: כל פריט מוצג ככותרת נפתחת (<details>/<summary>). לחיצה פותחת את הקוד.

  • הדגשת תחביר: Highlight.js נטען דינמית ומדגיש קוד בעת פתיחת הפריט.

  • קרדיט מחבר: מוצג ”נוסף על ידי @username“ (אם קיים) לצד השפה של הסניפט.

API – JSON

נתיב: GET /api/snippets

פרמטרים: - q – חיפוש חופשי בכותרת/תיאור/קוד (אופציונלי) - language – סינון לפי שפה (אופציונלי) - page – עמוד (ברירת מחדל: 1) - per_page – גודל עמוד (ברירת מחדל: 30, מקסימום: 60)

תגובה (דוגמה):

{
  "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 (תקציר)

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)

{
  "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

# עמוד ראשון, 30 פריטים
curl -sS \
  'https://example.com/api/snippets?page=1&per_page=30' \
  -H 'Accept: application/json'
# סינון לפי שפה וחיפוש חופשי
curl -sS \
  'https://example.com/api/snippets?language=python&q=markdown' \
  -H 'Accept: application/json'
# ללא תוצאות – חוזר items=[] ו-total=0
curl -sS 'https://example.com/api/snippets?q=__no_such__' -H 'Accept: application/json'

הגשות, אישור וניהול (אדמין)

  • תור ממתינים: /admin/snippets/pending – צפייה בהגשות ממתינות.

  • צפייה בפריט: /admin/snippets/view?id=<id> – מציג קוד מלא + כפתורי ”✏️ ערוך“ ו“🗑️ מחק“.

  • עריכה: /admin/snippets/edit?id=<id> (GET/POST) – עדכון כותרת/תיאור/שפה/קוד.

  • מחיקה: POST /admin/snippets/delete?id=<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.

  • טיפול בשגיאה: הצג/י למשתמש את טקסט השגיאה הקצר, הצע/י ערך תקין והגש/י מחדש.