יום שני, 25 בינואר 2016

פוסט 2 - בחירת הרעיון והכרות ראשונית עם המערכת

אז איך הכל התחיל?

ובכן, שנתיים וחצי בהן הייתי שכיר והועסקתי כמפתח צד שרת בג׳אווה, עובדה זו בשילוב עם החיבה שלי לטכנולוגיות צד לקוח, היו לקרקע מוצקה עבור הדחף שנוצר בי לפתח מוצר מאפס על כל מרכיביו (END-TO-END).

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

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

א. יודע לאמוד את היכולות שלי.
ב. יכול הלכה למעשה לפתח מוצר מ-0.
ג. יכול להתמודד עם כל קושי שיצוץ בדרך.

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

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

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

זאת הנקודה שבה אנו פורשים מסיפורי אלף לילה ולילה ועוברים לדבר שוב על הארכיטקטורה.

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

מלפני שניגשתי ממש לכתוב קוד (Day One) היה עיקרון שסביבו ביססתי את כל ה-Design של הארכיטקטורה והוא:

מערכת רובסטית (robust) שתקבל דיווחים ללא הבחנה, הצגת האירועים (מושג שאסביר בעתיד) תסונן על בסיס הגבולות המונציפליים של הצרכן (Tenant).

קיום של מערכת כזאת חייב תמיכה בשלושה עקרונות בסיסיים בפיתוח מוצר בענן והם:

1. Scalability - יכולת התמודדות עם כמות משתמשים משתנה בצורה פשוטה וזולה.
2. Continues Integration - CI, Continues Delivery - CD - תהליכים אוטומטיים המתבצעים מהרגע שהמפתח מסיים לכתוב פיצ'ר ועד שמגיעים למשתמש הקצה.


(אפשר להרחיב רבות על כל מושג מבין אלה)

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

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

  • Web Micro Service - אחראי על הצגת פאנל הניהול והצגת המידע המתקבל מהמיקרו סרביסס האחרים.
  • Tenant Micro Service - אחראי על ניהול המשתמשים, יצירה וזיהוי (ערים ורשויות מקומיות), משתמשי האפליקציה הם אנונימיים לחלוטין.
  • Listener Micro Service - אחראי על קבלת הדיווחים מהתושבים, מכיל את האלגוריתם לזיהוי אירועי אמת.
  • Event Micro Service - אחראי על שליפת אירועי האמת שנוצרו וניהולם (אירוע פתוח, בטיפול, טופל).
  • Photo Micro Service - אחראי על קבלת התמונות המתקבלות מהתושבים לאחר דיווח ושליפתם בעת הצורך.
  • Comment Micro Service - אחראי על קבלת התיאור המילולי המתקבל מהתושבים ושליפתו בעת הצורך.
  • Archive Micro Service - אחראי על ארכיון האירועים, מנהל אירועים ישנים וכאלה שטופלו או נסגרו (יש מערך תיעוד שלם של האירועים)
  • Notification Micro Service - אחראי על שליחת ההודעות (Push Notifications) לתושבים המדווחים אודות התקדמות הטיפול באירוע שדיווחו עליו.
  • Score Micro Service - אחראי על מנגון הניקוד, כל תושב המדווח על אירוע שמתברר שהוא אירוע אמת מקבל ניקוד.
  • Geo Micro Service - אחראי על הפקת כתובת מהקורדינטות המתקבלות מהתושבים ע״י פניה לשרתים של גוגל.
  • Report Micro Service - אחראי על הצגת וניהול הדוחות שהמערכת מייצרת.
התרשים הבא יעשה קצת שכל בכל הקשור לתפקידם של המיקרו סרביסס ולאיזה מידע אנו מגיעים דרכם:


מה שאנחנו רואים כאן זאת התצוגה שמספק ה-Web Micro Service הסבר קצר על מה שאנחנו לא רואים כאן:

המסך שאנחנו רואים הוא המסך לאחר תהליך ההזדהות בפאנל הניהול, בתהליך כמובן משתתף מיקרו סרביס נוסף שאנחנו לא רואים כאן והוא ה-Tenant Micro Service.

עוד מיקרו סרביס שאנחנו לא רואים כאן הוא ה-Report Micro Service, אליו ניתן להגיע דרך התפריט, בעתיד נראה אותו ונעסוק בו ובתפקידו

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

זהו לבינתיים,
מייק.





יום שני, 18 בינואר 2016

פוסט 3 - תיאור התהליך המרכזי במערכת

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

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

1. לדעת לסנן דיווחי סרק, הרי אין לי דרך לדעת מי המדווח.
2. לדעת מתי שני דיווחים או יותר מדברים על אותו אירוע ולא על אירועים שונים.

את הפתרון שמצאתי הטמעתי בהגדרת האירוע. כל אירוע מוגדר על ידי שלושה פרמטרים:
  • זמן - מה משך הזמן המקסימאלי שבמידה ומתקבלים בו שני דיווחים או יותר מאותו הסוג וקרובים מספיק - יצוותו לאירוע אחד. 
  • מרחק- מה המרחק המקסימאלי שבמידה ומתקבלים בו שני דיווחים או יותר מאותו הסוג ובמסגרת הזמן שהוגדרה - יצוותו לאירוע אחד.
  • מס' דיווחים - מה מספר הדיווחים שאני מצפה לקבל מאותו סוג אירוע ובמסגרת הטווח והזמן  שהוגדרו זה על מנת להגדירו כ"אירוע אמת" ולהכניסו למערכת (ולדטה בייס הראשי).
התרשים מטה מתאר את המתרחש כאשר נוצר אירוע אמת במערכת ועד ההופעה של האירוע בפאנל הניהול. (במקרה זה מס' המדווחים הוא 2):


מספר נקודות אודות התרשים:

א. תקשורת בין המיקרו סרביסס במערכת - התקשורת בין המיקרו סרביסס במערכת מבוססת על הודעות שמנוהלת על ידי שרת AMQP מסוג RabbitMQ.

ב. שני אופנים להפצת הודעות:
  • כאשר התקשורת היא ישירה בין מיקרו סרביס שולח (Producer), למיקרו סרביס מקבל (Consumer), ההודעה נכנסת ל-Queue, 
  • כאשר התקשורת היא בין מיקרו סרביס שולח (Producer), למספר מיקרו סרביסס מקבלים (Consumers), ההודעה נשלחת ל-Topic.
ג. התקשורת בין ה-Web Micro Service למיקרו סרביסס האחרים היא שונה והיא מתבצעת באמצעות פניות REST, כל מיקרו סרביס חושף REST API שנגיש ע״י ה-Web Micro Service בלבד.

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

ה-FLOW הסנדרטי הוא כדלהלן:

1. המיקרו סרביס שמקבל את ההודעות מהתושבים הוא Listener Micro Service.
2. Listener Micro Service אוגר הודעות ועדיין לא מדווח על ״אירוע אמת״ עד שלא מגיעים למספר הדיווחים המינימלי שהוגדר.
3. כאשר מתקיימים שלושת התנאים - מספיק דיווחים מאותו איזור ובטווח הזמן שהוגדר, ה-Listener Micro Service מיצר ״אירוע אמת״.
4. שתי פעולות מתבצעות כאשר זוהה ״אירוע אמת״:
  • הכנסה לדטה בייס הראשי.
  • שליחת הודעה ל-Topic שרשומים אליו שלושה מיקרו סרביסס, כפי שמתואר בתרשים:
5. ברגע שההודעה מגיעה ל-Topic, נכנסים לפעולה שלושת המיקרו סרביסס הבאים: 
    • Geo Micro Service - פונה לשרתים של גוגל עם הקורדינטות של ה״אירוע אמת״, מקבל חזרה כתובת מלאה ומכניס אותה לדטה בייס.
    • Notification Micro Service - שומר את המספר מזהה היחודי של התושבים שדיווחו על ה״אירוע אמת״. שימוש במידע זה יבוא לידי ביטוי במנגון לניהול האירועים ועדכון התושב, באמצעות הודעות פוש (Push Notifications), בהתקדמות הטיפול באירוע שהוא דיווח עליו.
    • Score Micro Service - מוסיף נקודה לתושבים שהדיווח שלהם התגלה כדיווח אמת וזאת ע״ב המספר מזהה היחודי שלהם בלבד. 
6. Event Micro Service הוא מיקרו סרביס סינגלטוני (Singleton), הוא מחזיק כל העת רשימה עדכנית של אירועי האמת שנמצאים בדטה בייס. (מתבצע באמצעות תהליך שבכל כמה שניות ניגש לדטה בייס ובודק אם יש אירוע חדש).

7. גם ל-Web Micro Service יש תהליך פנימי שרץ כל כמה שניות (Schedule Task) ופונה באמצעות פניית REST ל-Event Micro Service ובודק האם נכנסו אירועים חדשים.

8. נחזור רגע לאפליקציה שהתושבים מדווחים באמצעותה - לאחר שמועבר הדיווח (וגם כל התהליכים שתוארו מעלה אך התושב לא חשוף אליהם) נפתח פופ-אפ (Pop-up Dialog), השואל את התושב האם הוא מעוניין לצרף תמונה ממקום האירוע.

9. במידה והתושב מצרף תמונה ממקום האירוע התמונה נשלחת למיקרו סרביס אחר והוא ,Photo Micro Service. המיקרו סרביס הזה שומר את התמונה ותפקידו הוא ניהול התמונות שהתקבלו מהתושבים.

10. לאחר המתואר ב-9 בין אם התושב שלח תמונה ובין אם לאו, נפתח פופ-אפ, (Pop-up Dialog), השואל את התושב האם מעוניין לצרף תיאור/הערה בנוגע למתרחש באירוע, גם מידע הזה מגיע ישירות למיקרוסרביס אחר מבין אלה שהוזכרו והוא, Comment Micro Service. תפקידו הוא לנהל את המלל המתקבל מהתושבים.

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

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

זהו לבינתיים, 
מייק.


יום ראשון, 17 בינואר 2016

פוסט 4 - ממשק הניהול ואבטחה

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

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

Authentication, (זיהוי) - מנגון זיהוי המשתמשים, ישנם דרכים רבות לזהות משתמשים (טביעת אצבע, צורת הקלדה, קול וכו'..) אבל הדרך הסטנדרטית והמקובל היום היא עדיין ע"י שם משתמש וסיסמא.

Authorization, (הרשאות) - מנגון ניהול המשתמשים, לאחר ביצוע תהליך ההזדהות לכל יוזר מוגדר מרחב הרשאות (ROLE), לצורך העניין רשות מקומית\עיר מוגדרת כ-Tenant, המתשמשים במערכת שרשומים תחתיה מוגדרים כ-Users  מי שמוסיף רשויות וערים לשירות מוגדר כ-Admin וכן הלאה.

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

הגיע הזמן לדבר על קיצור הדרך הראשון והעיקרי שעזר לי המון וקידם אותי חודשים קדימה עם המוצר והוא JHipster.

JHipster - פרויקט מדהים! שעזר לי רבות בהקמת ה Web Micro Service וחסך לי המון התעסקות בדברים תשתיתיים שלא קשורים ל-Business Logic. הפרוייקט הזה מבוסס ספרינג (Spring Boot) בשילוב עם AngularJS, (השכבה שמטפלת בתצוגה), הוא משתמש בפרויקט ומדהים לכשעצמו שנקרא Yeoman, (מאפשר לך באמצעות Wizard לקנפג את המערכת שלך בצורה פשוטה וקלה).

JHipster פתר לי בצורה חלקית את כל כאב הראש של זיהוי וניהול המשתמשים והוא משלב שימוש בפרוטוקול OAuth2 ו-Spring Security, כיוון שהמוצר יושב (Deployed) על Cloud Foundry, בכדי להשלים את סידורי האבטחה ולקבל עוד שכבת הגנה גם מ-Cloud Foundry, היה עלי לשלב שימוש גם ב-UAA.

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

וכעת נצא מנקודת הנחה שהזיהוי עבר בהצלחה ונכנסנו למערכת.

התרשים הבא מתאר את ממשק הניהול, אני יודע שמבחינת User Experience) ,UX), היה ניתן לעשות דברים טיפה אחרת, אולי בגירסא הבאה :).

מספר דגשים לגבי התרשים:

- המסך שאנחנו רואים הוא המסך שמופיע לאחר תהליך ההזדהות (Login).
- התצוגה הראשית מורכבת ממידע המגיע ב-REST ממספר מיקרו סרביסס שונים - את הפניות יוזם ה-Web Micro Service לאחר שמלאכת הזיהוי הושלמה.
- במידה ואין אירועים אז המידע היחיד שיכיל פאנל הניהול נכון גירסא זו הוא מידע אודות המדווחים המובילים.
- במידה ויש אירועים במערכת ה-Web Micro Service יקח את הנתונים מהאירוע העדכני ביותר ויפנה ב-REST לשלושת המיקרו סרביסס הבאים:

  • Photo Micro Service - יבקש את התמונות שהתקבלו מהתושבים המדווחים.
  • Comment Micro Service - יבקש את התיאורים והתגובות שהתקבלו מהתושבים המדווחים.
  • Geo Micro Service - יבקש את הכתובת המדוייקת של מקום האירוע.
- ה- Web Micro Service פונה למיקרו סרביסס האחרים באמצעות פניית Ajax, פניה אסינכרונית, המידע שמגיע מהמיקרו סרביסס נטען באופן דינאמי בעמוד.
- פעולה נוספת שניתן לבצע דרך פאנל הניהול היא שליחת לכלל התשובים, בין אם פרסומית ובין אם אינפורמטיבית.
- מנגנון ניהול האירועים שארחיב עליו בתחילת הפוסט הבא גם הוא מוטמע במסך שאנו רואים בתרשים - לכל אירוע שמופיע ברשימה מצורפים ארבעה כפתורים:

 - האירוע טופל.

 - החזק אירוע ברשימת הדיווחים.

- הסר אירוע מרשימת הדיווחים והעבר לארכיון.

- סמן אירוע במצב ״מטופל כעת״ (In Progress).


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




יום שני, 11 בינואר 2016

פוסט 5 - מנגנונים עיקריים במערכת

אנחנו עומדים בפני אחד הפוסטים המעניינים לדעתי.
בפוסט הזה אנחנו הולכים לגעת בשני מנגנונים מעניינים. 
האחד -מנגנון שליחת הודעות הפוש לתושבים המדווחים הישר ממשק הניהול.
השני - המנגנון המאפשר למערכת להתמודד עם ריבוי לקוחות בענן (Multi Tenancy).

בכדי להציג את מנגון שליחת ההודעות עלי לגעת בקיצור הדרך השני והמשמעותי לא פחות מזה שהוצג קודם לכן, לקיצור דרך השני קוראים Ionic.
Ionic הוא אחלה פתרון לסטראט-אפים מתחילים שרוצים לחסוך זמן ולפתח אפליקציות Native, גם למכשירים של אפל וגם לאנדרואיד מבלי לדעת אף אחת משפות הפיתוח שלהן.
מה שלמעשה עושים זה לכתוב אפליקציה ב-HTML5 וב-AngularJS, ״מקמפלים״ והתוצר של הקימפול הוא שתי אפליקציות אחת לאנדרואיד והשניה לאייפון וזהו, לשלוח
ל-App Review ולחניות, זה עובד נהדר!

חוץ מה-Framework המדהים הזה יש אתר ,Ionic.io, המציע סל של שירותים למשתמשי ה-Framework, אחד מהם הוא Push Notification. 

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



אז מה יש לנו כאן:

התרשים הבא מתאר מצב שקורה בשני תרחישים שונים:

  • שינוי סטטוס של אירוע ברשימה למצב ״בטיפול״, (In Progress) - במצב כזה אנו רוצים לעדכן את התושב שהאירוע שדיווח עליו כעת נמצא בטיפול ע״י הגורמים הרלוונטים, זה נראה ככה:

  • שינוי סטטוס של אירוע ברשימה למצב ״טופל״, (Fixed) - במצב כזה אנו רוצים לעדכן את התושב שהגורמים הרלוונטים סיימו לטפל באירוע שדיווח, זה נראה ככה:

לפני שנציג את אשר מתאר התרשים אוסיף פרט חשוב:
כל תושב שמשתמש באפליקציה, בעת עלייתה בפעם הראשונה, מבצע רישום לשירותי Ionic.io ומקבל מספר מזהה יחודי (Token), הרישום מתבצע ע״י פניית REST ל-Notification Micro Service, 
שמעביר את הפניה לשרתים של Ionic.io ושומר את הטוקן שהמשתמש קיבל, התוצאה של התהליך הזה הוא מפה (Map), של משתמשים והמספר מזהה שקיבלו מ-Ionic.io, ניגע בזה בהמשך.

התרשים מתאר את המצב הבא:

א. מתקבלים דיווחים על ״מפגע רעש״
ב. נוסף ״אירוע אמת״ ברשימת האירועים.
ג. לאחר עשר דקות הפקח העירוני מדווח שהוא יוצא למקום.
ד. משנים בממשק הניהול את סטטוס האירוע ל״בטיפול״ .
ה. נשלחת הודעה ב-REST ל-Event Micro Service לעדכן את הסטטוס בדטה בייס.
ו. נשלחת הודעה ב-REST ל-Notification Micro Service לשלוח לכל המדווחים על האירוע הזה, הודעה בדבר שינוי הסטטוס.
ז. ה-Notification Micro Service שולף את המספרים המזהים של כל המדווחים ומעביר רשימה (REST) ל-Ionic.io ואת הנוסח של שההודעה.
ח. Ionic.io מקבלים את רשימת התושבים אליהם אנו רוצים להעביר עדכון, נוסח העדכון ומבצע לבד את ההפניות ל-Apns ו-GCM.

Apple push notification service, Apns - שרת שליחת הודעות הפוש של אפל. (מצריך חשבון מפתח בכדי להשתמש בשירות)
Google Cloud Messaging - GCM - שרת שליחת הודעות הפוש של גוגל. (לא מצריך חשבון מפתח בכדי להשתמש בשירות).

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

הפתרון למעשה הוא פתרון פשוט אבל חכם - עבור כל לקוח אני מספק "Promotion Code", לקוד הזה משויכיים הגבולות המוניצפליים של אותו לקוח: לדוגמא הלקוח הוא עיריית חיפה, ה-"Promotion Code" שהופק עבורו הוא - "Haifa", האובייקט הג'אווה שמייצג אותו נראה ככה, וככה גם נשמר ב-Database:


כחלק מתהליך רישום משתמש (user) במערכת, ישנו שדה חובה (mandatory), שמצפה לקבל Promotion Code, הקוד נשמר יחד עם המשתמש ולא מתאפשר רישום משמתש חדש מבלי שיסופק ע"י המשתמש Promotion Code שנמצא במערכת. לאחר תהליך הרישום ברגע שהמשתמש נכנס למערכת כל האירועים שמתקבלים מה-Event Micro Service מסוננים לפי אירועים שנמצאים בשטח הריבוע הדימיוני שמיצרים הגבולות המוגדרים ב-Promotion Code המשויך למשתמש.



עוד עניין חשוב שאנו מקבלים בחינם מהמנגון הזה הוא יכולת יצירת משתמשים (users) מרובה עבור לקוח (Tenant).

לדוגמא:

הלקוח (Tenant): עיריית רמת גן.
משתמשים (Users):
- מוקדן 106.
- איש השירות בצוות המזרקות. (שיכול לשנות את סטטוס האירוע בשטח).


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