פלטפורמת חריגות לדיור · AfifAI
מקרה בוחן · 2026 · פלטפורמת נתונים ו־⁠AI

פלטפורמה אחת לבדיקת חריגות בתיק נכסים לאומי

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

Python · FastAPINext.js · TypeScriptAzure Container AppsMicrosoft FabricAzure OpenAIEntra IDTerraformAzure DevOps
לקוח
חברת דיור ציבורי ארצית בישראל (חסוי)
התפקיד שלי
ראש צוות, ארכיטקט ומפתח בפועל
שלב
סביבות פיתוח וייצור ב־⁠Azure, ופייפליין יומי בפרודקשן
סטטוס
באוויר
במבט מהיר
⁦2–10⁩רפליקות backend שכותבות למצב בדיקה משותף בלי לאבד עדכונים (קודם: הכתיבה האחרונה מנצחת)
33 עד 0קריאות LLM לדוחות בהרצה יומית שבה הנתונים לא השתנו
≈1 MBנקרא לכל כרטיס נכס, במקום טבלה של כ־⁠300 MB: דלי אחד מתוך 300
1,846טסטים ב־⁠Python ובדיקת TypeScript לפני כל מיזוג (קודם לא היה שער)
0נקודות קצה ציבוריות ב־⁠backend וסודות שמורים בפייפליין, אחרי המעבר ל־⁠Entra
15תרחישי בדיקה ב־⁠4 מחלקות, ועוד מודול חשמל עם 10 מסכים
42שלבי פייפליין ב־⁠8 פאזות, מה־⁠lakehouse של ה־⁠ERP ועד תוצאות לבדיקה
9,472חשבונות חשמל שמקבלים ציון אוטומטי, מתוך 9,429 קובצי PDF
הבעיה

עשרות אלפי נכסים, והסימנים מפוזרים בכל ה־⁠ERP

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

מה היה באחריותי

ארכיטקטורה, הטמעה והקשחה לפרודקשן

  • הובלתי את הצוות וקבעתי את הארכיטקטורה: פייפליין אופליין שעושה את העבודה הכבדה מול ה־⁠ERP, ו־⁠API רזה שרק מגיש תוצרים מוכנים.
  • פיתחתי לאורך כל השכבות: ראוטרים ב־⁠FastAPI, ממשק Next.js בעברית, ה־⁠DAG של הפייפליין, הגלאים והמדרגים, ותהליכי ה־⁠LLM לדוחות ולעוזרים.
  • העברתי את ההטמעה ל־⁠Azure DevOps של הלקוח: בדיקות PR, פריסה אוטומטית ל־⁠dev, פריסה ל־⁠prod רק מ־⁠master ורק אחרי אישור, ופייפליין plan/apply ל־⁠Terraform.
  • העברתי את הפרודקשן אל מאחורי Entra ID. ה־⁠backend הפך לפנימי בלבד, וכל קריאת API עוברת דרך proxy באותו origin.
  • איתרתי וסגרתי את המסלולים שבהם היו עלולים ללכת לאיבוד נתוני בדיקה משותפים בין רפליקות.
ארכיטקטורה

העבודה הכבדה אופליין, API רזה ופרטי אונליין

התרשים רחב מהמסך: החליקו הצידה לצפייה בכולו →

ל־⁠backend אסור לייבא טוענים של נתונים גולמיים או לקרוא snapshots של ה־⁠ERP, וטסט אוכף את זה. כך כל בקשה נשארת בתוך קונטיינר של 2 GiB, וזמן התגובה לא תלוי בגודל ה־⁠ERP. האחסון מחולק לפי בעלות: הפייפליין הוא הבעלים של מה שהוא מחשב, והאפליקציה היא הבעלים של מה שאנשים מחליטים. הרצה חוזרת של הפייפליין אף פעם לא מוחקת בדיקה.

החלטות תכנון

מסלול בקשה קטן, ובני אדם מחליטים

תוצרים מוכנים במקום שאילתות חיות ל־⁠ERP

כל ה־⁠joins, הפיצ׳רים והדירוג רצים ב־⁠job הלילי, עם 4 ליבות ו־⁠28 GiB זיכרון. ה־⁠API קורא קובצי parquet שמחולקים ל־⁠300 דליים לפי hash, עם cache של 5 דקות ותקרה של 32 דליים. המחיר: הנתונים טריים רק כמו ההרצה האחרונה, ולכן כל הרצה כותבת manifest שמראה כמה הם עדכניים.

Blob עם בקרת מקביליות אופטימית, בלי בסיס נתונים חדש

מצב הבדיקה הוא כמה מסמכי JSON קטנים. במקום להוסיף בסיס נתונים, כל כתיבה משותפת עוברת דרך helper אחד: קורא עם ETag, מחיל את השינוי, כותב רק אם אף אחד לא שינה בינתיים, ומנסה עד 3 פעמים. המחיר: בעומס כבד מתקבל 503 נקי במקום תור.

הזדהות בקצה

באפליקציה אין קוד התחברות. הזדהות Entra ID מסוג Easy Auth מגינה על ה־⁠frontend, הדפדפן מדבר רק עם proxy באותו origin, וה־⁠backend סומך על כותרות הזהות רק כי אין לו ingress ציבורי. המחיר: הרשאות לפי משתמש מנוהלות בקבוצות Entra ולא באפליקציה.

ה־⁠AI מציע, אדם מחליט

קריאות ה־⁠LLM מחזירות פלט מובנה, מאומת ובעל גרסה. הדירוגים והערכות ה־⁠AI מוצגים כעדיפות לבדיקה ולא כהוכחה לאשמה. תשובות לפניות תקשורת עוברות טיוטה ואז אישור לפי תפקידים. המחיר: איטי יותר מפרסום אוטומטי, אבל לכל תוצאה יש בעלים.

שחרורים שאפשר לעקוב אחריהם ולבטל

ה־⁠images מתויגים ב־⁠SHA של הקומיט. prod רץ רק מ־⁠master ואחרי אישור, וכל פריסה מחכה עד שהגרסה החדשה מדווחת שהיא תקינה (עד 40 בדיקות בהפרש של 15 שניות). המחיר: כמה דקות נוספות לכל פריסה, ובתמורה rollback בצעד אחד.

יומן הנדסי

בעיות שמתגלות רק בפרודקשן

בטיחות נתונים

שינוי סטטוס אחד יכול היה למחוק את כל הבדיקות

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

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

מקביליות

שתי רפליקות, קובץ אחד, עדכון אחד שנעלם

ב־⁠prod רצות לפחות 2 רפליקות של ה־⁠backend. עדכוני מדרג השיפוץ, מנויי ההתראות ואישורי המחירון נכתבו בשיטת read-modify-write בלי בדיקת גרסה, כך ששתי שמירות כמעט בו־זמניות השאירו רק את המאוחרת.

helper משותף אחד מבצע כתיבה מותנית ETag ומחיל את השינוי מחדש על הנתונים העדכניים. טסט גבול מכשיל את ה־⁠build אם קוד חדש כותב JSON משותף בדרך אחרת.

גישה

הזדהות בלי לגעת בקוד האפליקציה

הדפדפן פנה ישירות לכתובת הציבורית של ה־⁠backend. הזדהות שמגינה רק על ה־⁠frontend הייתה משאירה את ה־⁠API פתוח.

קריאות ה־⁠API עוברות עכשיו ל־⁠rewrite באותו origin (/backend-api) שנאפה לתוך ה־⁠build. ה־⁠ingress של ה־⁠backend הפך לפנימי, וכותרות הזהות נאמנות רק מאחורי הגבול הזה. שם המשתמש בכותרת מגיע עכשיו מה־⁠backend, ולא מקריאה של הדפדפן שנכשלה מאחורי ה־⁠proxy.

הטמעה

פריסות שנראו ירוקות ולא היו

ה־⁠builds הראשונים ב־⁠Azure DevOps נכשלו על נתיב Dockerfile שגוי ועל agent שלא היה מקובע לגרסה. בנוסף, קונטיינר תקין יכול היה להסתיר frontend שנבנה עם חיווט API שגוי.

קיבעתי את ה־⁠agent ל־⁠Ubuntu 24.04, איחדתי סקריפט build-and-deploy אחד לכל הרכיבים, נתתי לכל revision סיומת ייחודית, הוספתי המתנה לתקינות ובדיקה של הגדרות ה־⁠API בתוך ה־⁠build הארוז.

תשתית

Terraform שיכול היה להפתיע את prod

הסביבות הקיימות נוהלו ממחשב של מפתח, בלי plan שעבר בדיקה.

הרצות plan בלבד מפרסמות artifact עם סיכום. ה־⁠apply דורש אישור סביבה ורץ רק מ־⁠master. הרשאת admin ל־⁠Key Vault קובעה, כדי שה־⁠plans יפסיקו להציג drift מדומה.

עלות LLM

יצירה מחדש של דוחות שהנתונים שלהם לא השתנו

ההרצה היומית בוחרת את 20 הנכסים ו־⁠13 הבניינים המובילים לדוחות AI, בקצב של בקשה אחת לדקה כדי לעמוד במכסה.

לכל דוח יש טביעת אצבע של כל הראיות שלו: קריאות, ממצאים, הערות וכספים. אם הראיות לא השתנו, הדוח השמור משמש שוב. יצירה מחדש בהיקף גדול נעצרת אם אין לה אישור מפורש, וכל ה־⁠workers חולקים את זמני ההמתנה של Retry-After.

נסו בעצמכם

שני בודקים שומרים באותו רגע

רפליקה A ורפליקה B מטפלות שתיהן בשמירה לאותו קובץ בדיקות.

    המחשה של פרוטוקול הכתיבה. בלי נתוני לקוח.

    תוצאות

    איפה זה עומד

    תחום
    לפני
    אחרי
    מצב בדיקה משותף
    הכתיבה האחרונה מנצחת. קריאה שנכשלה יכלה לשמור קובץ ריק.
    כתיבה מותנית ETag עם 3 ניסיונות. שגיאת קריאה נכשלת בבטחה (503).
    גישה
    backend ציבורי ורשימות IP מורשות
    הזדהות Entra ID ב־⁠frontend, וה־⁠backend פנימי בלבד
    שחרור גרסה
    workflows שהופעלו ידנית, בלי שער מיזוג
    שער PR עם 1,846 טסטים ו־⁠tsc, פריסה אוטומטית ל־⁠dev, ופריסת prod מ־⁠master אחרי אישור
    מאמץ לשחרור
    כ־⁠⁦30–45⁩ דקות של צעדים ידניים לכל רכיבהערכה
    מיזוג ואז אישור אחד. בדיקת תקינות ו־⁠rollback לפי SHA.
    דוחות AI כשהנתונים לא השתנו
    33 קריאות, כ־⁠33 דקות בקצב המכסה
    0 קריאות. הדוח השמור משמש שוב.
    נתונים שנקראים לכרטיס נכס
    טבלה מלאה, ≈300 MB
    דלי אחד, ≈1 MB, נשמר ב־⁠cache ל־⁠5 דקות
    דוח נכס תקופתי
    כ־⁠2 שעות של ליקוט ידני מדוחות ERPהערכה
    נוצר מראיות מוכנות בתוך דקות
    בדיקת חשבונות חשמל
    כ־⁠300 שעות אנליסט למעבר מלא על כ־⁠9.5 אלף חשבונותהערכה
    ציון אוטומטי. רק מקרים חריגים מגיעים לאדם.

    מודול החשמל עולה כבוי עד שה־⁠worker של המפעיל ונתוני הפרודקשן יהיו מוכנים. טעינה חוזרת שלו נמדדה ב־⁠41.8 שניות, עם שיא של 696 MiB, בתוך מגבלת ה־⁠2 GiB של ה־⁠backend.

    טכנולוגיות

    טכנולוגיות

    Backend
    Python 3.12, FastAPI, pandas, PyArrow, Pydantic
    Frontend
    Next.js ו־⁠TypeScript, ממשק RTL בעברית, גרפים וייצוא
    נתונים
    Microsoft Fabric דרך OneLake ו־⁠SQL endpoint, וקובצי parquet מחולקים ב־⁠Azure Blob
    AI
    Azure OpenAI עם GPT-5.x ו־⁠GPT-4o, צ׳אט עם כלים, ופרומפטים מובנים עם גרסאות
    ענן
    Azure Container Apps ו־⁠Jobs, ACR, Key Vault, App Insights, Entra ID
    הטמעה
    Terraform, פייפליינים ב־⁠Azure DevOps, הזדהות workload identity ו־⁠pytest

    שיחת אבחון חינם · 30 דקות · ללא התחייבות

    הביאו תהליך אחד. קבלו תוכנית ומספר לשפר.

    כתבו בכמה שורות: איזה תהליך או מערכת, מה כואב היום (זמן, טעויות, עלויות או פיילוט AI שנתקע) ומי עובד עם זה. אחרי שיחה קצרה מקבלים תוך כ־3 ימים תוכנית כתובה והצעת מחיר סגורה.

    לשיחת אבחון חינםafif.mansour@gmail.com

    נפתח מייל מוכן מראש · מענה תוך יום עסקים

    ה־AI קורא. הקוד סופר.

    כל הפרויקטים