למה חוב טכני באוטומציות שונה מחוב טכני רגיל
ב-Salesforce קל יותר לצבור חוב טכני מאשר בסביבת פיתוח רגילה, כי הכלי מאפשר לכל אחד להוסיף אוטומציה בלי לעבור דרך תהליך קוד מסודר. כל Admin שמוסיף Flow Before Save כדי לפתור בעיה נקודתית, כל Trigger שמישהו הוסיף לפני שנתיים ואיש לא זוכר למה, וכל שדה נוסחה שמכיל תלות בשדה אחר שכבר לא קיים — כל אלה מצטברים לשכבה שאיש לא רואה בשלמותה.
ההבדל המהותי בין חוב טכני רגיל לחוב טכני באוטומציות Salesforce הוא שהאחרון כמעט תמיד נעדר תיעוד מרכזי. קוד יושב ב-Repository עם היסטוריית Commits; Flow יושב ב-Setup בלי הסבר למה נוצר. זה הופך את שלב הזיהוי לקשה במיוחד — לא כי הבעיה מסובכת טכנית, אלא כי אין למי לשאול.
מאמר זה עוסק בזיהוי, מדידה וצמצום של החוב הזה. הוא אינו דן בשאלה מתי לבחור Flow ומתי Apex מלכתחילה — לכך מוקדש Flow מול Apex: איך בוחרים.
שלושה סוגי חוב שמתנהגים אחרת
לא כל חוב טכני זהה, וטיפול גורף בכולם כאותה בעיה מוביל לבזבוז מאמץ. כדאי להפריד לשלוש קטגוריות:
| סוג חוב | דוגמה טיפוסית | מה קורה אם מתעלמים | עדיפות טיפול |
|---|---|---|---|
| חוב מבני | כמה Triggers על אותו אובייקט בלי Framework מאחד | סדר ריצה בלתי צפוי, כשל שקט | גבוהה |
| חוב לוגי | Flow עם עשרות ענפי החלטה שמייצג כלל עסקי שכבר השתנה | החלטות שגויות שרצות בשקט | גבוהה |
| חוב תחזוקתי | שדות, Flows ומשתני קבע ללא תיעוד או שימוש | זמן פיתוח מתארך, פחד לגעת | בינונית |
חוב מבני וחוב לוגי מייצרים סיכון תפעולי ממשי — הם עלולים לגרום לנתון שגוי שמגיע ללקוח או לדוח כספי. חוב תחזוקתי מאט את הצוות אבל לא בהכרח שובר תהליך. חלוקה זו קובעת את סדר הטיפול: קודם מסלקים סיכון תפעולי, אחר כך משפרים מהירות פיתוח.
איך מזהים חוב לפני שהוא מתפוצץ בייצור
הזיהוי לא צריך להתחיל בסקירת קוד ידנית מקיפה — זה יקר מדי ולא בר-קיימא. הוא מתחיל בכמה מדדים כמותיים שאפשר לשלוף תוך שעה:
- מספר Flows פעילים על כל אובייקט ליבה (Lead, Opportunity, Case וכדומה). מעבר לחמישה-שישה Flows פעילים על אותו אובייקט, סדר הריצה הופך קשה לחיזוי.
- מספר Triggers שאינם מאוחדים תחת Framework אחד לכל אובייקט. יותר מ-Trigger אחד לאובייקט הוא כבר סימן אזהרה, אלא אם קיימת שכבת ניתוב מפורשת.
- צפיפות שאילתות SOQL בתוך לולאות שמופיעה בלוגים כ-Governor Limit קרוב לסף, גם אם לא נחצה בפועל.
- זמן ריצה חריג של Flow או Apex Batch שגדל לאורך זמן בלי שהנפח העסקי גדל באותו יחס.
- שדות ומשתנים שאין להם שימוש מזוהה בדוח Field Usage, שנשארים "למקרה שמישהו צריך".
המדדים האלה לא מוכיחים בעיה חד-משמעית, אבל הם מספקים רשימת חשודים ממוקדת. שילוב שלהם עם עומק הבנת האינטגרציות שהאוטומציה תלויה בהן מפורט בדפוסי אינטגרציה Salesforce.
Decision Framework: מה מטפלים קודם
לא כל ממצא ברשימת החשודים שווה השקעה זהה. Framework פשוט לתעדוף מבוסס על שני צירים — השפעה עסקית והסתברות לתקלה:
| מצב | השפעה עסקית אם נכשל | הסתברות לכשל בטווח קרוב | פעולה |
|---|---|---|---|
| אוטומציה על תהליך הזמנה/חיוב עם Triggers מרובים ולא מתועדים | גבוהה | גבוהה | Refactor מיידי, מחוץ לתור הרגיל |
| Flow מורכב על עדכון סטטוס פנימי בלי השפעה חיצונית | נמוכה | גבוהה | תיעוד ופישוט בקצב רגיל |
| Trigger ישן שעובד יציב אך לא ברור מדוע קיים | גבוהה פוטנציאלית | נמוכה | תיעוד תחילה, לא נגיעה מיידית |
| שדות לא בשימוש ומשתני קבע יתומים | נמוכה | נמוכה | ניקוי מחזורי ברמת Release |
הכלל המנחה: לא מטפלים לפי מה שהכי מציק למפתחים, אלא לפי מה שהכי מסוכן לעסק. Trigger ישן ויציב שאיש לא מבין הוא לעיתים המקרה המפתה ביותר לגעת בו ראשון — וזה בדיוק המקרה שבו נגיעה לא זהירה גורמת לנזק הגדול ביותר.
תרחיש ארגוני: חברת ביטוח עם 14 Flows על Opportunity
נניח חברת ביטוח בינונית שמנהלת מכירות B2B דרך Salesforce כבר שש שנים. לאורך הזמן נצברו 14 Flows פעילים על אובייקט ה-Opportunity: שבעה מטפלים בעדכוני שלב, שלושה שולחים התראות פנימיות, שניים מסנכרנים נתונים לכלי BI חיצוני, ושניים נוספים הם שרידים מתהליך ישן שהוחלף לפני שנתיים אך מעולם לא הושבתו.
הטריגר לזיהוי הבעיה היה תקלה קונקרטית: עסקה עברה לשלב "סגור-זכה" אבל ההתראה לצוות החיתום לא נשלחה, כי Flow אחר עדכן את אותו שדה במקביל ויצר תזמון ריצה שלא נצפה מראש. הצוות בילה יומיים בניסיון להבין למה — לא כי הבאג היה מורכב, אלא כי אף אחד לא ידע את סדר הריצה המלא של 14 הרכיבים.
הטיפול לא היה "לכתוב הכול מחדש ב-Apex". הצוות מיפה תחילה את כל 14 ה-Flows וסיווג אותם לפי הטבלה שלמעלה: שני ה-Flows הישנים הושבתו לאחר אימות שאין תלות פעילה, שלושת ההתראות אוחדו ל-Flow אחד עם לוגיקת ניתוב ברורה, ושבעת עדכוני השלב אוחדו תחת Record-Triggered Flow יחיד עם סדר ריצה מפורש. תוצאה: מ-14 רכיבים ל-6, עם תיעוד סדר ריצה שכל מפתח חדש יכול לקרוא תוך רבעה שעה.
סיכונים בתהליך הצמצום עצמו
צמצום חוב טכני הוא פעולה בעלת סיכון משלה, לא רק תיקון סיכון קיים:
| סיכון | איך הוא נראה בפועל | פעולת מניעה |
|---|---|---|
| שינוי סדר ריצה שובר תלות נסתרת | תהליך שעבד מפסיק לעבוד אחרי איחוד Flows | מיפוי תלויות מלא ובדיקת Regression לפני כל איחוד |
| מחיקת רכיב "מת" שבעצם עדיין רץ בתרחיש נדיר | תקלה שמופיעה רק בסוף רבעון או בתרחיש קצה עונתי | בדיקת יומני הרצה על פני שנה מלאה, לא רק חודש אחרון |
| המרה ל-Apex בלי בעל תהליך שמבין את הכלל העסקי | הקוד החדש "נכון טכנית" אך מיישם כלל ישן שכבר השתנה | אימות כלל עסקי מול בעל תהליך לפני כתיבת קוד, לא רק מול הקוד הקיים |
| Refactor שנעשה ב-Sandbox אחד ולא מסונכרן | הבעיה חוזרת בסביבת ייצור אחרי Deploy הבא | לנהל את השינוי דרך תהליך Release רגיל ולא כתיקון "מחוץ לתור" |
הסיכון המשותף לכולם הוא אותה תופעה: הצוות בטוח שהוא "רק מנקה" ולכן מדלג על בדיקות שהיה עורך לפיצ'ר חדש. ברמת Governance, Refactor צריך לעבור את אותו תהליך קבלה כמו פיתוח רגיל — לא פחות.
מדדים למעקב שוטף אחרי הצמצום
כדי לדעת שהמאמץ באמת מקטין חוב ולא רק מזיז אותו, כדאי לעקוב אחרי:
- מספר רכיבי אוטומציה פעילים לאובייקט, כמדד מגמה רבעוני ולא נקודתי.
- זמן ממוצע לאבחון תקלת אוטומציה, מרגע הדיווח ועד זיהוי הרכיב האחראי.
- אחוז הרכיבים המתועדים מתוך סך האוטומציות הפעילות באשכול הליבה.
- מספר תקלות חוזרות על אותו רכיב בטווח של שלושה חודשים.
ארגונים שמתקשים לתעדף בין Refactor לפיתוח שוטף נעזרים בשירות ארכיטקטורת CRM לבניית תוכנית עבודה מחייבת ומדידה מולה.
Checklist תפעולי לפני שמתחילים Refactor
- ☐ קיימת מפה מלאה של כל האוטומציות הפעילות על האובייקט הרלוונטי
- ☐ ידוע סדר הריצה בפועל, לא רק לפי סדר יצירה
- ☐ כל רכיב שמיועד להסרה נבדק מול יומני הרצה על פני שנה מלאה
- ☐ בעל התהליך העסקי אישר את הכלל שמיושם מחדש
- ☐ קיימת סביבת בדיקה שמדמה נפח נתונים אמיתי
- ☐ הוגדר מדד "לפני ואחרי" למספר הרכיבים ולזמן האבחון
- ☐ תהליך ה-Refactor עובר Release רגיל, לא Deploy חריג
- ☐ הוקצתה קיבולת קבועה בכל Sprint לטיפול מתמשך, לא רק אירוע חד-פעמי
סיכום
חוב טכני באוטומציות Salesforce נבנה בשקט, רכיב אחד בכל פעם, ולכן גם צריך להיפרק בשקט — לא בפרויקט ניקוי גדול שעוצר פיתוח לחודש. הכלים הדרושים הם פשוטים יחסית: ספירת רכיבים לפי אובייקט, מיפוי סדר ריצה, וסיווג לפי השפעה עסקית מול הסתברות לכשל. מה שקובע הצלחה הוא המשכיות — הקצאת קיבולת קבועה לצמצום החוב לצד הפיתוח השוטף, ולא רדיפה נקודתית אחרי הרכיב שגרם לתקלה האחרונה. ארגון שמאמץ הרגל מדידה כזה מגיע למצב שבו כל מפתח חדש יכול להבין תוך שעה מה קורה בשמירת רשומה — וזה, בסופו של דבר, ההגדרה המעשית ביותר להיעדר חוב טכני.
