מוסכמות המוצר
1 · Accounts היא הטבלה המרכזית — לידים ולקוחות באותו מקום
Section titled “1 · Accounts היא הטבלה המרכזית — לידים ולקוחות באותו מקום”אין טבלת “לידים” נפרדת. שדה בוליאני יחיד מפריד:
IsAccount |
המשמעות |
|---|---|
false |
ליד: פנייה שעדיין לא הפכה ללקוח |
true |
לקוח |
המרה = הפיכת הדגל + חותמת ב‑LeadConversionDate (שם השדה בבסיס המוצר; אצל חלק מהלקוחות קיים במקביל ConversionDate — שלפו סכימה).
שדות שני העולמות יושבים על אותה שורה: LeadStatusId, LeadOwnerId, LeadSourceId מצד אחד; StatusId, TypeId, OwnerId מהשני. אחרי המרה משתנה התשובה לשאלה איזה שדה סטטוס משמעותי — מקור נפוץ לדוחות שגויים.
כל רשומה עסקית אחרת (Sales, Cases, Tasks, Activities, טבלאות מותאמות) מקושרת ל‑Accounts בשדה Pointer בשם AccountId. מפת הטבלאות.
2 · שמות באנגלית, ערכים בעברית
Section titled “2 · שמות באנגלית, ערכים בעברית”שמות טבלאות ושדות: PascalCase / CamelCase באנגלית. התוכן בעברית.
| המוסכמה | התבנית | דוגמאות |
|---|---|---|
| טבלאות | PascalCase, ברבים לישויות | Accounts, SaleRows, PriceQuotes, Conversations |
| מחלקות מערכת | קידומת _ (שמורה) |
_User, _Timeline, _Dictionary, _syslogTriggers |
| שדות Pointer | <Entity>Id |
AccountId, SaleStatusId, OwnerId |
| שדה תצוגה | לכל טבלת lookup וישות יש Name:String — חריג אחד במוצר: UserStatuses, עם name באות קטנה |
ברירת המחדל של כל רשימה נפתחת |
| טבלאות lookup | <Entity>Statuses · <Entity>Types · <Entity>States |
CaseStatuses, TaskTypes, CaseSubTypes, CaseStates |
| מטא‑מצב | StateId על טבלת סטטוס → טבלת *States קבועה |
CaseStatuses.StateId→CaseStates, LeadStatuses.StateId→AccountStatusesStates |
| חותמת אוטומציה | updatedByTrigger:String על כל טבלה שטריגר נוגע בה — מזהה הטריגר שכתב אחרון |
Accounts, Tasks, SaleRows |
3 · שדה Pointer מסתיים ב‑Id
Section titled “3 · שדה Pointer מסתיים ב‑Id”| השדה | הטבלה שאליה הוא מצביע |
|---|---|
AccountId |
Accounts |
ContactId |
Contacts |
SaleStatusId |
SaleStatuses |
LeadSourceId |
LeadSource |
OwnerId |
_User |
CurrentUserId |
_User |
צורת הכתיבה של Pointer בכל שכבה: סוגי נתונים.
4 · התוויות בעברית — _Dictionary
Section titled “4 · התוויות בעברית — _Dictionary”שדות אינם מגיעים עם תווית עברית מהקופסה: במערכת חדשה _Dictionary כלל אינה קיימת, ואף שדה בתשובת הסכימה אינו נושא dictionary. השכבה נולדת עם ה‑label הראשון.
כשנוצר שדה עם label (למשל דרך Add-Field-to-Table), נכתבת מיד שורה ל‑_Dictionary:
{ "tblName": "Sales", "field": "OwnerSetDate", "value": "תאריך הגדרת אחראי" }ומאותו רגע התווית חוזרת בתוך הגדרת השדה ב‑Get-Schema של שכבת ה‑MCP:
"OwnerSetDate": { "type": "Date", "dictionary": "תאריך הגדרת אחראי" }כך סוכן AI בונה טופס בעברית מהסכימה, בלי לקודד תרגומים ובלי לצאת מסנכרון כשהלקוח משנה תווית.
מעל התוויות יושב מילון המונחים, שמחליף את שם הישות המוצג (מכירה→פרויקט) ואינו נוגע בשמות הסכימה. Set-Terminology-Dictionary לבדו אינו מעדכן טקסטים שכבר יושבים בעמודים ובתפריטים (“מכירות” נשאר בתפריט); להחלפה בתוכן העמודים יש כלי נפרד, Replace-Terms, שרץ דף אחר דף. מילון מונחים.
5 · בחירה מרובה — תבנית שם מיוחדת
Section titled “5 · בחירה מרובה — תבנית שם מיוחדת”אין טיפוס “בחירה מרובה”. שם השדה הוא המטא‑דאטה:
{ "array_interests_Pointer_Interests": ["uNbbHuMGlK", "j17RjXmHdN"] }- הטיפוס בסכימה חייב להיות
Array. _Pointer_הוא ליטרל עם P גדולה; שם טבלת היעד case‑sensitive.- שגיאת אותיות (
array_x_pointer_Y) או טיפוסPointerשוברים את המנגנון בשקט: השדה נשמר בלי הרנדור הנכון. - ערך שנבחר ולא נמצא בטבלת ה‑lookup — השמיטו את השדה מהגוף, אל תשלחו מחרוזת ריקה.
צורות האחסון והתחביר לשאילתה: סוגי נתונים.
6 · רשימות תלויות — האב יושב על העמוד, לא על הסכימה
Section titled “6 · רשימות תלויות — האב יושב על העמוד, לא על הסכימה”רשימה נפתחת מסוננת לפי בחירה קודמת (מחלקה → תת‑מחלקה) עובדת בשלושה חלקים:
- טבלת הבן מחזיקה Pointer יחיד חזרה לטבלת האב.
- הטבלה המארחת מחזיקה שני שדות Pointer — אחד לאב, אחד לבן.
- ההפעלה יושבת על שדה הבן בעמוד, לא בסכימה.
לכן אותה סכימה מתנהגת כרשימה תלויה בעמוד אחד וכרשימה רגילה באחר, ומי שמסתכל רק בסכימה לא יראה את ההבדל.
7 · המוסכמות שאין להן חריגים
Section titled “7 · המוסכמות שאין להן חריגים”| הכלל | ההשלכה |
|---|---|
objectId הוא בדיוק 10 תווים |
מזהה באורך אחר בשדה table_<Field> של web2table נזרק בשקט (200 והשדה ריק); בשדה account_<Field> — ובכל כתיבה ב‑REST — הבקשה כולה נכשלת ב‑400 {"code":111,"error":"schema mismatch … expected Pointer<…> but got String"}. כלי Get-Data של MCP אוכף minLength/maxLength = 10 בסכימה |
| שם שדה אינו ניתן לשינוי | “תיקון” = שדה חדש + מיגרציה. לכן שדות עם שגיאות כתיב שורדים בייצור לנצח |
| טיפוס שדה ננעל אחרי הערך הראשון | תכננו שם וטיפוס לפני היצירה. התסמין: שדה Date/Pointer מחזיר שגיאה 111, אבל שדה String ממיר בשקט |
אין אכיפת ייחודיות על PhoneNumber / Email |
חיפוש‑לפני‑יצירה הוא באחריותכם |
| טבלה חדשה נולדת חסרת הרשאות | “השדות מופיעים ריקים” — התקלה מספר 1 אחרי הקמה |
8 · כתיבות מפעילות אוטומציות
Section titled “8 · כתיבות מפעילות אוטומציות”כל כתיבה — גם דרך Master Key, גם ב‑batch, גם מפונקציית שרת — מפעילה טריגרים מסוג data change: התראות, מיילים והודעות WhatsApp ללקוחות אמיתיים. השרשרת מוגבלת ל‑3 רמות עומק (הרשומה הרביעית בשרשרת כבר לא נוצרת, וב‑_syslogTriggers נרשם blocked! trigger step is to deep -3), אבל כל רשומה מפעילה את הרמה הראשונה.
לפני טעינה המונית תאמו עם מי שמחזיק את האוטומציות. ל‑POST /parse/batch אין דגל השתקה, ודגל skipTriggers ברמת הבקשה מתעלמים ממנו.
המשך מכאן
Section titled “המשך מכאן”- סוגי נתונים — הפורמט ב‑JSON לכל טיפוס, בשלוש השכבות
- מפת הטבלאות — לאיזו טבלה כותבים
- מילון מונחים — מהמונח של הלקוח אל שם המחלקה
- סכימות — המקור המחייב לכל מערכת
- עבודה עם רשומות — ה‑CRUD עצמו