פלטפורמת תפעול אבטחה · AfifAI
מקרה בוחן · תפעול אבטחה · ⁦2024–2026⁩

מהתראת מצלמה ועד כונן בדרך, על מפה חיה אחת

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

⁦.NET 8⁩ / ⁦C#⁩SQL ServerRabbitMQReact + TypeScriptFlutterMapbox GLPusher / FCMAWS · Docker
לקוח
חברת שירותי אבטחה ישראלית (חסוי)
התפקיד שלי
ראש צוות, ארכיטקט ומפתח בפועל
לוח זמנים
ינואר 2024 – ספטמבר 2026, בפרודקשן
סטטוס
באוויר
במבט אחד
6 עד 0JOINים לטעינת רשימת ההתראות הפתוחות. היום זו טבלת cache אחת
0התחברויות מחדש בגלל ניתוק רשת רגעי. קודם, רענון אחד שנכשל חייב כניסה מלאה עם OTP
−⁦71%⁩שדות לכל אתר במסכי רשימה (35 ← 10), בזכות endpoints רזים
N עד 1קריאות למסד הנתונים לסגירת התראות מצלמה ישנות בכל ריצת סנכרון (stored procedure אחת)
480endpoints ב־⁠API, על פני 4 שירותי backend ו־⁠2 workers
322Kשורות קוד ב־⁠7 ריפוזיטורים, כ־⁠11,000 קומיטים
6 + 5שפות בווב ובמובייל, כולל עברית RTL, כ־⁠1,000 מפתחות בכל שפה
84טסטים מקצה לקצה, ועוד 7 תרחישי ביצועים עם מדידת זמנים
הבעיה

הרבה אתרים, הרבה מערכות, ושניות שמשנות

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

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

הארכיטקטורה והחלקים הקשים

  • תכננתי את חלוקת השירותים: API ניהולי ו־⁠API מיקום, worker להודעות ו־⁠worker לסנכרון מערכות וידאו, כולם על אותה שכבת נתונים.
  • הייתי אחראי על מודל הנתונים והביצועים שלו: 174 טבלאות, נתונים מרחביים, 327 אינדקסים, stored procedures לנתיבים החמים ו־⁠cache להתראות פתוחות.
  • הגדרתי את מודל הזמן־אמת (ערוצי push לווב, push למובייל, סירנה להתראה קריטית) ואת חוקי הסשן: מכשיר פעיל אחד בכל רגע.
  • הובלתי את קונסולת הווב, את בניית אפליקציית הכוננים מחדש ב־⁠Flutter ואת אוטומציית ה־⁠QA, ועברתי בעצמי על הנתיבים הקריטיים.
  • הטמעתי פיתוח בעזרת AI: חוקי פרויקט, 25 skills בריפוזיטורים ושינויים שמתחילים ממפרט, כדי שהצוות יספק מהר יותר ובתוך גבולות ברורים.
ארכיטקטורה

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

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

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

החלטות תכנון

להוזיל את הנתיב החם ולהוציא ממנו את העבודה האיטית

טבלת cache להתראות פתוחות

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

קודם רזה, פרטים לפי דרישה

מסכי רשימה ומפה קוראים ל־⁠endpoints רזים (10 מתוך 35 שדות אתר). פאנל התראה או אירוע טוען קודם רשומה רזה, ואת החלקים הכבדים רק כשפותחים אותם. יש יותר endpoints לתחזק, אבל כל טעינה ראשונה קלה.

הודעות דרך תור

שליחת SMS, שיחות קוליות ו־⁠push לאתר שלם עברה לתור משימות RabbitMQ ול־⁠worker נפרד. ה־⁠API עונה מיד, והספקים יכולים להיות איטיים או לקבל ניסיון חוזר בלי לחסום את המוקדן. המחיר: עוד שירות לפרוס ולנטר.

מכשיר פעיל אחד לכל סוג

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

פיתוח בעזרת AI, מתחיל ממפרט

בכל ריפוזיטורי יש חוקי פרויקט, memory bank ו־⁠skills לתבניות שלו: controllers, שכבת אחסון, קריאות API ב־⁠Redux והרשאות. שינויים גדולים מתחילים ממפרט כתוב; באפליקציית הכוננים נסגרו 57 כאלה. ה־⁠code review התקצר, ואנשים חדשים בצוות הגיעו לתפוקה מהר יותר. המחיר: לשמור את החוקים מעודכנים.

יומן הנדסי

מה האט או נשבר, ומה תיקן

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

נובמבר 2024

שאילתות שסורקות במקום לחפש

ככל שהלקוחות גדלו, רשימות מסוננות ושורות שנמחקו במחיקה רכה נסרקו בכל בקשה.

הוספתי אינדקס לכל foreign key ולכל דגל מחיקה רכה, והמשכנו להוסיף אינדקסים מכסים לסינונים החמים (327 בסך הכול). job לילי מרענן עכשיו סטטיסטיקות במסד הראשי ובמסד הביקורת.

מרץ 2025

סנכרון וידאו שסוגר התראות אחת־אחת

כל ריצת סנכרון משכה מכשירים והתראות לכל אתר, ואז סגרה התראות ישנות שורה אחרי שורה.

upsert בכמויות, ו־⁠stored procedure אחת שסוגרת את כל ההתראות הישנות ומנקה את ה־⁠cache בקריאה אחת. ה־⁠worker נועל אתר אחד בכל פעם ומריץ במקביל מספר אתרים שאפשר להגדיר.

אוקטובר 2025

עמוד 2 הציג שורות לא נכונות

חלק מה־⁠endpoints של רשימות עשו paging לפני המיון, ולכן המשתמשים קיבלו פרוסה שרירותית של הנתונים שרק נראתה ממוינת.

המיון עבר לפני ה־⁠paging בתבנית הרשימות המשותפת, עם עוד שדות מיון ותיעוד, והתבנית הפכה ל־⁠skill בריפו כדי ש־⁠endpoints חדשים יעבדו לפיה.

ינואר 2026

מוקדנים שמחכים לספקי SMS

שליחה לאתר שלם הריצה את ה־⁠SMS, השיחות הקוליות וה־⁠push בתוך בקשת ה־⁠API.

שלושתם עוברים היום דרך תור המשימות ו־⁠worker הודעות ייעודי.

פברואר 2026

רשימת ההתראות הפתוחות הייתה השאילתה הכבדה ביותר

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

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

אפריל 2026

מיקום ברקע שנתקע

שירות המיקום הנייטיב ברקע נכנס ל־⁠deadlock על 401, שלח כפילויות ונעצר כשהאפליקציה נסגרה.

לשירותי המיקום הנייטיב ב־⁠iOS וב־⁠Android יש עכשיו אחסון טוקנים ותור שליחה משלהם. התור מתרוקן כשהאפליקציה נפתחת, ויש נתיב רענון אחד.

יוני 2026

ניתוק רשת של שנייה ניתק כוננים

שכבת הרענון התייחסה לכשל DNS כמו לטוקן שנדחה, והכוננים נשלחו חזרה לכניסה עם OTP.

כשלים מסווגים היום במקום שבו הם קורים. הרענון מבצע 3 ניסיונות עם המתנה של 400 ואז 800 מילישניות, ורק 401 או 403 אמיתיים סוגרים את הסשן.

יוני 2026

פאנלים כבדים מעל המפה

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

הפאנל מביא קודם רשומה רזה וטוען את החלקים שלו בעצלות. חיפושים חמים עוברים דרך אינדקס id ← ישות עם cache לפי reference. מסכי המפה מפוצלים ל־⁠chunks נפרדים.

תוצאה

איפה זה נחת

רשימת ההתראות הפתוחות

טבלה אחת, בלי JOINים, רק התראות פתוחות

רשימות אתרים ומפה

10 שדות לכל אתר; קריאה אחת לעד 1,000 אתרים

סגירת התראות מצלמה ישנות

קריאה אחת ל־⁠stored procedure בכל ריצה, אתרים במקביל

SMS / שיחה קולית / push לכל האתר

נכנסים לתור של worker; ה־⁠API חוזר תוך כ־⁠0.3 שניות

ניתוק רשת רגעי בטלפון של כונן

3 ניסיונות עם המתנה; הסשן נשמר ומוצג באנר אופליין

כונן בלי קליטה בשטח

נשמרות מקומית (מיקום: עד 500 נקודות, תוקף 4 שעות) ונשלחות בבת אחת כשהקליטה חוזרת

פריסת שירות

push של תגית גרסה ← אימג׳ Docker ל־⁠registry (4 שירותים), כ־⁠10 דקות

מספרים שמסומנים ב״כ־⁠" או ב־⁠≈ הם הערכות. כל השאר נספרו מהקוד ומהיסטוריית הקומיטים.

טכנולוגיות

טכנולוגיות

Backend
⁦.NET 8⁩, ⁦ASP.NET Core⁩, EF Core, worker services, JWT
נתונים
SQL Server עם טיפוסים מרחביים, stored procedures, מסד ביקורת, job סטטיסטיקות לילי
הודעות
RabbitMQ, Pusher, Firebase Cloud Messaging, ערוצי צ׳אט, SMS, שיחות קוליות, מייל
קונסולת ווב
React 18, TypeScript, Vite, Redux Toolkit, Mapbox GL, Turf, fabric.js
מובייל
Flutter (Dart), GetX, מיקום ברקע נייטיב ב־⁠Kotlin וב־⁠Swift, התראות קריטיות
אספקה
Docker, AWS (container registry, S3), GitHub Actions, Bitbucket Pipelines, Playwright + Allure

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

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

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

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

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

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

כל הפרויקטים