RACQUET · ספר ההפעלה
כל מסך במערכת, כל כפתור עליו, מי רשאי ללחוץ, מה משתנה — ומה כבר אי אפשר להחזיר. החוברת נכתבה מול המערכת החיה: כל צילום מסך כאן צולם מהמערכת עצמה, וכל שם של כפתור הוא השם שמופיע על המסך, מילה במילה.
המשתמשים, המועדונים, התחרויות, הקורסים, המחנות, הפרסומים בלוח יד שנייה והביקורות — כולם נזרעו לצורך הדגמה ולימוד. אין כאן אף לקוח אמיתי ואף כסף אמיתי. אפשר להתאמן על כל דבר בחוברת הזאת בלי לפחד, למעט הפעולות שמסומנות בפרק מה אי אפשר להחזיר — אותן כדאי לקרוא לפני שלוחצים, כי הן יתנהגו בדיוק אותו דבר גם ביום שהנתונים יהיו אמיתיים.
איפה זה גר, איך נכנסים, ומה קורה לפני שנכנסים.
האפליקציה מוגשת מהשרת בכתובת https://www.data-pulse.co.il/racquet/app/. הקבצים עצמם יושבים ב־C:\Racquet\public\app\index.html, ו־nginx מגיש את התיקייה C:\Racquet\public\ תחת הכינוי /racquet/. ה־API יושב מאחורי אותו שם, תחת /racquet/api/v1/, ומופנה פנימה אל 127.0.0.1:8790.
הדומיין רשום ושייך למוצר, אבל ה־DNS שלו מצביע כרגע לשרת אחר, ואין עליו תעודת אבטחה. עד שהמעבר יושלם — הכתובת לעבודה היא זו שלמעלה. פרטי המעבר ב־docs/DOMAIN_PLAN.md.
שלוש נקודות שמנהל חייב להכיר במסך הזה:
ארבע קבוצות. כל פריט נתלה לפי הרשאה, ולכן שני אנשים לא רואים את אותו תפריט.
| קבוצה | מה בתוכה | למי היא מוצגת |
|---|---|---|
| שירותים | חיפוש שירותים · קורסים והשתלמויות · מחנות אימונים · לוח יד שנייה | לכולם. לוח יד שנייה ו־חיפוש שירותים כתובים ישירות בדף; השניים האחרים נתלים בזמן ריצה. |
| לשחק | תחרויות · הרמה שלי · SOS · מגרשים ברגע האחרון | הרמה שלי — רק למי שמשובץ בליגה. SOS — רק לנותן שירות מאושר, או למנהל של מועדון מפורסם. |
| ניהול | ניהול המערכת · תמיכה ובקשות שינוי | מי שמחזיק platform.user.read, או מנהל מועדון מפורסם שהוא גם נותן שירות מאושר. |
| שלי | הפרופיל שלי · ההזמנות שלי | לכל מי שמחובר. ליד ההזמנות שלי מופיע מונה. |
לפני שנכנסים לניהול, כדאי להכיר את המסכים שהמשתמשים רואים — כי כל החלטת ניהול משנה משהו באחד מהם.
רוב המשתמשים יגיעו מטלפון. שלושה דברים משתנים שם מהותית.
מתחת לרוחב 720px מוסרות מעקב בקשות, לאישור, בקשות שינוי ו־פניות תמיכה. ארבעתן טבלאות רחבות — מזהה, ממי, נושא, מצב ותאריך — ובמסך צר הן גורמות לתוכן לגלוש הצידה. גלילת רצועת הלשוניות מכוונת; גלילת הדף מתחתיה לא. כולן מסכי צוות שאיש לא עובד בהם מטלפון, ולכן הן מוסרות ולא נדחסות.
המשמעות המעשית: אישור בקשת שינוי או מענה לפנייה נעשים ממחשב בלבד. סיבוב הטלפון לרוחב מחזיר אותן, והלשונית שהייתה פתוחה נשמרת.
מי רשאי מה — ולמה מנהל המערכת דווקא לא יכול לנהל מועדון.
יש עשרה תפקידים. חמישה בהיקף פלטפורמה — הם נצמדים לאדם — וחמישה בהיקף ארגון — הם נצמדים לחברות שלו במועדון או בעסק מסוים.
| קוד | השם על המסך | היקף | מה הוא בפועל |
|---|---|---|---|
| sysadmin | מנהל מערכת | פלטפורמה | מחזיק את כל 22 הרשאות הפלטפורמה. התפקיד היחיד שמעניק תפקידים. |
| moderator | מנהל תוכן | פלטפורמה | דיווחים, תמונות פרופיל, ביקורות, והשהיית חשבון. |
| support_agent | נציג תמיכה | פלטפורמה | קריאה ומענה בפניות תמיכה, וקריאת רשימת המשתמשים. |
| verifier | מאשר תעודות | פלטפורמה | אישור ודחייה של תעודות בלבד. |
| content_editor | עורך תוכן | פלטפורמה | הקטלוגים בלבד: ענפים, קטגוריות, סוגי תעודות, פורמטים, ערכי ניקוד. |
| org_owner | בעלים של מועדון | ארגון | כל שמונה הרשאות הארגון, כולל הסרת חברים והענקת תפקידים בתוכו. |
| org_manager | מנהל מועדון | ארגון | שש: פרופיל, הזמנת חברים, פרסום שירותים, זמינות, קבלת בקשות, הצעות מגרש. |
| org_coach | מאמן במועדון | ארגון | שתיים: ניהול זמינות וקבלת בקשות. |
| org_staff | צוות המועדון | ארגון | אחת: קבלת בקשות. |
| org_customer | לקוח | ארגון | אפס הרשאות. זו אמירה „אני משחק כאן”, לא סמכות. |
שימו לב: במסכי המועדון עצמם מופיעה גרסה מקוצרת של אותם שמות — בעלים, מנהל, מאמן, צוות, לקוח. אותו תפקיד, שני ניסוחים.
| הרשאה | מנהל מערכת | נציג תמיכה | מאשר תעודות | מנהל תוכן | עורך תוכן |
|---|---|---|---|---|---|
| platform.user.read | ✓ | ✓ | ✓ | ✓ | |
| platform.user.suspend | ✓ | ✓ | |||
| platform.role.assign | ✓ | ||||
| platform.certificate.verify | ✓ | ✓ | |||
| platform.moderation.decide | ✓ | ✓ | |||
| platform.support.read | ✓ | ✓ | |||
| platform.support.respond | ✓ | ✓ | |||
| platform.catalog.approve | ✓ | ✓ | |||
| platform.feature_flag.toggle | ✓ | ||||
| platform.change_request.read | ✓ | ||||
| platform.change_request.decide | ✓ | ||||
| platform.audit.read | ✓ |
עשר הרשאות נוספות נולדו אחרי שהמטריצה נכתבה, וכולן מוחזקות במנהל מערכת בלבד: platform.user.create, platform.user.mail, platform.organisation.read, platform.organisation.manage, platform.provider.approve, platform.tournament.manage, platform.rating.manage, platform.setting.manage, platform.course.approve, platform.academy.curate.
שמונה הרשאות הארגון: org.profile.edit, org.member.invite, org.member.remove, org.member.role.assign, org.service.publish, org.availability.manage, org.request.accept, org.court_offer.publish.
מנהל מערכת מחזיק את כל הרשאות הפלטפורמה ואפס הרשאות ארגון. להפעיל את הפלטפורמה אינו זהה ליכולת לפעול בתוך מועדון של לקוח משלם. לפרסם את שירותיו, לערוך את הפרופיל שלו, להסיר את חבריו — אלה החלטות של המועדון, שנעשות בידי אנשי המועדון.
זה נאכף במסד ולא רק בקוד: UserRoles.scope CHECK (scope='platform'), MembershipRoles.scope CHECK (scope='organisation'), ואילוץ ייחודיות על Roles(id, scope). מבנית בלתי אפשרי לחבר תפקיד פלטפורמה לחברות בארגון, או תפקיד ארגון ישירות לאדם.
יוצא מן הכלל אחד: מנהל פלטפורמה שפותח מועדון חדש הופך ל־בעלים שלו — כי החלופה משאירה מועדון בלי בעלים.
platform.user.create, platform.user.mail, platform.rating.manage, platform.setting.manage ו־platform.academy.curate אין להן שם עברי בשום מקום באפליקציה. הן יופיעו כקוד גולמי בכרטיס תפקידים והרשאות וגם בתוך משפט השגיאה של 403. לא באג מסוכן — אבל שווה לדעת לפני שמישהו שואל.
הכניסה: תפריט ← ניהול ← ניהול המערכת. כותרת המסך היא ניהול, ומעליה הגדרות מערכת. בראש המסך יושבת שורה אחת שכדאי לקרוא פעם אחת ולזכור:
„המסך הזה נפתח רק למי שמחזיק הרשאות ניהול. הסתרה של כפתור היא נימוס, לא שמירה — כל פעולה כאן נבדקת שוב בשרת.”
שלושה כללים שחלים על כל 26 הכרטיסים:
לרוב הכרטיסים יש אותה שורת כלים: שדה חיפוש, בורר מיון שמציע לכל עמודה „‹עמודה› — עולה” ו„‹עמודה› — יורד”, ומונה שאומר „N ‹פריטים›” או „N מתוך M ‹פריטים›”. בקטלוגים מצטרף רמז הגרירה: „גרור שורה, או השתמש בחיצים, כדי לשנות את הסדר.”
מעל רצועת הלשוניות יושב קישור ספר ההפעלה של המערכת, שנפתח בלשונית חדשה אל /racquet/docs/ADMIN_HANDBOOK_HE.html. הוא מוצג רק למי שמחזיק platform.setting.manage — כלומר למנהל מערכת. אם הקובץ עדיין לא הועלה לשרת, תיפתח במקומו הודעת „הדף לא נמצא”.
ארבע לשוניות: משתמשים · תפקידים · נותני שירות · תפקידים והרשאות.
הרשאה לפתיחה: platform.user.read. לעריכה ולהשהיה: platform.user.suspend. לפתיחת חשבון: platform.user.create — מנהל מערכת בלבד.
מסננים: מצב („כל המצבים”), תפקיד („כל התפקידים” / „ללא תפקיד”), ענף („כל הענפים” / „ללא ענף”), מועדון („כל המועדונים” / „ללא מועדון”). מצבי חשבון: ממתין · פעיל · מושהה.
| כפתור | מה קורה | סיבה | אישור |
|---|---|---|---|
| + משתמש חדש | פותח חשבון פעיל ומחזיר סיסמה זמנית שמוצגת פעם אחת. | — | — |
| עריכה | פותח שדות שם תצוגה, טלפון, אימייל ואת שאר הפעולות מתחת לשורה. שמירה שולח. | — | — |
| השהיית החשבון / הפעלת החשבון | מנתק מיד את כל הכניסות הפתוחות. „החשבון הושהה, והכניסות הפתוחות שלו בוטלו.” | שדה סיבה להשהיה — לא חובה | אין |
| הסרת תמונה | מוחק את קובץ התמונה. „להסיר את התמונה של ‹שם›? הקובץ יימחק, ובעל החשבון יראה שהתמונה הוסרה.” | אין שדה סיבה | כן, להסיר / ביטול |
| שליחת מייל לנבחרים | מסמנים שורות בעמודת הבחירה, ממלאים נושא ותוכן ההודעה, ושולחים. דורש platform.user.mail. | אין | אין |
„הסיסמה הזאת מוצגת פעם אחת בלבד… העתק אותה עכשיו ומסור אותה לבעל החשבון בערוץ בטוח.” יש העתקה ו־סגירה ומחיקה מהמסך. היא אינה נשמרת בצורה קריאה בשום מקום ואי אפשר לשלוף אותה שוב — אם אבדה, הדרך היחידה היא לאפס סיסמה מחדש.
הרשאה: platform.role.assign — מנהל מערכת בלבד.
הרשאה: platform.provider.approve.
הכרטיס מסביר את עצמו: „מי שסימן בפרופיל „נותן/ת שירות” מופיע כאן עד שמנהל מחליט. עד האישור השירותים שלו נשמרים כטיוטה ואינם מופיעים בחיפוש. אישור לא צריך נימוק; דחייה וביטול אישור כן — הנימוק נשמר, והאדם קורא אותו בפרופיל שלו.”
| מ־ | כפתור | אל | נימוק |
|---|---|---|---|
| ממתין / נדחה / מאושר | אישור | מאושר | לא |
| ממתין | דחייה | נדחה | חובה |
| מאושר | ביטול אישור | נדחה | חובה |
שדות הנימוק נושאים את שם האדם: נימוק לדחייה (חובה — ‹שם› יקרא אותו בפרופיל) ו־נימוק לביטול האישור (חובה — ‹שם› יקרא אותו בפרופיל), ואישור בשני שלבים — אישור הדחייה / אישור הביטול.
מה קורה בפועל: אישור הוא על האדם, לא על כל שירות בנפרד — מאמן שאושר מוסיף שירות שני בלי בדיקה נוספת. ביטול אישור מוריד מיד את כל שירותיו המפורסמים מהחיפוש, כי providers.require_approved נבדק בכל פרסום.
נבדק ואומת מול המערכת החיה בעת כתיבת החוברת: חשבון שסימן את עצמו כנותן שירות ומחזיק platform.provider.approve מקבל 403 permission_denied עם reason: cannot_decide_your_own_provider_status. צריך מנהל שני. אותו כלל חל על תמונות לאישור: „אי אפשר להחליט על התמונה של עצמך. מנהל אחר יעשה את זה.”
דחייה מנומקת אפשר להפוך בלחיצה אחת, בלי אישור ובלי נימוק. אם מחזירים אישור למי שנדחה — כדאי לכתוב את הסיבה בפנייה או בבקשת שינוי, כי היומן יראה רק provider.approved בלי הסבר.
הרשאה: platform.role.assign. לקריאה בלבד.
„הצעה שטרם אושרה. חלוקת ההרשאות לתפקידים שמוצגת כאן היא הצעה בלבד, ועדיין לא התקבלה עליה החלטת מוצר.” אין כאן יצירה, עריכה או מחיקה — זה מסך קריאה שנועד לענות על „מה בעצם מותר לנציג תמיכה”, לא לשנות את התשובה.
שתי לשוניות על אותו מנוע: מועדונים ו־עסקים וחנויות.
הרשאה לקריאה: platform.organisation.read. לעריכה: platform.organisation.manage. שתיהן מנהל מערכת בלבד.
עמודות: שם · סוג · מצב · בעלים וחברים · פעולות. תא הבעלים כתוב „‹שם› · N חברים”, ובהיעדר בעלים „אין בעלים רשום”. סוגים: מועדון · עסק · חנות · אחר. מצבים: טיוטה · מפורסם · מושהה · בארכיון.
שלושתם הם בורר מצב ולחיצה על שמירת השינויים. זו החריגה הבולטת במסך: כל שאר הפעולות ההרסניות דורשות אישור דו־שלבי או סיבה, וזו לא. השהיית מועדון עוצרת מיד את יכולתו למכור הצעות מגרש ומורידה את שירותיו מהחיפוש.
הכותרת, המונה והודעת הריק מקודדים לתמיד למילה „מועדונים”. גם בלשונית העסקים המסך יאמר „N מועדונים” ו„אין מועדונים שמתאימים לסינון.” הנתונים נכונים — רק הטקסט שגוי.
חמש לשוניות: תחרויות · רמות (ליגות) · דירוגים · פורמטי משחק · ערכי ניקוד.
הרשאה: platform.tournament.manage (תווית במסך: ניהול תחרויות), או מנהל של מועדון מפורסם שהוא גם נותן שירות מאושר. פרק שלם על ניהול תחרות נמצא בסעיף 13.
הפעולות מתחת לכל שורה: עריכה · פרסום (או פתיחת ההרשמה מחדש) · סגירת ההרשמה · ביטול התחרות… · נרשמים · הגרלה (הופך ל־לוח אחרי ההגרלה, ולידו הגרלה מחדש) · לוח זמנים · יום התחרות. בטיוטה שלושת האחרונים מוצגים כטקסט מושבת: „הגרלה — אחרי הפרסום”, „לוח זמנים — אחרי הפרסום”, „יום התחרות — אחרי הפרסום”.
הרשאה: זהה לתחרויות.
ליגה היא עונה אחת של רמה אחת בענף אחד. חמש הרמות: רמה ד · רמה ג · רמה ב · רמה א · ליגת העל. 1–2 בתים, עד עשרה שחקנים בבית, כל אחד נגד כל אחד. ניצחון 2 נקודות, הפסד 1, ויתור 0 למוותר ו־2 למנצח.
הרצף המלא: יצירה → הוספת שחקנים (חשבונות קיימים בלבד — אין טופס הרשמה) → חלוקה לבתים (אוטומטית) → בניית לוח (מחשבת מארח לכל משחק לפי „בנק” אירוח) → תאריך יעד → אישור תוצאות שהמנצח דיווח, או הזנה ישירה → פלייאוף → סגירת עונה… → העברת שחקנים לעונה הבאה.
לפני האישור מוצגת תצוגה מקדימה מלאה: אלוף, „עולים ל‹רמה› (N)”, „יורדים ל‹רמה› (N)”, „נשארים (N)”, וגם הכללים „אין עלייה מליגת העל” ו„אין ירידה מרמה ד”. רק אז אישור וסגירת העונה → כן, לסגור את העונה / לא. אין ביטול סגירה.
בלי אישור כלל: פתיחת הרמה, חלוקה לבתים (אוטומטית) (דורסת כל שיוך בתים קיים), הסרה של שחקן, ביטול המשחק. בניית לוח מחדש כן שואל, ונעלם ברגע שהוכרע משחק. פרישה… מציע בורר: „פרישה: המשחקים שנותרו מבוטלים” או „פרישה: הפסדים טכניים”.
לצפייה: platform.rating.manage או platform.tournament.manage. לשינוי: platform.rating.manage בלבד.
הדירוג הוא ELO שמחושב מתוצאות משחקים — של תחרות או של רמה. K=40 בעשרת המשחקים הראשונים, 24 עד השלושים, 16 אחר כך. ויתור ועולה בלי משחק לעולם אינם מזיזים דירוג. שלושת סוגי השורות ביומן הדירוג: משחק · תיקון ידני · איפוס לרמה המוצהרת. טווח מותר לתיקון ידני: 500–2500.
לחיצה על שורה פותחת את יומן השחקן — „לפני ← אחרי” לכל משחק, והסיבה לכל תיקון. תיקון ידני דורש סיבה (חובה) של שלוש אותיות לפחות („צריך לכתוב סיבה — לפחות שלוש אותיות.”) ושואל „לשנות את הדירוג של ‹שם› מ־‹א› ל־‹ב›?” → כן, לתקן / לא.
האזהרה שהמסך נושא, מילה במילה:
„החישוב מוחק את יומן הדירוגים של הענף ובונה אותו מחדש מכל המשחקים ששוחקו, לפי סדר המשחק. כל תיקון ידני וכל איפוס בענף הזה יימחקו — הם אינם משחקים ואי אפשר לשחזר אותם. אם תיקנת דירוג בגלל תוצאה שגויה, תקן/י את התוצאה עצמה בלוח לפני ההרצה, אחרת התיקון יאבד והתוצאה השגויה תחזור.”
האישור: „לחשב מחדש את כל הדירוגים ב‹ענף›? כל תיקון ידני וכל איפוס בענף יימחקו ולא ניתן יהיה לשחזר אותם.” → כן, לחשב מחדש / לא. התשובה מחזירה כמה תיקונים נזרקו, והמספר נשמר ביומן.
אי־עקביות שכדאי להכיר: פאנל החישוב מחדש נשלט ב־platform.tournament.manage, לא ב־platform.rating.manage. כלומר מי שאינו רשאי לתקן דירוג יחיד כן רשאי למחוק את כל התיקונים בענף.
שניהם קטלוגים — ראו את מנוע הקטלוגים בסעיף הבא. שניהם דורשים platform.catalog.approve.
בערכי ניקוד יש שתי עמודות מעבר לקטלוג הרגיל: ערכי ניקוד וברירת מחדל. כל שורה נפתחת לשבעה שדות מספר (0–10000) שנערכים במקום, עם שמירת הערכים, ותיבת ברירת מחדל — אחת לכל היותר. הטבלה הנזרעת נקראת ברירת מחדל. הערכים המקוריים: אלוף 100 · סגן 75 · חצי גמר 50 · רבע גמר 35 · שמינית 25 · סיבוב 32 = 15 · השתתפות 5.
סדר הקדימויות — הצר מנצח את הרחב: ערכים מיוחדים שהוקלדו לתחרות עצמה ← הטבלה בשם שנבחרה לה ← הטבלה המסומנת ברירת מחדל ← ברירת המחדל שבקוד.
שלוש לשוניות: ענפים · סוגי תעודות · קטגוריות. יחד עם פורמטי משחק וערכי ניקוד מקבוצת התחרויות — חמישה קטלוגים על מנוע אחד.
הרשאה לכל החמישה: platform.catalog.approve — תווית במסך ניהול הקטלוגים. זו ההרשאה היחידה של עורך תוכן.
עמודות הבסיס: סדר · ‹שם היחיד› · מזהה · זמין לבחירה · פעולות.
המסקנה המעשית: בקטלוג לא מוחקים — מכבים. מחיקה אפשרית רק על פריט שנולד בטעות ואיש עוד לא נגע בו.
שינוי סדר: גרירה, או החיצים ▲/▼ („להעלות את ‹שם› מקום אחד”). פעיל רק ברשימה מלאה שממוינת לפי סדר.
התבנית מקודדת בזכר: „+ קטגוריה חדש”, „אין קטגוריות שמתאימים לסינון”. צורם בעברית, לא מזיק.
ארבע לשוניות: תעודות לאישור · תמונות לאישור · מפרסמי קורסים · לאישור מחשב בלבד.
הרשאה: platform.certificate.verify.
שדה נימוק (חובה בדחייה, לא באישור), וכפתורים אישור, דחייה, פתיחת המסמך. אין אישור דו־שלבי — הנימוק הוא כל ההגנה: „דחייה צריכה נימוק — הוא נשמר, והמעלה יקרא אותו.”
אישור תעודה מסמן את המסמך כנקי ורושם ביומן במפורש "automated_scan": false ו־ "document_cleared_by": "manual_review". כלומר העין של המאשר היא הסריקה. אל תפתח מסמך שלא נראה נכון, ואל תאשר קובץ שלא פתחת.
הערה שנייה: זהו הכרטיס היחיד שלא משתמש במשפט השגיאה האחיד, ולכן 403 כאן קורא רק „אין הרשאה לפעולה הזאת.” בלי שם ההרשאה.
הרשאה: platform.moderation.decide.
הרשאה: platform.course.approve — מנהל מערכת בלבד.
מי שנמצא כאן רשאי לפרסם קורסים והשתלמויות וגם מחנות אימונים. אין מסך נפרד למחנות והמחיר נאמר בגלוי: אי אפשר היום לאשר מישהו למחנות ולא לקורסים.
הוספה: שם · טלפון · אימייל · ארגון („ללא ארגון — אדם פרטי”) · הערה → הוספת מפרסם. מפרסם יכול להיות אדם — ואז הוא חייב להיות נותן שירות מאושר — או ארגון, ואז כל מי שמחזיק org.profile.edit בו מפרסם בשמו.
ביטול: ביטול ההרשאה… → הערה חובה → ביטול ההרשאה / להשאיר. „ביטול הרשאה דורש הערה — היא נשמרת ביומן.” ההרשאה מסומנת כמבוטלת ולא נמחקת, ו„קורסים שכבר פורסמו נשארים על כנם.” המפרסם פשוט לא יכול לגעת בהם יותר.
הרשאה: platform.change_request.read, והחלטה דורשת platform.change_request.decide. כותרת הכרטיס: בקשות שינוי לאישור.
שדות: הנחיות לעובד (רק אם מאשרים לעובד) והערת מנהל (חובה בדחייה). שלוש החלטות:
חמש לשוניות. שלוש מהן מחשב בלבד.
טופס פתיחה: כותרת · תחום · דחיפות · פירוט → פתיחת הבקשה. אחר כך אישור הבקשה („הבקשה אושרה. עכשיו אפשר להעביר אותה לעבודה.”), ואז בורר מצב הבקשה („ללא שינוי מצב — שמירת הערה בלבד” / „העברה ל‹מצב›”) עם מה נעשה (הערה) ו־שמירה.
הסירוב המרכזי, ששווה להכיר לפני שהוא מפתיע: „הבקשה עוד לא אושרה, ולכן אי אפשר להעביר אותה לעבודה. לחץ קודם „אישור הבקשה” — האישור נרשם על שמך, בדיוק כמו לחיצה על הקישור במייל.”
בורר מצב העובד: בתור · בעבודה · תוקן · נכשל · הועלה לאוויר — דיווח של אדם. הבחירה האחרונה קיימת כדי שהיומן יידע מי אמר שהתיקון עלה: „נרשם שהתיקון הועלה לאוויר. הדיווח הזה נזקף לך, לא לעובד.”
הרשאה: platform.support.read; מענה דורש platform.support.respond.
שליחת תשובה ללקוח → „התשובה נשלחה ללקוח.”
הערה פנימית → „ההערה נשמרה לצוות בלבד.”
כל הודעה בשרשור מסומנת במפורש הערה פנימית או תשובה ללקוח. זו הגנה מכוונת מפני היפוך בוליאני אחד שהיה מדליף הערכה פנימית ללקוח. קרא את התווית לפני שאתה שולח.
הרשאה: platform.moderation.decide.
שדה סיבה להחלטה — חובה: „צריך לכתוב סיבה. היא נשמרת עם ההחלטה.” שלוש החלטות: טופל · לקחת לבדיקה · דחייה. „הדיווח כבר הוכרע.” — אין פתיחה מחדש.
הרשאה: platform.moderation.decide.
הטקסט שהכרטיס נושא: „ביקורות שמישהו דיווח עליהן ואף אחד עוד לא הסיר. ההסרה מסתירה את הביקורת מהעמוד הציבורי ומהממוצע — היא לא מוחקת אותה, כדי שאפשר יהיה לבדוק את ההחלטה בדיעבד. סיבה היא חובה.”
שדה סיבת ההסרה (חובה, נשמרת עם ההחלטה), כפתור הסרת הביקורת → „להסיר את הביקורת מהעמוד הציבורי ומהממוצע?” → כן, להסיר.
שלוש לשוניות: לוח יד שנייה · מתגי תכונות · יומן פעולות.
| מקטע | הרשאה | מה יש בו |
|---|---|---|
| מכסת פרסומים לחודש | platform.setting.manage | מכסה לכל המשתמשים + שמירת המכסה (ברירת מחדל 5); מזהה ציבורי של המשתמש + המכסה שלו (ריק = ביטול החריגה) + שמירת החריגה. |
| קטגוריות הלוח | platform.catalog.approve | קטלוג רגיל: הוספה, שינוי שם, סדר, כיבוי. |
| פרסומים שדווחו | platform.moderation.decide | סיבת ההסרה (חובה, נשמרת עם ההחלטה והמוכר רואה אותה) + הסרת הפרסום. |
הכרטיס מופיע אם מחזיקים לפחות אחת מהשלוש. הכלל שכדאי לזכור: „חשבון שמנהל חנות לא יכול לפרסם בלוח.”
„להסיר את הפרסום ולמחוק את התמונות שלו?” → כן, להסיר. שורת הפרסום עצמה נשארת עם מי הסיר, מתי ולמה, והמוכר קורא את הסיבה. כשמנהל תוכן מסיר — „הפרסום הוסר והמקום במכסה הוחזר למוכר.” כשהמוכר מסיר בעצמו, המקום לא חוזר.
הרשאה: platform.feature_flag.toggle. לתצוגה בלבד.
„הדלקת מתג היא החלטת מוצר עם השלכות משפטיות וכספיות, והיא שלך בלבד. עמודת האישור ריקה בכולם, וזו התשובה.” המסך אומר מה דלוק ומה כבוי, ומי אישר — ותו לא. הדלקה או כיבוי נעשים בשרת, בתוך בסיס הנתונים, ורק אחרי החלטה מתועדת.
הרשאה: platform.audit.read — מנהל מערכת בלבד.
כל שורה נושאת: תיאור בעברית וגם את הקוד — מסך שמראה רק פרוזה אי אפשר להצליב מול בסיס הנתונים; זמן; „בוצע על ידי ‹שם›” או „ללא משתמש מזוהה”; הישות; הארגון; ו„סיבה: ‹טקסט›” כשיש.
כל שורה שנכתבה בטיפול באותה בקשה נושאת את אותו מזהה בקשה. זה מה שהופך את „מה קרה כשזה השתבש” משעה של חיטוט לשאילתה אחת. המסך אינו חושף אותו כמסנן, אבל ה־API כן — וכך גם השאילתה הישירה בסעיף התפעול.
„אין דרך לכתוב, לערוך או למחוק שורת יומן.” POST, PATCH ו־DELETE כולם מוחזרים 405. יומן שאפשר לתקן אינו יומן.
שני צירים נפרדים, ארבעה מצבים, הגרלה אחת שנועלת כמעט הכול.
יש שבעה ערכים בבורר סוג התחרות — הם אומרים מי משחק — ובנפרד ארבעה ערכים בבורר מבנה, שאומרים איך הלוח בנוי. בלבול בין השניים הוא הטעות הנפוצה ביותר בשיחה על המודול הזה.
| התווית במסך | מה מייחד |
|---|---|
| יחידים | יחידים בלי הגבלת מגדר. ברירת המחדל של כל תחרות. |
| יחידים גברים | יחידים; המגדר בפרופיל נבדק בכשירות ההרשמה. |
| יחידים נשים | אותו כלל, הפוך. |
| זוגות | הצד הוא זוג, בלי הגבלת מגדר. |
| זוגות גברים | מגבלת המגדר חלה על שני בני הזוג. |
| זוגות נשים | אותו כלל. |
| זוגות מעורב | נדרש אחד מכל מגדר. מי שלא הצהיר מגדר בפרופיל פשוט אינו יכול להירשם. |
הצירוף השמיני, „יחידים מעורב”, נדחה גם בשירות וגם באילוץ במסד — הוא לא קיים. הבחירה יחידים/זוגות ננעלת ברגע שיש נרשם ראשון.
| התווית במסך | איך הלוח בנוי | מדריך |
|---|---|---|
| נוקאאוט | הדחה ישירה. גודל הלוח הוא החזקה של 2 מעל מספר הנרשמים, עד 128. זה המבנה היחיד שבו קיימת הגרלת תנחומים. | GUIDE_TOURNAMENT_KNOCKOUT_HE.html |
| בתים | בתים בלבד, בלי שלב הדחה. אין דירוג חוצה־בתים, ולכן כולם מקבלים ניקוד השתתפות; אלוף נקבע רק אם יש בית אחד. | אין מדריך |
| בתים ואז נוקאאוט | שניים מכל בית עולים ללוח. הצלבה קבועה ל־2, 4 או 8 בתים; במספר אחר — הגרלה חוזרת עד שאין זוג מאותו בית בסיבוב הראשון. | GUIDE_TOURNAMENT_GROUPS_KO_HE.html |
| בתים עם דירוג סופי | כולם מדורגים יחד, הדירוג נחתך לרביעיות, וכל רביעייה משחקת על המקומות שלה. לכל משתתף יוצא מקום סופי מדויק. | GUIDE_TOURNAMENT_POOLS20_HE.html |
מדריך רביעי, GUIDE_TOURNAMENT_DOUBLES_HE.html, חוצה מבנים ומכסה את ארבעת סוגי הזוגות. ארבעת המדריכים יושבים לצד החוברת הזאת, בתיקיית docs/.
| מ־ | הכפתור | אל | מה נדרש |
|---|---|---|---|
| טיוטה | פרסום | פורסמה | חובה תאריך התחלה, אחרת הטופס נעצר. |
| פורסמה | סגירת ההרשמה | ההרשמה נסגרה | — |
| ההרשמה נסגרה | פתיחת ההרשמה מחדש | פורסמה | — |
| כל מצב | ביטול התחרות… | בוטלה | סיבת הביטול (תוצג לנרשמים) — חובה. |
| בוטלה | — | — | קפואה. אי אפשר לערוך, אי אפשר להחזיר, ויום התחרות חסום. |
כשעובר מועד סגירת ההרשמה, או כשהתחרות מתחילה, ההרשמה נחסמת — אבל המצב נשאר פורסמה. רק לחיצה על סגירת ההרשמה כותבת ההרשמה נסגרה. אל תסיק מהמצב שההרשמה עדיין פתוחה.
שני צירים נוספים שמופיעים על המסך: טרם הוגרל · הוגרל · במשחק · הסתיימה למצב הלוח; ו־רשום/ה · ברשימת המתנה · ביטל/ה · נדחה/תה לנרשם. משחק: ממתין · נקבע · שוחק · ויתור · פרישה · עולה בלי משחק.
מי שלא אושר כנותן שירות מקבל סירוב עם provider_not_approved; מי שיש לו רק עסק או חנות, או מועדון בטיוטה, מקבל no_published_club.
„מנהל התחרות” אינו תפקיד במערכת. אלה ארבעה שדות טקסט בטופס — שם מנהל התחרות, טלפון, אימייל וכתובת — והטלפון והאימייל מוחזרים רק למי שמחובר. ברשימה הציבורית מוצג השם בלבד.
כמה מדורגים? המספר לא מוקלד — הוא נגזר מגודל הלוח: עד 8 → שניים, עד 16 → ארבעה, עד 32 → שמונה, עד 64 → שישה־עשר, מעבר → שלושים־ושניים.
איך מגרילים. הגרלה פותח רשימה ממוספרת שסדרה הוא סדר ההרשמה. סדר לפי דירוג מסדר לפי הדירוג המחושב מתוצאות (הגבוה ראשון; מי שאין לו — בסוף). החיצים ▲/▼ מזיזים שורה. בצע הגרלה שואל לפני שהוא מבצע: כן, להגריל / לא.
שיבוץ המדורגים בנוקאאוט: בלוח 8 — מספר 1 לשורה 1 ומספר 2 לשורה 8; בלוח 16 — 1 ו־16, והזוג 3–4 לשורות 5 ו־12; בלוח 32 — 1 ו־32, הזוג 3–4 ל־9 ו־24, והרביעייה 5–8 ל־8, 16, 17 ו־25. בתוך כל קבוצה ההגרלה אקראית. חופשים ממלאים את החוסר עד החזקה של 2, ניתנים למדורגים לפי הסדר, ולעולם לא שניים באותו משחק. מי שקיבל חופש עובר לסיבוב הבא כבר בזמן ההגרלה.
בבתים: מספר הבתים הוא תקרת (נרשמים ÷ גודל בית), והגדלים נבדלים ב־1 לכל היותר. ראשי הבתים הם המדורגים הבכירים, ואחריהם דרג נוסף אחד לכל בית באקראי. גודל בית: 3 שחקנים, 4 שחקנים או 5 שחקנים.
הרמז שמופיע בטופס אחרי ההגרלה, מילה במילה:
„הלוח כבר הוגרל: המבנה, התנחומים, המדורגים וגודל הבית קפואים. רק הפורמט ניתן לשינוי.”
הגרלה מחדש מוחקת את הלוח הקיים ובונה אותו מאפס. אחרי התוצאה הראשונה הכפתור נעלם לגמרי — הלוח הוא היסטוריה, והדרך היחידה אחורה היא ביטול תוצאות אחת־אחת.
ביטול תוצאה אפשרי רק כל עוד אף אחד מהשניים לא שיחק הלאה. הזנת תוצאה על משחק ששוחק מסורבת — קודם ביטול, אחר כך הזנה מחדש.
היומן שומר את זרע ההגרלה בשורה tournament.draw, יחד עם המדורגים, החופשים, גודל הלוח והבתים — כך שאפשר לשחזר בדיוק כל הגרלה בדיעבד.
| המספר | מה הוא | מתי משתנה |
|---|---|---|
| הניקוד שלי | הישגים בתחרויות בשנה האחרונה. | פעם אחת, בסוף התחרות. |
| לפי תוצאות (ELO) | דירוג מחושב ממשחק למשחק — תחרות ורמה כאחת. | בכל תוצאה שנרשמת, לאורך כל הדרך. |
| רמה | הצהרה עצמית של השחקן בפרופיל. | רק כשהוא משנה אותה בעצמו. |
אף אחד משלושתם אינו קורא את השני.
מתי ניקוד נזקף: ברגע שהלוח מגיע להסתיימה, באותה טרנזקציה של התוצאה האחרונה. ביטול שמחזיר את הלוח אחורה מבטל גם את הניקוד. כישלון בזקיפת ניקוד לעולם לא חוסם הזנת תוצאה.
הערכים: אלוף 100 · סגן 75 · חצי גמר 50 · רבע גמר 35 · שמינית 25 · סיבוב 32 = 15 · השתתפות 5. מנצח התנחומים מורם לניקוד השמינית, לעולם לא מעבר לרבע גמר, ורק אם זה יותר ממה שהלוח הראשי כבר נתן.
פקיעה: הניקוד תקף מתאריך התחלת התחרות ועד אותו תאריך בשנה שאחריה, לא כולל. השורה לא נמחקת — היא נשארת ביומן ומפסיקה להיספר.
בזוגות: דירוג הזוג הוא ממוצע השניים, והתוצאה מזיזה את שניהם באותו הפרש. שחקן חדש בסולם הזוגות מתחיל מדירוג היחידים שלו אם יש לו. הסולמות לעולם לא מתערבבים. בניקוד — שני בני הזוג מקבלים את ניקוד השלב במלואו, לא חצי כל אחד.
שני הכפתורים הנוספים באותו סרגל: סדר משחקים ל-PDF ו־ תוצאות ל-PDF, שניהם במקף רגיל.
מה כל מודול עושה, מה בו של המנהל, ומה בו קורה מעצמו.
„דקה 90”: מועדון מפרסם משבצת על מגרש שהתפנה, עם מחיר רגיל ומחיר מבצע, ושחקן לוקח אותה. רק מועדון שמצבו „מפורסם” יכול למכור; מנהל פלטפורמה אינו יכול לפרסם הצעה בשם מועדון. הלקיחה יוצרת הזמנה מסוג מגרש ברגע האחרון שנולדת ישר במצב אושרה — אין שלב „המועדון מאשר”.
אין לשונית ניהול למודול הזה. הכול נעשה מכרטיס המועדון בלשונית המועדונים שלי: + מגרש חדש, + פרסום הצעה, ו־ביטול ההצעה → כן, לבטל / להשאיר. הצעה שנתפסה אי אפשר לבטל. הרשאות: org.profile.edit למגרשים, org.court_offer.publish להצעות.
המנהל נוגע במודול רק בעקיפין: השהיית מועדון עוצרת מכירה, ומתג מגרשים ברגע האחרון בכרטיס מתגי תכונות מחליט אם המודול קיים בכלל. אין worker ואין משימה מתוזמנת — הצעה שחלונה עבר פשוט מפסיקה להופיע.
שלב חיים נוסף קיים בקוד ואינו מתועד ב־docs/COURTS_HE.md: אחרי „נתפסה” המועדון מאשר תשלום ומוסר קוד שער לשחקן.
לוח קורסים, סדנאות והשתלמויות. הלב הוא רשימת ההיתרים — רק מי שנמצא בכרטיס מפרסמי קורסים יכול לפרסם. אין תשלום דרך המערכת; המחיר הוא מידע.
מצבים: טיוטה · פורסם · מלא · הסתיים · בוטל. מלא אינו החלטה של אף אחד — הוא נגזר מספירת הנרשמים וחוזר לפורסם כשמישהו מבטל. קורס מלא לא דוחה אלא מכניס לברשימת המתנה, בלי קידום אוטומטי — המפרסם מעביר ידנית.
המנהל אינו עורך, מפרסם או מבטל קורסים של אחרים — אין מסך כזה. הוא שולט ברשימת המפרסמים בלבד. ביטול קורס דורש סיבה, מקפיא את הקורס, משאיר את כל ההרשמות כפי שהן, ולא שולח שום הודעה.
לוח ציוד משומש בין אנשים פרטיים. הלוח עצמו ציבורי; הטלפון פשוט אינו קיים בתשובת השרת לקורא שאינו מחובר — הוא לא מוסתר בעיצוב.
מצבים: טיוטה · מפורסם · נמכר · פג תוקף · הוסר. מצב הפריט: חדש · כמו חדש · משומש · לחלקים. פרסום פג אחרי 60 יום — אין משימה מתוזמנת, הפקיעה מחושבת בקריאה.
המנהל שולט במכסה החודשית, בקטגוריות הלוח ובתור ההסרה — ראו סעיף 12.1.
דירוג חד־צדדי של לקוח על נותן שירות, 1–5 כוכבים וטקסט חופשי. ביקורת נולדת מבקשה שהושלמה, לא מכתיבה חופשית, ותוקפה 30 יום: „אפשר לכתוב ולערוך עד 30 יום מסיום השירות…”, ואחר כך „החלון לכתיבת ביקורת נסגר (30 יום מסיום השירות).”
אין למודול פריט תפריט. הכתיבה נעשית מההזמנות שלי, בכפתור כתיבת ביקורת / עריכת הביקורת. לנותן השירות מגיעה תגובה אחת בלבד לכל ביקורת.
הציון והביקורות מוצגים בפומבי רק אחרי חמש התקשרויות שהושלמו — התקשרויות, לא ביקורות. עד אז הכרטיס נושא את התג חדש. ביקורות לעולם לא משפיעות על סדר החיפוש.
הסריקה שמזמינה לכתוב ביקורת, ומזכירה אחרי שבעה ימים, היא POST /admin/reviews/remind, והיא מתוזמנת: המשימה Racquet_Review_Sweep מריצה אותה כל יום ב־06:10 תחת חשבון SYSTEM. אומת מול השרת ב־8.9.2026.
מה שאין לה זה מסך. אין באפליקציה כפתור להריץ אותה עכשיו, ואין שום מקום שאומר מתי היא רצה לאחרונה או מה היא עשתה — התשובה היחידה נמצאת בקובץ C:\Racquet\logs\sweeps.log בשרת. שורה תקינה משם:
2026-09-08 00:55:03 reviews 200 {"considered":0,"invited":0,"reminded":0,
"failed":0,"mail_configured":true}
הסריקה אידמפוטנטית — כל שורה מסומנת ברגע שהמייל יצא — ולכן בטוח להריץ אותה שוב ביד: schtasks /run /tn Racquet_Review_Sweep. דורשת platform.user.mail.
ראו סעיף 8.2. שוברי השוויון, לפי הסדר: המשחק ביניהם → אחוז מערכות → אחוז משחקונים → הגרלה עם זרע שנשמר. משחקי ליגה מזינים את ה־ELO בדיוק כמו משחקי תחרות. משחק שעבר את תאריך היעד מסומן „באיחור” — ההחלטה מה לעשות בו היא של המנהל, לא של המערכת.
ראו סעיף 8.3. הנקודה שחוזרת: תיקון ידני הוא שורה ביומן, לא עדכון שקט, והוא גם חוסם ביטול תוצאה בלוח אם נרשם אחריו. שני סולמות נפרדים — יחידים וזוגות — וחישוב מחדש מריץ את הסולם שנבחר בלבד.
קריאה דחופה: מנהל מועדון מפורסם או נותן שירות מאושר מפרסם צורך מיידי („המאמן חולה, צריך מחליף ל־17:00”), והמערכת מיידעת עד 30 נותני שירות מתאימים באזור. הפותח בוחר אחד — אין תשלום, אין הסלמה, אין SMS ואין פוש.
שלוש לשוניות: לפתוח SOS · SOS פתוחים בשבילי · ה־SOS שלי. מצבים: פתוח · נבחר מישהו · בוטל · פג. „אני זמין” אפשר לענות פעם אחת בלבד. הקריאה פגה אחרי שש שעות, והתפוגה מחושבת בקריאה — אין worker.
קיים מסלול שרת שמציג את כל הקריאות למי שמחזיק platform.support.read, אבל המסך לא נבנה ואין SOS בין 26 כרטיסי הניהול. היום מנהל עוקב אחרי SOS רק דרך יומן פעולות — קודי הפעולה מתחילים ב־sos..
בנוסף: פריט התפריט SOS נתלה רק לנותן שירות מאושר או למנהל מועדון מפורסם. חשבון ניהול נקי אינו רואה אותו, ולכן אין כאן צילום של המסך.
שני דברים נפרדים באותו מסך:
כל עוד אף אחד לא נרשם אפשר לתקן; מרגע ההרשמה הראשונה השדה קפוא. בנוסף, המסד עצמו מונע רישום קטין בלי שם, תאריך לידה, שם מלווה וטלפון מלווה — ויומן הביקורת לא נושא אף אחד מהפרטים האלה. אין במערכת שום מידע רפואי, ויש בדיקה אוטומטית שנופלת אם מישהו יוסיף שדה כזה.
התיעוד מבטיח לשונית אקדמיות מומלצות במסך הניהול — היא אינה קיימת. ניהול האקדמיות אפשרי היום רק דרך ה־API, ובלעדיו הרשימה הציבורית תישאר ריקה.
שבעה אזורים — צפון · חיפה והקריות · השרון · מרכז · ירושלים והסביבה · דרום · כל הארץ / אונליין — ומתחתם 32 תת־אזורים. זה הבסיס לכל סינון מיקום במוצר.
אין מסך ניהול לאזורים, בכוונה. הוספה, פיצול או שינוי שם דורשים מיגרציה בבסיס הנתונים, כי תת־אזור שמישהו כבר בחר מקושר משלוש טבלאות, ופיצול הוא החלטת מוצר — לאן עוברים מי שבחרו את הישן. משתמש בוחר עד 12 תת־אזורים.
כלל התנהגות אחד שכדאי לדעת: מי שלא בחר אזורים מוצג בכל סינון אזור — החיפוש קורא „אין אזור” כ„מוצע בכל מקום”.
ראו סעיף 6.3 לאישור האדם. מעבר שירות למצב מפורסם נחסם על שלושה שערים, וכולם צריכים להיפתח:
שירות של ארגון פטור מהראשון והשלישי — המועדון עונה על אנשיו. מצבי שירות: טיוטה · מפורסם · מושהה · בארכיון. סוגים: אימון · שזירה · שותף לאימון · שותף למשחק · כושר · טיפול · אחר.
גישה לשירות שאינו שלך מוחזרת כ־404, לא 403 — מכוון: 403 היה מאשר שהשירות קיים למי שסורק מזהים.
מה רץ מעצמו, מתי, איפה הלוגים, ומה עושים כשמשהו נופל.
| שם המשימה | מתי | מה היא עושה |
|---|---|---|
| Racquet_API | בעלייה | מפעילה את שרת ה־API על 127.0.0.1:8790. |
| Racquet_DB_Backup | 05:00 כל יום | גיבוי מלא של בסיס הנתונים, העלאה ל־Google Drive, וניקוי ישנים. |
| Racquet_Mail_Sweep | כל 15 דקות | שולחת את תור דואר התחרויות. |
| Racquet_Review_Sweep | 06:10 כל יום | סריקת הביקורות. |
לראות את כולן בבת אחת, בשרת:
Get-ScheduledTask | Where-Object { $_.TaskName -match 'Racquet' } |
ForEach-Object { $_.TaskName + '(' + $_.State + ')' }
הרצה ידנית: schtasks /run /tn Racquet_Mail_Sweep, או ישירות powershell -NoProfile -ExecutionPolicy Bypass -File C:\Racquet\racquet_sweeps.ps1 -Job reviews.
אומת בשרת ב־8.9.2026: הפקודה שלמעלה מחזירה בדיוק את ארבע השורות האלה ולא יותר. לכן בכל מקום בחוברת שכתוב „אין worker ואין משימה מתוזמנת” על מודול — מגרשים, לוח יד שנייה, SOS, קורסים, מחנות — זו בדיקה שנעשתה, לא הנחה.
ומלכודת אחת בלוח המשימות של Windows: משימה שעדיין לא הגיע זמנה מציגה LastTaskResult = 267011 ותאריך ריצה אחרון של 1999. זה 0x41303 — „המשימה עוד לא רצה” — ואינו כישלון. כך נראה Racquet_Review_Sweep ביום שנוצר.
הסקריפט מחזיר 0 גם כשהשרת ענה 500 — במכוון, כי משימה שנכשלת בקול רם כל רבע שעה מלמדת אנשים להתעלם ממנה. רק C:\Racquet\logs\sweeps.log אומר את האמת. קוד יציאה 1 קיים רק כשההזדהות נכשלה.
הגיבוי רץ ב־05:00 ולא בשעה אחרת. הוא מייצר קובץ בשם Racquet_yyyy-MM-dd_HHmm.bak בתיקייה C:\Backups\Racquet\ — למשל Racquet_2026-09-07_0500.bak, בערך 30MB — ורושם ל־ C:\Backups\Racquet\backup.log.
שמירה: שבעת הקבצים האחרונים מקומית — ספירה, לא ימים (-LocalKeepCount 7) — ושלושים יום ב־Google Drive. כשל בהעלאה לענן אינו מפיל את הגיבוי; הקובץ המקומי בטוח, והלוג יאמר זאת.
העותק בענן אינו יושב בתיקייה בשם RACQUET. המשימה מריצה את הסקריפט עם -RemoteBase gdrive:DataPulse-BackUp, והקובץ נוחת תחת תאריך הלילה:
gdrive:DataPulse-BackUp/<yyyy-MM-dd>/Racquet/Racquet_<yyyy-MM-dd>_0500.bak
זו תיקיית הגיבויים המשותפת לכל פרויקטי DataPulse. מי שיחפש gdrive:Racquet-Backups לא ימצא שם דבר.
לילה תקין נראה כך — שורות אמיתיות מהשרת, מהגיבוי של 7.9.2026:
2026-09-07 05:00:01 === Racquet backup start ===
2026-09-07 05:00:03 SQL backup OK: C:\Backups\Racquet\Racquet_2026-09-07_0500.bak (31.1 MB)
2026-09-07 05:00:44 uploaded to gdrive:DataPulse-BackUp/2026-09-07/Racquet
2026-09-07 05:14:49 drive retention applied (removed > 30 d under gdrive:DataPulse-BackUp/*/Racquet)
2026-09-07 05:14:49 local backups kept: 7 (ceiling 7)
2026-09-07 05:14:49 === Racquet backup done ===
rclone copy gdrive:DataPulse-BackUp/2026-09-07/Racquet/Racquet_2026-09-07_0500.bak ^
C:\restore\ --config C:\Backups\rclone.conf
RESTORE DATABASE [Racquet]
FROM DISK='C:\restore\Racquet_2026-09-07_0500.bak'
WITH REPLACE;
אם צריך לרשום את המשימה מחדש מאפס:
schtasks /create /tn Racquet_DB_Backup ^
/tr "powershell -NoProfile -ExecutionPolicy Bypass -File C:\Backups\backup_db.ps1 ^
-Database Racquet -Dir C:\Backups\Racquet -RemoteBase gdrive:DataPulse-BackUp ^
-RcloneExe C:\Backups\rclone\rclone.exe -RcloneConf C:\Backups\rclone.conf ^
-LocalKeepCount 7" ^
/sc DAILY /st 05:00 /ru SYSTEM /rl HIGHEST /f
זו בדיוק שורת הפעולה הרשומה במשימה היום — הועתקה מהשרת, לא נבנתה מהזיכרון.
הפריסה מעלה גרסה חדשה של הקוד ושל העמודים. יש בה שלושה שערים, לא שניים:
לפני כל פריסה נשמר עותק מלא של backend ושל public תחת C:\Backups\Racquet\deploy_<stamp>\ (חותמת הזמן של הפריסה). גלגול אחורה = להעתיק את התיקייה הזאת חזרה ידנית ולהפעיל מחדש את Racquet_API. אין פקודה אחת שעושה את זה.
מקרה שכדאי להכיר: אם השער השני נכשל באמצע פריסה מלאה, ייתכן מצב של קוד חדש בשרת ועמודים ישנים חיים. אז — לשחזר מהתיקייה הנ״ל.
להבדיל מזה, סקריפטי ה־nginx כן מגלגלים לבד: הם שומרים גיבוי מתוארך, בודקים את התצורה, טוענים מחדש, מוודאים שכל האתרים עונים, ומשחזרים בכשל.
| מה | איפה | מתגלגל? |
|---|---|---|
| ה־API | C:\Racquet\logs\api.log | כן, יומי — api.log.2026-09-07 וכדומה |
| הסריקות | C:\Racquet\logs\sweeps.log | לא |
| הגיבוי | C:\Backups\Racquet\backup.log | לא |
| nginx | C:\nginx\logs\access.log | לא — 597MB |
| הפריסה | אין לוג פריסה כלל — נבדק: ב־C:\Backups\Racquet יש רק קבצי .bak, backup.log ותיקיות deploy_*. | |
שורת גישה תקינה ב־nginx נראית כך:
93.172.44.10 - - [08/Sep/2026:06:10:04 +0300] "GET /racquet/app/ HTTP/1.1" 200 1348406
"https://www.data-pulse.co.il/racquet/" "Mozilla/5.0 (iPhone; ...)"
בשרת מחכים כמה כלי ניתוח מוכנים, כולם לקריאה בלבד, תחת Scripts\server\: errors_since.py (כל שגיאות ה־5xx של היום לפי שעה), errors_detail.py, cr_traffic.py, sessions_today.py, support_today.py.
המסך יומן פעולות נותן את רוב מה שצריך, אבל לא את מסנן מזהה הבקשה — שהוא המסנן החזק ביותר. מול בסיס הנתונים:
USE Racquet;
GO
SET NOCOUNT ON;
DECLARE @action nvarchar(120) = N'tournament.'; -- prefix; NULL = all
DECLARE @actorName nvarchar(200) = NULL;
DECLARE @since datetime2(3) = '2026-09-01';
DECLARE @until date = '2026-09-08';
DECLARE @corr uniqueidentifier = NULL;
SELECT TOP (200)
a.id, a.created_at, a.action_code, a.entity_type, a.entity_reference,
a.correlation_id, a.reason, a.safe_metadata,
u.public_id AS actor_public_id, p.display_name AS actor_name,
o.name AS organisation_name
FROM dbo.AuditEvents a
LEFT JOIN dbo.Users u ON u.id = a.actor_user_id
LEFT JOIN dbo.Profiles p ON p.user_id = a.actor_user_id
LEFT JOIN dbo.Organisations o ON o.id = a.organisation_id
WHERE (@action IS NULL OR a.action_code LIKE @action + N'%')
AND (@actorName IS NULL OR p.display_name LIKE N'%' + @actorName + N'%')
AND (@corr IS NULL OR a.correlation_id = @corr)
AND (@since IS NULL OR a.created_at >= @since)
AND (@until IS NULL OR a.created_at < DATEADD(day, 1, @until))
ORDER BY a.id DESC;
GO
הרצה בשרת: sqlcmd -S SERVER2\SQLEXPRESS -E -d Racquet -I -b -i <file.sql>.
שתי עובדות על היומן שכדאי להכיר: הוא נכתב בתוך אותה טרנזקציה של השינוי שהוא מתאר — הרשומה והשינוי מתחייבים או מתגלגלים אחורה יחד; והוא מסרב לכתוב מפתחות רגישים (סיסמה, טוקן, סוד, הרשאה) ויזרוק שגיאה במקום לשמור אותם.
הפרק שכדאי לקרוא לפני הלחיצה, לא אחריה.
הסרת תפקיד, מחיקת פריט קטלוג, הסרת תמונת פרופיל, ומייל המוני. היומן ידע מי ומתי, אבל לא למה. אם הפעולה חריגה — כתוב את הסיבה בבקשת שינוי או בפנייה, כדי שתישאר עקבה.
דברים שנמצאו תוך כדי כתיבת החוברת ומעבר על המערכת החיה. אף אחד מהם אינו חוסם עבודה — אבל מנהל שלא יודע עליהם יבזבז זמן.
המספרים כאן נמדדו בשרת ב־8.9.2026, לא נאמדו.