תשלומי מילואים: מסקרייפר לתוסף Chrome

פורסם במקור כפוסט בלינקדאין, והורחב כאן.

הקוד ב־GitHubOmerLapidot/btl-scraper

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

נאמר מראש: הכלי עדיין לא בשל. פרסמתי אותו כדי לקבל הערות, לא כדי שמישהו יסמוך עליו.

הכסף מגיע בשני מסלולים, ורוב האנשים בודקים רק אחד

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

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

השלב הראשון: סקרייפר שאפשר לתת רק לעצמי

הכלי הראשון היה תוכנית Node שמתחברת ל-API של הפורטל וקוראת הכל: מעמד ביטוחי, חוב דמי ביטוח ובריאות, חוב גמלאות, יומן הגבייה, נתוני מילואים, מסמכים שהעליתם, פניות קודמות, ורשימת המכתבים — כולל הורדת ה-PDF של כל מכתב. אין לו תלויות npm בכלל; הוא מדבר עם הפורטל דרך ה-fetch המובנה של Node.

הדבר היחיד שהתעקשתי עליו מההתחלה הוא שהכלי יהיה קריאה בלבד, ושזה ייאכף במבנה ולא בהצהרה. יש בקוד רשימת נתיבים מוגדרת מראש ונעולה לשינוי (frozen Set), וכל בקשה עוברת דרך בדיקה שזורקת שגיאה לפני שנשלחה בקשת רשת כלשהי אם הנתיב לא ברשימה. אין התאמת תבניות ואין גישוש אחר endpoints. להוסיף מקור מידע חדש זו עריכה מכוונת של הרשימה, לא תופעת לוואי.

זה עבד יפה. הוא פשוט לא כלי שאפשר לתת לאדם אחר.

הפתרון: לרכוב על ה-session שכבר יש לכם

התוסף לא מבקש סיסמה, לא רואה אותה ולא שומר אותה. אתם מתחברים לאתר בעצמכם כרגיל. משם, התוסף משתמש ב-session שהדפדפן שלכם כבר מחזיק כדי לקרוא את אותם endpoints שהאתר עצמו קורא.

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

כמה החלטות נגזרו מזה ישירות:

  • הרשאות מינימום. לתוסף יש גישה ל-ps.btl.gov.il בלבד. לא לשום אתר אחר.
  • הנתונים שנמשכים לא נשמרים בדיסק. מה שנקרא נשמר בזיכרון בלבד ונמחק כשסוגרים את הדפדפן.
  • אין קריאות רשת חיצוניות. הפונטים ארוזים בתוך גיליון הסגנון, יש CSP הדוק, והקריאה היחידה שיוצאת היא לאתר של הביטוח הלאומי — אותו origin שאתם ממילא מחוברים אליו.
  • דיאגנוסטיקה בלי דליפות. המסך שמסביר "למה זה לא עבד" מציג שמות של מפתחות אחסון ואורך token, אף פעם לא ערכים. כשקריאה נכשלת נרשם רק קוד הסטטוס ולא גוף התשובה, כי בנקודה מאומתת גוף התשובה עלול לגרור את השם ותעודת הזהות של המשתמש לתוך לוג.

חישוב המילואים בתוסף הוא פורט מילולי של הקוד מהסקרייפר, ואימתתי שהפלט זהה בין השניים. לא רציתי שתי גרסאות של אותה מתמטיקה שנפרדות בשקט.

הפלט: טבלה, ואז קובץ שאפשר למסור לכל LLM

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

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

עצרתי כאן בכוונה ולא בניתי סוכן שעושה את ההשוואה בעצמו. תלוש שכר ודוח תנועות בנק הם מידע רגיש, והבחירה למי מוסרים אותם צריכה להישאר אצלכם.

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

מה עוד לא עובד

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

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

מה שלמדתי

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

זה חוזר כמעט בכל אוטומציה שאני בונה בארגונים: השאלה "מי מחזיק את המפתחות" מגיעה לפני השאלה "מה הכלי עושה". ככה בדיוק נראה תהליך העבודה שלי.

שאלות שחוזרות

איך אפשר לבדוק אם קיבלתי את כל תגמולי המילואים שמגיעים לי?

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

האם תוסף Chrome שקורא את הביטוח הלאומי רואה את הסיסמה שלי?

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

מהי תוספת ה-40% בתגמולי מילואים?

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

האם הכלי הזה מוכן לשימוש?

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