§01/Applytide
מוצר · פלטפורמה · בינה מלאכותית יישומית
Applytide
הדפדפן הפך למעקף עבור תהליך שהיה צריך מערכת הפעלה משלו.
פלטפורמה לניהול מועמדויות: צינור מיון, מסמכים, תזכורות, אנליטיקה והכנה לראיונות.
- תפקיד
- מוצר · עיצוב · הנדסת פול־סטאק
- תקופה
- אוג׳ 2025 — אפר׳ 2026
- סטטוס
- קוד המקור בארכיון
- צוות
- פרויקט עצמאי · יוצר יחיד
המאגר הציבורי נמצא בארכיון. אין טענה לפריסה חיה או לשימוש חיצוני.
§02/גרסת 60 שניות
גרסת 60 שניות
- 01 / מה היה שבור
- איתור משרות, מסמכים מותאמים, מעקבים והקשר לראיונות התפזרו בין טאבים, קבצים, תיבות דואר וזיכרון.
- 02 / המהלך
- להפוך את הקליטה לכמעט בלתי מורגשת, ואז לתת לכל מועמדות היסטוריה מובנית אחת מאיתור ועד החלטה.
- 03 / התרומה שלי
- הגדרתי, עיצבתי ובניתי את Applytide באופן עצמאי מקצה לקצה: קליטה מהדפדפן, ממשק React, שירותי FastAPI, מודל הנתונים, כלי המסמכים, התשתית ושכבת AI מוגבלת תקציב.
- 04 / מה אפשר לבדוק
- מאגר ציבורי בארכיון עם היסטוריה מתוארכת משמעותית וקוד דפדפן, חזית, שרת ותשתיות שניתן לבדוק.
§03/הסיפור המלא
הסיפור
התקציר למעלה עומד בפני עצמו. כאן אפשר לפתוח את קבלת ההחלטות, פרק אחד בכל פעם.
01/איתותהמעקב הוא העבודה
המעקב הוא העבודה
כל מי שמנהל חיפוש עבודה רציני מפעיל צינור: איתור, סינון, הגשה, מעקב, ראיון, החלטה. יש לו שלבים, שיעורי המרה, וזמן מחזור. זה תהליך, ואנשים מריצים אותו בגיליון אלקטרוני או בראש.
החיכוך הוא לא במציאת משרות. הוא בהנהלת החשבונות סביבן — איזו גרסה של קורות החיים הלכה לאן, מה כתבת במכתב המקדים, מתי הבטחת לחזור, ואילו הגשות עדיין חיות. העבודה הזו משעממת, בתדירות גבוהה, ובדיוק בשביל זה יש תוכנה.
מה שטעיתי בו בהתחלה: הנחתי שהשלב הכואב הוא כתיבת ההגשות. הוא לא. השלב הכואב היה הקליטה — להוציא משרה מטאב בדפדפן ולהכניס אותה לרשומה מובנית לפני שהטאב נסגר. כל מה שבהמשך תלוי בכך שהרגע הבודד הזה יהיה נטול חיכוך.
02/מסגוראילוצים שבאמת תחמו את העיצוב
אילוצים שבאמת תחמו את העיצוב
שני אילוצים אמיתיים עיצבו כמעט כל החלטה. הראשון היה עלות: לכל פיצ׳ר שקורא למודל שפה מוצמד חשבון בלתי חסום, ופרויקט אישי לא יכול לספוג את זה. השני היה אמון: המערכת הזו מחזיקה את קורות החיים של המשתמש, את היסטוריית ההעסקה שלו, ורשימה של כל חברה שהוא מדבר איתה בשקט. זה מאגר קטן עם רדיוס נזק גבוה מאוד.
לכן אבטחה ובקרת עלויות לא היו פיצ׳רים להוסיף אחר כך — הן היו אילוצי מסגור. בגלל זה הבנייה כוללת דברים שפרויקט צד בדרך כלל מדלג עליהם: סשנים בעוגיות HttpOnly במקום טוקנים ב־localStorage, אימות דו־שלבי מבוסס TOTP, מעקב סשנים ניתן לביטול, הגבלות קצב לכל נקודת קצה, ותקרת הוצאה יומית קשיחה לקריאות בינה מלאכותית שנאכפת ב־Redis.
מחוץ להיקף במפורש: הגשה אוטומטית. הוצאתי אותה מההיקף משום שהגשה המונית ממטבת את נפח ההגשות ומגבירה את הרעש בתהליך החיפוש.
03/תכנוןקליטה קודם, כי הכול תלוי בה
קליטה קודם, כי הכול תלוי בה
מכיוון שהקליטה הייתה השלב הנושא, תוסף הדפדפן נבנה מוקדם ולא כתוספת. להכניס משרה למערכת בלחיצה אחת זה ההבדל בין כלי שמישהו משתמש בו לכלי שמישהו מתכוון להשתמש בו.
השאר תוזמן לאורך הצינור עצמו: קליטה, אחר כך שלבי הקנבן שממדלים את התהליך, אחר כך מסמכים, ואז שכבות התזכורות והאנליטיקה שהופכות משמעותיות רק כשיש היסטוריה להסיק ממנה. אנליטיקה אחרונה זו בחירה מכוונת — דשבורד מעל שלוש רשומות הוא קישוט.
הארכיטקטורה תוכננה כשירותים נפרדים מלכתחילה במקומות שבהם הגבולות היו באמת שונים: רינדור מייל HTML הוא עניין של Node, תזמון רקע הוא לא עניין של ה־API, והפרוקסי ההפוך הוא המקום שאליו שייכת הגבלת הקצב.
04/בנייהשמונה רשומות Compose, לפי הגדרת ספירה
שמונה רשומות Compose, לפי הגדרת ספירה
בקומיט הציבורי שנבדק, Docker Compose מכיל שמונה רשומות שירות, כולל MailDev שמיועד לפיתוח. הטופולוגיה כוללת גם Nginx, אפליקציית React, שרת FastAPI, שירות מיילים ב־Node, PostgreSQL, Redis ותהליך מתזמן.
השרת בנוי בשכבות — 15 הרשמות include_router בגבול ה־API, שכבת דומיין, 19 הצהרות מחלקות מודל SQLAlchemy תחת Alembic, ותשתית למיילים, מודל שפה, אבטחה ועובדי רקע. אלה ספירות של צילום מצב לפי הגדרה מתועדת, לא תוצאות מוצר.
הבעיה הקשה ביותר הייתה חילוץ: להפוך דף משרה שרירותי לשדות מובנים. התשובה הנאיבית היא לשלוח את הדף למודל. התשובה הזו שגויה מסיבות שמפורטות ביומן ההחלטות למטה.
השנייה בקושי הייתה בינאום. תמיכה מלאה בעברית פירושה RTL אמיתי — לא גיליון סגנונות משוקף, אלא פריסה שנכונה בשני הכיוונים, כולל שדות קלט, גרפים, וגרירה ושחרור. התאמה בדיעבד יקרה, ולכן זה תוכנן פנימה ולא הוברג מבחוץ.
05/הוכחהתקציבים, בדיקות תקינות, והדברים שאי אפשר לבדוק ביחידה
תקציבים, בדיקות תקינות, והדברים שאי אפשר לבדוק ביחידה
חלק מזה היה שגרתי: סכמות Pydantic שמאמתות כל גבול של נקודת קצה, שאילתות פרמטריות לכל אורך הדרך, נקודת קצה לבדיקת תקינות שבודקת גם את Postgres וגם את Redis.
קוד המקור רושם שימוש במודל שפה לכל קריאה, עם ספירת טוקנים וייחוס לחשבון מול תקציב יומי הניתן להגדרה. זהו מנגנון להגבלת הוצאה; ללא ראיות תפעוליות, זו אינה טענה לאמינות בייצור.
ניהול סשנים ניתן לבדיקה באותה רוח: משתמש יכול לראות את הסשנים הפעילים שלו ולבטל אותם. השאלה שמאמתת את זה היא לא ״האם נקודת הקצה מחזירה 200״, אלא ״האם משתמש שאיבד מחשב נייד באמת יכול להתאושש״.
06/שטחמה הארכיון מוכיח — ומה לא
מה הארכיון מוכיח — ומה לא
מאגר Applytide הציבורי מסומן כארכיון. לא מוצגים כאן פריסה חיה או תוצאות משימוש חיצוני.
עצרתי כשהמשך העבודה היה הופך מתיקוף החלטות המוצר וההנדסה לתפעול תשתית, מימון שימוש במודלים ותחזוקת משטח אבטחה.
קוד המקור מדגים באופן עצמאי ארכיטקטורה מרובת שירותים, בקרות סשנים ותקציב, ממשק דו־לשוני והחלטות עיצוב מתועדות. הוא אינו מוכיח לבדו אבטחה בייצור, אמינות או אימוץ.
§04/הראיות שמתחת
מערכת וארכיטקטורה
- 8
- רשומות Compose
- 19
- מודלי נתונים
- 15
- ראוטרים ב־API
- 2
- שפות
בקומיט שנבדק; כולל MailDev
הצהרות מחלקות SQLAlchemy
הרשמות include_router
אנגלית / עברית, RTL מלא
טכנולוגיות
- React 18
- TypeScript
- FastAPI
- PostgreSQL
- Redis
- Docker
- Nginx
- OpenAI API
- Chrome MV3
החלטות ופשרות
D-01
2025
מפל חילוץ תלת־שלבי (JSON-LD ← DOM ← מודל שפה) במקום ניתוח מבוסס מודל בלבד.
- למה
- חלק מלוחות המשרות מפרסמים נתוני JobPosting מובנים שניתן לחלץ בלי קריאה למודל. כשהם קיימים ותקינים, הם משמרים שדות מהמקור ישירות; הפרויקט לא מדד את הכיסוי או הדיוק שלהם בין לוחות. מודל נשאר המסלול הפחות צפוי לשדות כמו שכר, שבהם טעות בטוחה בעצמה יקרה.
- פשרה
- שלושה מסלולי קוד ושלושה מצבי כשל נפרדים לתחזוקה במקום אחד, בתמורה להימנעות מעלות מודל ומטרנספורמציה נוספת כשנתוני מקור מובנים זמינים. הכיסוי והדיוק לא נמדדו.
- לבחון מחדש אם
- אם עלות המודל לחילוץ תרד מספיק כדי שהחשבון יפסיק להיות משמעותי, או אם כיסוי הנתונים המובנים בלוחות יקרוס.
D-02
2025
תקציב יומי קשיח למודל שפה שנאכף ב־Redis, עם ייחוס לכל משתמש.
- למה
- כל פיצ׳ר בינה מלאכותית שחשוף למשתמשים הוא התחייבות ללא תקרה. רישום צריכת טוקנים בדיעבד מספר לך מה השתבש; תקציב עוצר את זה.
- פשרה
- משתמשים יכולים להיתקל בתקרה ולחוות חוויה מדורדרת ביום גרוע, וזה רגע מוצרי גרוע יותר מלשלם בשקט. העדפתי חשבון חסום.
- לבחון מחדש אם
- אם דפוסי השימוש יהפכו צפויים מספיק כדי לעבור מתקרה קשיחה למכסות לכל משתמש.
D-03
2025
JWT בעוגיות HttpOnly, לא טוקנים ב־localStorage.
- למה
- המאגר הוא היסטוריית ההעסקה של המשתמש ורשימת החברות שהוא מדבר איתן בפרטיות. כל XSS ב־SPA הופך טוקנים ב־localStorage להשתלטות מלאה על החשבון.
- פשרה
- CSRF הופך לדאגה שצריך לטפל בה במפורש, והגדרות cross-origin נעשות קשות יותר. זו מחלקת בעיות טובה יותר להיות אחראי עליה.
- לבחון מחדש אם
- לא בלי סיבה טובה מאוד.
D-04
2025
הוצאתי הגשה המונית אוטומטית מהיקף המוצר.
- למה
- זה ממטב את המדד שהמוצר מציג בזמן שהוא מחמיר את התוצאה האמיתית של המשתמש, והוא פוגע במערכת שבה הוא פועל. כלי להרצת חיפוש טוב לא צריך לשלוח פיצ׳ר שמריץ אותו רע בקנה מידה.
- פשרה
- ויתרתי על היכולת הכי מובנת מאליה מבחינה שיווקית ועל סיפור הצמיחה שמוצמד אליה.
- לבחון מחדש אם
- לא.
D-05
2026-04
לארכב במקום לתפעל.
- למה
- העבודה שנותרה הייתה תפעולית — תשתית, ספיגת עלויות בינה מלאכותית של אחרים, ותחזוקת משטח אבטחה שראוי לתשומת לב אמיתית. זו התחייבות לתפעל מוצר, וזו החלטה אחרת מלבנות אחד.
- פשרה
- אין פריסה חיה להראות, ואין מדדי שימוש. הקוד, הארכיטקטורה וההנמקה נשארים ניתנים לבדיקה.
- לבחון מחדש אם
- אם תהיה סיבה לתפעל אותו שתצדיק את עלות ההרצה ואת חובת הזהירות.
משחק האילוצים
חוגת אילוצים
איך דף משרה שרירותי אמור להפוך לנתונים מובנים?
הזיזו את האילוצים וראו לאיזו תשובה הם מצביעים. ההחלטה מעולם לא הייתה על הטכנולוגיה הטובה ביותר — היא הייתה על מי שורדת את שני המספרים האלה.
מה שבאמת בניתי
המפל התלת־שלבי — JSON-LD, אחר כך ניתוח DOM, אחר כך נפילה למודל שפה. זהו המסלול שמומש: הוא נמנע מקריאה למודל כשקיימים נתונים מובנים שימושיים. הכיסוי ודיוק החילוץ לא נמדדו.
התנאים האמיתיים: קיבולת תפעול של אדם אחד, חשיפה מתמשכת לעלות, ורף נכונות גבוה מספיק כדי ששדה שכר שגוי יהיה גרוע יותר משדה שכר חסר. הצירוף הזה מצביע על המפל.
אילו הייתי בונה את זה היום
- 01
לבנות קודם את מערך ההערכה לחילוץ. קיבלתי החלטות ניתוב בין שלושת השלבים על סמך שיקול דעת, בזמן שקורפוס מתויג ומייצג היה הופך אותן למדידות.
- 02
להתחיל בשפה אחת ולהוסיף עברית בנקודת בדיקה מוגדרת. תכנון דו־כיווני מהיום הראשון הטיל מס על כל רכיב לפני שתועד שימוש חיצוני כלשהו.
- 03
לוותר על פאנל הניהול. הוא נבנה כי הוא היה מעניין, והוא שירת מנהל אחד — אותי. המאמץ הזה היה שייך לאמינות הקליטה.