Feature Chain — מעקב אחרי כל ה-full-stack עם operationId אחד

אילו קבצים צריך לגעת בהם כדי לשנות פיצ’ר אחד? הקלד operationId אחד — והתשובה מופיעה.


הבעיה

באפליקציית full-stack, “פיצ’ר אחד” לא חי בקובץ אחד.

נניח שצריך לשנות פיצ’ר בשם “ExecuteWorkflow”. הפיצ’ר הזה נמצא במפרט ה-API, בלוגיקת השירות, בסכמת בסיס הנתונים, במדיניות ההרשאות, בתרשים מעבר המצבים, בקריאות לפונקציות חיצוניות, בתרחישי הבדיקה ובקומפוננטות הפרונט-אנד.

עד כה היו שתי דרכים לתפוס את כל ההיקף הזה:

  1. להריץ grep עשרות פעמים
  2. לעקוב אחרי הקוד ידנית

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

גרוע יותר כשמעבירים את העריכה ל-AI. ב-200 endpoints ה-AI כבר לא מצליח להחזיק את כל הקונטקסט. הקונטקסט קורס, הדפוסים נסחפים, והפיצ’ר ה-201 עולה פי 10 מהפיצ’ר ה-21. זה הקיר שבו vibe coding נתקל.

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


מה זה Feature Chain

Feature Chain הוא אוסף כל צמתי המקור המחוברים לפיצ’ר API אחד (operationId).

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

yongol chain ExecuteWorkflow specs/
── Feature Chain: ExecuteWorkflow ──

  OpenAPI    api/openapi.yaml                         POST /workflows/{id}/execute
  SSaC       service/workflow/execute_workflow.ssac   @get @empty @auth @state @call @publish @response
  DDL        db/workflows.sql                         CREATE TABLE workflows
  DDL        db/execution_logs.sql                    CREATE TABLE execution_logs
  Rego       policy/authz.rego                        resource: workflow
  StateDiag  states/workflow.md                       diagram: workflow → ExecuteWorkflow
  FuncSpec   func/billing/check_credits.go            @func billing.CheckCredits
  FuncSpec   func/billing/deduct_credit.go            @func billing.DeductCredit
  FuncSpec   func/worker/process_actions.go           @func worker.ProcessActions
  FuncSpec   func/webhook/deliver.go                  @func webhook.Deliver
  Hurl       tests/scenario-happy-path.hurl           scenario: scenario-happy-path.hurl

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


למה זה עובד

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

במסגרת yongol, כל שכבת SSOT (Single Source of Truth) מצביעה סימבולית על שכבות אחרות:

  • @get Model.Method של SSaC → טבלת DDL
  • @auth action resource של SSaC → מדיניות הרשאות Rego
  • @state diagramID של SSaC → תרשים מצבים Mermaid
  • @call pkg.Func של SSaC → מימוש FuncSpec
  • @publish "topic" של SSaC → פונקציות שנרשמות לאותו topic
  • operationId של OpenAPI → שם קובץ SSaC
  • תרחיש Hurl → endpoint ב-OpenAPI
  • apiClient.<op>() של React TSX → operationId ב-OpenAPI

ההפניות האלה תוכננו במקור עבור yongol validate — השלב שמבצע validation צולב של 9 SSOTs לפני הקומפילציה. מכיוון ש-validate כבר מפרסר אותן, שימוש חוזר באותה תשתית הופך את חילוץ ה-feature chain למעבר על גרף.


נתיב המעבר

כשמתחילים מ-operationId, גרף ההפניות נפרס כך:

operationId (נקודת כניסה)
├── OpenAPI → path + method
├── SSaC → קובץ פונקציית שירות
│   ├── @get → טבלאות DDL
│   ├── @auth → כללי מדיניות Rego
│   ├── @state → מעברי Mermaid stateDiagram
│   ├── @call → מימושי FuncSpec
│   └── @publish → מנויי תור
├── Hurl → תרחישי בדיקה שמפנים ל-operationId
└── React TSX → קבצי frontend שקוראים ל-endpoint דרך apiClient

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


מה זה משנה

הגדרת היקף השינוי

“היכן לגעת כדי לשנות את הפיצ’ר הזה?”

כדי לענות על זה אנחנו קוראים קוד, מריצים grep, שואלים עמית. Feature Chain מחליף את השאלה בפקודה אחת. שום קובץ לא נשמט — כל עוד קיימת ההפניה הסימבולית.

עריכה מונעת AI

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

עם Feature Chain זה אחרת. תן לו operationId אחד וכל ההיקף מזוהה אוטומטית. הקונטקסט ל-AI מוכן ללא פספוסים. מכיוון ש-9 ה-SSOTs הם מפרטים דקלרטיביים — דחוסים הרבה יותר מקוד Go המיוצר — אפשר להכניס את כל השרשרת לחלון הקונטקסט בשפע.

Code review

ב-review של PR, “אם נגעו בפיצ’ר הזה, לא אמור היה להשתנות גם הקובץ ההוא?” הופך לטריוויאלי לאימות — רק להשוות מול השרשרת. חוסר עקביות בין שכבות נתפס על ידי המבנה במקום על ידי אנשים.

Onboarding

כשמפתח שרק הצטרף אומר “אני רוצה להבין איך ExecuteWorkflow עובד”, תראה לו Feature Chain אחד. מה-API ועד ה-DB, ממדיניות ההרשאות ועד תרחישי הבדיקה — כל טופוגרפיית הפיצ’ר על מסך אחד.


למה davka operationId

בחירת נקודת הכניסה חשובה. Feature Chain בחר ב-operationId.

הסיבה פשוטה. באפליקציית full-stack, יחידת פיצ’ר היא endpoint של API. המשתמש לוחץ על כפתור, API נקרא, לוגיקת השירות רצה, ה-DB נקרא, ההרשאות נבדקות, מתרחשים מעברי מצב. ההתחלה של כל הזרם הזה היא operationId.

operationId כבר מוגדר במפרט OpenAPI, והוא שם משותף לכל הצוות. תגיד “צריך לשנות את ExecuteWorkflow” — ומהנדס ה-backend, מהנדס ה-frontend וה-QA יחשבו על אותו הדבר. Feature Chain מעוצב סביב השם האוניברסלי הזה כחוט שחוצה את כל ה-stack.

yongol מכנה זאת “operationId הוא אבן הפינה (keystone)”. מזהה PascalCase יחיד קושר פיזית 9 שכבות.


תנאים מוקדמים

כדי ש-Feature Chain יעבוד, יש הנחות:

  1. המקורות חייבים להפנות סימבולית זה לזה. ההנחיות @get, @auth, @state, @call, @publish של SSaC חייבות להצביע במפורש על SSOTs אחרים. אם ההפניה משתמעת — למשל שם טבלה ב-DB שקיים רק כמחרוזת בתוך הקוד — אי אפשר לעקוב אחריה.

  2. yongol validate חייב לעבור. Feature Chain עוקב אחרי הפניות סימבוליות; אם ההפניות אינן תקפות — התוצאה שגויה. validate מבטיח את שלמות ההפניות, ו-Feature Chain עובר מעליו.

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


העתיד: GEUL + SILK

כיום, Feature Chain עובר על ידי קריאה לכל parser של SSOT בתורו. הוא קורא ל-parser של SSaC, ל-DDL, ל-Rego, ל-Mermaid, ל-Hurl ול-TSX, ואז מצרף את התוצאות.

כשכל ה-SSOTs יתורגמו לגרף GEUL, Feature Chain יהפוך לשאילתת אינדקס אחת. עם פעולת AND ברמת הביט של SIDX ב-SILK, כל הצמתים המחוברים ל-operationId יחולצו בשאילתה אחת.

ממעבר על כל parser לשאילתת גרף. הממשק של Feature Chain נשאר זהה, אך הפנים משתנה מן היסוד.


סיכום

באפליקציית full-stack, “פיצ’ר” לא חי בקובץ אחד. הוא משתרע על פני שכבות רבות, והשכבות האלה מפנות זו לזו. Feature Chain עוקב אחרי ההפניות האלה כדי לחלץ אוטומטית את ההיקף המלא של פיצ’ר אחד.

הקלד operationId אחד ותקבל הכול: ממפרט ה-API ועד סכמת ה-DB, ממדיניות ההרשאות ועד תרחישי הבדיקה, ממימוש הפונקציה ועד קומפוננטת הפרונט-אנד. עשרות קריאות grep מוחלפות בפקודה אחת. ה-AI מקבל קונטקסט ללא חוסרים; האדם מקבל חופש על פסים.

קוד: github.com/park-jun-woo/yongol