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

על רוב ההחלטות הארכיטקטוניות כותבים כשהן מצליחות. על ההחלטה הזו אני כותב כי ביטלתי אותה. במרץ 2026 פיצלתי את הפלטפורמה של תע“ץ למאגר קוד נפרד לכל חלק. ביוני החזרתי הכול למקום אחד, ביום אחד, בלי לאבד אף קומיט. שתי ההחלטות היו נכונות בזמן שקיבלתי אותן, והחלק המעניין הוא איך ידעתי מתי לשנות כיוון.
הבעיה
הפלטפורמה הדיגיטלית של תע“ץ היא הפלטפורמה הפנימית של מרכז תעסוקת עובדי צה”ל: פורטל בעברית, מערכת ניהול התוכן שמאחוריו, שירות קבצים ומדיה מאובטח, שירות התראות ומנוע חיפוש, כולם על מערכת עיצוב משותפת אחת ועם כניסה אחידה אחת. היא נותנת לסגלי משא“ן, למפקדים ולעובדים מקום אחד שבו הם מוצאים בעצמם מידע רשמי, ברשת סגורה בלי אינטרנט. כתבתי את האפיון שלה באוקטובר 2025, ובחמשת החודשים הראשונים כל הקוד שלה היה במאגר אחד.
המאגר הזה גדל מהר. כבר בינואר 2026 ספריית הרכיבים המשותפת חולקה בתוכו לחבילות של ליבה, ממשק, מבנה דפים וכלי עזר, ולצידן רכיבים של לוח שנה, עורך וסייר קבצים. עד פברואר נוספו לו גם שירות הקבצים והמדיה עם אפליקציית הניהול שלו, כניסה אחידה (SSO) ומנוע חיפוש שנכתב מחדש.
ואז, במרץ, השתנו שני דברים:
- הצטרפה מפתחת נוספת. מזל אביטבול הגיעה כדי לבנות את שירות ההתראות. עד אז הייתי המפתח היחיד בפרויקט.
- החלקים התחילו להתקדם בקצבים שונים. הפורטל השתנה כל שבוע. את החבילות המשותפות היה צריך לשנות בזהירות, כי הכול נשען עליהן. ולשירות הקבצים והמדיה היו תלויות Python משלו.
מה ניסיתי: מאגר לכל חלק
במרץ 2026 פיצלתי את הקוד למאגר נפרד לכל חלק: החבילות המשותפות, הפורטל, שירות הקבצים והמדיה, הכניסה האחידה, ואחר כך גם שירות ההתראות, עם מאגר מרכזי שקשר ביניהם. המטרות נכתבו בתוכנית הפיצול:
- לכל חלק יהיה מחזור שחרור משלו וסביבת Python מבודדת משלו;
- את החבילות המשותפות משדרגים לפי גרסה, כך שכל חלק עובר לגרסה חדשה כשהוא מוכן;
- מפתחת נוספת יכולה לעבוד במאגר אחד בכל פעם, בלי להפריע לכל השאר.
כל מאגר קיבל גם קובץ CONTEXT.md, מסמך קצר שסוכן AI קורא לפני שהוא נוגע באותו חלק.
באותה תוכנית כתבתי גם את המחיר, עוד לפני ששילמתי אותו: שינוי שחוצה כמה חלקים דורש כמה בקשות מיזוג. ידעתי שזו נקודת התורפה, וקיבלתי אותה כי באותו רגע עבודה במקביל הייתה חשובה יותר.
והפיצול עשה את שלו. מזל בנתה את שירות ההתראות, כ-4,000 שורות, ואת סביבת ה-Docker לפיתוח מקומי, על מבנה השירות המשותף שקבעתי. חמש מתוך שש בקשות המיזוג שלה מוזגו אחרי הסקירה שלי; השישית נסגרה כשהשירות שלה עבר למאגר משלו. מרץ היה החודש העמוס השני של הפלטפורמה, עם 76 קומיטים.
החשבון הגיע
במאי 2026 כתבתי מחדש את הספרייה המשותפת. במאגר אחד זה היה נשאר שינוי אחד. בכמה מאגרים זה היה גל שלם: חמש בקשות מיזוג מתואמות שאפשר היה למזג רק יחד.
וגם כך זה השתבש. מיזוג אחד בוטל, והקונפליקטים בו נפתרו ידנית. התיאום עצמו הפך לחלק גדול מהעבודה: סדר המיזוגים דרש לא פחות תשומת לב מהשינוי.
הפיצול גם הפך אותי לשומר הסף של הפלטפורמה. במאגרים של הפיצול נפתחו 22 בקשות מיזוג; 20 מתוכן מוזגו, כולן על ידיי ואחרי סקירה. זה היה טוב לאיכות, אבל המשמעות הייתה שכל שינוי שחוצה כמה חלקים חיכה בתור לאדם אחד, שצריך לעבור על חמישה מאגרים בסדר הנכון.
זה היה הסימן. לא תחושה כללית שמאגר אחד (monorepo) עדיף, אלא בדיוק המחיר שהתוכנית שלי חזתה, והפעם במספרים: בבקשות מיזוג ובמיזוג אחד שבוטל.
מה עבד: סביבת עבודה אחת, עם כל ההיסטוריה
ביוני 2026 החזרתי את החלקים לסביבת עבודה אחת של pnpm, ביום אחד, עם כל קומיט מההיסטוריה שלהם. החבילות המשותפות, הפורטל,
שירות הקבצים והמדיה ושירות ההתראות נכנסו בעזרת git subtree add, כל אחד כמיזוג לתוך תיקייה משלו, כך ששום קומיט לא נדחס
ושום דבר לא אבד; את מאגר הכניסה הוצאתי משימוש באותו יום, כי הכניסה האחידה עברה לשירות חיצוני.
סביבת העבודה שומרת על הגבולות שהפיצול נתן לי, אבל הפעם כחבילות ולא כמאגרים:
taaz workspace
├── packages @taaz/ui · core · layout · utils
│ calendar · editor · explorer · showcase
├── apps portal · file and media service
└── services notifications · search
שמונה חבילות משותפות, שתי אפליקציות ושני שירותים. שינוי שחוצה כמה חלקים הוא שוב קומיט אחד וסקירה אחת, והחבילות המשותפות עדיין נפרדות, לכל אחת שם ומקום משלה.
התברר שהאיחוד גם התאים למה שבא אחריו. מיוני עבדתי עם Claude Code, לפי מסמכי תכנון, תוכניות עבודה ובדיקות כתובים, וסוכן שרואה את כל החבילות יחד יכול לבצע שינוי רוחבי בקומיט אחד וקוהרנטי. יוני היה החודש העמוס ביותר של הפלטפורמה, ובפער גדול: 196 קומיטים. מתוך 217 הקומיטים מיוני ואילך, 179 נעשו עם Claude Code בהכוונה שלי. המעבר לכניסה החיצונית ותהליך העבודה של המפרסמים, שנכנס לסייר הקבצים באותו חודש, נגעו כל אחד בכמה חלקים בבת אחת.
סביבת העבודה גם הוזילה את עבודות הניקוי שבאו אחר כך. ביולי העברתי את קוד הפריסה של הפלטפורמה ל-Launchpad, כלי הפריסה שלי, והפלטפורמה נפטרה מ-3,186 שורות של מנוע פריסה משלה. באוגוסט, בקשה של ההנהלה להסתיר חגים מסוימים מלוח השנה עברה ממסמך תכנון כתוב ב-09:18 ליכולת גמורה ב-16:57, דרך ה-API, מסך מערכת ניהול התוכן ולוח השנה הציבורי: עשרה קומיטים ביום עבודה אחד.
מה הייתי עושה אחרת
גם היום הייתי מחלק את העבודה כדי שמפתחת שנייה תוכל לעבוד, אבל אני לא בטוח שהייתי מפצל בשביל זה את המאגר. את רוב מה שרציתי במרץ – קצב שחרור לכל חלק, חבילות משותפות עם גרסאות ומפתחת עם תחום משלה – אפשר לקבל גם מסביבת עבודה אחת עם גבולות ברורים בין החבילות. בחרתי בהפרדה החזקה לפני שניסיתי הפרדה קלה יותר.
הייתי גם כותב בתוכנית תנאי יציאה, ולא רק את המחיר. התוכנית ממרץ אמרה כמה הפיצול יעלה, אבל לא אמרה מתי המחיר יהיה גבוה מדי. במאי זיהיתי את זה בעצמי, אבל משפט כמו “אם שינוי משותף דורש יותר משתי בקשות מיזוג מתואמות, מאחדים בחזרה” היה הופך את ההחלטה למהירה יותר ופחות אישית.
ודבר אחד שאני שמח שעשיתי: כתבתי את המחיר לפני ששילמתי אותו. כשהגיע מאי, לא התווכחתי עם עצמי אם הפיצול היה טעות; פשוט בדקתי תחזית.
איפה זה רץ
הפלטפורמה רצה בסביבת הייצור ברשת הסגורה של תע“ץ, ונבנתה ליותר מ-14,500 משתמשים. זה פרויקט הדגל שלי, וסיפור הפרויקט של הפלטפורמה הדיגיטלית של תע“ץ מכסה את המערכת כולה: הפורטל, מערכת ניהול התוכן, שירות הקבצים והמדיה, מערכת העיצוב ושלושת הדורות של הארכיטקטורה שלה. מזל אביטבול בנתה את שירות ההתראות ואת סביבת הפיתוח המקומית; כל שאר ההחלטות בפוסט הזה היו שלי.
הפרויקט
אתר אחד, שני כיווני קריאה, שלוש רמות תנועה: איך בניתי את idanach.com